PHP Itch to Scratch: Object Notation

Marco Tabini, co-founder of php|architect and Blue Palabora, posed an interesting topic: Is PHP running out of itches to scratch?

I think it’s fair to say that the pace at which PHP core is being developed has slowed down considerably over the past couple of years, while the development of many projects based on it, like programming and application frameworks, has sped up and continues to grow at a fast pace.

He goes on to point out some of the reasons for the slow down of development for the PHP Core. But at the end, he states it ultimately boils down to find a better way to bring features build downstream back upstream.

The risk facing us, as I see it, is not that Drupal, or WordPress, or whoever may decide to fork PHP or abandon it altogether. Rather, the problem is that there is no real way for these projects to provide upstream positive feedback to PHP core.

As I pointed out that the meeting that Cal references (I was the instigator of the discussion), core developers can’t improve PHP if they don’t know what needs improving, and downstream developers are forced to resort to needlessly duplicate functionality that they could instead feed into and pull out of core. This, in turn, would enable the latter to focus on what really makes their projects unique and make the whole PHP ecosystem better in the process.

So I thought I would do my part by first my blogging about a few “itches” I’d love to see scratched. My first itch would be some form of Object Notation for PHP.

JavaScript Object Notation

One of the great features of JavaScript has been it’s Object Notation, which has spread across other platforms in the form of JSON. What makes it so nice is you can quickly pass basic objects in your code in a very OOP fashion. My favorite use is for passing settings to a given function. In the jQuery library, you can do the following:

[javascript]
var url = ‘/example/ajax/url’;
// You can use the short hand $ variable, or you can use the full jQuery variable.
jQuery.ajax(url, { success: function(data){ alert(data); }, cache: true });
[/javascript]

Now, if you look at the ajax function documentation, you will see it has as of this posting 33 different options. All of them are defaulted one way or another, and so you only need to pass exactly what you’d like. On the function declaration side, it has something similar to this:

[javascript]
jQuery.ajax = function(url, settings)
{
var defaults = { cached: false, success: null, error: null /* … declare / build defaults */ };
settings.extend(defaults);

/* Continue Execution */
}
[/javascript]

What this allows is as more settings are required, the default can be set and code already implementing this function will continue to work normally. So a developer can easily override a setting, and pass only the parameters they need, with few keystrokes.

The Current PHP Way

With PHP, you only really have two options: first, is to use many arguments, and second, use an array. While they can get the job done, it isn’t as graceful.

Function / Method Arguments

If you use arguments, you might have a basic function or method that starts off with three arguments:

[php]
class Telephone
{
public function CallPerson($name, $number, $onAnswer)
{
/* … continue execution … */
}
}
[/php]

However, lets say as the project moves on, more methods are added to give more granular control over “calling a person.”

[php]
class Telephone
{
public function CallPerson($name, $number, $onAnswer, $redial = false, $redailAttempts = 3, $onBusySignal = null, $logConversation = null, $seeWhatIMean = ‘I hope so.’)
{
/* … continue execution … */
}
}
[/php]

It can become very difficult to manage. Also, if I want to set an anonymous function for $onBusySignal, but keep the defaults for $redial and $redialAttempts, I have to go to the declaration and see what their defaults are. Later, if I want to change the defaults, I have to go back through my code and see where I had to pass extra default arguments just to set an argument that was further down the line.

Using Arrays for Settings

While this is a much better approach for functions that will had many settings, it isn’t as clean or nice to implement. Using the same example of our class Telephone and CallPerson method:

[php]
class Telephone
{
public function CallPerson($name, $number, $settings)
{
$defaults = array(“onAnswer” => null, “redial” => false, “redialAttempts” => 3, “onBusySignal” => null, “logConversation” => null);
$settings = array_merge($defaults, $settings);

/* … continue execution … */

if($settings[“redial”] == true)
{
/* do something special */
}

/* … continue execution … */
}
}
[/php]

