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

时间:2022-09-25 07:33:16

I have seen these,

我见过这些,

How to autoload class with a different filename? PHP

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

Load a class with a different name than the one passed to the autoloader as argument

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

I can change but in my MV* structure I have:

我可以改变但是在我的MV *结构中我有:

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

In the actually classes they are,

在它们的实际课程中,

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

I was trying to be consistent with the names. If I do not put the class name suffix (Controller, Model), I cannot load the class because that is redeclaring.

我试图与名字保持一致。如果我没有把类名后缀(Controller,Model),我无法加载该类,因为这是重新声明的。

If I keep the names of my classes, autoload fails because it will look for a class file named

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

CustomerController

when the file name is really,

当文件名真的是,

customer.controller.php

Are my only ways to (in no order):

是我唯一的方式(无序):

  • use create_alias
  • rename my files (customer.model.php to customermodel.php)
  • 重命名我的文件(customer.model.php到customermodel.php)

  • rename my classes
  • 重命名我的课程

  • use regular expressions
  • 使用正则表达式

  • use a bootstrap with included files (include, require_once, etc.)
  • 使用包含文件的引导程序(include,require_once等)

?

Example code,

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

spl_autoload_register('model_autoloader');

It seems I have to rename files,

好像我要重命名文件,

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

"The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name."

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

1 个解决方案

#1


1  

Looks to me this can be handled with some basic string manipulation and some conventions.

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

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;
}

The output is

输出是

Customer -> /models/customer.php

客户 - > /models/customer.php

CustomerController -> /controllers/customer.controller.php

CustomerController - > /controllers/customer.controller.php

You now need to use makeFileName inside the autoloader function.

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

I myself am strongly against stuff like this. I'd use namespaces and file names that reflect the namespace and class name. I'd also use Composer.

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

(I found splitCamelCase here.)

(我在这里找到了splitCamelCase。)

#1


1  

Looks to me this can be handled with some basic string manipulation and some conventions.

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

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;
}

The output is

输出是

Customer -> /models/customer.php

客户 - > /models/customer.php

CustomerController -> /controllers/customer.controller.php

CustomerController - > /controllers/customer.controller.php

You now need to use makeFileName inside the autoloader function.

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

I myself am strongly against stuff like this. I'd use namespaces and file names that reflect the namespace and class name. I'd also use Composer.

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

(I found splitCamelCase here.)

(我在这里找到了splitCamelCase。)