使用下划线(PEAR样式)表示法从子文件夹自动加载php类

时间:2011-04-06 17:03:48

标签: php oop mod-rewrite autoload

我对面向对象的PHP和MVC有点新意,所以我真的需要一些帮助。

我有一个MVC样式文件夹结构,文件系统中有子文件夹 - 例如view/classes/subfolder/classname.php

我正在将mod_rewrite用于人类友好的URL,如/classname/foldername/calssname,然后将这些URL作为下划线分隔值传递给页面加载器。
- 例如foldername_classname

// Page Loader File
require_once($_SERVER['DOCUMENT_ROOT'].'/local/classLoader.php');
session_start();
$page = new $_REQUEST['page'];

我之前一直在使用[if / else if / else]块来测试每个可能的文件夹,但这似乎效率低下,所以我正在寻找一种更好的方法让自动加载器看起来在许多不同的位置。

这是我最近的失败,它无法找到所请求的任何类,只是输出一个异常,最终导致致命错误!:

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');


<小时/> 我还想知道文件夹/类映射的URL应该如何工作:
- 即网址:/foldername/classname mod_rewritten为foldername_classname;
classname.php文件夹下的班级文件名为foldername;
class foldername_classname extends another_class { etc.

的php类定义

这是正确的方法吗?

1 个答案:

答案 0 :(得分:4)

相当偶然,与a different matter相关,我找到了the solution to my problem

所以回答我自己的问题(希望能帮助别人):

  • 文件名应该只是URL的最后一部分
    .../not-this-part/but-this
  • 文件夹结构应该是URL结构的映射 例如
    .../folder/subfolder/class
  • 并且应该将类定义为完整路径,但使用下划线而不是正斜杠 例如
    class folder_subfolder_class {

然后我为每个类系统(模型,视图和控制器)编写了一个函数,并使用spl_autoload_register()将每个函数注册为__autoload函数。因此...

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');
...

对于那些想知道mod_rewrite部分...

的人
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