Intereting Posts
PHP FPM возвращает HTTP 500 для всех ошибок PHP Безопасный способ отображения адреса электронной почты и номера контакта Можно ли отключить переменную сеанса с определенным и переменным индексом? как получить дату вчера, используя php? Неустранимая ошибка: вызов неопределенной функции array_replace_recursive () для решения CI Controller При использовании Kohana DB, как избежать дублирования кода при необходимости подсчета для разбивки на страницы? Сообщение класса 'Facebook' не найдено Symfony & FOSUserBundle: 3 разных профиля, в зависимости от роли INET_ATON () и INET_NTOA () в PHP? Как загрузить изображение из приложения Android на веб-сервер в определенную папку PHP показывает вывод foreach на экран, для каждого элемента Используйте ширину DIV в инструкции If в файле Php как отправлять данные JSON с Android на php url? Попытка подключить две базы данных к файлу php и сохранить сеанс пользователя Как создать запрос в Drupal 8

Обоснование обработки текстовыми значениями SimpleXMLElement в addChild и addAttribute

Разве это не противоречивое поведение? (PHP 5.2.6)

<?php $a = new SimpleXMLElement('<a/>'); $a->addAttribute('b', 'One & Two'); //$a->addChild('c', 'Three & Four'); -- results in "unterminated entity reference" warning! $a->addChild('c', 'Three &amp; Four'); $a->d = 'Five & Six'; print($a->asXML()); 

Оказывает:

 <?xml version="1.0"?> <ab="One &amp; Two"> <c>Three &amp; Four</c> <d>Five &amp; Six</d> </a> 

На bugs.php.net они отвергают все представления об этом, говоря, что это особенность. Почему это возможно? Кстати, в документах ничего не говорится об этом несоответствии экранировки текстовых значений SimpleXMLElement.

Может ли кто-нибудь убедить меня, что это лучшее решение для проектирования API?

Solutions Collecting From Web of "Обоснование обработки текстовыми значениями SimpleXMLElement в addChild и addAttribute"

Чтобы убедиться, что мы на одной странице, у вас есть три ситуации.

  1. Вставка амперсанда в атрибут с помощью addAttribute

  2. Вставка амперсанда в элемент с помощью addChild

  3. Вставка амперсанда в элемент путем перегрузки свойств

Это несоответствие между 2 и 3, которое вас смущает. Почему addChild не автоматически выходит из амперсанда, тогда как добавление свойства к объекту и установка его значения автоматически исчезают из амперсанда?

Основываясь на моих инстинктах и ​​поддерживая эту ошибку , это было продуманное дизайнерское решение. Перегрузка свойств ($ a-> d = 'Five & Six';) предназначена для того, чтобы делать «ускорение для меня». Метод addChild предназначен для добавления метода «добавить то, что я говорю вам добавить». Итак, какое бы поведение вам ни понадобилось, SimpleXML может вас устраивать.

Допустим, у вас была база данных с текстом, где все амперсанды уже сбежали. Для вас здесь не работает автоматическое экранирование. Здесь вы можете использовать addChild. Или предположим, что вам нужно вставить объект в документ

 $a = simplexml_load_string('<root></root>'); $a->b = 'This is a non-breaking space &nbsp;'; $a->addChild('c','This is a non-breaking space &nbsp;'); print $a->asXML(); 

Это то, о чем говорит разработчик PHP в этой ошибке. Поведение addChild предназначено для предоставления «менее простой и надежной» поддержки, когда вам нужно вставить амперсанд в документ без его экранирования.

Конечно, это оставляет нам первую ситуацию, о которой я упоминал, метод addAttribute. Метод addAttribute позволяет избежать амперсандов. Итак, теперь мы можем указать несогласованность как

  1. Метод addAttribute ускоряет амперсанды
  2. Метод addChild не избегает амперсандов
  3. Такое поведение несколько противоречиво. Разумно, что пользователь будет ожидать, что методы на SimpleXML будут избегать вещей согласованным образом

