]> granicus.if.org Git - php/commitdiff
in preparation for a performance optimization that involves
authorGreg Beaver <cellog@php.net>
Fri, 27 Jun 2008 01:21:12 +0000 (01:21 +0000)
committerGreg Beaver <cellog@php.net>
Fri, 27 Jun 2008 01:21:12 +0000 (01:21 +0000)
eliminating phar's interception of zend_compile in favor of a new to-be-added hook in PHP 5.3+,
allow "include 'phar:///path/to/my.phar';" to work as equivalent to
php /path/to/my.phar
this slight change in scripting still allows inclusion and execution of phar stub, but removes the need to
check and modify path in zend_compile, which allows us to play much nicer with external tools like
debuggers/opcode caches

ext/phar/cgidebug
ext/phar/phar.c
ext/phar/phar.phar
ext/phar/stream.c
ext/phar/tests/017.phpt
ext/phar/tests/tar/tar_bz2.phpt
ext/phar/tests/zip/phar_magic.phpt

index cc3d6b41e675471ce7bffc95ed2e66f2f769049e..1907581900e270aec7d327af92cb1896d7aca04e 100755 (executable)
@@ -1,11 +1,11 @@
 #!/bin/sh
-export SCRIPT_NAME=/frontcontroller9.php
-export PATH_INFO=/hi
-export SCRIPT_FILENAME=/home/cellog/workspace/php5/ext/phar/tests/cache_list/frontcontroller9.php
-export PATH_TRANSLATED=/home/cellog/workspace/php5/ext/phar/tests/cache_list/frontcontroller9.php
+export SCRIPT_NAME=/front.phar.php
+export PATH_INFO=/index.php
+export SCRIPT_FILENAME=/home/cellog/workspace/php5/ext/phar/tests/front.phar.php
+export PATH_TRANSLATED=/home/cellog/workspace/php5/ext/phar/tests/front.phar.php
 export REDIRECT_STATUS=1
 export REQUEST_METHOD=GET
-export REQUEST_URI=/frontcontroller9.php/hi
-cd /home/cellog/workspace/php5/ext/phar/tests/cache_list
-ddd ../../../../sapi/cgi/php-cgi &
+export REQUEST_URI=/front.phar.php/index.php
+cd /home/cellog/workspace/php5
+ddd sapi/cgi/php-cgi &
 cd /home/cellog/workspace/php5/ext/phar
index 6a0620eebf743989140c004250929bfe32d45be1..d984fcd631f9479e222195a558aa9953559fd1d7 100644 (file)
@@ -3187,7 +3187,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
                                /* compressed phar */
 #if PHP_VERSION_ID >= 50300
                                file_handle->type = ZEND_HANDLE_STREAM;
-                               file_handle->free_filename = 0;
                                /* we do our own reading directly from the phar, don't change the next line */
                                file_handle->handle.stream.handle  = phar;
                                file_handle->handle.stream.reader  = phar_zend_stream_reader;
@@ -3200,7 +3199,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
                                memset(&file_handle->handle.stream.mmap, 0, sizeof(file_handle->handle.stream.mmap));
 #else /* PHP_VERSION_ID */
                                file_handle->type = ZEND_HANDLE_STREAM;
-                               file_handle->free_filename = 0;
                                /* we do our own reading directly from the phar, don't change the next line */
                                file_handle->handle.stream.handle = phar;
                                file_handle->handle.stream.reader = phar_zend_stream_reader;
index e299feb7d6b7b55ceb184c2b06e0bf361edc2a97..30ad018170c63730cbcb642cdf65bf81ba7fd61b 100755 (executable)
Binary files a/ext/phar/phar.phar and b/ext/phar/phar.phar differ
index 262c3f207b8646ef788a0fbe703cb9ba348ba639..54fb66ed2b9612b35edf95c166fc9b5562f0daab 100644 (file)
@@ -157,6 +157,7 @@ php_url* phar_parse_url(php_stream_wrapper *wrapper, char *filename, char *mode,
  */
 static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */
 {
+       phar_archive_data *phar;
        phar_entry_data *idata;
        char *internal_file;
        char *error;
@@ -234,8 +235,55 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat
                }
                return fpf;
        } else {
+               if (!*internal_file && (options & STREAM_OPEN_FOR_INCLUDE)) {
+                       /* retrieve the stub */
+                       if (FAILURE == phar_get_archive(&phar, resource->host, host_len, NULL, 0, NULL TSRMLS_CC)) {
+                               php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "file %s is not a valid phar archive");
+                               efree(internal_file);
+                               php_url_free(resource);
+                               return NULL;
+                       }
+                       if (phar->is_tar || phar->is_zip) {
+                               if ((FAILURE == phar_get_entry_data(&idata, resource->host, host_len, ".phar/stub.php", sizeof(".phar/stub.php")-1, "r", 0, &error, 0 TSRMLS_CC)) || !idata) {
+                                       goto idata_error;
+                               }
+                               efree(internal_file);
+                               if (opened_path) {
+                                       spprintf(opened_path, MAXPATHLEN, "%s", phar->fname);
+                               }
+                               php_url_free(resource);
+                               goto phar_stub;
+                       } else {
+                               phar_entry_info *entry;
+
+                               entry = (phar_entry_info *) ecalloc(1, sizeof(phar_entry_info));
+                               entry->is_temp_dir = 1;
+                               entry->filename = "";
+                               entry->filename_len = 0;
+                               entry->phar = phar;
+                               entry->offset = entry->offset_abs = 0;
+                               entry->compressed_filesize = entry->uncompressed_filesize = phar->halt_offset;
+                               entry->is_crc_checked = 1;
+
+                               idata = (phar_entry_data *) ecalloc(1, sizeof(phar_entry_data));
+                               idata->fp = phar_get_pharfp(phar TSRMLS_CC);
+                               idata->phar = phar;
+                               idata->internal_file = entry;
+                               if (!phar->is_persistent) {
+                                       ++(entry->phar->refcount);
+                               }
+                               ++(entry->fp_refcount);
+                               php_url_free(resource);
+                               if (opened_path) {
+                                       spprintf(opened_path, MAXPATHLEN, "%s", phar->fname);
+                               }
+                               efree(internal_file);
+                               goto phar_stub;
+                       }
+               }
                /* read-only access is allowed to magic files in .phar directory */
                if ((FAILURE == phar_get_entry_data(&idata, resource->host, host_len, internal_file, strlen(internal_file), "r", 0, &error, 0 TSRMLS_CC)) || !idata) {
+idata_error:
                        if (error) {
                                php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
                                efree(error);
@@ -283,11 +331,12 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat
                        PHAR_G(cwd) = NULL;
                }
        }
