如何自动加载文件名与类名不同的类


How do I autoload classes that have a file name different from the class name?

我见过这些,

如何使用不同的文件名自动加载类?.PHP

加载

一个名称与作为参数传递给自动加载器的名称不同的类

我可以更改,但在我的 MV* 结构中,我有:

/models
    customer.class.php
    order.class.php
/controllers
    customer.controller.php
    order.controller.php
/views
...

在实际的类中,它们是,

class CustomerController {}
class OrderController{}
class CustomerModel{}
class OrderModel{}

我试图与名字保持一致。 如果我不输入类名后缀(控制器、模型),我就无法加载类,因为它正在重新声明。

如果我保留类的名称,自动加载将失败,因为它将查找名为

CustomerController

当文件名确实是,

customer.controller.php

是我唯一的方法(不按顺序):

  • 使用create_alias
  • 将我的文件 (customer.model.php重命名为 customermodel.php)
  • 重命名我的类
  • 使用正则表达式
  • 对包含的文件使用引导程序 ( includerequire_once等)

示例代码,

function model_autoloader($class) {
    include MODEL_PATH . $class . '.model.php';
}
spl_autoload_register('model_autoloader');

看来我必须重命名文件,

http://www.php-fig.org/psr/psr-4/

"终止类名对应于以 .php 结尾的文件名。文件名必须与终止类名的大小写匹配。

在我看来,

这可以通过一些基本的字符串操作和一些约定来处理。

define('CLASS_PATH_ROOT', '/');
function splitCamelCase($str) {
  return preg_split('/(?<=''w)(?=[A-Z])/', $str);
}
function makeFileName($segments) {
    if(count($segments) === 1) { // a "model"
        return CLASS_PATH_ROOT . 'models/' . strtolower($segments[0]) . '.php';
    }
    
    // else get type/folder name from last segment
    $type = strtolower(array_pop($segments));
    
    if($type === 'controller') {
        $folderName = 'controllers';
    }
    else {
        $folderName = $type;
    }
    
    $fileName = strtolower(join($segments, '.'));
    
    return CLASS_PATH_ROOT . $folderName . '/' . $fileName . '.' . $type . '.php';
}
$classNames = array('Customer', 'CustomerController');
foreach($classNames as $className) {
    $parts = splitCamelCase($className);
    
    $fileName = makeFileName($parts);
    
    echo $className . ' -> '. $fileName . PHP_EOL;
}

输出为

客户 ->/型号/客户.php

CustomerController ->/controllers/customer.controller.php

您现在需要在自动加载机功能中使用makeFileName

我自己强烈反对这样的事情。我会使用反映命名空间和类名的命名空间和文件名。我也会使用作曲家。

(我在这里找到了splitCamelCase