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).
Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Thursday, 20 November 2014

SimpleXML and mixed, nested namespaces

I work with several third party marketplace APIs, one of which is Amazon's MWS API.
When processing their GetMatchingProductForId response I discovered that they sometimes namespace the XML nodes (with ns2).

PHP's SimpleXML doesn't allow access to namespaced nodes via the usual interface of $simpleXml->node but I found you can specify a namespace to the children() method like so:

$simpleXml
    ->children('ns2', true)
    ->namespacedNode

That works great but then I hit a problem. As I mentioned, Amazon namespace some of the nodes but not all and the node I was really after was not namespaced itself but was a child of a namespaced node. After I applied the code above I found that I couldn't access the child node:

$simpleXml
    ->children('ns2', true)
    ->namespacedNode
    ->nonNamespacedNode

I thought all was lost until I discovered you can reset SimpleXML's namespace filter back to none again with another call to children() so you can get at the non-namespaced child node:

$simpleXml
    ->children('ns2', true)
    ->namespacedNode
    ->children()
    ->nonNamespacedNode

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.

Friday, 9 April 2010

PHP-GTK Tips

I've been developing a PHP-GTK application over the past few months and have found that there are very few resources out there to help (the entire project seems a bit dead tbh..), however I have come across a few invaluable things that I thought I'd share:


php-gtk2 Cookbook: This is by far the best resource I have found. It has loads of examples and you can even look them up by widget type. It also has a help forum full of useful answers.
You have to register to see all of the code but it's free and I haven't had any spam as a result so I highly recommend it.

Official API documentation: This is a bit feeble but contains all the classes and methods (even if it doesn't explain them very well).
One thing to watch out for with this is that the class pages don't show you inherited methods (even from interfaces) so you have to read through the entire hierarchy to get the full picture.

Glade UI Designer: A handy tool for constructing interfaces for GTK. These produce an XML file which you can then read into your PHP code with the GTKBuilder class. Much nicer than having to create all of your interfaces in code.
Be wary though that it is a bit flakey (crashes sometimes) and it can only do so much for you, some of it will still need to be done in code.

When looking for other resources remember that GTK isn't specific to PHP and so you may find more results for just searching for GTK stuff.

Hope that helped!

Friday, 6 February 2009

"shell_exec(): Unable to execute"

I spent ages trying to get round this PHP warning today:

"PHP Warning: shell_exec(): Unable to execute '[any bash command]'"


I hadn't changed anything and it was working 5mins before so what was wrong?

A colleague of mine suggested restarting Apache... and it worked!
I don't fully understand why, something to do with Apache running out of resources or something. Anywho, thought it might be useful for someone.