#php

The benefits of autoload and namespace in PHP programing

In this post I will show you some examples to run PHP code with and without autoload or namespace, thereby you will see the benefits of PHP programming with autoload and namespace.

1. If use autoload you don’t need to declare require many times.

I create a project folder name Post20180420 and then create some simple classes with file structure like so:

Post20180420
|---space1
|   |   AnyClass.php
|   |   ClassA.php
|   |   ClassB.php
|   |   ClassC.php
|
|   ex1.php

// space1/ClassA.php
<?php

echo __FILE__ . "<br>"; // to show the file location

class ClassA
{
    public function drink()
    {
        echo 'drink';
    }
}

// space1/ClassB.php
<?php

echo __FILE__ . "<br>";

class ClassB
{
    public function eat()
    {
        echo 'eat';
    }
}

// space1/ClassC.php
<?php

echo __FILE__ . "<br>";

class ClassC
{
    public function echoSomething()
    {
        echo 'something';
    }
}

I have a file name ex1.php roles like a main file to execute:

// ex1.php
<?php

require_once __DIR__ . '/space1/ClassA.php';
require_once __DIR__ . '/space1/ClassB.php';
require_once __DIR__ . '/space1/ClassC.php';

$a = new ClassA();
$b = new ClassB();
$c = new ClassC();

$a->drink();
echo "<br>";

$b->eat();
echo "<br>";

$c->echoSomething();
echo "<br>";

In file ex1.php I need to call the methods of classes ClassA ClassB ClassC, so I have to declare require_once three times, that’s OK. But in case, I have many classes to call, it will annoy a lot when I have a ton of classes to require. PHP autoload method will resolve this problem. I rewrite the code with function spl_autoload_register:

// ex1.php
<?php

spl_autoload_register(function ($className) {    require_once __DIR__ . "/space1/{$className}.php";});
$a = new ClassA();
$b = new ClassB();
$c = new ClassC();

$a->drink();
echo "<br>";

$b->eat();
echo "<br>";

$c->echoSomething();
echo "<br>";

Output:

D:\PROJECTS\dev\anttr\snippets\Post20180420\space1\ClassA.php
D:\PROJECTS\dev\anttr\snippets\Post20180420\space1\ClassB.php
D:\PROJECTS\dev\anttr\snippets\Post20180420\space1\ClassC.php
drink
eat
something

The results are same but I don’t need to require many time.

2. With autoload, a class just be loaded when its methods are called, it increases performance.

Let’s take a look to ClassD without autoload and file ex2.php

Post20180420
|---space1
|   |   AnyClass.php
|   |   ClassA.php
|   |   ClassB.php
|   |   ClassC.php
|   |   ClassD.php
|
|   ex1.php
|   ex2.php

// space1/ClassD.php
<?php

require_once __DIR__ . '/ClassA.php';
require_once __DIR__ . '/ClassB.php';
require_once __DIR__ . '/ClassC.php';

echo __FILE__ . "<br>";
class ClassD
{
    public function drinkSomething($something)
    {
        $second = new ClassA();
        $second->drink();
        echo " $something";
    }

    public function eatSomething($something)
    {
        $first = new ClassB();
        $first->eat();
        echo " $something";
    }

    public function printSomething()
    {
        $c = new ClassC();        $c->echoSomething();    }
}

// ex2.php
<?php
spl_autoload_register(function ($className) {
    require_once __DIR__ . "/space1/{$className}.php";
});

$d = new ClassD();
$d->printSomething();

In every class I write the line echo __FILE__ . "<br>" to show file location, it will be called when the file is load.

In ex2.php I use method \ClassD::printSomething() refer to \ClassC::echoSomething(), I execute ex2.php and get the result:

D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\ClassA.php
D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\ClassB.php
D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\ClassC.php
D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\ClassD.php
something

The output shows that ClassA ClassB ClassC ClassD was loaded, although I just use ClassC and ClassD. So it’s not really good for performance. Now, I edit ClassD to use autoload and see the result:

