rfc:autoload_include

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
Last revisionBoth sides next revision
rfc:autoload_include [2009/11/10 16:27] – created lsmithrfc:autoload_include [2010/01/05 15:08] – stream_resolve_include_path was added to 5.3.3 lsmith
Line 1: Line 1:
-====== Request for Comments: How to write RFCs ====== +====== Alternative to include/require for autoloaders ====== 
-  * Version: 0.9+  * Version: 1.0
   * Date: 2009-11-10   * Date: 2009-11-10
   * Author: Lukas Smith <smith@pooteeweet.org>   * Author: Lukas Smith <smith@pooteeweet.org>
-  * Status: Draft+  * Status: updated stream_resolve_include_path() was added in PHP 5.3.3
   * First Published at: http://wiki.php.net/rfc/autoload_include   * First Published at: http://wiki.php.net/rfc/autoload_include
  
Line 10: Line 10:
 ===== Introduction ===== ===== Introduction =====
  
-Many autoloaders ([[phd|http://svn.php.net/viewvc/phd/trunk/render.php?annotate=290241]], [[ZF|http://framework.zend.com/code/browse/Standard_Library/standard/trunk/library/Zend/Loader.php?r=16206]], [[PEAR2|http://svn.php.net/viewvc/pear2/Autoload/trunk/src/Autoload.php?view=markup&pathrev=290473]]) use the following "hack" to determine of a file exists before loading it:+Currently many autoloaders require the use of inefficient and in extreme cases even error prone "hacks" to be able to handle syntax errors differently than missing files when using include/require. 
 + 
 +===== Current situation ===== 
 + 
 +Many autoloaders ([[http://svn.php.net/viewvc/phd/trunk/render.php?annotate=290241|phd]], [[http://framework.zend.com/code/browse/Standard_Library/standard/trunk/library/Zend/Loader.php?r=16206|ZF]], [[http://svn.php.net/viewvc/pear2/Autoload/trunk/src/Autoload.php?view=markup&pathrev=290473|PEAR2]]) use the following "hack" to determine of a file exists before loading it:
 <code php> <code php>
 if ($fp = @fopen($file, 'r', true)) { if ($fp = @fopen($file, 'r', true)) {
Line 23: Line 27:
  
 An alternative approach is to read the include path setting and iterate over all the directories using file_exists(). This is overly expensive, especially with larger include paths. Furthermore it also suffers from the potential race condition, even if the "use_include_path" flag from fopen() would be added to file_exists() - though adding this flag is probably not desirably for the reason of adding another place where the ini settings are read. An alternative approach is to read the include path setting and iterate over all the directories using file_exists(). This is overly expensive, especially with larger include paths. Furthermore it also suffers from the potential race condition, even if the "use_include_path" flag from fopen() would be added to file_exists() - though adding this flag is probably not desirably for the reason of adding another place where the ini settings are read.
- 
 ===== Proposal ===== ===== Proposal =====
  
 In order to solve the above issues this RFC proposes the addition of a new construct/function for now called "autoload_include" for lack of a better name that largely behaves like the "include" does today with the following differences, that when the include failed because of a missing file no warning is raised and php null is returned. In order to solve the above issues this RFC proposes the addition of a new construct/function for now called "autoload_include" for lack of a better name that largely behaves like the "include" does today with the following differences, that when the include failed because of a missing file no warning is raised and php null is returned.
  
 +The current working title "autoload_include" is probably not ideal and should probably be replaced with a more meaningful name.
 ===== Optional related aspects ===== ===== Optional related aspects =====
  
-A potential interesting additional difference could be to return the name of the loaded file in case the file was loaded successfully and the file does not return any value explicitly. This could make it possible to assist in caching the lookup.+A potential interesting additional difference could be to return the name of the loaded file in case the file was loaded successfully and the file does not return any value explicitly. This could make it possible to assist in caching the lookup. Potentially the "spl" prefix should be used as well. 
 + 
 +Alternative name proposals: 
 +  * include_silent 
 +  * contain 
 +  * superset 
 +  * import 
 +  * load 
 +===== Alternative proposals ===== 
 + 
 +==== Add stream support to include/require ==== 
 + 
 +[[http://news.php.net/php.internals/45994|Make include/require able to handle resources]]. This would prevent the race condition scenario without the need of a new function. 
 + 
 +<code php> 
 +if ($fp = @fopen($file, 'r', true)) { 
 + include($fp); 
 + fclose($fp); 
 +
 +</code> 
 + 
 +However Stas notes that this would "this would break security distinction between file ops and include ops, when URLs are allowed for open but not include", but Greg notes this should be solvable since "the wrapper used to open the file pointer is stored in the resource, so we can just check it against the same restrictions we would for static urls". That being said Stas additionally notes that this could pose challenges for byte code caches since they would have to "watch all file opens, in case some of these will later be used for include" as well as "somehow be able to get filename back from open stream to get the cached file"
 +==== Add function to resolve the include path ==== 
 + 
 +Either add a "use_include_path" flag to file_exists() or add a new file_find() function that supports searching the include path and returns the absolute path to the first match or false if none could be found. The later would be superior since it would also enable the optional feature mentioned above. It would still however require file system access twice, though it would only have to resolve the include path once. It also does not solve the edge case of a race condition, which however seems very rare for files that are included via autoload. There is actually already an implementation which was put into HEAD aka PHP6 as the result of a [[http://devzone.zend.com/node/view/id/1514#Heading7|previous discussion]].  
 + 
 +That being said the current implementation needs some tweaks as Greg points out: 
 +"stream_resolve_include_path() as currently constructed could not be intercepted, and is actually unable to process an include_path that contains streams.  I'm guessing it was written long before PHP 5.3. This could be easily fixed by having stream_resolve_include_path call zend_resolve_path() instead of doing its own internal calculations. With these changes, an opcode cache could easily cache the results."
  
-===== Changelog =====+===== Patches =====
  
 +  * [[http://valokuva.org/patches/php/new/stream_resolve_include_path.txt}|patch to add an improved stream_resolve_include_path() to 5.3]]
rfc/autoload_include.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1