In the last article I raised a question, how to implement automatic loading a class?
In fact, PHP already has the appropriate mechanism to implement this function, the mechanism is autoload, it will be invoked when attempting to use a class that has not yet been defined.
Now we can define the AutoLoad function at the beginning of the route.php (of course, this is not normal, but for simplicity, do this first).
Our present automatic import needs to import two kinds of files, one is the framework class file, the other is the User Application module class file, in order to simplify the code, you can assume that all the files of the framework are stored under the/library/test directory, the user class files are stored in the/userapps/ The modules directory is below, and will only be under the Controllers,models,helpers three directories, and there are no subdirectories below these directories.
For this automatically imported function, it needs to first attempt to import the framework class file, if it does not exist, the user class file, and then try to import the user class file, and if so, include it.
Note:
Because I want to use userapps/modules this directory frequently, I have defined a modules_path this constant;
01 |
function __autoload ($className) { |
02 |
$frameworkFileName = Framework_path. '/' . $className. '. php '; |
03 |
if (Is_file ($frameworkFileName)) { |
04 |
Include $frameworkFileName; |
07 |
$controllerFileName = Modules_path. '/controllers/'. $className. '. php '; |
08 |
if (Is_file ($controllerFileName)) { |
09 |
Include $controllerFileName; |
11 |
$modelFileName = Modules_path. '/models/'. $className. '. php '; |
12 |
if (Is_file ($modelFileName)) { |
13 |
Include $modelFileName; |
15 |
$helperFileName = Modules_path. '/helpers/'. $className. '. php '; |
16 |
if (Is_file ($helperFileName)) { |
17 |
Include $helperFileName; |
19 |
throw New Exception ("Class not Found"); |
When you have finished writing this function, you can test it in the previously written indexcontroller.php, such as creating a file test.php under the same directory as Indexcontroller, with the following file code:
3 |
Public Function test () { |
Then use the following in indexcontroller.php:
2 |
Class Indexcontroller { |
3 |
Public Function index () { |
If test appears, then congratulations, the Automatic import success!!
Now think again, if you're using this approach to automate imports for a very complex project, what's the problem?
In fact, the problem is quite serious, first of all, for the framework of the file, we can not keep all the files under a directory, so that when the file is more than the search after the trouble; for user-class files, such as the controller's file, we can not store it all under a directory, we need to follow the module segmentation directory. If implemented with __autoload, the code for this function is too large, and if there is a change in a place that might be far-reaching, it would be detrimental to the maintenance of the project.
So how do we solve this problem?
Method One:
We define a number of helper functions, such as importing a framework file, we define a frameworkautoloadhelper, define a userautoloadhelper for the user file, and then store the business logic in the two functions, and finally on __ AutoLoad call these two functions can be, when the user features need to modify, code maintenance is better;
Method 2:
A spl_autoload_register has been defined in SPL, which can be used to distribute functions that are automatically imported into multiple classes, and to give control of automatic import to the user, which is more important for the framework, so I recommend this approach.
How to achieve this way, readers can check their own PHP manual.
When we use the spl_autoload_register, does everything just sit back and relax?
In fact, we can now think about whether the automatic import can be removed, because when the business logic is very complex and automatic import design is not particularly good time, the efficiency of automatic import is not very high!!
do you want to use include instead of automatic import? No.
We all know the difference between include,include_once,require,require_once!!
Include and require each call contains this file, Include_once and require_once will only be imported once, include if contains a nonexistent file, will only throw a warning, the program will continue to execute, and require will stop execution, So these four functions I recommend to use require_once, but unfortunately, this function is very inefficient, because it has to consider too many things!!
PS: When using these four functions, it is best to use absolute path, so the efficiency is higher;
If we use require, then the efficiency will be much higher, but if use require how to achieve require_once function?
I'm giving you a clue to use the static variable:
2 |
function Testrequireonce ($file) { |
3 |
Static $_config = Array (); |
4 |
if (!isset ($_config[$file])) { |
6 |
$_config[$file] = $file; |
Of course, you can also use class_exists to determine.