Autoload php classes from subfolders using underscore (PEAR style) notation

爱⌒轻易说出口 提交于 2019-12-24 12:23:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!