What is the best way to include PHP libraries when using static factory pattern?

thesmart picture thesmart · Nov 5, 2008 · Viewed 9.4k times · Source

I have several static factory patterns in my PHP library. However, memory footprint is getting out of hand and we want to reduce the number of files required during execution time. Here is an example of where we are today:

require_once('Car.php');
require_once('Truck.php');

abstract class Auto
{
    // ... some stuff ...

    public static function Create($type)
    {
        switch ($type) {
            case 'Truck':
                return new Truck();
                break;
            case 'Car':
            default:
                return new Car();
                break;
        }
    }
}

This is undesirable because Car.php AND Truck.php will need to be included even though only one or the other may be needed. As far as I know, require/include and their ..._once variation include libraries at the same scope as it's call. Is this true?

If so, I believe this would lead to a memory leak:

    abstract class Auto
    {
        // ... some stuff ...

        public static function Create($type)
        {
            switch ($type) {
                case 'Truck':
                    require_once('Truck.php');
                    return new Truck();
                    break;
                case 'Car':
                default:
                    require_once('Car.php');
                    return new Car();
                    break;
            }
        }
    }

It looks to me that in the 2nd example, multiple calls to Create() would lead to multiple requires because of the scope of the call even though the require_once flavor is used.

Is this true? What is the best way to include libraries dynamically in php in an example such as these?

Thanks!

Answer

Kent Fredric picture Kent Fredric · Nov 5, 2008

The Autoload facility is often seen as Evil, but it works at these task quite nicely.

If you can get a good filesystem <-> classname mapping so you can, when given a class to provide, find it, then it will save you overhead and only load classes when needed.

It works for static classes too, so once the static class is in scope, it doesn't need to even call the "is file included yet" test of require once, because the Class is already in the symbol table.

Then you can just create

require("autoloader.php"); 
$x = new Car();  
$x = new Bike(); 

and it will just bring them in when needed.

See Php.net/__autoload for more details.