__autoload disaster - conflicts with Joomla
I have just changed all my code to use __autoload to find that it conflicts with the joomla autoloader. I integrate my app with joomla in some cases to register users etc.
I found spl_autoload_register() with aparently allows many autoloaders.
What should I do?
update: this is what joomla does
Loads this file from /library/loader.php
function __autoload($class)
{
if(JLoader::load($class)) {
return true;
}
return false;
}
Update 2:
OK, right after I load the Joomla library I call
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
//autoloader so that it does not interfere with mine
spl_autoload_register('__autoload');
This is what my autoload looks like:
<?php
//IMPORT
function myAutoload($class_name)
{
$path = str_replace('_', '/', $class_name);
include $path . '.php';
}
?>
spl_autoload_register('myAutoload',false,true);
Mine gets called first and the joomla one second, however, the the app still can't find the Joomla classes.
Update 3:
After running:
echo "PRE: myAutoload:" . spl_autoload_functions() . "<br />";
spl_autoload_register('myAutoload',false,true);
echo "POST: myAutoload:" . spl_autoload_functions() . "<br />";
and
echo "PRE: JoomlaAutoLoad:" . spl_autoload_functions() . "<br />";
//autoloader so that it does not interfere with mine
spl_autoload_register('__autoload');
echo "POST: JoomlaAutoLoad:" . spl_autoload_functions() . "<br />";
My output was: PRE: myAutoload: POST: myAutoload:Array
UPDATE 4:
I had to change the Joomla imports to this:
require_once ( JPATH_BASE .DS.'libraries'.DS.'loader.php' );
echo "PRE: JoomlaAutoLoad:" . var_dump(spl_autoload_functions()) . "<br />";
//autoloader so that it does not interfere with mine
spl_autoload_register('__autoload');
echo "POST: JoomlaAutoLoad:" . var_dump(spl_autoload_functions()) . "<br />";
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
Here is the output
PRE: myAutoload:
array
0 => string 'myAutoload' (length=10)
POST: myAutolo开发者_Go百科ad:
array
0 => string 'myAutoload' (length=10)
PRE: JoomlaAutoLoad:
array
0 => string 'myAutoload' (length=10)
1 => string '__autoload' (length=10)
POST: JoomlaAutoLoad:
I have worked out that after I include these Joomla files
require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
The spl_autoload_functions() returns nothing, so somehow joomla is stuffing it up.
you should decide which autoload function should have priority over the other one, and use spl_autoload_register()
accordingly (look at the third argument). How is the Joomla autoload function registered?
I have most simple answer to this question, at least worked for me every time for joomla 1.5.22 ::
require_once ( JPATH_SITE .DS.'libraries'.DS.'loader.php' );
spl_autoload_register('__autoload');
put these two lines before your own autoload register to give joomla preferance in stack
spl_autoload_register('DataMapper::autoload');
Just for the record, just tried this solution and it works for me in Joomla 1.5:
Go to \libraries\loader.php(160) and replace
function __autoload {...}
with
spl_autoload_register(array('JLoader', 'load'));
- Now you've fixed the Joomla side of things. You're actually done, there is no step 2. But just for the record, I'd double-check that your own libraries also are playing nice and using spl_autoload_register. If everyone is playing nice there should be no reference to any functions called __autoload anywhere anymore.
Voila. Done.
To read a clear and concise explanation of why this works, go here:
http://www.nicollet.net/2010/06/autoloading-be-friendly-to-intruders/
i did it other way, just calling this method in a helper:
public static function configureZend(){
$params = self::getParameters();
$zf_path = $params->get('zend_location');//this should be the zend framework directory location
define( 'ZFLIBPATH', $zf_path );
set_include_path( ZFLIBPATH );
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->pushAutoloader(array('JLoader','load'),'');
}
works all right, doesnt need to change any source of the joomla core, and all zend clases work fine.
精彩评论