// space1/ClassD.php
<?php
//require_once __DIR__ . '/ClassA.php';
//require_once __DIR__ . '/ClassB.php';
//require_once __DIR__ . '/ClassC.php';

spl_autoload_register(function ($className) {    require_once __DIR__ . "/{$className}.php";});
echo __FILE__ . "<br>";

class ClassD
{
    public function drinkSomething($something)
    {
        $a = new ClassA();
        $a->drink();
        echo " $something";
    }

    public function eatSomething($something)
    {
        $b = new ClassB();
        $b->eat();
        echo " $something";
    }

    public function printSomething()
    {
        $c = new ClassC();
        $c->echoSomething();
    }
}

Here is the output. Like expected, there are 2 classes are loaded:

D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\ClassD.php
D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\ClassC.php
something

3. With namespace, it be able create the classes with the same name. No need to define a class with the too long name anymore.

In the more complicated project I need to define some classes with the same name as the existing class. Without namespace I cannot do that. I define the new space2 folder and ex3.php:

Post20180420
|---space1
|   |   ClassA.php
|   |   ClassB.php
|   |   ClassC.php
|   |   ClassD.php
|
|---space2
|   |   ClassA.php
|   |   ClassB.php
|   |   ClassC.php
|
|   ex1.php
|   ex2.php
|   ex3.php

Following is content of ClassA in space2

// space2/ClassA.php
<?php
echo __FILE__ . "<br>";

class ClassA
{
    public function drink()
    {
        echo 'Class A from Space2';
    }
}

In ex3.php I need to call to the drink methods of 2 classes space1/ClassA and space2/ClassA.

// ex3.php
<?php
require_once __DIR__ . "/space1/ClassA.php";
require_once __DIR__ . "/space2/ClassA.php";

$a1 = new ClassA(); // ?$a2 = new ClassA(); // ?$a1->drink(); // ?$a2->drink(); // ?

Fatal error: Cannot declare class ClassA, because the name is already in use in D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space2\ClassA.php

Apparently, no way to do that without rename 2 of ClassA to the different names like space1/Space1_ClassA and space2/Space2_ClassA.

Post20180420
|---space1
|   |   ClassA.php
|   |   ClassB.php
|   |   ClassC.php
|   |   ClassD.php
|   |   Space1_ClassA.php
|
|---space2
|   |   ClassA.php
|   |   ClassB.php
|   |   ClassC.php
|   |   Space2_ClassA.php
|
|   ex1_with_autoload.php
|   ex1.php
|   ex2.php
|   ex3.php

// space1/Space1_ClassA.php
<?php
echo __FILE__ . "<br>";

class Space1_ClassA
{
    public function echoSomething()
    {
        echo 'ClassA from Space1';
    }
}

// space2/Space2_ClassA.php
<?php
echo __FILE__ . "<br>";

class Space2_ClassA
{
    public function echoSomething()
    {
        echo 'ClassA from Space2';
    }
}

// ex3.php
<?php
//require_once __DIR__ . "/space1/ClassA.php";
//require_once __DIR__ . "/space2/ClassA.php";

require_once __DIR__ . "/space1/Space1_ClassA.php";require_once __DIR__ . "/space2/Space2_ClassA.php";
//$a1 = new ClassA(); // ?
//$a2 = new ClassA(); // ?
//$a1->drink(); // ?
//$a2->drink(); // ?

$a1 = new Space1_ClassA();
$a2 = new Space2_ClassA();

$a1->echoSomething();
echo "<br>";
$a2->echoSomething();

Now, the output is OK:

D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space1\Space1_ClassA.php
D:\PROJECTS\dev\anttr\content\snippets\2018-04-20\space2\Space2_ClassA.php
ClassA from Space1
ClassA from Space2

With the complicated projects, you will get the headache to think of names for a ton of class in deeper folder, namespace will resolve that problem. So, how to use namespace and autoload? Let visit my post.

Truong An

Truong An

Self-learner, passionate software engineer from Vietnam

Read More