In depth understanding of PHP's require and include order recommendation

  • 2020-03-31 21:28:42
  • OfStack

Hence the following question:

How does include_path work?

What's the order if you have multiple include_paths?

When does include_path not work?

Today, I will introduce this problem comprehensively, starting with an example.

The following directory structure:

    Root        ├ 1. Php        ├ 3. Php        └ subdir                  ├ 2. Php                    └ 3. PHP

In PHP:

 
<?php 
ini_set("include_path", ".:path_to_subdir"); 
require("2.php"); 
?> 

And in 2.php:

<?php 
require("3.php"); 
?> 

3. PHP in the root directory prints out "root" and 3. PHP in the subdir directory prints out "subdir";

Now, here's my question:
1. What output do you get when you run 1.php in the root directory?
2. Run 1.php from the previous directory under subdir. What output do you get?
3. When you cancel the current directory path in the include_path (that is, the include_path= "path_to_subdir"), what are the outputs of the above two questions?
In PHP include_path
When PHP encounters a directive requiring (_once)/include(_once), it first makes the following judgment:

 
 Is the file path to be included an absolute path ? 
 If it is ,  Directly include ,  And an end . 
 If it is not ,  Go to the other logic ( After many calls ,  Enter after macro expansion _php_stream_fopen_with_path) Find this file  

Next, in _php_stream_fopen_with_path, make the following judgment:
 
 Is the file path to be included a relative path ( like ./file, ../dir/file,  The following use " Directory relative path instead ")? 
 If it is ,  skip include_path Function logic ,  Resolve relative paths directly ( And then separately ) 

Depending on the include_path and the path of the currently executing file, a list of directories to be selected will be formed, such as the following for the example in the previous article
 
".:path_to_subdir:current_script_dir 

Then, starting at the head of the list, extract a path from the list according to DEFAULT_DIR_SEPARATOR(the context of this article is ":"), append the file name to be included to the path, and try.
So far, we've been able to answer my first three questions.
1. Because the execution is in the root directory, when 1.php contains 2.php, the second standby path of the include_path works (path_to_subdir), and path_to_subdir/2.php is found. When 2.php contains 3.php, the current working directory is root, so when the include_path contains 3.php, the first standby path ". So the output is "root".
2. Same as 1, except that the current path is subdir, so the output is "subdir".
3. Since the current path is include_path, it is path_to_subdir that works when 3.php is included in 2.php when running in the root directory, so both root and subdir will get "subdir" output.
If I empty my include_path in 2.php,
 
<?php 
ini_set("include_path", ''); 
require("3.php"); 
?> 

Then current_script_dir will work, and current_script_dir is the path to 2.php at this point, so you'll still get "subdir" output.
Directory relative path
In the case of directory relative paths, the base point of the relative path is always the current working directory.
To illustrate the situation in directory relative path, let's look at another column, the same directory structure as above, except that 1.php becomes:
 
<?php 
ini_set("include_path", "/"); 
require("./subdir/2.php"); 
?> 

2. PHP becomes:
 
<?php 
require("./3.php"); 
?> 

If executed in the root directory, looking for 3.php in 2.php will look in the relative path of the current directory, so the output is "root", whereas if executed in the subdir of the previous directory, 1.php(php-f..) /1.php) will exit because "./subdir/2.php "is not found under subdir.
Afterword.
Because with include_path and relative paths, performance depends on the number of times you look, at worst, if you have 10 include_paths, you may have to retry up to 11 times to find the file you want to include, so use absolute paths when you can.
2. Because the basedir of the relative path of the directory is always the current working path, it needs to be related to the actual deployment path if it is to be used, so very little is actually used (of course, there are also modules that are done with chdir).
3. In modular system design, you should generally use the absolute path within the module by obtaining the deployment path of the module (dirname(s) (s). Php5.3 provides the constant s).


Related articles: