TLDR: все несколько сложнее чем вам бы хотелось - универсальные списки и инфоблоки не совсем одно и то же (хоть одно и является производным другого).
Для начала вам нужно получить само свойство из PROPERTY_VALUES, а потом понять с каким сохранением (админка/API/публичная) вы имеете дело и после этого уже пылесосить значения.
подскажите что не так, ? может в php 8 какойто бздык ?
Нет, не "бздык", а особенности работы механизма.
Давайте разберемся что такое PROPERTY_VALUES - это ассоциативный массив значений пользовательских полей.
Ключами в нем могут выступать ЛИБО идентификаторы свойств ЛИБО их код (но не одновременно!).
Т.е.
"PROPERTY_VALUES" => [
64 => [
99 => [
'VALUE' => "str2"
]
]
],
И
"PROPERTY_VALUES" => [
"STR" => [
99 => [
'VALUE' => "str2"
]
]
],
При условии что 64 - это идентификатор свойства инфоблока с кодом STR эти два фрагмента равнозначны.
Теперь кода мы поняли что такое PROPERTY_VALUES, давайте разберем одно свойство (у меня это "STR"):
"STR" => [
99 => [
'VALUE' => "str2"
]
]
Поскольку универсальный список это дефакто расширение инфоблоков, то они так же максимально универсальный и одной из этих "универсальных" возможностей является переключение типа множственности свойств.
В указанном примере не смотря на то что поле ID:64 с кодом "STR" не множественное мы все равно передаем ассоциативный массив, причем ключами могут быть как числа (например 1, 2, 30, 3465 и т.п.), так и составные значения (n0, n1, n2, ... или вообще пустая строка). Если передано число то это идентификатор сохраненного значения в таблице свойств, а если это составное значение с префиксом, то это еще не добавленный в таблицу элемент. Это определяет поведение которое будет заложено в значение.
Например:
"STR" => [
99 => [
'VALUE' => "str2"
]
]
Это изменение свойства с кодом "STR", которое хранится в таблице значений свойств с ID:99 на "str2".
А вот фрагмент:
"STR" => [
"n0" => [
'VALUE' => "str2"
]
]
Означает что у элемента в значение свойства "STR" нужно добавить новый элемент со значением "str2", т.е. создать.
Для можнственных полей это можно комбинировать, например:
"STR" => [
99 => [
'VALUE' => "str2"
],
'n0' => [
'VALUE' => "str2"
]
]
Это означает что значение которое хранится в ID:99 для поля STR будет заменено на "str2" И будет добавлено еще одно значение "str2".
Ну и наконец перейдем к самому значению, которое хранится в ключе:
[
'VALUE' => "str2"
]
В битриксе значением всегда является пара - VALUE и DESCRIPTION, причем ключ DESCRIPTION опционален, но это решало бы много проблем, если бы не одна особенность - не все поля подразумевают такой вид и некоторые хранят список значений.
Например, обратите внимание как хранятся пользовательское свойство строка (множественное) и пользовательское свойство привязка к элементам CRM (множественная):
[
"STR" => [
99 => [
"VALUE" => "123123",
],
100 => [
"VALUE" => "123321",
"DESCRIPTION" => "abc"
],
"n0" => [
"VALUE" => ""
]
],
"CRM_LINK" => [
"C_1",
"L_1",
"L_3",
]
]
Как видите сильно по-разному, значит и природа поля тоже будет играть важную роль.
Или вот например, два равнозначных момента:
"STR" => [
'n1' => [
'VALUE' => "str2"
]
]
"STR" => [
'n1' => [
'VALUE' => "str2",
"DESCRIPTION" => ""
]
]
Соответственно чтобы вам правильно работать необходимо сначала получить значение поля по коду, а потом понять с чем вы имеете дело.