File Load---Understand the first step of a project

Source: Internet
Author: User
Tags autoload php tutorial
When I first started writing PHP, I was always worried about the question: Am I here to load a class file with a new one? After all, a run on the report fatal error, what * * File not found, class can not be instantiated and so is a very "low-level" error, afraid of others to see jokes. So every time a new task, I always want to make it clear the loading process (previously only know a few HTML tags and style, do not know that the web development), sometimes the chief looked at the Bambo to see this, and quickly write logic, according to do so on the line ... Your sister, you know, of course. D: And later found that the original process is similar.

In the development of an IDE, such as C++/java, is generally a new project, through the IDE to add a new file to the specified directory, and then #include/import come in, PHP makes this step more process, The loading process of the file basically determines the directory structure and file categories of this project (framework or self-built project).

Regardless of the framework or self-built project must have a portal file, this time to load some basic information, such as configuration files, general methods, etc., using the basic manual directly loading a single file form, using one of the following four methods:

Include, require, include_once, require_once

    include (' config.php ');     require (' database.php ');

Involving the loading of class files, a few are directly loaded, for example, the general method is written as a static method in a class utilities, because there are many methods to use behind (such as error output, curl request, random string generation ...) ), so it is common to load the configuration file with the class package.

Include (' utilities.php ');

The more general case is: Dynamic loading of classes. First do not talk about the way to load, to see when a class and an instance will probably be used:

1. Most obvious, $obj = new A; Its variant $classname = ' A '; $obj = $className; are the same;

2. Invocation of static methods, static variables, and constants of the class, i.e. utilities::httprequest (), Utilities:: $instance, Utilities::host;

3. In PHP functions, the use of the callback function, the most typical Call_user_func_array (Call_user_func), there are other places to use callback, such as the Array_walk, Array_map in the array, They require a callback function as a parameter.

The callback function is very flexible and can be more than just a simple function, but also a method of an object, including static class methods. Because you can use object methods or static methods, it is time to load the corresponding class file. Since php5.3, the callback function can also be implemented in the same way as JS, using anonymous functions.

     class a{         publicstaticfunction cube ($var) {             return  Pow($var, 3);         }                    Public function twice ($var) {             return $var;         }     }      //  Use static method of class     $numcall_user_func(' A::cube ', 5);      // working with Objects     $obj New A;      $num Call_user_func_array (array($objarray(7));

Strictly speaking, the Call_user_func_array in the previous example has previously instantiated the object, but there is such a usage, and it can use the class static method entirely.

The first thing to understand is why you need to load dynamically. PHP is a scripting language, and when we access it, we use scripts as available resources, such as the root directory now has a index.php file, it does not include any other files, when we directly to localhost/ When index.php comes to access, it can access all the resources in index.php, and if a normal class A is defined in index.php, the program responds by instantiating an object of a in the script: Oh, I've seen the definition of a and can instantiate it directly (no need to load other files). If there are classes B, C, D and many other classes, all written in the index.php obviously not, it is written in other files, and then include (include is already doing the work of loading), so it is "visible" to the program.

But with the increase of the system function, the class is more and more, the function of each class is different, some directly define the operation of the database, read the data of the database, some of the methods to run when the access script is controlled, some are the pages to be displayed, some of the third-party core libraries we quoted, so, When we put all the files in a directory, although can be directly include loading, but these files appear to be messy and difficult to find, maintenance costs are high. Good Bai, then in the root directory and then build a few directories, directory a dedicated to the database to deal with the script, directory B is the system's various configuration information files, directory C is the control of our entry into the program when the entry control method of the script, directory D is about to display to the browser page ...

So the MVC architecture slowly evolved, we can no longer like the previous direct include, the script is placed in a specific directory, such as the controller directory is stored in a variety of controllers, when loading the controller, we have to include (' root/controller/ Indexcontroller.php '), each time in front of the file to get a bunch of include not only look at the headache, it is almost tired of people do not love. Now that you have an out-of-the-box method for getting the current file path and class name, why not match the class name with the file name, and as long as the script for the Controller class is placed entirely underneath the controllers subdirectory of the root directory, you can write a method that, as long as the Controller class, runs the include in this method ( ROOT. ' controller/'. $className. php '), root is the root directory constant, $className the passed-in class name, as long as the model class, so include (root. ' model/'. $className. php '); This is the function to dynamically control which directory to look for, this project might be:

Virtually, the corresponding rules of the class name and file name are established, the corresponding rules of the file and the directory in which it is located, what are the directories and files under this project? Ah originally is the controller, put configuration information config, and so on, again in the invisibly learned the structure of the project, and above said, using the function according to certain conditions (incoming parameters) know automatically to which directory to load the file, Instead of writing a dead include, the so-called file is dynamically loaded.

