We have made several discussions about the removal of APC. include_once_override. This APC configuration item has never been well implemented.
Here, I would like to share with you the reasons for this problem and some inspiration for us.
We have been discussing whether to use include or include_once (all of the following include require_once) for a long time. The conclusion is that we should try to use include instead of include_once, include_once needs to query the list of loaded files, check whether the file exists, and then load the file.
It is true that the reason is correct. However, what I want to say today is another reason.
We know that PHP needs to obtain the opened_path of the file to determine whether a file is loaded, which means, for example:
- <?php
- set_include_path("/tmp/:/tmp2/");
- include_once("2.php");
- ?></SPAN< li>
When PHP sees include_once "2. PHP ", he does not know the actual path of the file, and cannot judge whether the file has been loaded from the loaded file list. Therefore, in the implementation of include_once, will first try to parse the actual path of this file (for a common file, this resolution is just like checking the getcwd and file path, so if it is a relative path, it is generally not successful), if the resolution is successful, search for EG (include_files). If the file exists, it indicates that it has been included. Otherwise, open the file to obtain the opened_path of the file. for example, in the above example, this file exists in
"/Tmp2/2. php ".
Then, after obtaining the opened_path, PHP goes to the loaded file list to check whether the file is included. If the file is not included, compile the file directly without the open file.
- 1. Try to parse the absolute path of the file. If the file can be parsed successfully, check for EG (included_files). If the file exists, return and continue
- 2. open the file and obtain the open path (opened path) of the file)
- 3. Use opened path to go to EG (included_files) to check whether the file exists. If the file exists, the file is returned and the file does not exist.
- 4. Compile the file (compile_file
This is not a problem in most cases, but the problem is when you use APC...
When APC is used, APC hijacks the pointer to the compile_file compilation file to directly obtain the compilation result from the cache, avoiding open to the actual file, this avoids system call for open.
However, when you use include_once in the code, PHP has tried to open file before compile_file, and then enters the compile file hijacked by APC, an additional open operation is generated. to solve this problem, APC introduces include_once_override. When include_once_override is enabled, APC will hijack PHP's zend_include_or_eval opcode handler and use stat to determine the absolute path of the file, then, if it finds that it is not loaded,
Rewrite opcode to include and create a tricky solution.
However, it is a pity that, as I said, the implementation of the include_once_override of APC has always been poor, and some undefined problems may occur, such:
- <?php
- set_include_path("/tmp");
- function a($arg = array()) {
- include_once("b.php");
- }
-
- a();
- a();
- ?></SPAN< li>
Then, we place B. php In "/tmp/B. php". The content is as follows:
- <?php
- class B {}
- ?></SPAN< li>
When APC. include_once_override is enabled, the following error is returned for continuous access:
- Fatal error - include() : Cannot redeclare class
(Note: 02: 07: 20: I have fixed this APC BUG:
#63070)
To eliminate these technical factors, I have always believed that we should use include instead of include_once, because we can completely implement our own planning, and a file is loaded only once. you can also achieve this by means of automatic loading.
You use include_once to prove that you have no confidence in your code.
Therefore, we recommend that you do not use include_once
Address: http://www.laruence.com/2012/09/12/2765.html