php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #38006 Cannot add a 'Stream wrapped' path to include path
Submitted: 2006-07-04 15:02 UTC Modified: 2010-12-22 12:57 UTC
Votes:3
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: flconseil at yahoo dot fr Assigned: johannes (profile)
Status: Closed Package: *General Issues
PHP Version: 5.1.4 OS: Unix & Windows
Private report: No CVE-ID: None
 [2006-07-04 15:02 UTC] flconseil at yahoo dot fr
Description:
------------
After having declared a new stream wrapper, I want to add a sub-path of this stram wrapper to the include path. The set_onclude_path() works fine, but, then, PHP does not use this path when searching a file through the include path.

It seems annoying, but normal on Unix, as the path separator is ':'. But it also fails on Windows, where the path separator is ';'.

It will be hard to maintain backward compatibility but, if dirname() is able to work on these paths, I think that it should be possible to append them to the include path.

One solution would be to consider the include path as an array, instead of maintaining it as a string. The get_include_path() and set_include_path() could be kept as compatibility functions, the php.ini file could be kept the same, but there would be two new functions get_include_path_array() and set_include_path_array() which would work with arrays and would be compatible with stream wrapper paths. More important, the PHP engine would only use the array internally and could find files in stream wrapped pseudo-directories. The stream wrapper should be ready to support '/' and '\' characters as directory separators, if they want to work on Windows and Unix.


Reproduce code:
---------------
1. I register a stream wrapper for the 'phk' prefix

2. 'include('phk://example/ex.php');' works OK. My virtual file is included.

3. I add this path to the include path :
set_include_path(get_include_path().PATH_SEPARATOR.'phk://example');

4. I try to 'include(ex.php)' without specifying the path, as it is in the include path -> it fails.

Expected result:
----------------
file included

Actual result:
--------------
PHP Warning:  include(ex.php): failed to open stream: No such file or directory in ... on line ...
PHP Warning:  include(): Failed opening 'ex.php' for inclusion (include_path='/logi/http/php/lib/php:/logi/http/php/lib/adodb:phk://example') in ... on line ...


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-07-06 20:14 UTC] tony2001@php.net
Reclassified as feature request.
 [2006-07-10 13:44 UTC] flconseil at yahoo dot fr
From a first look at the source code, I would do it this way :

1. As the Unix path_separator is ':', implement include_path internally as an array. This array could contain wrapped paths.

For compatibility, get_include_path() would return an implode() of this array without the stream-wrapped paths (so that it can re-explode() it). set_include_path() and restore_include_path() would populate the array with an explode() of their string. The ini parameter would be unchanged.

The stream-wrapped paths could be added and retrieved from the array only through 2 new PHP functions: get_include_path_array() and set_include_path_array(). A new function could be welcome: append_include_path(string) which would allow people writing packages to add a path to the include path without destroying any previously set stream-wrapped path in it.

2. Today, the include path is searched in the plain wrapper. And the wrapper to call is determined from the function's argument, before the search. Which means that, in the current version, it is impossible to open a non-absolute URL in a stream wrapper (let alone the chdir() issue).

The first solution I thought of was to catch urls at the beginning of _php_stream_fopen() and re-call _php_stream_open_wrapper_ex() from there with the USE_PATH flag cleared. This way, the wrapper would be recognized and dispatched correctly, and a wrapper->open() would be attempted. It is not very clean but it is quite simple to implement. The main problem is that we loose the context argument in the battle, because it is not transmitted to the 'plain' code.

Second solution : Taking the file search code out of the plain wrapper and putting it at the beginning of _php_stream_open_wrapper_ex, replacing the 'path_to_open=path;' statement. Then, we could clear the USE_PATH flag, and execute the rest of the code with a resolved path.

Of course, these two solutions require to modify php_plain_file_stream_opener() (or the corresponding code in the 2nd solution) to use the include path array instead of PG(include_path). If we choose the first solution, we can even keep the string format to send the 'path' arg to _php_stream_fopen_with_path(). We just have to choose an other separator, like char(1).

I won't start anything before PHP core experts tell me what they think about it. So, feel free to contact me at flconseil at yahoo dot fr.
 [2010-12-22 12:57 UTC] johannes@php.net
-Status: Open +Status: Closed -Package: Feature/Change Request +Package: *General Issues -Assigned To: +Assigned To: johannes
 [2010-12-22 12:57 UTC] johannes@php.net
Introduced in PHP 5.3
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Mon Apr 28 19:01:29 2025 UTC