-       fpf = php_stream_alloc(&phar_ops, idata, NULL, mode);
        if (opened_path) {
                spprintf(opened_path, MAXPATHLEN, "phar://%s/%s", idata->phar->fname, idata->internal_file->filename);
        }
        efree(internal_file);
+phar_stub:
+       fpf = php_stream_alloc(&phar_ops, idata, NULL, mode);
        return fpf;
 }
 /* }}} */
@@ -297,8 +346,14 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat
  */
 static int phar_stream_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */
 {
+       phar_entry_info *entry = ((phar_entry_data *)stream->abstract)->internal_file;
+
        phar_entry_delref((phar_entry_data *)stream->abstract TSRMLS_CC);
 
+       if (entry->is_temp_dir) {
+               /* phar archive stub, free it */
+               efree(entry);
+       }
        return 0;
 }
 /* }}} */
index ec012eaa113c6830e5dc171dedefbb619a131280..2857218000bdfd7f429c3f436a838f6fde0882a1 100644 (file)
@@ -10,17 +10,22 @@ $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
 $pname = 'phar://' . $fname;
 $file = "<?php
 Phar::mapPhar('hio');
+var_dump(__FILE__);
+var_dump(substr(__FILE__, 0, 4) != 'phar');
 __HALT_COMPILER(); ?>";
 
 $files = array();
 $files['a'] = 'abc';
 include 'files/phar_test.inc';
 
-include $fname;
+include $pname;
 $dir = opendir('phar://hio');
 ?>
 --CLEAN--
 <?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
 --EXPECTF--
+string(%d) "%s017.phar.php"
+bool(true)
+
 Warning: opendir(phar://hio): failed to open dir: phar error: no directory in "phar://hio", must have at least phar://hio/ for root directory (always use full path to a new phar)
 phar url "phar://hio" is unknown in %s017.php on line %d
\ No newline at end of file
index c18314e5fff723d7d42bcdf08148c6bc7344b0f6..a6218e7229d3fbc01c0b5b62e6f7571679b2ca24 100644 (file)
@@ -23,13 +23,16 @@ $tar->addFile('internal/file/here', "hi there!\n");
 $tar->mkDir('internal/dir');
 $tar->mkDir('dir');
 $tar->addFile('.phar/stub.php', '<?php
+var_dump(__FILE__);
+var_dump(substr(__FILE__, 0, 4) != "phar");
 Phar::mapPhar();
 var_dump("it worked");
 include "phar://" . __FILE__ . "/tar_004.php";
+__HALT_COMPILER();
 ');
 $tar->close();
 
-include $fname;
+include $alias;
 
 $phar = new Phar($fname);
 $phar['test'] = 'hi';
@@ -48,6 +51,8 @@ var_dump($phar2->isCompressed() == Phar::BZ2);
 @unlink(dirname(__FILE__) . '/tar_bz2.phar.tar');
 ?>
 --EXPECTF--
+string(%d) "%star_bz2.phar"
+bool(true)
 string(9) "it worked"
 string(%d) "phar://%star_bz2.phar/tar_004.php"
 bool(true)
index 4a17207376e1d5c7a308606c040662945643b49b..74ff019101a2db037ba9deb82f3599e95c2c6157 100644 (file)
@@ -8,16 +8,19 @@ phar.readonly=0
 --FILE--
 <?php
 $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip.php';
+$pname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.zip.php';
 $p = new Phar($fname);
 var_dump($p->isFileFormat(Phar::ZIP));
 $p['a'] = '<?php include "b/c.php";' . "\n";
 $p['b/c.php'] = '<?php echo "in b\n";$a = fopen("a", "r", true);echo stream_get_contents($a);fclose($a);include dirname(__FILE__) . "/../d";';
 $p['d'] = "in d\n";
 $p->setStub('<?php
+var_dump(__FILE__);
+var_dump(substr(__FILE__, 0, 4) != "phar");
 set_include_path("phar://" . __FILE__);
 include "phar://" . __FILE__ . "/a";
 __HALT_COMPILER();');
-include $fname;
+include $pname;
 ?>
 ===DONE===
 --CLEAN--
@@ -27,6 +30,8 @@ __HALT_COMPILER();
 ?>
 --EXPECTF--
 bool(true)
+string(%d) "%sphar_magic.phar.zip.php"
+bool(true)
 in b
 <?php include "b/c.php";
 in d