|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-06-04 04:50 UTC] pecl at wormhole dot no
Description: ------------ I'm having a problem with a parent and child class that is autoloaded differently when using APC. Short summary: - I have a function, requireClass(), which register class and package in an array. - ChildClass extends ParentClass - Both classes are located in a package: package - Having an empty APC cache, I load the first script which runs requireClass on both classes and then creates one instance of both. Then I load a second script which runs requireClass on the ChildClass and creates an instance of it. When running with APC on, the ParentClass is autoloaded before requireClass is called from the ChildClass, causing autoload not to know where the class is located. I've zipped the code to reproduce the problem, see link in the 'Reproduce code' section. *General Cache Information* APC Version 3.0.19 PHP Version 5.2.3-1ubuntu6.3 APC Host localhost Server Software Apache/2.2.4 (Ubuntu) PHP/5.2.3-1ubuntu6.3 Shared Memory 1 Segment(s) with 512.0 MBytes (mmap memory, pthread mutex locking) File Upload Support 1 *Runtime Settings* apc.cache_by_default 1 apc.coredump_unmap 0 apc.enable_cli 0 apc.enabled 1 apc.file_update_protection 2 apc.filters apc.gc_ttl 3600 apc.include_once_override 0 apc.max_file_size 1M apc.mmap_file_mask apc.num_files_hint 1000 apc.report_autofilter 0 apc.rfc1867 0 apc.rfc1867_freq 0 apc.rfc1867_name APC_UPLOAD_PROGRESS apc.rfc1867_prefix upload_ apc.shm_segments 1 apc.shm_size 512 apc.slam_defense 0 apc.stat 1 apc.stat_ctime 0 apc.ttl 0 apc.user_entries_hint 4096 apc.user_ttl 0 apc.write_lock 1 Reproduce code: --------------- http://geirhelge.wormhole.no/files/apc.tar.gz 1. Clear cache 2. Run first.php 3. Run second.php It works fine if you run second.php first with an empty cache. Expected result: ---------------- Adding [package.ChildClass] to classMap autoloading [ChildClass] Adding [package.ParentClass] to classMap autoloading [ParentClass] Done Actual result: -------------- Adding [package.ChildClass] to classMap autoloading [ChildClass] autoloading [ParentClass] Warning: include(/var/www/sandbox/apc/ParentClass.php) [function.include]: failed to open stream: No such file or directory in /var/www/sandbox/apc/include/functions.php on line 11 Warning: include() [function.include]: Failed opening '/var/www/sandbox/apc/ParentClass.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/sandbox/apc/include/functions.php on line 11 Adding [package.ParentClass] to classMap autoloading [ParentClass] Done PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 22:00:01 2025 UTC |
The following patch prevents the compiler from early binding of superclasses declared outside the current file. Index: apc_main.c =================================================================== RCS file: /repository/pecl/apc/apc_main.c,v retrieving revision 3.123 diff -u -u -b -B -r3.123 apc_main.c --- apc_main.c 22 Jul 2008 23:42:00 -0000 3.123 +++ apc_main.c 23 Jul 2008 08:05:01 -0000 @@ -345,6 +344,10 @@ /* TODO: check what happens with EG(included_files) */ } + HashTable *old = EG(class_table); + EG(class_table) = emalloc(sizeof(HashTable)); + zend_hash_init(EG(class_table), 0, NULL, NULL, 0); + /* remember how many functions and classes existed before compilation */ num_functions = zend_hash_num_elements(CG(function_table)); num_classes = zend_hash_num_elements(CG(class_table)); @@ -352,6 +355,8 @@ /* compile the file using the default compile function */ op_array = old_compile_file(h, type TSRMLS_CC); if (op_array == NULL) { + zend_hash_destroy(EG(class_table)); + EG(class_table) = old; return NULL; } @@ -359,6 +364,8 @@ if (APCG(filters) && apc_compiled_filters) { int ret = apc_regex_match_array(apc_compiled_filters, h->opened_path); if(ret == APC_NEGATIVE_MATCH || (ret != APC_POSITIVE_MATCH && !APCG(cache_by_default))) { + zend_hash_destroy(EG(class_table)); + EG(class_table) = old; /* never cache, never find */ return op_array; } @@ -378,6 +385,8 @@ #ifdef __DEBUG_APC__ fprintf(stderr,"Stat failed %s - bailing (%s) (%d)\n",filename,SG(request_info).path_translated); #endif + zend_hash_destroy(EG(class_table)); + EG(class_table) = old; return op_array; } } @@ -390,6 +399,8 @@ if(APCG(write_lock)) { if(!apc_cache_write_lock(apc_cache)) { HANDLE_UNBLOCK_INTERRUPTIONS(); + zend_hash_destroy(EG(class_table)); + EG(class_table) = old; return op_array; } } @@ -436,6 +447,9 @@ #endif HANDLE_UNBLOCK_INTERRUPTIONS(); + zend_hash_destroy(EG(class_table)); + EG(class_table) = old; + return op_array; } /* }}} */