PHP Traits

Like this article? Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

It’s another quick primer this time. Today we’re going to talk about a PHP 5.4+ feature called traits. While Laravel doesn’t make heavy use of traits they are sprinkled around the core codebase, so you’ll want to get familiar with them.

The Problem

Sometimes when you’re working in a class based object oriented system, you’ll find yourself in a situation where you want functionality from another class in your own class. If your class doesn’t have a parent class, you can accomplish this by extending the class whose behavior your want. Pretend you’re creating a messenger class.

class Messenger
{
}

While you’re working on the messenger class, other members of your team have written a Hello class.

class Hello
{
    public function hello()
    {
        echo "Hello","\n"
    }
}

If you want Hello’s functionality, you can extend it.

class Messenger extends Hello
{
}

$o = new Messenger;
$o->hello();

Pretty basic object oriented stuff. However, lets say someone on your team has also written a class Goodbye.

class Goodbye
{
    public function goodbye()
    {
        echo "Goodbye","\n";
    }
}

As it stands right now, there’s no way for you to incorporate Goodbye’s functionality into your Messenger class. That is, in PHP, a class can only have one parent class. Some languages have experimented with allowing a class to have many parents (with a feature called multiple inheritance), but multiple inheritance creates a slew of ambiguities and has a bad reputation as it complicates simpler single class inheritance.

When PHP’s core team considered this programming problem for PHP 5.4, instead of multiple inheritance they developed a language feature called “traits”.

What’s a Trait

Traits are PHP’s take on the multiple inheritance problem. Think of a trait as something in-between a class and an interface. You can define a trait in PHP with the following

trait Hello
{
}

Similar to interfaces, you can define abstract methods on traits

trait Hello
{
    abstract public function sendMessage();
}

However, different from interfaces, you can also define concrete methods on traits

trait Hello
{
    abstract public function sendMessage();

    public function hello()
    {
        echo "Hello World","\n";
    }

}    

You may not directly instantiate traits. The following program

trait Hello
{
    abstract public function sendMessage();

    public function hello()
    {
        echo "Hello World","\n";
    }
}    

$o = new Hello;

will halt with the error.

Fatal error: Cannot instantiate trait Hello

So far, traits look a lot like abstract classes. However, a class cannot extend a trait. The following program

trait Hello
{
    abstract public function sendMessage();

    public function hello()
    {
        echo "Hello World","\n";
    }
}    

class Messenger extends Hello
{
}

$o = new Messenger

will halt with the error

Fatal error: Class Messenger cannot extend from trait

Instead, a class uses traits. Consider the following program.

trait Hello
{
    abstract public function sendMessage();

    public function hello()
    {
        echo "Hello World","\n";
    }
}    

class Messenger
{
    use Hello;
    public function sendMessage()
    {
        echo 'I am going to say hello',"\n";
        echo $this->hello(),"\n";
    }
}

$o = new Messenger;
$o->sendMessage();

This program will run with the following output

I am going to say hello
Hello World

Notice that our class definition contains a

use Hello;

This tells PHP we want our class Messenger to use the trait Hello. The use keyword here has nothing to do with PHP namespaces. When use is inside a class block, PHP knows it means use a trait — when use is outside a class block, PHP knows it means alias or import a namespace.

When a classes uses a trait, it has access to all the trait’s methods, just as though it had extended from it. Notice we’re calling the hello method

echo $this->hello(),"\n";

There’s no hello defined on Messenger. Instead, hello is defined on the trait.

Multiple Magic

So far the functionality we’ve described can all be accomplished without traits. That is, other than the use operator, this all looks like plain old class inheritance. That’s about to change. Consider the following program

trait Goodbye
{
    public function goodbye()
    {
        echo "Goodbye","\n";
    }    
}

trait Hello
{
    public function hello()
    {
        echo "Hello World","\n";
    }
}    


class Messenger
{
    use Hello, Goodbye;
    public function sendMessage()
    {
        echo 'You say goodbye',"\n";
        echo $this->goodbye();

        echo 'and I say hello',"\n";
        echo $this->hello(),"\n";
    }
}

$o = new Messenger;
$o->sendMessage();

Here we’ve defined two traits. One named Goodbye, the other named Hello. Then, in our Messenger class, we’ve used both

