Tips and tricks for LAMP (Linux Apache MySQL PHP) developers.

When I cant find a suitable solution to a problem and have to work it out for myself I'll post the result here so hopefully others will find it useful. (All code is offered in good faith. It may not be the best solution, just a solution).

Monday, 25 February 2013

SimpleXML and large files

I encountered an issue earlier today whilst trying to process a fairly large (~37MB) XML file through SimpleXML.

It worked just fine on mine and a colleague's development systems but failed with weird errors on the live server, for instance reporting there was "Extra content at the end of the document".

After about an hour of trying to figure it out we realised our dev systems were using libxml v2.6.x and the live server was using 2.7.6. We then read that somewhere between those versions some hard-coded limits were added in that can cause the problem we were seeing.

To get around it you need to specify the LIBXML_PARSEHUGE flag:

$simplexml = simplexml_load_file($file_path, 'SimpleXMLElement', LIBXML_PARSEHUGE);
//OR
$simplexml = new SimpleXMLElement($xml_string, LIBXML_PARSEHUGE);

Saturday, 9 February 2013

Documentation using ApiGen and Swagger UI

At work we're writing an API and an SDK that'll talk to that API. We hope to one day make this SDK available to third parties and so we wanted to ensure there was good documentation for it.

I suggested early on that the code itself should be where we write the documentation (in DocBlocks) and then generate external documentation from there. That way both the code and the documentation are complete and consistent with each other.

This suggested the use of something like PHPDocumentor but that's a little long-in-the-tooth and produces rather dry-looking documentation (in our opinion). ApiGen is similar to PHPDoc but is a bit more modern with support for namespaces, traits, etc but still just produces boring HTML by default.

My boss had encountered Swagger UI which is a collection of JavaScript and CSS files that render nice looking docs. The problem is that Swagger is designed specifically for RESTful APIs, not PHP SDKs.

I looked into it though and found at least a partial solution:
ApiGen allow you to write your own templates (PHPDoc also has this) and the input to Swagger UI is just a collection of JSON files and so we decided to write ApiGen templates that produced Swagger UI JSON.

Swagger UI needs an 'index' JSON file that defines what APIs are available and then a JSON file for each of those APIs. In our case we had a file per Class in the SDK. In each of the Class JSON files you then define the (public) methods.

The spec for Swagger UI JSON files is here:

ApiGen templates use Nette Framework Latte Templates: http://doc.nette.org/en/templating

We wrote an overview.latte file that loops all the classes and enumerates them and a class.latte file that loops all the methods of a class and details those.

I said this was a partial solution - we have got all this working nicely but Swagger UI still looks like it's describing a RESTful interface. For example: for every method we defined we had to say whether it was GET, PUT or POST which obviously isn't relevant. That said you can edit the Swagger JavaScript to do whatever you want so you can change things like the above.