php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #53351 Autoload should not cancel if called for same class twice
Submitted: 2010-11-19 09:46 UTC Modified: 2010-11-19 19:28 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: php at addiks dot de Assigned: Kalle (profile)
Status: Closed Package: SPL related
PHP Version: 5.3.3 OS: Ubuntu 10.04
Private report: No CVE-ID: None
 [2010-11-19 09:46 UTC] php at addiks dot de
Description:
------------
hi,

currently i am using a require-all-script in my system that just plain require-once's all files with correct ending (".class.php";".mdl.php";...) it can find.
This happens inside of an autoload-method,
calling itself again when a depency (e.g. inheritance) occours.
when called again, it will skip all already called includes, since they are require-_once_. Whith this loader i can just add a class file and it will be loaded automaticly without needing me to register it somewhere manually.

But it seems i have misunderstood the documentation,
because i now have noticed that when two classes extends the same class,
it will fail at the second child-class complaining that the parent-class is missing instead of just calling autoload again for the same class,
which i thought will happen.

now i have to build the initial-loader much more complex, holding a cached depency-list of classes or looking into the source-code when called.

Test script:
---------------
<?php

function __autoload($class){

	// throws "Class C not found"
	//   i think it would be cool if it would call autoload again to load C,
	//   so this require_once wont be called again, class C would be loaded and everything would be fine.
	require_once("B.class.php"); // <-- "<?php class B extends C{}"

	// this will never be called
	require_once("C.class.php"); // <-- "<?php class C{}"
}

// this will call autoload to load class "C"
require_once("A.class.php"); // <-- "<?php class A extends C{}"

echo "this will never be echo'd...";

?>

Expected result:
----------------
<?php // EXPECTED:

function __autoload($class){

	// calls autoload again, will be skipped in that second call
	require_once("B.class.php"); // <-- "<?php class B extends C{}"

	// will be included in second call, then skippen when back in first run
	require_once("C.class.php"); // <-- "<?php class C{}"
}

// this will call autoload to load class "C"
require_once("A.class.php"); // <-- "<?php class A extends C{}"

// C, B and A are loaded correctly

?>

Actual result:
--------------
<?php // ACTUAL:

function __autoload($class){

	// throws fatal error "Class C not found"
	require_once("B.class.php"); // <-- "<?php class B extends C{}"

	// this will never be called
	require_once("C.class.php"); // <-- "<?php class C{}"
}

// this will call autoload to load class "C"
require_once("A.class.php"); // <-- "<?php class A extends C{}"

// none class clould be loaded, since it Fatal-error's at B.

?>

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-11-19 19:28 UTC] Kalle@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: Kalle
 [2010-11-19 19:28 UTC] Kalle@php.net
This isn't really a logically solution to start skipping calls as the compiler has no idea about its previous state.

If you have:
a.php:
class A {
}

b.php:
class B extends A {
}

and in your main script:
function __autoload($class) {
    require $class . '.php';
}

then it will work, because in your current case you are ending up in a recursive call and will either have a fatal error about it or a memory_limit reach (as the Engine will keep running the code until it runs dry of memory)

So the proper solution here is to not have such statically code that depends on other stuff in the autoloader, and its not something that any of us are going to implement, sorry :)
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Dec 02 04:01:24 2020 UTC