php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #70507 Combination of is_file() + include (e.g. "include_if_exists")
Submitted: 2015-09-15 18:03 UTC Modified: 2017-08-05 04:46 UTC
Votes:2
Avg. Score:2.5 ± 1.5
Reproduced:0 of 2 (0.0%)
From: andreas at dqxtech dot net Assigned:
Status: Suspended Package: Scripting Engine problem
PHP Version: 7.0.0RC2 OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: andreas at dqxtech dot net
New email:
PHP Version: OS:

 

 [2015-09-15 18:03 UTC] andreas at dqxtech dot net
Description:
------------
For slightly improved class loader performance, it would be nice to have a combination of is_file() + include, as a new language construct.

Currently, include raises a warning if the file does not exist, is not accessible, or is not a file.

This means that a class loader cache that is not sure if the file exists needs to call is_file() before include. And to be strict, it would also have to call is_readable().

The new language construct would include the file if it exists, and return either TRUE or FALSE to indicate the success. This way the script does not need to hit the filesystem more than once.

An explicit return value of the file can be ignored, because this is mostly designed for class files.

There could be some more interesting behavior on failure. E.g. instead of just returning FALSE, it could return an object with an indication what went wrong.. Or this information could be retrieved from elsewhere.

The goal is to optimize the performance in case of success, not on failure.

-------

This being said: Maybe this is all not necessary, if the compiler/optimizer can automatically merge the is_file() and the include.

Test script:
---------------
spl_autoload_register('my_autoload_callback');

function my_autoload_callback($class) {
  $file = my_autoload_cache_lookup($class);
  if (!$file) {
    return;
  }
  if (true === include_if_exists $file) {
    // Done with the classloader.
    return;
  }
  my_autoload_cache_unset($class);
  $file = my_autoload_psr4_lookup($class);
  if (!$file) {
    return;
  }
  if (true === include_if_exists $file) {
    my_autoload_cache_set($class, $file);
  }
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-09-15 20:08 UTC] requinix@php.net
-Package: PHP Language Specification +Package: Scripting Engine problem
 [2015-09-15 20:08 UTC] requinix@php.net
For consistency there would have to be two functions: include_if_exists and include_once_if_exists. And files executed through those would not be able to use "return" to return values to the caller; having the functions an object would be a jarring departure from how the others work.

If you're concerned about how include/etc. do their own file lookups then wouldn't it be better to fix that specifically? PHP has a file stat cache already where the result of the first lookup is reused throughout execution (unless the cache gets cleared). I did some quick strace tests and it doesn't look like the functions are using it...
 [2015-09-15 20:16 UTC] andreas at dqxtech dot net
> If you're concerned about how include/etc. do their own file lookups then wouldn't it be better to fix that specifically? PHP has a file stat cache already where the result of the first lookup is reused throughout execution (unless the cache gets cleared). I did some quick strace tests and it doesn't look like the functions are using it...

Sure, sounds a good idea!
I'm afraid I'm not going to be of much help here though. Never touched the internals stuff.
 [2015-09-15 20:18 UTC] andreas at dqxtech dot net
Does this cache also cover file permissions?
 [2015-09-15 21:39 UTC] stas@php.net
Can't you just do @include? 

I think opcache is already caching file existence checks, so doing file_exists (or is_file) should be very cheap once the file is in cache.
 [2015-09-15 22:08 UTC] andreas at dqxtech dot net
> I think opcache is already caching file existence checks, so doing file_exists (or is_file) should be very cheap once the file is in cache.

If you guys agree this is the case then fine..
I recall measuring a slight difference there. Not a big worry, but relevant enough for the "fastest classloader in town" game..

> Can't you just do @include?

Someone will tell me I shouldn't. I am sure of that :)
 [2015-09-15 22:10 UTC] andreas at dqxtech dot net
> If you guys agree this is the case then fine..

At least requinix above says that not all functions are using the file exists cache.

> I recall measuring a slight difference there. Not a big worry, but relevant enough for the "fastest classloader in town" game..

And I imagine filesystem performance can be different depending on the environment.
 [2015-09-16 01:44 UTC] yohgaki@php.net
> Someone will tell me I shouldn't. I am sure of that :)

Right. Generally speaking, it is advised.
"@" operator is like "goto" for me. Sloppy use of "goto" ruins code, but decent use of "goto" achieves clean and robust code.

if (@include($script)) {
  // ERROR!!
}

is good use case of "@" IMO.
 [2015-09-16 01:45 UTC] yohgaki@php.net
if (@include($script)) {
should be
if (!@include($script)) {
 [2017-08-05 04:46 UTC] stas@php.net
-Status: Open +Status: Suspended
 [2017-08-05 04:46 UTC] stas@php.net
Thank you for your interest in PHP and for submitting a feature request. Please be aware that due to the magnitude of change this request requires, it would be necessary to discuss it on PHP Internals list (internals@lists.php.net) as an RFC. Please read the guide about creating RFCs here:
https://wiki.php.net/rfc/howto
If you haven't had experience with writing RFCs before, it is advised to seek guidance on the Internals list (http://php.net/mailing-lists.php) and/or solicit help from one of the experienced developers. 

Please to not consider this comment as a negative view on the merits of your proposal - every proposal which requires changes of certain magnitude, even the very successful and widely supported ones, must be done through the RFC process. This helps make the process predictable, transparent and accessible to all developers.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC