PHP autoloading is the ability to define a 'use' operator to automatically load a class. It does not use the 'require' operator.
Autoloading is part of the 'composer' that manages PHP packages and is a necessary feature of PHP.
I will explain how to use it in a detailed and easy to understand manner.
This is written by a Japanese who can't speak English with the help of translation application. Sorry if it's not good.
- What is autoloading?
- Let's use autoload!
- Creating composer.json file
- Installation of the autoload package
- PHP sample program creation
- Editing composer.json
- Updating the autoload map file
- Let's run the program!
- Updating the autoload map
- Be careful when using 'dump-autoload -o'
- Non-class can also autoload
- Laravel is already in
- Summary of autoload
- The types specified in autoload
- Development environment autoload
What is autoloading?
Autoloading is the ability to use PHP classes without 'require' a class file, just defining a 'use' operator.
<?php
require "TestClass1.php";
require "TestClass2.php";
require "TestClass3.php";
use TestClass1;
use TestClass2;
use TestClass3;
$test1 = new TestClass1();
$test2 = new TestClass2();
$test3 = new TestClass3();
<?php
require vendor/autoload.php
use TestClass1;
use TestClass2;
use TestClass3;
$test1 = new TestClass1();
$test2 = new TestClass2();
$test3 = new TestClass3();
I don't get an error when I don't have TestClass* written anywhere and I haven't imported TestClass*.php.
That's because TestClass* was already required by the autoload.
In object-oriented programming, we use a lot of classes. And there is a rule of 'one file, one class'.
If we don't have autoload, we have to write a lot of class file requirements. We have autoloading to avoid doing that.
Let's use autoload!
Let's use autoload before I explain. Just work in the same way.
First, install the composer in the PHP environment, because you can't use it without the composer.
Creating composer.json file
Go to the PHP project home. Here is 'user-test/php-test-autoload'.
...─ php-test-autoload
├─ (empty)
Still, the contents of the project are empty. Now run the command composers.
composer init
You will be asked for various inputs, but for now, just press the Enter key.
...─ php-test-autoload
├─ composer.json
There should be a composer.json in the home of the project.
{
"name": "user-test/php-test-autoload",
"authors": [
{
"name": "user-test",
"email": "user-test@gmail.com"
}
],
"require": {}
}
The 'authors' can be empty. It must be set in php.ini and will not be added.
Installation of the autoload package
The project only has a composer.json. Next, install the autoload package.
composer install
The autoload package has been installed.
...─ php-test-autoload
├─ vendor
│ ├─ composer
│ │ ├─ autoload_classmap.php
│ │ ├─ autoload_namespaces.php
│ │ ├─ autoload_psr4.php
│ │ ├─ autoload_real.php
│ │ ├─ autoload_static.php
│ │ ├─ ClassLoader.php
│ │ ├─ installed.php
│ │ └─ LICENSE
│ └─ autoload.php
└─ composer.json
The vendor directory is the installation location for the packages to be added to the 'require' of composer.json.
Since autoload is a feature of the composer, it was installed in the 'vendor/composer' directory.
vendor/autoload.php
There is also a program that runs autoload? Just load it with the 'require' operator and you can autoload it.
Since autoload is a basic feature of the composer, it is always installed with the first 'composer install' command.
Same thing if composer.json's 'require' is empty.
The 'require' in compsoer.json is a list of packages to be installed in the project.
PHP sample program creation
The autoload package has been added to the project. Next, add the sample program to the project.
...─ php-test-autoload
├─ src
│ ├─ main.php
│ ├─ TestClass1.php
│ ├─ Test2
│ │ └─ TestClass2.php
│ └─ Test3
│ └─ TestClass3.php
├─ vendor
│ ├─ composer
│ │ ├─ autoload_classmap.php
│ │ ├─ autoload_namespaces.php
│ │ ├─ autoload_psr4.php
│ │ ├─ autoload_real.php
│ │ ├─ autoload_static.php
│ │ ├─ ClassLoader.php
│ │ ├─ installed.php
│ │ └─ LICENSE
│ └─ autoload.php
└─ composer.json
<?php
namespace Origin;
class TestClass1 {
function __construct() {
echo "new instance TestClass1\n";
}
}
<?php
namespace Origin\Test2;
class TestClass2 {
function __construct() {
echo "new instance TestClass2\n";
}
}
Do the same for TestClass3; note the difference in namespace between TestClass1, TestClass2 and TestClass3.
It will come out later, but this time we will use psr4 coding conventions. psr4 has the following rules
- Class files must have namespace.
- The namespace should match the directory configuration and name.
- Namespace names start with a capital letter.
PSR (PHP Standards Recommendations)
A standardization effort for PHP coding, developed by PHP-FIG.
PHP-FIG (PHP Framework Interop Group)
PHP Framework Interoperability Group, an organization where PHP projects get together to discuss and coordinate the compatibility of each other's products.
Many famous projects are participating.
<?php
require "vendor/autoload.php";
use Origin\TestClass1;
use Origin\Test2\TestClass2;
use Origin\Test3\TestClass3;
new TestClass1();
new TestClass2();
new TestClass3();
Editing composer.json
Register the directory where the class files are located, so that autoload can get them.
Registration is done with the composer's configuration file, composer.json.
{
"name": "user-test/php-test-autoload",
"authors": [
{
"name": "user-test",
"email": "user-test@gmail.com"
}
],
"require": {},
"autoload": {
"psr-4": {
"Origin\\": "src/"
}
}
}
In autoload{}, the class files in the src directory are registered to begin with 'Origin'.
In psr4, namespace names must start with a capital letter, so 'src' cannot be used.
Here, when loading the class, we convert 'src' to 'Origin' to match the namespace.
Match directory configuration and namespace configuration
The composer.json will be updated when you install the package using composer.
The class of the package is automatically added to the autoload{}. You do not have to work by yourself.
This time, I edited it directly in my own program and not in the composer package.
If you edit composer.json directly, you must execute the following command.
composer validate
This is the composer.json syntax check command. If you get an error, your edits are wrong.
Be careful, as you will not be able to use composer commands.
Updating the autoload map file
Update autoload.
composer update
This updates the settings in composer.json to be precise. Since we added autoload{}, this will also update autoload.
The mechanism of autoload is simple.
composer install
composer update
composer require
Execute this command to create and update the map file.
The contents of the map file is just an array, in which the classes and namespaces are defined.
Autoload doesn't load a class, it just refers to the defined class.
...─ php-test-autoload
└─ vendor
└─ composer
├─ autoload_classmap.php
├─ autoload_namespaces.php
├─ autoload_psr4.php
├─ autoload_static.php
└─ installed.php
You saw earlier, these files of autoload are map files.
The autoload registration of psr4 in composer.json will be updated like this
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Origin\\' => array($baseDir . '/src'),
);
The conversion 'src' -> 'Origin' is registered in the map.
When the composer command updates the composer.json file, it expands the contents defined in autoload{} to the autoload map file.
vendor/autoload.php is a summary of all the map files. So only 'require'.
Let's run the program!
The autoload sample program is now complete. Let's run it.
php src/main.php
new instance TestClass1
new instance TestClass2
new instance TestClass3
If you run it in the home of the project and get the same result, the usage of autoload is OK.
Updating the autoload map
Earlier, we updated the map file with this command.
composer update
But this command is for updating the composer.json file, not for updating the map.
For example, when you add the source code, the class is not registered in the map.
The composer.json has not been edited, so the "composer update" command will not work either.
In that case, use the following command.
composer dump-autoload
This reconstructs the autoload map only.
Class not Found
Let's do this once it occurs.
Surprisingly, sometimes it is not a bug in the program, but just the map is not updated.
Be careful when using 'dump-autoload -o'
Autoload has a map optimization feature called 'Autoloader Optimization' for fast loading.
composer dump-autoload -o
'-o' option. But be careful.
With this option, the rules of psr-4 will be ignored when rebuilding the class map.
Class files with namespace and directory configurations that do not conform to psr-4 will also be registered in the class map.
You may suddenly get a lot of "Class not Found".
This happens when you are updating a map with options and one time you update it without options. Surprisingly, this pattern is very common.
It should be noted that this is a common occurrence in Laravel.
Development Environment | No options |
Production Environment | Optional |
It is better to use this usage.
Non-class can also autoload
Autoload can autoloading even outside of classes.
- interface
- function
- const
<?php
require vendor/autoload.php;
use My\Full\ClassName as ClassName;
use My\Full\InterfaceName as IFName;
class Test extends ClassName implements IFName {
// ...
}
// >= PHP 5.6
use function My\Full\functionName as func;
$ret = func();
// >= PHP 5.6
use const My\Full\CONSTANT CONST_A;
$val = CONST_A;
However, function and const are only supported by PHP version 5.6 or later.
Laravel is already in
The PHP web framework Laravel includes a composer.
There is also composer.json and the autoload package in vendor/composer.
require vendor/autoload.php
This is also not necessary. It is already implemented in public/index.php.
Summary of autoload
- Write "require vendor/autoload.php" only once in the source code.
- The use operator allows classes, interfaces, functions and const to be autoloaded.
- Write the configuration in the composer.json file.
This is the only basic usage of autoload.
I'd like to say "this is the end", but I'll continue with the advanced part.
Didn't you also describe the psr4 used in composer.json's autoload{} ?
Other methods of specification are also described.
The types specified in autoload
The composer.json's autoload{} can be specified in a variety of ways other than psr-4.
Let's take a look at them one by one.
files
"autoload": {
"files": [
"src/functions/func1.php",
"src/const/const1.php",
]
}
Autoload functions and const from .php files. Use it outside of classes and interfaces.
Map files
vendor/composer/autoload_files.php
psr-4
"autoload": {
"psr-4": { "Vendor\\": "src/vendor/" }
}
"autoload": {
"psr-4": { "Vendor\\": ["src/Vendor/", "lib/Vendor/"] }
}
Use in Laravel and other psr-compliant ones.
The psr-4 namespace and directory configuration should match.
Specify the directory location of its top-level namespace directory.
You can also specify more than one, enclosed in [].
In PHP it is normal to conform to the PSR, and it is rare not to participate like in WordPress.
However, there are many projects that do not participate.
When the namespace and directory configuration do not match in psr-4, an error occurs during application execution.
Class not Found
The error of the package itself does not occur, so it looks as if the application has a bug.
The map information in autoload may be outdated or a bug in the package.
psr-4 also includes what you set up in psr-0.
No need for psr-0 settings, which will be explained later.
Map files
vendor/composer/autoload_psr-4.php
vendor/composer/autoload_static.php
vendor/composer/autoload_classmap.php
psr-0
"autoload": {
"psr-0": {
"Vendor\\": "src/Vendor/",
"Vendor\\Namespace\\": "src/Vendor/",
"Vendor_Namespace_": "src/"
}
}
The current level of psr is predominantly 4.
Since larger psr levels include lower levels, psr-0 is rarely used.
Use it with older source code, such as projects that have been around for a few years, or those that are up to psr-2 compliant.
There is no psr-2 in composer autoload.
Map files
vendor/composer/autoload_classmap.php
classmap
"autoload": {
"classmap": ["src/", "lib/", "Something.php"]
}
Use when not complying with psr, such as WordPress.
Map files
vendor/composer/autoload_classmap.php
exclude-from-classmap
"autoload": {
"exclude-from-classmap": ["/Tests/", "/test/", "/tests/"]
}
Set the autoload exclusion.
Specify classes that are not used in the production environment, such as test classes.
Map files
vendor/composer/autoload_classmap.php
Development environment autoload
Set the autoload of the development environment.
Specify the test class and so on. The only directory that can be specified is the root directory.