The built-in PHP
extension for SOAP
doesn't validate everything in the incoming SOAP
request against the XML Schema
in the WSDL
. It does check for the existence of basic entities, but when you have something complicated like simpleType
restrictions the extension pretty much ignores their existence.
What is the best way to validate the SOAP
request against XML Schema
contained in the WSDL
?
Using native SoapServer PHP is a little bit tricky but is possible too:
function validate(string $xmlEnvelope, string $wsdl) : ?array{
libxml_use_internal_errors(true);
//extracting schema from WSDL
$xml = new DOMDocument();
$wsdl_string = file_get_contents($wsdl);
//extracting namespaces from WSDL
$outer = new SimpleXMLElement($wsdl_string);
$wsdl_namespaces = $outer->getDocNamespaces();
//extracting the schema tag inside WSDL
$xml->loadXML($wsdl_string);
$xpath = new DOMXPath($xml);
$xpath->registerNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
$schemaNode = $xpath->evaluate('//xsd:schema');
$schemaXML = "";
foreach ($schemaNode as $node) {
//add namespaces from WSDL to schema
foreach($wsdl_namespaces as $prefix => $ns){
$node->setAttribute("xmlns:$prefix", $ns);
}
$schemaXML .= simplexml_import_dom($node)
->asXML();
}
//capturing de XML envelope
$xml = new DOMDocument();
$xml->loadXML($xmlEnvelope);
//extracting namespaces from soap Envelope
$outer = new SimpleXMLElement($xmlEnvelope);
$envelope_namespaces = $outer->getDocNamespaces();
$xpath = new DOMXPath($xml);
$xpath->registerNamespace('soapEnv', 'http://schemas.xmlsoap.org/soap/envelope/');
$envelopeBody = $xpath->evaluate('//soapEnv:Body/*[1]');
$envelopeBodyXML = "";
foreach ($envelopeBody as $node) {
//add namespaces from envelope to the body content
foreach($envelope_namespaces as $prefix => $ns){
$node->setAttribute("xmlns:$prefix", $ns);
}
$envelopeBodyXML .= simplexml_import_dom($node)
->asXML();
}
$doc = new DOMDocument();
$doc->loadXML($envelopeBodyXML); // load xml
$is_valid_xml = $doc->schemaValidateSource($schemaXML); // path to xsd file
return libxml_get_errors();
}
and inside your SoapServer function implementation:
function myFunction($param) {
$xmlEnvelope = file_get_contents("php://input");
$errors = validate($xmlEnvelope, $wsdl);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With