use Hello, Goodbye;

Run the above program, and you’ll get the following output

You say goodbye
Goodbye
and I say hello
Hello World

This is the point of traits. A client programmer can pull in any trait they want into their class to adopt the trait’s functionality.

While not as powerful as multiple inheritance (i.e. you need to write your code as traits in the first place), traits cordon off the ambiguities that arise from multiple inheritance into a separate system. This allows that separate system to develop advanced features for dealing with those ambiguities without complicating existing class syntax. If you’re interested in how these ambiguities are resolved, the PHP manual has a more in depth discussion of all the features of PHP’s traits.

With PHP 5.3 finally deprecated, you’ll start seeing traits used more often. In particular, there are parts of the Laravel framework that rely on traits for their functionality. Next time we’ll have a quick primer on Laravel’s MacroableTrait.

Originally published October 19, 2014

Laravel Facade Troubleshooting

Like this article? Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Last time we described the PHP patterns used to implement Laravel’s facade feature, and started to describe some of the “gotchas” involved. We briefly discussed how a facade introduces a second type of singleton/shared service into the system, as well as the inherent problem of hijacking/borrowing a word that’s already in use to describe another object oriented programming pattern.

This week we’re going to continue that critique of facades, with particular attention paid to typical problems you may run into implementing your facades, or using facades in a system/application you’re not intimately familiar with.

Aliases and Global Classes

One problem you’ll run into with facades is the global namespace problem. The facades classes that ship with Laravel have a proper PHP namespace, but in order to provide dead simple access to the facade class, the system creates a globally available class aliases

Class Alias: DB
Actual Facade Class: Illuminate\Support\Facades\DB

These globally available aliases are generically named (DB, Redis, etc.), and can lead to namespace collisions — i.e. client developers create classes (typically model or migration classes) named the same as the aliases. This, in turn, can lead to confusing situations with misleading error messages.

This is more than a hypothetical ivory tower concern. Consider this stack exchange question. Here the user has some other class named Redis in the global namespace. Instead of loading the facade alias, PHP defers to their class. It’s not obvious that this is what PHP’s doing, and the user ends up confused and stuck.

The big trade off, as it always is with a global namespace, is ease of use. While Laravel’s system code uses namespaces, the system itself is biased towards giving client programmers the ability to ignore namespaces all together.

