В PHP легко передать json-объекты с помощью json_encode()
.
Однако есть ли это эквивалент XML?
JSON может выражать массивы php, целые числа, строки и т. Д. Изначально. У XML нет таких понятий – просто элементы, атрибуты и текст. Если вы хотите передать объект стенографически, используйте JSON. Если вы хотите реализовать сложный API, используйте XML, например, интерфейс php DOM .
Вы можете определить свою собственную xml_encode()
например, такую как http://darklaunch.com/2009/05/23/php-xml-encode-using-domdocument-convert-array-to-xml-json-encode
function xml_encode($mixed, $domElement=null, $DOMDocument=null) { if (is_null($DOMDocument)) { $DOMDocument =new DOMDocument; $DOMDocument->formatOutput = true; xml_encode($mixed, $DOMDocument, $DOMDocument); echo $DOMDocument->saveXML(); } else { // To cope with embedded objects if (is_object($mixed)) { $mixed = get_object_vars($mixed); } if (is_array($mixed)) { foreach ($mixed as $index => $mixedElement) { if (is_int($index)) { if ($index === 0) { $node = $domElement; } else { $node = $DOMDocument->createElement($domElement->tagName); $domElement->parentNode->appendChild($node); } } else { $plural = $DOMDocument->createElement($index); $domElement->appendChild($plural); $node = $plural; if (!(rtrim($index, 's') === $index)) { $singular = $DOMDocument->createElement(rtrim($index, 's')); $plural->appendChild($singular); $node = $singular; } } xml_encode($mixedElement, $node, $DOMDocument); } } else { $mixed = is_bool($mixed) ? ($mixed ? 'true' : 'false') : $mixed; $domElement->appendChild($DOMDocument->createTextNode($mixed)); } } }
Вы можете использовать xmlrpc_encode
.
xmlrpc_encode ($your_array);
Будьте осторожны, потому что эта функция ЭКСПЕРИМЕНТАЛЬНАЯ.
вот один для php7.0 +, я уверен, что он далеко не оптимален, код нетривиальный, и он НЕ тестировался много, но по крайней мере он работает для моих данных (в отличие от кода Сефа) …
пример:
$test = array ( 'normal1' => 'foo', 'normal2' => 'bar', 'foo_assoc' => [ 'foo', 'bar', 'baz', [ 'derp', 'derpmore' ] ], 'foo_nonassoc' => [ 'derppp' => 'yes', 'daarpp' => 'no', 'lel', 'far' => 'away' ], 'normal3' => 'lala', 'deep' => [ 'deeper' => [ 'deeper2' => [ 'deepest' => [ 'quite', 'deep', 'indeed' ], 'checkmate' ] ] ], 'special' => 'encoding<special>characters&test', 'me_n_you' => 'true' ); echo (hhb_xml_encode ( $test ));
вывод:
<normal1>foo</normal1> <normal2>bar</normal2> <foo_assoc>foo</foo_assoc> <foo_assoc>bar</foo_assoc> <foo_assoc>baz</foo_assoc> <foo_assoc>derp</foo_assoc> <foo_assoc>derpmore</foo_assoc> <foo_nonassoc> <derppp>yes</derppp> <daarpp>no</daarpp> <foo_nonassoc>lel</foo_nonassoc> <far>away</far> </foo_nonassoc> <normal3>lala</normal3> <deep> <deeper> <deeper2> <deepest>quite</deepest> <deepest>deep</deepest> <deepest>indeed</deepest> <deeper2>checkmate</deeper2> </deeper2> </deeper> </deep> <special>encoding<special>characters&test</special> <me_n_you>true</me_n_you>
function: – Edit: исправлена ошибка с кодированием пустых массивов.
function hhb_xml_encode(array $arr, string $name_for_numeric_keys = 'val'): string { if (empty ( $arr )) { // avoid having a special case for <root/> and <root></root> i guess return ''; } $is_iterable_compat = function ($v): bool { // php 7.0 compat for php7.1+'s is_itrable return is_array ( $v ) || ($v instanceof \Traversable); }; $isAssoc = function (array $arr): bool { // thanks to Mark Amery for this if (array () === $arr) return false; return array_keys ( $arr ) !== range ( 0, count ( $arr ) - 1 ); }; $endsWith = function (string $haystack, string $needle): bool { // thanks to MrHus $length = strlen ( $needle ); if ($length == 0) { return true; } return (substr ( $haystack, - $length ) === $needle); }; $formatXML = function (string $xml) use ($endsWith): string { // there seems to be a bug with formatOutput on DOMDocuments that have used importNode with $deep=true // on PHP 7.0.15... $domd = new DOMDocument ( '1.0', 'UTF-8' ); $domd->preserveWhiteSpace = false; $domd->formatOutput = true; $domd->loadXML ( '<root>' . $xml . '</root>' ); $ret = trim ( $domd->saveXML ( $domd->getElementsByTagName ( "root" )->item ( 0 ) ) ); assert ( 0 === strpos ( $ret, '<root>' ) ); assert ( $endsWith ( $ret, '</root>' ) ); $full = trim ( substr ( $ret, strlen ( '<root>' ), - strlen ( '</root>' ) ) ); $ret = ''; // ... seems each line except the first line starts with 2 ugly spaces, // presumably its the <root> element that starts with no spaces at all. foreach ( explode ( "\n", $full ) as $line ) { if (substr ( $line, 0, 2 ) === ' ') { $ret .= substr ( $line, 2 ) . "\n"; } else { $ret .= $line . "\n"; } } $ret = trim ( $ret ); return $ret; }; // $arr = new RecursiveArrayIterator ( $arr ); // $iterator = new RecursiveIteratorIterator ( $arr, RecursiveIteratorIterator::SELF_FIRST ); $iterator = $arr; $domd = new DOMDocument (); $root = $domd->createElement ( 'root' ); foreach ( $iterator as $key => $val ) { // var_dump ( $key, $val ); $ele = $domd->createElement ( is_int ( $key ) ? $name_for_numeric_keys : $key ); if (! empty ( $val ) || $val === '0') { if ($is_iterable_compat ( $val )) { $asoc = $isAssoc ( $val ); $tmp = hhb_xml_encode ( $val, is_int ( $key ) ? $name_for_numeric_keys : $key ); // var_dump ( $tmp ); // die (); $tmp = @DOMDocument::loadXML ( '<root>' . $tmp . '</root>' ); foreach ( $tmp->getElementsByTagName ( "root" )->item ( 0 )->childNodes ?? [ ] as $tmp2 ) { $tmp3 = $domd->importNode ( $tmp2, true ); if ($asoc) { $ele->appendChild ( $tmp3 ); } else { $root->appendChild ( $tmp3 ); } } unset ( $tmp, $tmp2, $tmp3 ); if (! $asoc) { // echo 'REMOVING';die(); // $ele->parentNode->removeChild($ele); continue; } } else { $ele->textContent = $val; } } $root->appendChild ( $ele ); } $domd->preserveWhiteSpace = false; $domd->formatOutput = true; $ret = trim ( $domd->saveXML ( $root ) ); assert ( 0 === strpos ( $ret, '<root>' ) ); assert ( $endsWith ( $ret, '</root>' ) ); $ret = trim ( substr ( $ret, strlen ( '<root>' ), - strlen ( '</root>' ) ) ); // seems to be a bug with formatOutput on DOMDocuments that have used importNode with $deep=true.. $ret = $formatXML ( $ret ); return $ret; }
Это работает для меня в большинстве случаев:
$str = htmlentities($str , ENT_XML1);
Документы: http://php.net/manual/en/function.htmlentities.php