Therefore, when you want to create a new * * class file, you will know, oh in this project, I should put in this directory, the name of the file should be the same as the class name, so it can be loaded to ~ ~ ~ Next is to write business logic of a "pleasant process."

Knowing when to load dynamically and why it should be dynamically loaded, the next step is to implement it, that is, the use of functions to load a file, that is, to write this "function" to achieve this process. There are three ways to use it:

1. __autoload

The first time I learned that is the use of this, magic function, as long as the definition of PHP program will be used in a class automatically call it for the file dynamic loading, as if it is a function, it is necessary to make the program to __autoload definition visible, or from where to call it? In general, as the next procedure in most places to use the method, we will be placed in a separate file, at the entrance of the program to load, a project must have a few files are manually included, can be included in the beginning of a separate include, or placed in the configuration information, Loading the configuration information is loaded in. It's prototype:

  void __autoload ( string $class)

Parameter the name of the class name that is currently loaded (note that if there is a namespace, the namespace prefix is included), here is a simple example of the structure of the picture above:

    //file:autoload.php//root is a defined root directory constant    function__autoload ($className){        Try{            if(file_exists(ROOT. ' controller/'.$className.'. php ')) {//Check Controller                include(ROOT. ' controller/'.$className.'. Php); }            Else if(file_exists(ROOT. ' model/'.$className.'. php ')) {//Check Model                include(ROOT. ' model/'.$className.'. Php); }            Else if(file_exists(ROOT. ' lib/'.$className.'. php ')) {//Check Lib                include(ROOT. ' lib/'.$className.'. Php); }            Else{//the file could not be found                Throw New Exception("Error:can ' t find file {$className}.php "); }        }        Catch(Exception $e){            Echo $e.GetMessage (); Exit; }    }

  

2. Spl_autoload_register

__autoload is actually pretty much the same, but it's PHP-defined, and if something is written and called, it tells the program that I don't have to __autoload to load the file, and I've defined a method that specifically loads the file (for example, the name is LoadClass), When you need to load a class file later, you can use it. Spl_autoload_register is such a way to tell the program to do this, and the custom loading method will be more flexible, you can specify multiple load functions, the Spl_autoload_register function will put these functions in a queue, and activate them, When invoked, activate one by one: "If there must be multiple autoload functions, spl_autoload_register () allows for this." It effectively creates a queue of autoload functions, and runs through each of the them in the order they is defined. ", Php.net (http://php.net/manual/en/function.spl-autoload-register.php) did explain this, spl_autoload_ The unregister is logged off from the Load function queue.

In addition to the spl_autoload_functions () function, you can obtain which functions we have registered, and the Spl_autoload_call ($class) function, which attempts to invoke all of the registered load functions to load the $class class file.

For Spl_autoload_register's explanation, my understanding is that if you register n functions with Spl_autoload_register in the load queue, because it activates them automatically, now I'm going to instantiate a class that fails to load in the 1th load function. Then try the 2nd function, the second fails to try the 3rd, "', until the nth function is finished, if not loaded successfully, the error, as long as the middle of a successful loading success, but the fact seems a bit out of the way.

Or use the directory structure in the previous image,

1. Create indexcontroller.php file under Controller, including class Indexcontroller;

2, in the model directory to create usermodel.php files, including class Usermodel;

3, the first page to write a class load script autoload.php, the code is as follows:

    //file:Autoload.php    Define(' DS ',directory_separator); Define(' ROOT ',RTrim(dirname(__file__), '/\\').DS); classautoload{ Public Static functionAutoloadregister ($loadFunc= ' Autoload::loadcontrollerclass ',$enable=true){            return $enable? Spl_autoload_register ($loadFunc): Spl_autoload_unregister ($loadFunc); }        //loading the Controller class         Public Static functionLoadcontrollerclass ($className){            if(file_exists(ROOT. ' Controller '). Ds.$className.'. php ')) {//Check Controller                include(ROOT. ' Controller '). Ds.$className.'. Php); EchoROOT. ' Controller '. Ds.$className.'. php '. '
'; } Else{ Echo"Error:can ' t find file {$className}.php in ". ROOT. " Controller "; Exit; } } //Load Model Classes Public Static functionLoadmodelclass ($className){ if(file_exists(ROOT. ' Model '). Ds.$className.'. php ')) {//Check Model include(ROOT. ' Model '). Ds.$className.'. Php); EchoROOT. ' Model '. Ds.$className.'. php '. '
'; } Else{ Echo"Error:can ' t find file {$className}.php in ". ROOT. " Model "; Exit; } } }

4, test the script, test whether the class can be loaded

    //registering two load functionsAutoload::autoloadregister (' Autoload::loadcontrollerclass '); Autoload:: Autoloadregister (' Autoload::loadmodelclass ');//See which load functions are registered in total    Echo' Register functions=>
