Cameron's Thoughts
Archives
Programming

PHP and the Lack of Named Parameters

When using PHP, one issue I've had for a while is figuring out a way to map API input parameters to methods in my code.



For instance, I have an API for John VanOrange that allows anyone to access most of the site's functionality. The public API methods all map to classes and functions inside those classes. Each of these methods allow for various parameters to be passed into them.



Here is an example; let's say you want to add a tag to an image. This requires two parameters, 'name' and 'image'. Using Jquery, the call would look like this:







My issue has been, how do I allow users to easily define the parameters of these methods?



Why is this complicated? PHP doesn't have named parameters. This means that when passing parameters to a function, you must have the parameters be in a specified order. This is needlessly complicated for some end user that doesn't know, and shouldn't have to know, the internal working of the API method. In the previous example, without named parameters, I would have to require the user to pass the tag and the image in a specific order, and there would be no rhyme or reason for it.



How have I been solving this problem? Up until now, all the methods used with the public API had one single parameter, an array. My interface for the public API would convert the request to an associative array and pass any and all the parameters into that array.



Example:







This has a TON of downsides. This means that I then have to write code to check for required elements in that array. I also have to write code to define default values for array elements. It also means that writing usable PHP DocBlocks are out of the question. Plus, editors are not able to auto-complete variables. I imagine there may be some security concerns as well, but in general, the whole concept is a big no-no.





I figured there had to be a better way. There is call_user_func and call_user_func_array functions that allows calling functions passing the parameters if they are in an array. But, again, that requires an indexed array that already knows what order the parameters need to be in. What I really need is a call_user_func_assoc_array that maps an associative array to the parameters within a function. But, alas, that doesn't exist.



There is hope however. PHP 5 introduced the Reflection API. Honestly, I'm not that familiar with it, but after reading up on it, I learned it could solve my problem.







What all is that doing? It's creating a ReflectionClass object that has details of the ins and out of the class we need to call. Then, you create a ReflectionMethod object that has the details of the specific method we need access to. Then, we can query the parameters of that method. After that, it's as simple as a foreach loop to go through all the expected parameters of that method, and match any that are in the associative array that came from the public API. Finally, we use invokeArgs to call the method.



I imagine this code could be cleaned up a bit. But, so far, this is doing exactly what I needed and I've been able to clean up all my code and remove all the arrays as function parameters.