Now, one issue you’ll run into is using Arrays is more keystrokes. Not only do you have the 6 key strokes for declaring “array(” but each key is wrapped in a set of quotes, the “=>” linking between key and value is two key strokes instead of 1 for “:” in JavaScript. While others might not find it as big of a deal, it is amazing how much of an impact that can make on someone. Especially if this method will be used commonly among the application. A developer might put off implementing an array for settings and use arguments for more and more granular, until they end up with a situation like our first example.

You run into the same problems while passing settings to the method:

[php]
$telephone = new Telephone();
$telephone->CallPerson(‘Marco’, ‘437-555-3920’, array(“redial” => true
, “redialAttempts” => 10
, “onBusySignal” = function($tel){ /* code to spam Marco with twitter messages to get off the phone */}));
[/php]

Also, another thing with Arrays in PHP they do not pass by reference, but by value. So if you had some code to check validity of your settings and make changes, it won’t pass them back unless you explicitly pass by reference.

Proposed PHP Object Notation Example

Now, what I would love to see is the following:

[php]
$telephone = new Telephone();
$telephone->CallPerson(‘Marco’, ‘437-555-3920’, { redial: true, redialAttempts: 10, onBusySignal: function(){ /* code */} });
[/php]

Now, to keep with conventions, I would think it a good option to use “=>” instead of “:”, since “:” isn’t used anywhere else in PHP in this fashion. But with the prevalence of JSON, I think people would understand “:” easily knowing they were dealing with object notation.

I would expect the code above to perform the same as if I did the following:

[php]
$settings = new stdClass();
$settings->redial = true;
$settings->redialAttempts = 10;
$settings->onBusySignal = function(tel) { /* code here */ };
$telephone = new Telephone();
$telephone->CallPerson(‘Marco’, ‘437-555-3920’, $settings);
[/php]

Once again, I realize it is possible to achieve the same effect by either using an array or an object like above. My biggest reason for my suggestion is it is convient for the developer. With the new anonymous (lambda) functions in PHP 5.3, I think this would be another nice thing to open up patterns in programming that would just be easier to use.

My two cents on an itch I’d like to see scratched. As always, there might be things I’m overlooking that either a) provide functionality a lot closer to what I want that I know about, or b) challenges into implementing an object notation into PHP. But I do believe if it were possible, it would be very convenient for developers using PHP. So let me know your thoughts.

5 thoughts on “PHP Itch to Scratch: Object Notation

  1. What you are talking about is named parameters. This is something that I and plenty of others have requested be supported in PHP for many, many years.

    It was specifically talked about and rejected back in 2005: http://www.php.net/~derick/meeting-notes.html#named-parameters

    Like

  2. Your array example demonstrates a perfectly good and accepted way to do what you want. I don’t think significant changes/additions to the language syntax to save a few characters is a good idea. I’d personally like to see Javascript-style array shorthand ($foo = [1, 2, 3];) but I understand the reasons against it. I think a full JSON implementation is taking things too far.

    Maybe time to change IDE/editor, that will have a much greater effect on how long it takes to type such things?

    Like

  3. Actually, you could propose something a bit better.

    You currently have (natively in PHP), functions such as “func_get_args” and “func_num_args” that allow you to receive ilimited arguments in a function/method and process them.

    So, what you could propose would be something like, “instead of receiving a ‘comma-separated’ arguments list, I receive an associative array on construct and build/set the properties with those configs”.

    Most PHP frameworks already have that (check on Google PHP Framework Kohana).

    Still I think it’s way better (at least in a matter of performance) to manage arrays than objects.


    Example:
    # Class
    class MyClass{

    private $prop1 = "";
    private $prop2 = "";
    private $etc = "";

    function __construct()
    {
    # Either you receive 1 parameter and is an array...
    # Or you receive many parameteres, and then you'll just have to deal with it
    if( func_num_args() > 0 )
    {
    $args = func_get_args();
    if( is_array( $args[0] ) && (count($args)==1) )
    {
    foreach( $args[0] as $key => $value )
    $this->$key = $value;
    }
    else
    {
    $this->prop1 = $args[0];
    $this->prop2 = $args[1];
    $this->etc = $args[2];
    }
    }
    }
    }

    # Usage - example 1
    $settings = array(
    'prop1' => "value1",
    'prop2' => "value2",
    'etc' => "etc"
    );
    $myObject = new myClass($settings);

    # Usage - example 2
    $myObject = new myClass("value1","value2","etc");

    Like

  4. Thanks for the reponses,

    @Jaik

    I currently use NetBeans, and it works well. But there is already a precedence for increasing the convenience for common tasks in PHP. Look at the Alternative If Then Syntax (http://www.php.net/manual/en/control-structures.alternative-syntax.php) and the If Then Shortcodes (I couldn’t even find them in the PHP Documentation, i.e. $var = ($condition == true) ? 1 : 2;).

    So the Object Notation would allow for developers to quickly create objects and arrays. Performance issues could be left to the developer. But like in JavaScript, the Object Notation has been so successful that is has become a very common pattern across many JavaScript libraries. In PHP, developers wouldn’t be required to use this pattern, but it would be an option to the developers if they choose to use it. Just like the alternative syntax options for if/then statements, it would be optional.

    So I guess my question is what are the downsides? I haven’t found anyone to be able to explain to me a logical downside to implementing Object Notation. There might be some that I’m not seeing, but I’ve yet to have anyone tell me such.

    @Ricardo

    That is a pretty good example, and actually I used a very similar technique for a MySQL DB Library I’ve written. But look at how much tip-toeing you are doing around PHP to accomplish that? It isn’t so bad in Constructors, because you could make a generic base object that you extend. But that doesn’t work for class methods as cleanly.

    By adding Object Notation it can enable Developers to quickly make objects, and even arrays if they support it. We will be saving a great deal more keystrokes than we do with if/then shortcodes.

    Like

  5. Man, I would absolutely love it if you could do this in PHP. I love the elegance of using object notation in jQuery. I couldn’t agree more with this article. JSON is such a nice format and should definitely be implemented in PHP. I’ve been wanting this for some time now. Nice to see someone else on the same wavelength. Shame they rejected it in 2005. A rethink perhaps?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close