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

4

7

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!

Tuttifrutti answered 5/11, 2008 at 21:37 Comment(0)
G
7

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.

Gradeigh answered 5/11, 2008 at 21:42 Comment(2)
Is autoload a syntactic sugar such that requires aren't locally scoped?Tuttifrutti
When the file "required" contains class definitions, there is no issue with local scope. PHP does not support "inner classes" like Java; all classes are defined at the "top level" of the current namespace.Transonic
T
2

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.

Transonic answered 5/11, 2008 at 21:44 Comment(0)
E
1

Take a look to the __autoload() function.

Estebanesteem answered 5/11, 2008 at 21:43 Comment(0)
C
0

The point of the require_once function is that no matter the scope, you won't include a file twice and redefine a class causing a PHP error. So no worries about memory leaks, if the require_once is hit, the class def goes in the global symbol table only one time.

But aside from that, yeah use autoloader.

Counselor answered 5/11, 2008 at 22:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.