PHP – Instantiate a class from a string with namespace

I know this is old but I just learned it today. Instantiating a class from a string requires a full namespace of the class, otherwise it won’t work. You cannot use a namespace to make shortcuts. See example below.

Shortcut? No!

<?php

namespace Argus;
use Argus\Authentication\Type;

class Authentication
{
    public static function factory($type, array $options = array()) {
        $class = 'Type\\'.$type;
        return new $class($options);
    }
}

// Then use it like this
$auth = Authentication::factory('Password');

Above code won’t work as it won’t be able to find the class. It needs the full path/namespace!

Specify the full namespace string

<?php

namespace Argus;

class Authentication
{
    public static function factory($type, array $options = array()) {
        $class = 'Argus\\Authentication\\Type\\'.$type;
        return new $class($options);
    }
}

With our very basic example above, (I don’t know if factory pattern is still popular), we are creating an object based on the authentication method. Also notice the double slashes as we are dealing with string so we escape it normally as a normal string.

We then call it like this:

<?php

use Argus\Authentication;

$auth = Authentication::factory('Password');

Then we should get an instance of Aurgus\Authentication\Type\Password class (assuming that the class exists).

That’s it!

This entry was posted in php, Programming and tagged , . Bookmark the permalink.

3 Responses to PHP – Instantiate a class from a string with namespace

  1. Vokiel says:

    I propose to use Reflection API to do some checks before initiating the object.

    Firstly check if the class exists:

    if (!class_exists($commandClassName)) {
    // throw some exception
    }

    Then you create ReflectionClass object

    $reflectedClass = new \ReflectionClass($class);
    // check if can be instantiable
    if (!$reflectedClass->IsInstantiable()) {
    // throw some exception
    }
    // Maybe check interface
    if (!$reflectedClass->implementsInterface('SomeInterface')) {
    // throw some exception
    }
    // Maybe also check required methods
    if (!$reflectedClass->hasMethod('execute')) {
    // throw some exception
    }

  2. lysender says:

    @Volkiel, thanks for the input. I was too thinking of using Reflection but on the other hand, I don’t really need a robust checking since instantiating is pre-determined.

    I really wish there is a way to get a class, property or method without using those magical string concatenation like $this->{$some_string}. Something where JavaScript or Python is very capable of.

  3. jul says:

    Thanks, I was getting crazy about that error

Leave a Reply

Your email address will not be published. Required fields are marked *