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

时间: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。)

相关文章