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

Reply via email to