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.