PHP Handling SimpleXMLElement Errors

  • devilwood
  • Silver Member
  • Silver Member
  • User avatar
  • Posts: 437

Post 3+ Months Ago

I'm writing a simple API to interface with my system. The first task I want my server script to do is verify the XML structure. I'm not sure if defining a xsd or schema is what I need to do as that seems to just define keys and fieldtypes.

My problem is that I use PHP to read the XML string that is being submitted and using strpos to check for the proper tags. This would work if I only had one type of XML call to my server script. However, I have a few and I define the call in the XML <call>UPDATE</call>. So, if I get an UPDATE call then I know there would be some required tags I would need to look for. So, I have to first pull the <call> tag out which requires me to start parsing the XML prematurely.

Code: [ Select ]
$api = new SimpleXMLElement( $xml );
$call = $api->call; // this value would be UPDATE
  1. $api = new SimpleXMLElement( $xml );
  2. $call = $api->call; // this value would be UPDATE


The problem is when I create the SimpleXMLElement object on malformed XML I get a Fatal Error.

Code: [ Select ]
Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML'


My first thought was to suppress the error and then send back a custom error to the user who obviously sent in malformed XML. I used

Code: [ Select ]
libxml_use_internal_errors(true);


This still doesn't suppress the fatal error.

I need a way to send a error to the user or another way to get the <call> value from the XML request without parsing it with SimplXMLElement.
Right now, the API client sends the XML request with the <call> tag via cURL. The headers contain POST, content-type, and content-length. Is there a way maybe I can modify the header to contain the specific call that I can retrieve on my API server script?
  • joebert
  • Fart Bubbles
  • Genius
  • User avatar
  • Posts: 13504
  • Loc: Florida

Post 3+ Months Ago

Try/Catch ?

http://php.net/manual/en/language.exceptions.php
  • spork
  • Brewmaster
  • Silver Member
  • User avatar
  • Posts: 6254
  • Loc: Seattle, WA

Post 3+ Months Ago

Ew. Don't do manual XML parsing/validation. If you're working with DOM documents use this:

http://php.net/manual/en/domdocument.schemavalidate.php

Otherwise, use whatever appropriate library PHP provides. Here's a quick search (Google link provided for convenience, not to be snarky).
  • devilwood
  • Silver Member
  • Silver Member
  • User avatar
  • Posts: 437

Post 3+ Months Ago

Right, I looked at building a validation using the xsd but it seemed overkill because I'm not sure how that validation works with different request XML. For instance, a user may call UPDATE in the request XML. The XML may look like this:

Code: [ Select ]

<api>
<call>UPDATE</call>
<apptoken>MD5</apptoken>
<recordid>30294</recordid>
</api>
  1. <api>
  2. <call>UPDATE</call>
  3. <apptoken>MD5</apptoken>
  4. <recordid>30294</recordid>
  5. </api>


Of course, all calls I would check that <apptoken> element was included and in the case of an UPDATE call I would require that <recordid> be set. Otherwise, I throw an XML response error letting the user know they submitted malformed XML and must include a <recordid> tag. However, if the call is READ then a specific <recordid> is optional my api server will not error if that tag is missing because if the <recordid> tag is missing on a READ call then it will just default to read everything which is fine.

I would guess I would need an xsd for each call?? like UPDATE.xsd but I would still need the call in the cURL request in order to load the proper .xsd. Also, I'm not sure how I build specific, custom errors with the xsd validator. I figure catch would come into play here as well.

I think catch is what I'm looking for. If it will stop the exception and allow me to send a custom error back to the user then I should be good to go until I get more time to look more at validating through xsd. Thanks for the Google Search, I had already gone to the first 5 results. However, going back to the second result made me remember that I was going to use that tutorial but I had still ran into the same issue of being able to use a specific schema based on the incoming request XML.

Is it possible to add a custom header in my cURL request like:

Code: [ Select ]

            $headers = array(
                "POST".$url,
                "Content-Type: application/xml;",
                "Content-Length: ".$content_length,
                "Call: ".$call
            );
  1.             $headers = array(
  2.                 "POST".$url,
  3.                 "Content-Type: application/xml;",
  4.                 "Content-Length: ".$content_length,
  5.                 "Call: ".$call
  6.             );


And then retrieve on the server api with:

Code: [ Select ]

$headers = apache_request_headers();
$call = $headers['Call'];
  1. $headers = apache_request_headers();
  2. $call = $headers['Call'];



I could then feed the call into my api class which could then load the xsd schema needed to validate. Any problems or pitfalls with this course?

Post Information

  • Total Posts in this topic: 4 posts
  • Users browsing this forum: No registered users and 52 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.