问题
I'm a bit new to Object Oriented PHP and MVC's so I really need some help please.
I have an MVC style folder structure with subfolders in the filesystem
- e.g. view/classes/subfolder/classname.php
I'm using mod_rewrite for human friendly URL's, as /classname
or /foldername/calssname
, which are then passed to a page loader as underscore separated values.
- e.g. foldername_classname
// Page Loader File require_once($_SERVER['DOCUMENT_ROOT'].'/local/classLoader.php'); session_start(); $page = new $_REQUEST['page'];
I have previously been using an [if / else if / else] block to test in each possible folder but this seems inefficient, so I'm looking for a better way to have the autoloader look in many different locations.
Here's my latest failure, which doesn't manage to find any of the classes requested and just outputs an exception for each ending up with a fatal error!:
function classToPath($class) { $path = str_replace('_', '/', $class) . '.php'; return $path; } function autoloadController($class) { echo 'LoadController'.'
'; $root = '/controller/classes/'; $pathtoclass = $root.classToPath($class); try { if( file_exists($pathtoclass) ) require_once($pathtoclass); else throw new Exception('Cannot load controller '.$class); } catch(Exception $e) { echo 'Controller exception: ' . $e->getMessage() . "
"; } } function autoloadModel($class) { echo 'LoadModel'.'
'; $root = '/model/classes/'; $pathtoclass = $root.classToPath($class); try { if( file_exists($pathtoclass) ) require_once($pathtoclass); else throw new Exception('Cannot load model '.$class); } catch(Exception $e) { echo 'Model exception: ' . $e->getMessage() . "
"; } } function autoloadView($class) { echo 'LoadView'.'
'; $root = '/view/classes/'; $pathtoclass = $root.classToPath($class); try { if( file_exists($pathtoclass) ) require_once($pathtoclass); else throw new Exception('Cannot load view '.$class); } catch(Exception $e) { echo 'View exception: ' . $e->getMessage() . "
"; } } spl_autoload_register('autoloadController'); spl_autoload_register('autoloadModel'); spl_autoload_register('autoloadView');
I was also wondering exactly how the URL to folder/class mapping should work:
- i.e. URL:
/foldername/classname
mod_rewritten to foldername_classname
;with a class filename of
classname.php
under the foldername
folder;and a php class definition of
class foldername_classname extends another_class { etc.
Is this the correct method?
回答1:
Rather by chance, relating to a different matter, I found the solution to my problem!
So to answer my own questions (and hopefully help others):
- the filename should be just the last part of the URL
i.e..../not-this-part/but-this
- the folder structure should be a map of the URL structure
e.g..../folder/subfolder/class
- and the class should be defined as the full path but with underscores instead of forward slashes
e.g.class folder_subfolder_class {
I then wrote a function for each class system (model, view & controller) and used spl_autoload_register()
to register each function as an __autoload
function. Thus...
function loadController($class) { $path = $_SERVER['DOCUMENT_ROOT'].'/application/controller/'; $filename = str_replace( '_', DIRECTORY_SEPARATOR, strtolower($class) ).'.php'; if( file_exists($path.$filename) ) { require_once($path.$filename); } } etc..etc.. spl_autoload_register('loadController'); ...
For those wondering about the mod_rewrite
part...
IfModule mod_rewrite.c RewriteEngine On RewriteBase / RewriteCond %{SCRIPT_FILENAME} !-f RewriteCond %{SCRIPT_FILENAME} !-d RewriteRule ^([a-z]+)/([a-z]+)/?$ /?page=$1_$2 [QSA,NC,L] RewriteRule ^([a-z]+)/?$ /?page=$1 [QSA,NC,L] /IfModule
来源:https://stackoverflow.com/questions/5570202/autoload-php-classes-from-subfolders-using-underscore-pear-style-notation