Consider that Laravel has global facade classes, an app/routes.php file included in the global namespace, an app/start/*.php files hierarchy for global startup tasks, and an autoloader and code generation tools that that ship loading and creating classes in the global namespace (from/in the app/commands, app/controllers, app/models, and app/database/seeds folders).

While this may make “modern” PHP developers cringe, it does remove the namespace learning curve barrier for people new to Laravel and new to programming. I suspect it’s one of the reasons Laravel’s such a popular framework.

One Abstraction Over the Line

Another tricky part of facades is the issue of meta-programming in general. Facades provide a great way for folks completely new to programming with a way to “do things”, but a programmer with a small bit of experience will see something like

DB::select

and assume there’s a class DB with a method select somewhere. In hiding the implementation details of the service container, facades also hide the actual class doing the work, which makes it harder for a developer to know what class actually implements a service.

Even as an experienced developer, I couldn’t tell you off the top of my head what the “DB” facade’s actual class is. Whenever I need to know this, I need to

  1. Open up the app configuration

  2. Look for the DB alias and the actual class

  3. Get the service identifier (db) from the facade class definition

  4. Use grep or ack to search through my source code to find how the service was bound and/or extended

  5. Jump to that class definition

  6. Then, sometimes, some extra searching if someone’s used App:extend to change a service definition

The same goes for all standard IDE and code completion/browsing tools — unless they’re configured to work specifically with Laravel, looking up method definitions can be a flow breaking event.

Facades make reading the client programmer’s intent easy, but at the expensive of making learning how the system works more difficult.

This might be a tenable situation if facades were the only abstraction to use static method calls. However, Laravel’s default ORM (Eloquent), also uses static method calls. Things like the following

Users::all(...);
Users::where(...)->get();

are a common site in any Laravel application. Neither all, nor where, are defined as static methods on an Eloquent model. Instead, Eloquent leverages the power of __callStatic to give model objects special features.

We’ll cover the specifics of this ORM magic in another article, but the takeaway here is, in Laravel static method call syntax (::) might mean calling a static method, might mean calling a facade, or might mean calling a magic ORM method. That is, as a programmer, you can’t just look at

Someclass::foo(...);

and know where to find the method foo.

In the end, Laravel’s meta-programming creates a weird, two plateau learning curve. Of all the modern PHP programming frameworks it’s the easiest to get started with. However, that ease comes at the cost of a very steep learning curve when you’re ready to start digging into how the framework does its job.

In future articles article we’ll dive deep on some of Laravel’s other magic methods, including the aforementioned Eloquent ORM and Laravel’s database manager service.

Originally published October 17, 2014

Unraveling Laravel Facades

So far in this series, whenever we’ve wanted to use a service, we’ve fetched Laravel’s application/service-container object with the global app function

$app = app();

and then used either make or ArrayAccess syntax to fetch a service

$service = $app['db'];
$service = $app->make('db');    

While this is a perfectly valid use of the framework, it’s not ideal for all situations and all developers. This is especially true for people just getting into Laravel and PHP programming.

PHP’s ArrayAccess feature, while useful, is advanced functionality that can confuse programmers just learning PHP. Most meta-programming falls under this category, as most new programmers start by assuming their programming language follows a strict set of rules. Changing the rules under them tends to confuse and frustrate people until they make the “programming the programming language” connection.

Calling make is also problematic. It’s not that calling make itself is incorrect, it’s that there are numerous other methods on the application object that can instantiate or return an object/service. Here’s some off the top of my head.

$app = app();
$object = $app->make(...);
$object = $app->register(...);
$object = $app->getRegistered(...);    
$object = $app->resolveProviderClass(...);        
$object = $app->extend(...);        
$object = $app->db;
$object = $app->offsetGet(...);
...

There’s also methods like $app->singleton and $app->instance which might look like they’re for instantiating objects and services, but aren’t (or aren’t directly)

Despite their public access level, many of these methods are meant to be used by the application object’s internal logic, (or programmers familiar with that logic). One of the disadvantages of combining the global application object and the service container object is it becomes a lot less obvious which methods client programmers use to interact with the service container, and which methods are meant for internal framework use.

This is where Laravel facades enter the picture.

Laravel Facades

Let’s jump in with some code. Calling a service method with a Laravel facade looks like this

DB::select('SELECT * FROM table');

The above is equivalent to

$app = app();
$app->make('db')->select('SELECT * FROM table');

How it’s equivalent is not a straightforward story, but it’s the story we’re going to tell today.

First, let’s define a facade’s job in Laravel

A Laravel facade provides access to a shared/singleton service without requiring the end client-programmer to use the application container.

That is, the point of facades are to provide access to services without the container. A Laravel application is still structured around using services, but for many applications a client programmer may be completely unaware of the application service container, and will only access services through facades.

A facade looks like a static method call (and ultimately, behind the scenes, is a static method call). A less experienced PHP programmer might look at

DB::select('SELECT * FROM table');

and assume there’s a class in the global namespace named DB, and that this class has a static method named select. However, you can search your Laravel code base up, down, left, and right, and you won’t find a global class DB anywhere in the system.

Facades are a classic example of meta-programming. Roughly defined, meta-programming is changing a language/platform’s behavior to build new features into the language. Meta-programming allows system developers to come up with new language constructs and ideas without needing to change the underlying language implementation. Meta-programming knowledge is an important part of any modern day developer’s toolkit, but it’s like ginger in cooking. A little goes a long way.

Today we’re going to unravel how Laravel facades work. One important warning: If you’re a classically trained object oriented programmer, Laravel’s facades are not the Gang of Four’s facades. We’ll get to that eventually, but for now assume you’re learning a whole new design pattern.

Facade Classes are Aliases

Let’s consider our previous facade call

DB::select('SELECT * FROM table');

This looks like a call to the static method select on the class DB. Earlier we said Laravel has no class DB defined. Lets use the Reflection API to figure out where PHP thinks this class is. As in previous articles, we’ll drop our code in a testbed route.

Route::get('testbed', function(){
    $r = new ReflectionClass('DB');
    var_dump(
        $r->getFilename()
    );

    var_dump(
        $r->getName()
    );
});

Above we’ve used the Reflection API to lookup both the class’s definition file, and the class’s name. If you run the above by loading the route testbed in your browser

http://laravel.example.com/index.php/testbed

You’ll see the following

string '/path/to/laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/DB.php' (length=115)

string 'Illuminate\Support\Facades\DB' (length=29)    

For some reason, PHP thinks the class’s name is Illuminate\Support\Facades\DB. If you’ve read last week’s article on PHP’s class aliases, you probably know what’s going on. The class DB is actually a class_alias. This alias allows a service developer to provide a short, easy to remember-and-type facade name for their service.

It’s beyond the scope of this article, but if you’re curious, these aliases are setup automatically by the Laravel autoloader

Illuminate\Foundation\AliasLoader::alias()

This autoloader class reads through the alises defined in app/config/app.php. You can see the DB alias here

#File: app/config/app.php
'aliases' => array(
    //...
    'DB'              => 'Illuminate\Support\Facades\DB',
    /...

By using an autoloader to define an alias, the Laravel core team ensures no aliases are loaded until they’re actually needed.

Facade Classes

Now that we know the real class Laravel uses when we type DB we can go look for the select method. However, if we look at the Illuminate/Support/Facades/DB class, we’ll be disappointed.

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/DB.php 
class DB extends Facade {
    protected static function getFacadeAccessor() { 
        return 'db'; 
    }    
}

There’s no select method defined. You might think there’s a select method in the parent Illuminate\Support\Facades\Facade class (defined in vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php), but it’s not there either. What we do have is a getFacadeAccessor method that returns a string — db.

Unless you’re already familiar with some of PHP’s meta-programming features, this entire state of affairs is pretty confusing and confounding. However, even if you don’t know about things like __callStatic, think back to how we defined a facade’s responsibilities

A Laravel facade provides access to a shared/singleton service without requiring the end client-programmer to use the application container.

A facade class has one responsibility — and that’s to define a getFacadeAccessor method, and have this method return a service identifier. In the DB facade above that identifier is the string db. This means a call to

DB::select(...)

Is equivalent to each of the following

app()->make('db')->select(...)
app()->db->select(...)
app()['db']->select(...)

If the accessor had been written

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/DB.php
protected static function getFacadeAccessor() { 
    return 'my_crazy_service'; 
}    

Then the static call DB::select would have been equivalent to

app()->make('my_crazy_service')->select(...)
app()->my_crazy_service->select(...)
app()['my_crazy_service']->select(...)

Of course, you’re probably wondering how a static call is somehow transformed into a method call to a service. To understand that, we’ll need to look more deeply into the definition of the Facade base class — the abstract class which all Laravel facades inherit from.

Facades and Magic Methods

If you read last week’s article, you already know about __callStatic. In brief, if you call a method that doesn’t exist on a PHP object, PHP will issue a fatal error unless that PHP object has a magic __call or __callStatic method defined. So, when a programmer calls

DB:select(...)

PHP says

Hmm, no select method is defined on DB or its parent classes, I better crash with a fata—- wait, there’s a __callStatic on the parent Facade class, I’ll call that instead.

Let’s take a look at __callStatic

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
public static function __callStatic($method, $args)
{
    $instance = static::getFacadeRoot();

    switch (count($args))
    {
        case 0:
            return $instance->$method();
        #... snipped for brevity ...#
        default:
            return call_user_func_array(array($instance, $method), $args);
    }
}

What __callStatic does is get an instance of an object with the getFacadeRoot method, and then pass on the static method name (passed in as $method) as a call to a regular method on the object.

It’s worth repeating that step by step. First, we have a call to a static method

DB::select('SELECT * FROM table');

PHP can’t find a select method to call, so instead PHP calls the __callStatic method, passing in the method name and arguments as parameters.

DB::__callStatic('select', array('SELECT * FROM table'));

In __callStatic, the Laravel framework code fetches a service object with a call to getFacadeRoot

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
public static function __callStatic($method, $args)
{
    $instance = static::getFacadeRoot('select', array('SELECT * FROM table'));
    //...
}

Finally, __callStatic passes the method call on to the object in $instance using PHP’s dynamic method calling feature, and returns the value

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php    
return $instance->select('SELECT * FROM table');

All of this explains the mystery of how a static looking method call is actually a call to an instance method on a service object, but it doesn’t explain how the facade class knows which service to instantiate.

This is where getFacadeAccessor comes into the picture.

The Facade Accessor

If we take a look at the method call that fetches the service object

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
$instance = static::getFacadeRoot('select', array('SELECT * FROM

We see the special static keyword. The static keyword is similar to self. Both are a way to refer to the current class without without using the full classname. You can read more in the PHP manual’s Late Static Binding section, but for now all you need to know is getFacadeRoot is defined on the same base Facade class. (Also, the keyword static is something completely different if used in a function context, so Drupal developers beware)

If we take a look at the getFacadeRoot method, we’ll see the following

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
public static function getFacadeRoot()
{
    return static::resolveFacadeInstance(
        static::getFacadeAccessor()
    );
}

Ah ha! Here’s that getFacadeAccesssor method we saw defined in the specific Facade class. You’ll remember that looks like this

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/DB.php
protected static function getFacadeAccessor() { 
    return 'db'; 
}

So, putting our x-ray variable specs back on, for our method call, getFacadeRoot actually looks like

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
return static::resolveFacadeInstance(
    'db'
);

This means our next stop is the resolveFacadeInstance method

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
protected static function resolveFacadeInstance($name)
{
    if (is_object($name)) return $name;

    if (isset(static::$resolvedInstance[$name]))
    {
        return static::$resolvedInstance[$name];
    }

    return static::$resolvedInstance[$name] = static::$app[$name];
}

This short method is the final key to understanding a facade. It’s the last line that’s most important

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php
return static::$resolvedInstance[$name] = static::$app[$name];

Here the facade code refers to the static property $app. The static property $app contains a reference to the application container object. In other words, the above could be rewritten to

//get an instance of the global appliaction objcet
$app = app();

//set a copy of the service we fetch on the $resolvedInstance property
static::$resolvedInstance[$name] = $app['db'];

//return the instance
return static::$resolvedInstance[$name];

The Facade is, ultimately, using the same code to fetch a service reference as a normal Laravel developer would. There’s one small wrinkle to be aware of, and that’s the conditional

#File: vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php    
if (isset(static::$resolvedInstance[$name]))
{
    return static::$resolvedInstance[$name];
}

If the facade has already fetched (or “resolved”) an instance of the service, it will return that instance. You’ll remember from our definition

A Laravel facade provides access to a shared/singleton service without requiring the end client-programmer to use the application container.

that a facade is meant to provide access to a shared/singleton service — well it turns out facades will work with unshared services as well, but because of the above conditional, theses unshared services will be treated as shared/singleton by the facade.

This might give an object system developer reason to pause, as it introduces a second level of “singleton” into the system. A facade might not catch a shared service that’s changed in the application object at runtime.

This (admittedly rare) edge case must have seemed like an acceptable tradeoff to the Laravel core team, and of all the complaints about facades this is a relatively minor one.

Facade Controversy

If you’ve spent anytime lurking in various programmer communities, you’ve probably gotten a whiff of the displeasure some programmers have for Laravel’s facades. Among these complaints

  • Laravel uses the word facade, but the influential “Gang of Four” book Design Patterns defines a facade in a completely different way

  • Facades end up creating a number of “God Objects” in the application, which in turn creates hard coded dependencies, which in turn makes writing unit tests difficult or impossible (which Laravel addresses by giving Facades test mocking abilities)

  • A general distrust of static method calls, dating back to the earliest days of object oriented programming

  • A willingness of some Laravel core team members to defend their decisions by pouring gasoline on the couch, setting it on fire, and spreading jello on the floor.

I can only speak for myself, but I’ve found it more useful to not have strong opinions about these sorts of things. It’s good to know and understand programming/computer science theory, and the story of how we got here. It’s also good to be able to drop yourself into the mindset of a programmer who does have strong opinions, and be able to talk coherently about your own decisions, but ultimately it’s a lot easier to swim with the flow of a framework’s design. The ability to work with multiple programming systems, warts and all, is the most important skill a 21st century developer needs.

That said, I have my own personal list of gripes about facades, which we’ll cover next time in the facade troubleshooting article.

Originally published October 8, 2014