Thoughts, ideas and notes about PHP web development.

A PHP Short Array Syntax Converter

In his PHP Town Hall podcast, Phil Sturgeon mentioned that it would be nice to have an automatic converter for the new short-hand PHP array syntax that was added in PHP 5.4. I agreed, but not that it would be hard to create one. Making use of Symfony’s nice Console package and PHP’s very own tokenizer, it was fairly easy to create.

In fact, the only real issue I faced was making sure that array typehints weren’t removed (as the token parser doesn’t make a difference between array typehints and array definitions). Maybe I have just missed something…

Anyway, you can find the tool here on GitHub. Improvements welcome.

Laravel 4: Eloquent attribute mutators

Custom getters and setters for Eloquent model attributes have existed for a while in Laravel. They allow you to manipulate your attributes when storing or retrieving them. The canonical example is saving a user’s password: for security reasons, you want to store only a hash of your password in the database – so you write a custom setter that automatically hashes any password passed to the user object.  Your application won’t have to worry about the implementation details of hashing your password and there’s no way to forget about it. And there’s lots of room for improvements: for example, you could also extend the function to send a confirmation email with the password when generating it for the first time.

In the upcoming Laravel 4 release, these custom getters and setters will work a little differently, though.

First of all, they are now called mutators. Why not.

Also, as Laravel 4 adheres to the PSR-0 standard, the mutators’ method names will now be “properly” (we’ll argue about that another time) camel-cased. So, if you have an attribute called “user_password”, the appropriate setter mutator would be called setUserPasswordAttribute(). Once more, some fancy method calling magic behind the scenes.

With Eloquent working all its magic behind the scenes, a password setter might look like this:

public function setPasswordAttribute($value)
{
    $this->attributes['password'] = Hash::make($value);
}

Now go forth and mutate!

UPDATE (2/21/2013): At some point, this functionality was changed. I updated the article to reflect the new behavior.

Laravel: CSS error classes in forms

Laravel and its validation system make it easy to handle form errors.

But what if you want to add a special CSS class to your form fields if the submitted value was invalid? Well, here you go:

<input type="text" name="field" class="input-text<?php echo $errors->first('field', ' errorclass'); ?>" />

See what we did there? The first() helper of Laravel’s Message class has two arguments: the field name and, optionally, a format string for the output of the error message. Usually this can be used to customize the HTML around the error message. Without a placeholder for the actual error message, the output will simply be a static string.

If the given field did not produce any error message, the return value of first() will simply be an empty string.

Serves the purpose.

Laravel: Session drivers in bundles

For a few months now, I have really gotten hooked on the fantastic Laravel framework. I don’t really want to write yet another post describing the many cool things in this fine piece of software – just take a look yourself.

With FluxBB now using Laravel for its next major version, I keep discovering small gotchas and trying things that I couldn’t really find any reference for. So this will probably be just the first of quite a few quick tutorials on how to achieve certain things with the framework.

Custom session drivers

While Laravel already comes along with some cool session drivers (Memcached and Redis are good examples), in some cases you may need to overwrite them to achieve some custom functionality. Laravel allows that through a barely-documented feature.

You can specify and setup your own custom session driver through the Session::extend() function:

<?php
Session::extend('mybundle::session', function() {
    return new MyBundle\Session\Driver();
});

All you need to do is pass a closure to the function that returns a fully instantiated session driver.

The key supplied in the first parameter can then be used in your application config (application/config/session.php) as a session driver. Well, that’s the theory.

As the session is setup before bundles are loaded, it seems virtually impossible to use a session driver that you registered in a bundle.

Luckily for us, there’s a small workaround that (ab)uses the fact that Laravel only starts the session if a session driver is configured in the session config file. So, to register and use a custom session driver from your bundle, set that config value to an empty string and add the following lines to your bundle’s start.php:

<?php
if (!Request::cli() && !Session::started())
{
    Session::extend('mybundle::session', function()
    {
        return new MyBundle\Session\Driver();
    });

    Config::set('session.driver', 'mybundle::session');

    Session::load();	
}

And off you go!

Can’t use function return value in write context

PHP likes to give this error message when using function return values directly with the empty construct.

if (empty(some_function()))
{
    // ... some code here
}

This is due to how empty is implemented in PHP.

The obvious solution is to store the value in a temporary variable first and then applying empty:

$value = some_function();
if (empty($value))
{
    // ... some code here
}

There is a shorter way, though.

Depending on whether you use empty or !empty, the shortest way to use the function return value directly is this:

// Replacing empty
if (!some_function())
{
    // ... some code here
}

// Replacing !empty
if ((bool) some_function())
{
    // ... some code here
}

This solution makes clever use of PHP’s type casting to booleans – and keeps the code short.

NOTE: This not only works for arrays, but also for strings.

Next Page »