Тогда это создает реальную проблему с SimpleXML api. Идеальная ситуация здесь была бы

  1. Перегрузка объектов на элементах объектов ускоряет амперсанды
  2. Перегрузка свойств объектов атрибутов ускоряет амперсанды
  3. Метод addChild не избегает амперсандов
  4. метод addAttribute не избегает амперсандов

Это невозможно, потому что SimpleXML не имеет понятия об объекте атрибута. Метод addAttribute является (как представляется,?) Единственным способом добавления атрибута. Из-за этого получается (кажется?) SimpleXML в неспособности создавать атрибуты с сущностями.

Все это показывает парадокс Simple XML. Идея этого API заключалась в том, чтобы обеспечить простой способ взаимодействия с чем-то, что оказывается сложным.

Команда могла бы добавить объект SimpleXMLAttribute, но это дополнительный уровень сложности. Если вам нужна иерархия нескольких объектов, используйте DomDoument.

Команда могла добавлять флаги к методам addAttribute и addChild, но флаги делают API более сложным.

Настоящий урок здесь? Может быть, это просто, трудно, и простой в крайнем сроке еще сложнее. Я не знаю, было ли это так или нет, но с SimpleXML кажется, что кто-то начал с простой идеи (используйте перегрузку свойств, чтобы упростить создание XML-документов), а затем скорректировали с учетом запросов проблем / функций ,

На самом деле, я считаю, что настоящим уроком является просто использование JSON;)

Это мое решение, особенно это решает добавить несколько дочерних элементов с тем же именем тега

 $job->addChild('industrycode')->{0} = $entry1; $job->addChild('industrycode')->{0} = $entry2; $job->addChild('industrycode')->{0} = $entry3; 

«Скажем, у вас была база данных с текстом, где все амперсанды уже сбежали».

Если вы делаете это, вы делаете это неправильно. Данные должны храниться в его наиболее точной форме, а не обрабатываться для любого типа вывода, который вы в настоящее время используете. Это еще хуже, если вы фактически храните в базе данных blobs (действительный) HTML. Использование addChild () и захват данных снова приведет к уничтожению вашего HTML; никакая разумная библиотека не демонстрирует такую ​​ужасную асимметрию.

addChild (), не кодирующий ваш текст для вас, полностью противоречит интуиции. Какой смысл в API, который не защищает вас от этого? Это похоже на json_encode () barfing, если вы используете двойную кавычку в одном из ваших значений.

В любом случае, чтобы ответить на исходный вопрос: Очевидно, я тоже считаю, что это нехорошее решение. Я действительно думаю, что это согласуется с множеством дизайнерских решений PHP, которые должны выполнять чью-то идею о том, что «быстрее», а не быть правильным.

Требование об экранировании символов & и < указано в разделе « Символьные данные и разметка», а не в разделе «Нормализация атрибутов», как указано в предыдущем ответе .

Процитировать XML Spec . :

«Символ амперсанда (&) и левая угловая скобка (<) НЕ ДОЛЖНЫ появляться в их литеральной форме, за исключением случаев, когда они используются в качестве разделителей разметки или в комментарии, инструкции обработки или секции CDATA. Если они необходимы в другом месте, они ДОЛЖНЫ быть экранированы с использованием либо числовых символьных ссылок, либо строк &amp; и &lt; соответственно "

У Алана Шторма было хорошее описание проблемы, но есть легкое решение парадокса, которое он описывает. Метод addChild () может иметь необязательный логический параметр, определяющий, следует ли автоматически выводить символы. Итак, я все еще убежден, что это просто (очень) плохой выбор дизайна.

Путаница усугубляется тем фактом, что документация для метода addChild () не делает никакой ссылки, поэтому проблема (хотя есть в обсуждении). Кроме того, метод избегает некоторых символов (а именно, меньше и больше знаков). Это приведет к заблуждению разработчиков, использующих метод, чтобы полагать, что он избегает символов в целом.

Я считаю, что это вызвано нормализацией атрибутов, требуемой спецификацией XML.