Posts Tagged ‘PHP’

Bending PHP to Your Will

Posted on 6 August 2011, in Uncategorized. 2 Comments.

One of the best features of Objective-C is protocols. These are akin to PHP and Java interfaces, but have one huge advantage: you can mark certain methods as required or optional. This is useful in implementing the delegate pattern because if you do not care about a certain method, you can simply not implement that method. In PHP, this is not possible with interfaces: you must implement all the methods of an interface in order to implement the interface. While this is fine and makes sense in most cases, it’s not always convenient.

So I set off to find a way to create protocols in PHP. The language is fairly dynamic, so I was able to come up with a solution called WeakInterface. Before jumping into the implementation details, let’s see how it works in practice:

First you define your interface as you would normally:

interface AllOptionalInterface {
  public function DoSomething();
  public function DoSomething1(Closure $arg);
}

The class that implements this only cares about the DoSomething method, so it implements it:

class AllOptionalImpl {
  public function DoSomething() {
    echo 'I did something!';
  }
}

Note that this class isn’t said to implement this interface because it does not implement all the methods. Now in the code that is going to call this interface, you do the following:

$delegate = new WeakInterface('AllOptionalInterface');
$delegate->Bind(new AllOptionalImpl);
$delegate->DoSomething();
$delegate->DoSomething1(function() { echo 'Wow!'; });

This code will output “I did something!”. Let’s go line-by-line. First, $delegate is being created as an instance of WeakInterface, whose constructor takes the name of the interface to “implement.” Then the interface is bound to an instance of the implementation. And then finally two methods are called on the interface, and the one with an implementation is actually called. Calling DoSomething1() is a no-op.

I mentioned above that in Objective-C you can mark some methods as required, too. And that’s done with a docstring when using WeakInterfaces:

interface OneRequiredInterface {
  public function DoSomething();
  /** @required */
  public function DoAnything();
}

If you failed to implement DoAnything(), the call to WeakInterface::Bind() would throw an exception. But what if the number and type hints of the arguments of an implementation do not match that of the interface? WeakInterface has that base covered, too. Bind() will also check the parameters of all method implementations to make sure that the signatures match the interface’s.

That’s WeakInterface in a nutshell, but how does it actually work? It’s easiest to start with a callstack. So when $delegate->DoSomething() is called, this is how WeakInterface actually invokes the implementation:

# Time Memory Function Location
1 0.0033 975328 hoplite\base\WeakInterface->DoSomething( ) ../example.php:14
2 0.0033 975856 hoplite\base\WeakInterface->__call( ) ../weak_interface.php:0
3 0.0033 975856 hoplite\base\internal\MethodImp->Invoke( ) ../weak_interface.php:84
4 0.0033 976568 ReflectionMethod->invokeArgs( ) ../weak_interface.php:145
5 0.0033 976608 AllOptionalImpl->DoSomething( ) ../example.php:0

WeakInterface implements the magic PHP method __call(), which is invoked whenever a method call is performed and no method is found by the runtime. It captures this and then forwards the invocation on to an implementation helper MethodImp, which then uses reflection to finally invoke the proper implementation.

Going deeper, when a WeakInterface is constructed, the interface passed to it is reflected and the method list is walked. For each method, a MethodImp is created. When the WeakInterface is bound, that set of MethodImps is looped over, checking that any required methods are implemented and that any implementations match the interface’s method signature. At call time, the method name is looked up in the MethodImp table and the arguments are forwarded to the actual implementation.

One note on performance: due to the number of intermediate method calls, using WeakInterface is roughly four times slower than a plain method call. For most applications, this should not be significant at all; but for performance-critical code, you should steer away from WeakInterface.

The code is available here along with a unit test.

The Road to MacGDBp, Part II

Posted on 5 June 2008, in MacGDBp. No Comments.

The bug with XML parsing I mentioned in the last post caused me days of grief. I’ve been trying to find the cause of that bug (off and on, albeit) for months. It turns out the fix was very simple. All that’s left is creating the breakpoint manager and then MacGDBp will be released. Hopefully by the end of next week v1.0 will be in your hands!

In this post, I’m going to talk about icon design. One of the ideas I had for this was to use the PHP logo in some way — but using logos in an icon is tacky. Instead, I decided to keep the purple of the PHP logo. Since PHP is internet-based, I decided to take inspiration from the words “World Wide Web” and I drew out a globe. So at this point, I had a purple globe. Now I had to decide what to design on top of the globe (because a purple globe only conveys internet connectivity). For this I really saw two options: a screwdriver and wrench or a toolbox. On Mac OS X, the screwdriver-wrench combination usually implies configuration (c.f. Color Sync Utility, Raid Utility, configure toolbar item, etc.). Debugging is not in the same vein as configuring, so I ruled that one out. The toolbox, while unused on Mac OS X (except for the Adobe ExtendScript Toolkit), seemed like a good fit. I should also note that I thought about drawing a yellow spray can — akin to the debug icon in Xcode — but quickly dismissed it for being too similar to Xcode.

This is the paper sketch I first did of the icon:

Then I recreated the sketches digitally. You can see how the design evolved here.

The final step (not outlined above) was adding drop shadow to the entire icon. This is the final design:

Hopefully the next post about MacGDBp will be the release announcement!

The Road to MacGDBp, Part I

Posted on 2 June 2008, in Uncategorized. 3 Comments.

Inmy last pipeline update, I said that MacGDBp would be out by May. Unfortunately, I’ve run into two bugs that I’m not quite sure how to work around. One of them involves NSXMLDocument raising assert() messages for what appears to be valid XML. Weird, right? So instead, I’m going to write an article about MacGDBp in hopes of whetting your appetite for it until it’s done.

History
The idea for MacGDBp has been in my head for a long time. PHP debuggers are far superior to var_dump() and print_f() debugging statements. Unfortunately, only the Zend IDE was available — but it cost money and was ugly (i.e., not Mac-esque). Next came Eclipse with the web tool kit. I had a heck of a time getting the debugger to work and ultimately gave up. Additionally, it too was ugly. So I put up with my combination of BBEdit (and later TextMate) and var_dump()/print_f().

Fast forward a few years to the introduction of the Xdebug extension. This extension is absolutely fantastic, if only for the stack traces in errors and uncaught exceptions. But it also has a remote debugging function. For about a month, I used the packaged command-line demonstration tool and read XML to glean debugging information. Then at the end of July/beginning of August 2007, I made the decision to write a native Mac application for the Xdebug remote debugger.

Evolution of Design
It’s rare for me to design an application without first sketching out the interface on paper. But because this was such a straight forward project, I decided to wing it. The second commit in the git repository was “Laying out an unhooked basic interface for the system.” This was the first revision.

Yes, ugly. But it improved after some tinkering:

Then I realized that I was trying to re-invent something that had already been well-designed. So with the next iteration, I mocked up Xcode’s debugging window.

After designing a couple of toolbar icons, we get to the final design. This is how the application will look when launched and unconnected to Xdebug:

And there you have the final design. In the next couple of days I’ll talk about how I designed the icon in an effort to stall while I squash the last few bugs.

A Note about System Requirements
MacGDBp will require 10.5. And this is not because I don’t want 10.4 support, but MacGDBp relies on a bug that was fixed in 10.5. In Mac OS X, there is a class called NSTreeController that I use for the variable list. But under 10.4, parts of this class were not properly exposed and were very buggy. I found a work-around, but it relied on using private, undocumented API calls. In 10.5, Apple fixed the bug and exposed the necessary parts.