According to the PHP manual _once functions support inclusion of remote URLs,
which they do. However, unlike when dealing with local files those functions
do not actually keep track of how many times the file is included and prevent
double inclusion of the same file. Meaning that those functions offer no
extra functionality when dealing with remote URLs.
In addition Zend code which handles include_once/require_once logic also does
not insert the remote URLs into the included_files hash table, so according
to functions get_included_files() and get_required_files those files are not
even included.
The attached patch modifies zend_execute.c, which allows the same kind of
functionality that prevents double inclusion of the same file on local drive
to work on remote URLs as well. Consequently it will also make remotely
included files appear in the included_files hash table.
Here are 2 small test scripts that can be used to test existing & patched
code.
hello
Array
(
[0] => /home/rei/a.php
[1] => http://localhost/a.php
)
b.php:
<?php
include_once "http://localhost/a.php";
include_once "http://localhost/a.php";
print_r(get_included_files());
?>
a.php:
<?php
echo "hello\n";
?>
PHP 4.3.0
----------------
hello
hello
Array
(
[0] => /home/rei/a.php
)
PHP 4.3.0 + patch
---------------------
hello
Array
(
[0] => /home/rei/a.php
[1] => http://localhost/a.php
)
Ilia
P.S. This is not something new, in fact I came across this problem in an
existing bug report at http://bugs.php.net/16150
--- zend_execute.c Wed Aug 14 17:45:02 2002
+++ zend_execute.c_new Wed Aug 14 17:42:18 2002
@@ -2084,6 +2084,7 @@
case ZEND_REQUIRE_ONCE: {
char *opened_path=NULL;
int dummy = 1;
+ int remote_file = 0;
zend_file_handle file_handle;
file_handle.handle.fp = zend_fopen(inc_filename->value.str.val, &opened_path);
@@ -2093,9 +2094,15 @@
file_handle.free_filename = 0;
if (file_handle.handle.fp) {
- if (!opened_path || zend_hash_add(&EG(included_files), opened_path, strlen(opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
+ if( !opened_path ) {
+ opened_path = estrdup(inc_filename->value.str.val);
+ remote_file = 1;
+ }
+
+ if (zend_hash_add(&EG(included_files), opened_path, strlen(opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
new_op_array = zend_compile_file(&file_handle, (EX(opline)->op2.u.constant.value.lval==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
zend_destroy_file_handle(&file_handle TSRMLS_CC);
+ if( remote_file ) efree(opened_path);
opened_path = NULL; /* zend_destroy_file_handle() already frees it */
} else {
fclose(file_handle.handle.fp);
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php