note 101234 deleted from soapheader.soapheader by danbrown
| From: | danbrown@php.net | Date: | Sat, 04 Dec 2010 00:31:56 +0000 |
| Subject: | note 101234 deleted from soapheader.soapheader by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-174604@lists.php.net to get a copy of this message | ||
Note Submitter: Guile
----
I need to pass a lot of informations with Soap Header. So I had to perform a header parser. Here is
the code I made (that's a bit ugly but it works).
Notice that :
- There is a closure as parameter in order to remove namespaces from tag names
- It ignores the "item" tag inside xml content for array passed to SoapHeader
<?php
$h = new SoapHeader('main', 'myArray',
array('key1'=>'value1', 'key2'=>'value2'));
?>
will result the following xml extract :
<env:Header>
<ns2:myArray>
<item>
<key>key1</key>
<value>value1</value>
</item>
<item>
<key>key2</key>
<value>value2</value>
</item>
</ns2:myArray>
</env:Header>
- didn't test yet for every cases (so can be improve)
- it is a little inspire from http://www.bin-co.com/php/scripts/xml2array/
but the result with their solution is not so good with the use of Soap Headers
<?php
/**
*
* @param string $content XML content
* @param callback $tagRenameCallback function to call that can change the tag name (ie Remove
namespace)
* @return array XML Content structure in a PHP array
*/
function xml2array(&$content, $tagRenameCallback = null) {
$result = array();
if (empty($content)) {
return $result;
}
$content = trim($content);
if (!function_exists('xml_parser_create')) {
throw new Exception('Cannot parse SOAP input header : xml_parser_create function not
found');
return $result;
}
//Get the XML parser of PHP - PHP must have this module for the parser to work
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($parser, $content, $xml_values);
xml_parser_free($parser);
if (empty($xml_values)) {
return $result;
}
$currentindex = 0;
$max = count($xml_values);
$backpath = array();
$current = &$result;
$bInItem = false;
$currentItem = '';
$level = -1;
while ($currentindex < $max) {
$val = &$xml_values[$currentindex];
$sTagName = $val['tag'];
if (!empty($tagRenameCallback) && is_callable($tagRenameCallback)) {
$sTagName = $tagRenameCallback($sTagName);
}
$sLowerCaseTagName = strtolower($sTagName);
if ($sLowerCaseTagName == 'item' && $val['type'] !=
'complete') {
$bInItem = !$bInItem;
} elseif ($val['type'] == 'open') {
$current[$sTagName] = array();
$level++;
$backpath[$level] = &$current;
$current = &$current[$sTagName];
$currentVal = null;
$currentItem = null;
} elseif ($val['type'] == 'close') {
$current = &$backpath[$level];
$level--;
} elseif ($val['type'] == 'complete') {
if ($bInItem) {
if ($sLowerCaseTagName == 'key') {
if (empty($val['value'])) {
throw new Exception('Unexpected empty xml tag in header');
} else {
$currentItem = $val['value'];
}
} elseif ($sLowerCaseTagName == 'value') {
if (!empty($val['value'])) {
$currentVal = $val['value'];
} else {
$currentVal = '';
}
} else {
throw new Exception('Unhandled xml tag inside ITEM tag : ' . $sLowerCaseTagName);
}
if (!is_null($currentItem) && !is_null($currentVal)) {
$current[$currentItem] = $currentVal;
$currentVal = null;
$currentItem = null;
}
} else {
$current[$sTagName] = $val['value'];
}
} else {
throw new Exception('Unhandled xml tag type : ' . $val['type']);
}
$currentindex++;
}
return $result;
}
// Get the SOAP Request XML Content
$strRequest = file_get_contents("php://input");
// Verify if there is a header tag in the xml content
// The following regular expression is compatible with any namespace you gave
if (preg_match('/<[^:\/]*:Header>.*<\/[^:]*:Header>/imsU', $strRequest,
$matches) > 0) {
$arrayHeader = self::xml2array($matches[0], function ($str) {
return preg_replace('/^([^:]*:)/', '', $str);
}));
}
?>