Zend_Layout vs. template inheritance

2009 October 31

Zend_Layout has always felt a little odd to me. It solves the problem of having redundant code in view scripts in applications with many pages using the same template. The solution seems simple: capture the output of the view script, assign it to a member of the master view script, then render the master view script. But does it really need to register a controller plugin, an action helper and a view helper in order to accomplish that? It feels over-engineered to me. This also makes it very closely coupled to the MVC stack, making it practically unusable by itself.
read more…

A foray into ActionScript

2009 August 13
by monzee

A couple of months ago, I was asked to write a desktop program that would interface with a GSM/VoIP gateway. The SMS web interface built into the box was lacking, so the client asked me to write a custom program with more features and a more intuitive interface.

I chose to use the Flex framework and Adobe AIR to deploy the program. Overall, it was an okay experience, although there are some parts that drove me nuts:

What I liked
  • Javascript-like syntax

    ActionScript is an implementation of ECMAScript, just like Javascript. Although coming from the same specs, programming in AS feels much closer to PHP than JS because of its classical object model complete with privates, statics, abstracts and everything else. This combined with the familiar C-like constructs allowed me to start from zero AS/Flex knowledge to a complete working program in a little over two weeks.

  • Accessor methods

    I pretty much use only public properties in my classes, but if there are times when I need to define custom logic during assignment or access (e.g. lazy connection to the socket), I could just define a get or set method for those properties. The best part, I don’t have to change the statements I already have written to use these accessors! They are automatically called whenever the property is accessed directly. It’s doable in PHP with __get and __set but you’ll end up with a giant switch statement in there and they likely won’t be discoverable by any IDE.

  • MXML layouts

    Laying out GUI widgets using HBoxes, VBoxes, Panels and other containers is a hundred times easier than HTML/CSS. Why can’t CSS be this simple? The default style looks good too, so I didn’t have to worry about changing the appearance and I was able to concentrate on the logic. Creating an interface through MXML reminded me a lot of Sonique2 (MML/MantisScript) and Winamp3 (XML/Maki) skinning, which were the main reasons I got into web/interface design and eventually PHP development.

What I wasn’t too crazy about
  • Asynchronicity, events and listeners

    I like its side-effect of maintaining the responsiveness of the application while doing a somewhat expensive task, but debugging is hell! It’s very difficult to follow the program flow. I also don’t think exceptions thrown by handlers are catchable, so I had to trigger error events and register even more handlers inside my handlers. And also made sure that the handlers are unregistered after they fired. The worst was when I had to send a sequence of commands to the socket connection. The listener was so deeply-nested and confusing that I just gave up error-handling altogether and just threw the commands in a queue which will be sent one-by-one regardless of the reply from the gateway.

  • Online resources are centered so much on FlexBuilder

    I’m sure it’s possible to develop Flex programs with just a text editor and the compiler bundled with Flex, but I wasn’t able to find any information on how to do so. Most tutorials just assume that you are using Adobe’s (not free) IDE. I wasn’t able to follow along even the simplest tutorials until I’ve found FlashDevelop. It is a good free IDE, but I wished it had a drag-and-drop GUI builder. That would have expedited my learning during the first couple of days.

Confusing as they are, I still think events are a good thing. I think that model would work in an MVC framework. I’m thinking of removing the dependency on the ZF MVC stack in my snap project to make it faster. If I ever do, the front controller would likely be a static event dispatcher object and the other components register themselves as listeners. I just wish I had more time to work on this.

Developing a Doctrine-backed ACL helper TDD-style, part 2

2009 June 20

In this second part, we will integrate Doctrine into our AccessManager helper. The database will be hit at least thrice per request: once for the rules for the requested resource, once for the global rules and at least once for the user roles. No additional tests here since I’m not sure how to approach mocking or stubbing with Doctrine and databases.
read more…

Developing a Doctrine-backed ACL helper TDD-style, part 1

2009 June 14

I figured my admin module needed to be unit tested since the code changes a lot and I’m constantly worried about breaking things in certain places while I add new features or factor out some common code. Writing tests at this point though does not follow the TDD way. I’m trying to get into this philosophy, so I’m gonna rebuild the ACL helper, this time guided by unit tests right from the start. All those code I have now aren’t fully trashed yet as I’m sure I’m going to copy-pasta a lot of those back in.

Note that I’m no expert on TDD. I’m a newbie, in fact. Don’t take anything in this post as a guideline on unit testing. I’m probably not even doing it properly. If you’re not interested in the TDD walkthrough, jump to the end and grab the (half-working) package containing a sample project.
read more…

Modular applications in ZF 1.8

2009 June 8

Modular applications are applications where big chunks of functionalities are encapsulated in module packages which can be easily shared between applications with minimal fuss. Although modules have existed in ZF for a long time, it is not really possible to reuse modules without adding a lot of glue to integrate the module with the application. The new autoloader and module bootstraps make this task easier.
read more…

Snap alpha, a ZF wrapper for PHP 5.3

2009 June 4
by monzee

Snap is a mini-framework on top of ZF inspired by the Sinatra framework. It makes heavy use of the new PHP 5.3 features to allow one to write concise code similar to Sinatra and Juno while taking full advantage of the well-tested ZF components.
read more…

New magic methods are awesome