';     Print_r (Spl_autoload_functions ());     // instantiate a controller class and model class separately    $indexCon New Indexcontroller;     $userMod new Usermodel;

The result is this.

  

It's not scientific, spl_autoload_functions array shows two functions are registered, but when instantiating the Usermodel class it is still running to the controller directory to find, two classes of the automatic loading method of the instantiation call is AutoLoad:: Loadcontrollerclass, so the Usermodel class file loading error ... Notice that the third parameter of the Spl_autoload_register method is the position placed in the stack when adding a load function, so I write a similar class otherload, just to put the Loadmodelclass method in the queue header:

    classotherload{ Public Static functionAutoloadregister ($loadFunc= ' Otherload::loadmodelclass ',$enable=true){            //By default, Loadmodelclass is placed on the team's first            return $enable? Spl_autoload_register ($loadFunc,true,true): Spl_autoload_unregister ($loadFunc); }        //Load Model Classes         Public Static functionLoadmodelclass ($className){            if(file_exists(ROOT. ' Model '). Ds.$className.'. php ')) {//Check Model                include(ROOT. ' Model '). Ds.$className.'. Php); EchoROOT. ' Model '. Ds.$className.'. php '. '
'; } Else{ Echo"Error:can ' t find file {$className}.php in ". ROOT. " Model "; Exit; } } }

The test is like this

    //registering three load functionsAutoload::autoloadregister (' Autoload::loadcontrollerclass '); Autoload:: Autoloadregister (' Autoload::loadmodelclass '); Otherload:: Autoloadregister (' Otherload::loadmodelclass '); //See which load functions are registered in total    Echo' Register functions=>
';     Print_r (Spl_autoload_functions ());     // instantiate a controller class and model class separately    $indexCon New Indexcontroller;     $userMod new Usermodel;

This time the result is this:

  

As you can see, this time it was not successful when loading the Indexcontroller class, because it only called the Loadmodelclass method, and then looked at the array returned by Spl_autoload_functions. The Loadmodelclass method of the Otherload class is at the top, is it that only the functions that are in the front of the load function queue are used for automatic loading, others are not valid? What's the situation?

Use Spl_autoload_call (' Indexcontroller ') to " attempt to invoke all registered functions to load the request class ", or to report the error.

Flipping through someone else's article, including a blog on GitHub, is a list of "multiple loading functions can be registered at once Bala Bala ...", or is there a problem with my understanding >3< (Win under test, PHP version 5.4.10) This is the case Spl_autoload_register method doesn't make much sense ╮(╯▽╰)╭ ...

There are several interesting places about Spl_autoload_register:

1, a function will only be loaded into the function queue once, repeated loading is the same;

2, Spl_autoload_register If you do not specify a load function (the first parameter), the load function spl_autoload is used by default (functionally similar to __autoload, which is its default implementation)

3, Spl_autoload_register specified __autoload as the load function, you must implement __autoload;

4. The spl_autoload_register and __autoload are implemented at the same time, and the loading function with Spl_autoload_register registration is preferred.

The above several cases can be found from the Php.net note in the test example, the foreigner is very interesting to write, for reference. The 2nd of the above should be noted, for example, to create a directory in the root directory and load it using the default function:

    // set the extension of the load file to load only the *.php file    Spl_autoload_extensions ('. php ');     // By default, the file is loaded with Spl_autoload and only the files in the current directory are loaded: Lowercase class name. PHP     spl_autoload_register ();     // test    //$obj = new A;

Spl_autoload_extensions sets the file that is only recognized by the extension type when loading, the default is. php or. inc files, which are set to. php, and then call the registration function. Create a a.php file in the root directory, a new Class A, load successfully, and then change the file name to a.php, so the load succeeds. Note that spl_autoload defaults to lowercase the class name, but a.php is still loaded successfully because the Windows file is case insensitive (creating a d.txt in the same directory, creating D.txt is considered the same file), and for Mac OS X. But Linux is case sensitive, so be aware of this when testing.

It's not all about auto-loading, like CI, which encapsulates the load file as a core class Ci_loader, the program starts with the necessary scripts (other core classes to use), and so on, when needed, the Ci_loader instance is an attribute member of the current controller class or model class. It is called by means of the various model (model), view (view), Database (object), helper (auxiliary function), and so on.

Regardless of the use of dynamic loading, it must be ensured that the files are categorized, the files are named according to certain rules, this is a robust, high-scale, high-use project necessary, write code to also convenient. Of course, the number of loading files, the amount of memory, each has a different, but also a number of criteria to judge a framework. Figuring out how to load, being familiar with a frame structure is not a very easy thing to =_= ...

  

The above describes the file loading---Understand the first step of a project, including aspects of the content, I hope to be interested in PHP tutorial friends helpful.

  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.