Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 425
thesmart Avatar asked Nov 05 '08 21:11

thesmart


3 Answers

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.

like image 164
Kent Fredric Avatar answered Oct 23 '22 09:10

Kent Fredric


I would recommend using the autoloader.

That is, don't use require_once() to require either subclass, but allows the autoloader to call a function which can load the referenced class when you call new Truck() or new Car().

As for the memory leak question, no, require_once is not scoped by the code block.

like image 33
Bill Karwin Avatar answered Oct 23 '22 07:10

Bill Karwin


Take a look to the __autoload() function.

like image 23
Davide Gualano Avatar answered Oct 23 '22 08:10

Davide Gualano