2009 June 1
by monzee

The past couple days, I worked again on the little Sinatra-like DSL thing I mentioned before. It makes use of the new PHP 5.3 features. The ones I really love are the new magic functions __invoke and __callStatic. Invoke allows you to call an object instance like a function, e.g.

$front = Front::getInstance();
$front('/')->get(function () { echo 'hello world!'; });
// this is how my little DSL project is invoked at the moment.

and __callStatic allows you to catch all undefined static method calls, which is very handy for singletons.

class Front {
    // this is a singleton
    static public function __callStatic($method, $args)
    {
        return call_user_func_array(array(static::getInstance(), $method), $args);
    }
}
Front::setParam('foo', 'bar'); // this is the same as Front::getInstance()->setParam('foo', 'bar');

(Update: meh, I spoke too soon. The example above doesn’t pass through __callStatic if there is an instance method setParam. It works because PHP allows instance methods to be called non-statically along with a strict notice. Note to self: test first before making claims.)

In addition to singletons, __callStatic could be used in ORM or table gateway finder methods.

$user = User::findByEmail('foo@example.com');
// would return a row object
// whereas before you need to instantiate a User first before finding.

But you know what would really be nice? A combination of the two.

class Hello {
    static public function __invokeStatic($name)
    {
        echo 'Hello, ' . $name . '!';
    }
}
Hello('mon'); // Hello, mon!

It might look retarded because you could just define a Hello($name) function and accomplish the same. The reason I think this feature is reasonable is the inability to import and alias namespace functions with the use keyword. For example,

namespace greet {

class Hello {
    static public function __invokeStatic($name) {
        echo 'Hello, ' . $name . '!';
    }
}

function hi($name) {
    echo 'Hi, ' . $name . '!';
}

}

namespace somethingElse {
    use greet\Hello as hey; // you cant use greet\hi

    hey('mon'); // Hello, mon!
    \greet\hi('mon'); // Hi, mon!
}

How I wish this were possible. I dislike the namespace separator (although a lot less now than before) and I’d like to limit the use of it in the use and namespace declaration only. Also, it is easier to maintain state with a static class function rather than a namespace function because namespace variables are actually globals. These two reasons really make namespace functions undesirable for me, and I imagine others would find the same once 5.3 becomes prevalent.

Migrating applications to 1.8

2009 May 21
by monzee

Old applications should still work in 1.8 but some might want to update their applications to use the new 1.8 features such as Zend_Application and Zend_Loader_Autoloader. The reference manual describes how to write a bootstrap for Zend_Application, so head that way for a detailed description of the inner workings of Zend_Application. In this post, I’ll show how one might go about converting their old bootstraps into something usable by Zend_Application.
read more…

Access control: Why not a helper?

2009 May 17
by monzee

Every single ACL tutorial I’ve seen (not that I’ve seen many) uses controller plugins to check access to pages. People seem to be forgetting that action helpers have a preDispatch() method too, and in some ways it really makes sense to stuff ACL checking in there rather than in a plugin.

Since we’re controlling access to a controller action, doesn’t it make sense to know if the controller or action exists in the first place? Plugins are not controller-aware. In fact, the controller object doesn’t exist yet during plugin preDispatch()! If your ACL plugin happens to use a database backend, an invalid request means unnecessary database hits. Sure, you can invoke the dispatcher’s isDispatchable() method, but why do that in the plugin when the dispatcher does exactly the same shortly after the plugin preDispatch()? Since most of your requests are indeed valid, querying the dispatcher in the plugin preDispatch means an additional superfluous file stat per request. Not that I advocate micro-optimizations like these, but still… I think it’s just better to fit your code into the framework than altering the flow of events in the framework to fit your code.

It is desirable sometimes to manipulate the ACL checker at a per-controller basis. For example, one might want to disable access control on a certain controller if the user comes from a specific IP. You could probably write a permission for that special case, but it’s much simpler to just disable checking when the request hits that controller and the conditions are satisfied. The controller init() method is the perfect place to add these exemptions since it is executed right before the helper preDispatch(). In addition, you could do stuff like adding access rules to the ACL object or embed the access rules as public properties of the controller, like I do in my ACL implementation (see below). Again, you can’t do this in a plugin naturally since the controller object hasn’t been instantiated yet during the plugin preDispatch().

And finally, action helpers are easily invokable inside controller actions. It is very likely that you would want to query the ACL object inside controller actions. Your ACL object doesn’t necessarily have to be limited to permissions for controller actions. You can also set permissions for your model objects. With a helper, you can very easily pull out the ACL object and ask if the user is allowed access to a certain object. With a plugin, you probably have to assign the object to the evil registry first in order to access it in the controller.

I have put my ACL/auth implementation up in googlecode. Visit the project page and hit source->browse or download the package for an example on how to implement an action helper ACL checker.

Variables in namespaces are global!

2009 April 11
tags:
by monzee

This surprised me:

namespace foo
{
    $foo = 'foo';
}

namespace bar
{
    echo $foo; // foo
}

I was looking for a way to import a namespace variable inside a function in the same namespace and the only way I found was to use global $foo; inside the function, which I thought was defeating the whole purpose of namespaces. Then I found out that there’s no such thing as namespace variables! That makes me feel less guilty about using global, but that’s still retarded.