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