Что касается самого SimpleXML, то это внутренний класс. Единственный интерфейс, который он реализует для пользовательского пространства PHP, это Traversable
.
Внутренне, когда к нему обращаются в квадратных скобках, SimpleXML ищет вещи в зависимости от значения и типа индекса / ключа.
Если тип является целочисленным (длинным), он пытается найти нумерованный элемент с нулевым индексом и предложить его значение. Если у вас есть конкретный элемент узла, например $root
для корневого элемента, $root[0]
будет представлять значение этого элемента:
$root = new SimpleXMLElement('<root a="vala"></root>');
$root[0] = 'hello';
# <root a="vala">hello</root>
# ^^^^^- changed value
Корневой элемент немного неинтересен, потому что существует только один. Это более интересно с элементами, у которых есть родители.
$root = new SimpleXMLElement('<root a="vala"><child /></root>');
$root->child[0] = 'hello';
# <root a="vala"><child>hello</child></root>
# ^^^^^- changed value
Устанавливает значение узла первого child
элемента. Индекс up-one добавит нового потомка:
$root = new SimpleXMLElement('<root a="vala"><child /></root>');
$root->child[1] = 'hello';
# <root a="vala"><child/><child>hello</child></root>
# ^-- added child --^
Это в значительной степени работает как с массивами. Строки, которые являются целым числом, работают как целое число:
$root->child['1'] = 'hello';
# <root a="vala"><child/><child>hello</child></root>
# ^-- added child --^
И, оставив скобки пустыми, в конце добавим новый элемент:
$root->child[] = 'hello';
$root->child[] = 'world';
# <root a="vala"><child/><child>hello</child><child>world</child></root>
Пока что для целых чисел и смещения "нет". Как и в случае стандартного массива PHP, его не следует путать с передачей NULL
. Это будет преобразовано в пустую строку ""
.
Для любой строки SimpleXML будет искать узел атрибута вместо узла дочернего элемента:
$root = new SimpleXMLElement('<root a="vala"></root>');
echo $root['a'], "\n"; # vala
Это также работает для добавления атрибутов:
$root = new SimpleXMLElement('<root a="vala"></root>');
$root['b'] = 'hello'; # <root a="vala" b="hello"/>
В граничном регистре используется пустая строка (""
) или NULL
, поскольку simplexml выдает ошибку, говоря, что атрибут без имени недопустим. Имеет смысл, так как атрибуты должны иметь имя:
Предупреждение: main (): невозможно записать или создать безымянный атрибут в ...
Еще один особый случай - поддержка магического метода __toString
. Если вы передадите объект как смещение, SimpleXML попытается преобразовать его в строку с помощью магического метода. Затем он будет использовать возвращенную строку, как описано выше.
Подводя итог: Класс SimpleXMLElement
не реализует интерфейс ArrayAccess
, но, поскольку это внутренний класс, он может добавить поведение, подобное массиву. И SimpleXML делает именно это.
Функция полезности в источниках PHP называется sxe_prop_dim_read
.
А что, если вы хотите сделать что-то похожее с вашими классами?
Для этого и нужен интерфейс ArrayAccess
. Реализуйте это в ваших собственных классах. PHP уже берет на себя часть внутренней работы, чтобы сделать смещения более массивными: integer stay integer; Строка, такая как целое число, преобразуется в целое число, а логические значения преобразуются в целое число.
Однако ArrayAccess
допускает больше, чем стандартный массив: допустимыми смещениями являются числа с плавающей запятой, NULL, массивы и объекты.
Особенно с NULL
, вы не можете отличаться между установкой смещения NULL
или установкой нового элемента - оба случая предоставят NULL
как смещение.
Пример реализации интерфейса доступен с другим вопросом: PHP, SPL, интерфейс ArrayAccess .