Php autoload using namespaces
The ability to refer to an external fully qualified name with an alias, or importing, is an important feature of namespaces. This is similar to the ability of unix-based filesystems to create symbolic links to a file or to a directory.
PHP can alias(/import) constants, functions, classes, interfaces, traits, enums and namespaces.
Aliasing is accomplished with the use operator. Here is an example showing all 5 kinds of importing:
Example #1 importing/aliasing with the use operator
namespace foo ;
use My \ Full \ Classname as Another ;
?php
// this is the same as use My\Full\NSname as NSname
use My \ Full \ NSname ;
// importing a global class
use ArrayObject ;
// importing a function
use function My \ Full \ functionName ;
// aliasing a function
use function My \ Full \ functionName as func ;
// importing a constant
use const My \ Full \ CONSTANT ;
$obj = new namespace\ Another ; // instantiates object of class foo\Another
$obj = new Another ; // instantiates object of class My\Full\Classname
NSname \ subns \ func (); // calls function My\Full\NSname\subns\func
$a = new ArrayObject (array( 1 )); // instantiates object of class ArrayObject
// without the «use ArrayObject» we would instantiate an object of class foo\ArrayObject
func (); // calls function My\Full\functionName
echo CONSTANT ; // echoes the value of My\Full\CONSTANT
?>
Note that for namespaced names (fully qualified namespace names containing namespace separator, such as Foo\Bar as opposed to global names that do not, such as FooBar ), the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.
PHP additionally supports a convenience shortcut to place multiple use statements on the same line
Example #2 importing/aliasing with the use operator, multiple use statements combined
use My \ Full \ Classname as Another , My \ Full \ NSname ;
?php
$obj = new Another ; // instantiates object of class My\Full\Classname
NSname \ subns \ func (); // calls function My\Full\NSname\subns\func
?>
Importing is performed at compile-time, and so does not affect dynamic class, function or constant names.
Example #3 Importing and dynamic names
use My \ Full \ Classname as Another , My \ Full \ NSname ;
?php
$obj = new Another ; // instantiates object of class My\Full\Classname
$a = ‘Another’ ;
$obj = new $a ; // instantiates object of class Another
?>
In addition, importing only affects unqualified and qualified names. Fully qualified names are absolute, and unaffected by imports.
Example #4 Importing and fully qualified names
use My \ Full \ Classname as Another , My \ Full \ NSname ;
?php
$obj = new Another ; // instantiates object of class My\Full\Classname
$obj = new \ Another ; // instantiates object of class Another
$obj = new Another \ thing ; // instantiates object of class My\Full\Classname\thing
$obj = new \ Another \ thing ; // instantiates object of class Another\thing
?>
Scoping rules for importing
The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the use keyword:
Example #5 Illegal importing rule
function toGreenlandic ()
use Languages \ Danish ;
Note:
Importing rules are per file basis, meaning included files will NOT inherit the parent file’s importing rules.
Group use declarations
Classes, functions and constants being imported from the same namespace can be grouped together in a single use statement.
use some \namespace\ ClassA ;
use some \namespace\ ClassB ;
use some \namespace\ ClassC as C ;
use function some \namespace\ fn_a ;
use function some \namespace\ fn_b ;
use function some \namespace\ fn_c ;
use const some \namespace\ ConstA ;
use const some \namespace\ ConstB ;
use const some \namespace\ ConstC ;
// is equivalent to the following groupped use declaration
use some \namespace\< ClassA , ClassB , ClassC as C >;
use function some \namespace\< fn_a , fn_b , fn_c >;
use const some \namespace\< ConstA , ConstB , ConstC >;
Autoloading Classes with Namespaces in PHP
Most of the developers working with OOP(Object Oriented Programming) tends to save each class definition in a separate file. In this case, developers face a big problem. They have to include lots of files at the beginning of the document. Let’s consider the following example.
Consider you are going to use several classes that are saved in separated files in your root directory.
Then create index.html in your root directory and add following code
You’ll get the above error because any programming language doesn’t find class files and include them by itself. So, you have to include all the class files before you call the class. (Usually it’s included at the beginning of the document)
But, when including files developers face below shown problem. If they use 10 classes they have to include all the class files at the beginning.
When your project grows day-by-day it may need to include 100 class files in a document. How can a developer do that in lot of documents without making a mistake? It’s impossible! To solve this problem the autoload function comes!
Autoloading
Mainly there are two ways to define a autoload function.
This will register autoload function and will try to load class files
); $dog = new dog(); $cat = new cat(); // static_methods below echo cow::getToken(); echo fox::$name;
Step By Step.
- First we define the autoload function with spl_autoload_register function.
- When a new class called the callback function triggers.
- Then, PHP sends the class’s name as a parameter or the function and we have used it as $className
- Then, we can use following functions to include the class file
- require
- require_once
- include
- include_once
- All of those functions have their own pros and cons. The best one to use when autoloading is include_once
- It won’t stop the execution if an error occurs. Also, it won’t include the same file twice. Therefore it’s used widely by developers to include class files.
- Did you notice something unusual in the code? Nevermind! In PHP include_once ‘class.php’ is same as include_once(‘class.php’) . Use anything you like.
- Finally we add the .php extension and include it.
Think about the time the code new dog(); is executed. Then PHP calls the callback function. «dog» is sent as the parameter ($className). Then «dog.php» is included.
How To Organize Your Classes Like a PRO
How does an experienced programmer organize their class files? They use some simple tricks. Here is a simple and powerful file structure
/ ajax inc class class1.php class2.php class3.php css js images
Simply, save all the class files in a folder in the root («class» is recommended as the folder name).
Then create your powerful autoload function.Explained.
- Here we create an autoload function as we discussed previously. (But this function has more advantages than the previous one)
- $_SERVER[‘DOCUMENT_ROOT’] (string) holds the path of the root folder in the server computer. This variable is set by the server when the page is requested. However, by using this trick you can use class files with any document in any sub folder.
- As an example, think that you are using class1 in the file /ajax/update.php . When you trigger the class, the class name is added to the $className variable in the spl_autoload_function . If we use previous function (mentioned in the first part of this tutorial) it will include a file relative to the current folder, /ajax/class/class1.php . By using $_SERVER[‘DOCUMENT_ROOT’] it will include something like /web/www/public_html/class/class1.php which is an absolute path.
Important! You must save the class files with the name of the class. Otherwise this trick won’t work.
Autoloading Namespaces
When a website becomes larger, it’s harder to keep all the class files in a same directory. Also we have to use very long names for files and classes, such as animal_dog_dog1_addName . It is a really bad practice. Namespaces are introduced to prevent this problem. Let’s see how it works!
By using namespaces you can save your classes in sub folders. The file of the class name can be saved in /class/dog as well as /class/cat. Here is the file structure.
class animals dog.php cat.php goat.php birds owl.php peacock.php pets dog.php cat.php mainClass1.php mainClass2.php mainClass3.php
In above file structure you can understand, different files with the same name can be saved in different locations (folders). Namespaces are based on this simple logic. Now the problem is how to autoload them? Here is how namespaces are called with PHP.
); $dog = new animal\dog(); $cat = new animal\cat(); // static functions animal\cat::name(); animal\cat::appearance();
Step By Step.
- First we defines the autoload function as we discussed earlier.
- «animal\dog» will be as the $className parameter to the autoload function.
- So, it will include /your_document_root/class/animal\dog.php . (See the back slash)
- This autoloading function will work fine on Windows OS. But the «\» will cause errors in other operating systems.
- Therefore we have to upgrade our autoloading function.
Explained.
- We have added str_replace function here
- It matches «\» (back slash).
- Then replaces it with the value of DIRECTORY_SEPARATOR constant. (This is a PRE-DEFINED-CONSTANT which hold a string, the directory separator according to the operating system)
- This piece of code replaces \ to / if necessary.
At The End
- Always name the class file with the name of the class.
- Use namespaces when necessary. (When the class files need to be stored in separate folders)
- Create a powerful autoload function as we discussed above, which supports normal classes as well as namespaces.
- It is a bad practice to add spl_autoload_register in all the php scripts. So, create a file called autoload.php and save it in the root directory (or in a directory you have include files).
- Then you just have to include autoload.php in a php script to register the autoload function. ( include_once $_SERVER[‘DOCUMENT_ROOT’] . ‘/autoload.php’ )
If you have any questions comment below. We are always here to help you.