Detailed Explanation of PHP Automatic Loading Mechanism Example
- 2021-10-24 19:04:07
- OfStack
This paper illustrates the automatic loading mechanism of PHP. Share it for your reference, as follows:
In php, we use
require
,
requre_once
,
include
,
include_once
These four commands load other php files, which is no problem in a small php file. I believe every beginner will encounter such an application scenario: use an Db. php to define database connection, and directly reference this file in other files to achieve the effect of code reuse.
Let's consider such an application scenario. If we use a framework or a third-party package, there are hundreds of class files in it, and we usually don't have to load these files ourselves. At this time, we use the automatic loading mechanism of php.
Define 1 auto-load mode
In traditional applications, you usually customize
__autoload()
. As follows
define("DIR", "/var/www/myWeb/myClass/");
function __autoload($classname) {
require DIR.$classname.'.class.php';
}
$book = new Book();
The above code works as follows:
1. Customize
__autoload
Function, which defines how the class file is loaded
2. When we have an new instance of Book, it first looks at whether this class is currently included, and if it does not exist, it will automatically call
__autoload
Function and pass the class name Book as an argument to this function. This is actually a dynamic loading method, and only the class files we need will be loaded.
STEP 3 Find
__autoload
Function, find the defined load action
require DIR.$classname.'.class.php';
At this time, it will go to the DIR directory to find the Book. class. php file, and load it if it exists.
4. The definition of class Book. class. php must meet the following conditions: class name and file name 1; One file defines only one class.
The file Book. class. php is as follows
class Book {
public function __construct() {
echo "this is Book's construct\n";
}
}
Register multiple load modes
For our own simple application, one loading mode may be enough, but for larger applications, the above method has obvious defects:
__autoload
Functions cannot be defined repeatedly, that is to say, we can only define one mode of loading files, and the final result is that our classes can only be placed in one place, which obviously does not meet the actual requirements. So php uses a function
requre_once
0
Instead of
__autolaod
.
The code is as follows:
define("MODEL_DIR", "/var/www/myWeb/myModel/");
define("CONTROLLER_DIR", "/var/www/myWeb/myController/");
// Definition Model Class loading mode
function loadModel($classname) {
$filename = MODEL_DIR.$classname.'.php';
if (file_exists($filename))
require $filename;
}
// Definition Controller Loading mode
function loadController($classname) {
$filename = CONTROLLER_DIR.$classname.'.php';
if (file_exists($filename))
require $filename;
}
// Register two load functions
spl_autoload_register("loadModel");
spl_autoload_register("loadController");
// Automatically load class files
$bookMode = new BookMode();
$bookController = new BookController();
In the above code, we can see:
1. You can define multiple load functions using any function name
2. In
requre_once
0
Registering the load function should actually be added to a data structure similar to a bidirectional queue.
3. When our new object does not exist in the current file, it will be automatically found in our load function, and it will be found according to our use
requre_once
0
Registration is carried out in the order.
4. It should be noted that if we define the __autoload method at this time, we must also register it, otherwise it will be ignored.
requre_once
0
There are three ways to register functions:
spl_autoload_register(funName); // Direct registration 1 Ordinary loading functions
spl_autoload_register(obj::method); // Registration 1 Static loading methods
spl_autoload_regitser(array(obj, method)); // When obj Is a class string, only static methods can be loaded. Otherwise, you can do it.
Instances
In various php frameworks, automatic loading mechanism is also widely used. Let's look at it through a small example of laravel.
laravel helps us manage dependencies through Ioc container, so that we can happily get class instances through function parameters, but we also find that we don't have require file, so how does the container find our file address? Let's solve this problem.
Through the entry file index. php, we can find the/vendor/composer/ClassLoader. php file.
Part of the code is as follows
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('obj', 'loadClassLoader'), true, true);
// Using registered load classes through namespaces
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('obj', 'loadClassLoader'));
if (PHP_VERSION_ID >= 50600) {
// This file defines the mapping of namespaces and entity files for package and user classes
// And others 1 Something
require_once __DIR__ . '/autoload_static.php';
// Initialization $loader1 Some attributes.
// We're concerned autoload_static.php Class mapping of files
// Has been assigned a value in $loader Adj. $classMap Attribute
call_user_func(\Composer\Autoload\ComposerStaticInit::getInitializer($loader));
// ...
}
// ...
$loader->register(true);
// ...
return $loader;
}
It calls the
getLoader()
Function and set the
loadClassLoader
Function to the load function registration queue. Then you can use namespaces
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
Instantiate the ClassLoader class.
Next, he loads the /autoload_static. php file, which reads roughly as follows
// It also defines package classes and psr Adj. 1 Some standards
public static $classMap = array (
'App\\Common\\Collection' => __DIR__ . '/../..' . '/app/Common/Collection.php',
'App\\Common\\MgDB' => __DIR__ . '/../..' . '/app/Common/MgDB.php',
'App\\Common\\Redis' => __DIR__ . '/../..' . '/app/Common/Redis.php',
)
I am excited to see here, because the above Collection and Redis are the classes defined by the author!
Then there is the noun "register" that we often hear in laravel. Look at the register method of the ClassLoader class as follows:
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
public function findFile($class)
{
// ...
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
// ...
}
The register method above also uses the auto-load mechanism. The exact location of the corresponding class will be found directly through the findFile function and the $classMap array. That's why we don't have to load the class file ourselves. When we instantiate a class that we can't find in the code, it loads the corresponding class here.
See here, we also found that its use and what we said before are not completely 1. We register the function to find classes through folders, while laravel register the function to register a mapping array and then call it directly (the whole mapping file has more than 3,000 lines...) Why do you have to wait for the next time to read through the loading source code part and then write a blog post (originally only want to find an example of a framework, honey embarrassment)
Author's exampleTwo years ago, when I was in charge of the online part of an association in the school, I mainly developed WeChat. Because a new function had to be added from time to time, it was painful to write in a general way, but it was a bit overqualified to use the framework. Because the following simple method is used:
require "./basic/init.php";
define('WEB_PATH', '');
// Declare and register the auto-load function, indicating the load path and load method
function wechatAutoload($class_name)
{
$file_road = './function/'.$class_name.'.class.php';
if(file_exists($file_road))
{
require_once($file_road);
}
}
spl_autoload_register('wechatAutoload');
//----------------------------------------------
After initializing the configuration, we registered a load function. In the future, every new function only needs to add a file under the function folder, and the other parts are changed little or no (according to the business scenario).
Reference: PHP: spl_autoload_register-Manual
For more readers interested in PHP related content, please check the topics on this site: "Introduction to php Object-Oriented Programming", "Encyclopedia of PHP Array (Array) Operation Skills", "Introduction to PHP Basic Syntax", "Summary of PHP Operation and Operator Usage", "Summary of php String (string) Usage", "Introduction to php+mysql Database Operation Skills" and "Summary of php Common Database Operation Skills"
I hope this article is helpful to everyone's PHP programming.