php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70651 Inconsistent usage of Current Working Directory
Submitted: 2015-10-06 15:04 UTC Modified: 2015-10-07 14:53 UTC
From: deivid dot garcia dot garcia at gmail dot com Assigned:
Status: Not a bug Package: Directory function related
PHP Version: 7.0.0RC4 OS: Windows/IIS/FastCGI
Private report: No CVE-ID: None
 [2015-10-06 15:04 UTC] deivid dot garcia dot garcia at gmail dot com
Description:
------------
is_dir and is_file are returning inconsistent results when being called from code registered by register_shutdown_function().



Test script:
---------------
<?php

function printline($line) { echo $line . "<br/>\r\n"; }

function _is_dir($dir) { printline("is_dir({$dir}): " . (is_dir($dir) ? "true" : "false")); }

function _is_file($file) { printline("is_file({$file}): " . (is_file($file) ? "true" : "false")); }

global $test;
$test = 1;

function test_dir() {
    global $test;
    printline("workding directory:" . getcwd());
    // sites/all is a regular directory in the webroot
    _is_dir('sites/all');
    // sites/default is a symlink directory in the webroot
    _is_dir('sites/default');
    // index.php is where this script in the webroot
    _is_file('index.php');
    if ($test == 2) {
        // php.exe not in webroot
        _is_file('php.exe');
        // cron.php is a file in the webroot
        _is_file('cron.php');
    }
}

test_dir();

printline("shutdown");

register_shutdown_function('test_dir');

return;

Expected result:
----------------
When $test == 1

Actual output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): false
is_dir(sites/default): false
is_file(index.php): true

Expected Output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): false
is_dir(sites/default): false
is_file(index.php): false

When $test == 2

Actual Output = Expected Output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
is_file(php.exe): false
is_file(cron.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): false
is_dir(sites/default): false
is_file(index.php): false
is_file(php.exe): true
is_file(cron.php): false




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-06 15:11 UTC] deivid dot garcia dot garcia at gmail dot com
Using reroute_enabled = 1 in the php ini setting for the Wincache extension yields further inconsistent results.

When $test == 2

Actual Output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
is_file(php.exe): false
is_file(cron.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
is_file(php.exe): true
is_file(cron.php): true

Expected Output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
is_file(php.exe): false
is_file(cron.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): false
is_dir(sites/default): false
is_file(index.php): false
is_file(php.exe): true
is_file(cron.php): false

When $test == 1

Actual Output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true

Expected Output:

workding directory:D:\REPOSITORIOS_SABENTIS\drupal7
is_dir(sites/all): true
is_dir(sites/default): true
is_file(index.php): true
shutdown
workding directory:C:\Program Files (x86)\PHP\php5.6
is_dir(sites/all): false
is_dir(sites/default): false
is_file(index.php): false
 [2015-10-06 15:15 UTC] deivid dot garcia dot garcia at gmail dot com
Just as a final note, having the current working directory change on shutdown functions is an unpleasant but described behaviour in the PHP docs for some web servers.

But I expect is_dir and is_file to make a consistent usage of what the current working directory is.
 [2015-10-07 14:06 UTC] ab@php.net
-Status: Open +Status: Not a bug
 [2015-10-07 14:06 UTC] ab@php.net
Thanks for the report. This behavior is documented and is unlikely to be changed. PHP depends on the C runtime in cases like this. Besides SAPIs changing CWD, any external extension could do it. That's where PHP core is not in control of this kind of change. An obvious solution in many cases is just using absolute paths.

Thanks.
 [2015-10-07 14:32 UTC] deivid dot garcia dot garcia at gmail dot com
There was too much info in the post... please reconsider looking at the *first* result:

is_dir(sites/all): false
is_dir(sites/default): false
is_file(index.php): true

These files/folders do exist and are under the same directory, all extensions disabled (only php core).

So it is using one CWD for is_dir and another CWD for is_file? Makes no sense.

And on the next run, with the same setup, index.php is reported as FALSE in the shutdown functions when nothing has changed.

So on one run in shutdown is_file(index.php) returns false, on the other one is_file(index.php) returns true, and nothing has changed.
 [2015-10-07 14:53 UTC] ab@php.net
Yeah, the paths are cached in PHP. You should use clearstatcache(true) prior doing anything in your test_dir(). It is not about CWD, but about about fstat cache.

Thanks.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Sun Sep 27 11:01:23 2020 UTC