问题
How can I autoload Slim/Slim.php instead of using require
?
// standard method
//require 'ext/Slim/Slim.php';
// autoload method:
define ('WEBSITE_DOCROOT', str_replace('\\', '/', dirname(__FILE__)).'/');
// Instance of SplAutoload.
$SplAutoload = new SplAutoload();
// Load classes.
$SplAutoload->fetch([
'ext/' // Slim/ is kept under ext/
]);
\Slim\Slim::registerAutoloader();
//Instantiate a Slim application:
$app = new \Slim\Slim();
//Define a HTTP GET route:
$app->get('/', function () {
echo "Hello!";
});
$app->get('/hello/:name/', function ($name) {
echo "Hello, $name";
});
//Run the Slim application:
$app->run();
I get this error,
Fatal error: Class 'Slim\Slim' not found in C:...
the SplAutoload class,
class SplAutoload
{
/**
* Set the property.
*/
public $directories;
public function fetch($directories)
{
// Store the data into the property.
$this->directories = $directories;
// Register the classes that were loaded by __autoload as well.
spl_autoload_register('__autoload');
// When using spl_autoload_register() with class methods, it might seem that it can use only public methods,
// though it can use private/protected methods as well, if registered from inside the class:
spl_autoload_register([$this,'getClass']);
}
private function getClass($className)
{
if(is_array($this->directories)): $mainDirectories = $this->directories;
else: $mainDirectories = array($this->directories); endif;
// Set other vars and arrays.
$subDirectories = [];
//print_r($mainDirectories);
$namespace = "\\";
$isNamespace = false;
// When you use namespace in a class, you get something like this when you auto load that class \foo\tidy.
// So use explode to split the string and then get the last item in the exloded array.
$parts = explode($namespace, $className);
// Check if the current class is a namespace class or not.
if(strpos($className, $namespace) !== false)
{
$isNamespace = true;
}
// Set the class file name.
$filename = end($parts).'.php';
// List any sub dirs in the main dirs above and store them in an array.
foreach($mainDirectories as $mainDirectory)
{
// Check if the directory exists.
// Create it if it doesn't.
if (!file_exists(WEBSITE_DOCROOT.$mainDirectory))
{
mkdir(WEBSITE_DOCROOT.$mainDirectory, 0777);
}
// Must use absolute path to get the files when ajax is used.
foreach(glob(WEBSITE_DOCROOT.$mainDirectory.'*', GLOB_ONLYDIR) as $dir)
{
// Must trim off the WEBSITE_DOCROOT.
$subDirectories[] = preg_replace('~.*?(?=core|local)~i', '', str_replace('\\', '/', $dir)) .'/';
}
}
// Mearge the main dirs with any sub dirs in them.
$mergedDirectories = array_merge($mainDirectories,$subDirectories);
// Loop the merge array and include the classes in them.
foreach($mergedDirectories as $mainDirectory)
{
if(file_exists(WEBSITE_DOCROOT.$mainDirectory.$filename))
{
include_once WEBSITE_DOCROOT.$mainDirectory.$filename;
// Check if the class has existed.
if($isNamespace === false) if (class_exists($className)) break;
}
}
}
}
or any other SPL autoloader that I should go for? zend-autoloader?
回答1:
With the way your autoloader handles namespaces, you'll need to use this:
$SplAutoload->fetch([
'ext/Slim/' // Slim/ is kept under ext/
]);
or change your autoloader so it includes the namespace as a directory.
来源:https://stackoverflow.com/questions/27826066/slim-framework-how-to-autoload-slim-slim-php-instead-of-using-require