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

发布于 2024-10-31 02:59:31 字数 2440 浏览 2 评论 0原文

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

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

我正在使用 mod_rewrite 来实现人类友好的 URL,如 /classname/foldername/calssname ,然后作为下划线分隔值传递给页面加载器。
- 例如 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');



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.

这是正确的方法吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紫罗兰の梦幻 2024-11-07 02:59:31

而是偶然,与 另一件事,我找到了解决我的问题的< /a>!

因此,回答我自己的问题(并希望对其他人有所帮助):

  • 文件名应该只是 URL 的最后一部分

    ie .../not-this-part/but-this
  • 文件夹结构应该是 URL 结构的映射

    例如 .../folder/subfolder/class
  • 并且类应定义为完整路径,但使用下划线而不是正斜杠

    例如 classfolder_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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文