rfc:autoload_include

This is an old revision of the document!


Alternative to include/require for autoloaders

This RFC aims to offer an alternative solution to the well known fopen() “hack” used in autoloaders in order to verify the existence of files inside the include path.

Introduction

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 (phd, ZF, PEAR2) use the following “hack” to determine of a file exists before loading it:

if ($fp = @fopen($file, 'r', true)) {
    fclose($fp);
    include $file;
}   

Just “blindly” including the file makes it impossible to determine if there was a syntax error or if the file was missing. In some cases when integrating files from different projects there might be different naming conventions which makes it necessary to attempt different possible filenames without suppressing potential parse errors.

Furthermore the above code first opens the file, closes the file and then finally includes the file. This means there are multiple function calls, multiple filesystem calls and even an very low risk for a race condition.

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

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.

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

1. Make include/require able to handle resources. This would prevent the race condition scenario without the need of a new function.

if ($fp = @fopen($file, 'r', true)) {
	include($fp);
	fclose($fp);
}

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”

Changelog

rfc/autoload_include.1257891745.txt.gz · Last modified: 2017/09/22 13:28 (external edit)