php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #58218 Class autoloades earlier when using APC
Submitted: 2008-06-04 04:50 UTC Modified: 2016-08-31 15:03 UTC
From: pecl at wormhole dot no Assigned: cmb (profile)
Status: Wont fix Package: APC (PECL)
PHP Version: 5.2.3 OS: Ubuntu7.10 Gutsy Gibbon
Private report: No CVE-ID: None
 [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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-07-09 07:39 UTC] gopalv82 at yahoo dot com
Interesting. 

I doubt there is any valid solution, except the 5.3.x delayed binding patches (as said in the following mail)

http://news.php.net/php.internals/36038

I'm in the process of testing out stuff for 5.3.x
 [2008-07-23 04:07 UTC] pr at bgagroup dot net
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;
 }
 /* }}} */
 [2016-08-31 15:03 UTC] cmb@php.net
-Status: Open +Status: Wont fix -Assigned To: +Assigned To: cmb
 [2016-08-31 15:03 UTC] cmb@php.net
According to <https://bugs.php.net/69618>, APC support has been
discontinued in favor of OPcache, APCu, the session upload
progress API and WinCache. Therefore this issue won't get fixed.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Dec 04 06:01:31 2024 UTC