Как мне автоматически загружать классы, у которых имя файла отличается от имени класса?


Я видел это,

Как автоматически загрузить класс с другим именем файла? 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

Мои единственные способы (в произвольном порядке):

  • использовать создать_алиас
  • переименовать мои файлы (customer.model.php чтобы customermodel.php )
  • переименовать мои классы
  • используйте регулярные выражения
  • используйте начальную загрузку с включенными файлами (include, require_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. Имя файла ДОЛЖНО соответствовать регистру имени завершающего класса"

.
Author: Community, 2015-06-17

1 answers

Мне кажется, что с этим можно справиться с помощью некоторых базовых манипуляций со строками и некоторых соглашений.

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

Вывод

Клиент ->/models/customer.php

Пользовательский контроллер ->/controllers/customer.controller.php

Теперь вам нужно использовать makeFileName внутри функции автозапуска.

Я сам категорически против подобных вещей. Я бы использовал пространства имен и имена файлов, которые отражают пространство имен и имя класса. Я бы также использовал Композитор.

(Я нашел splitCamelCase здесь.)

 1
Author: Sergiu Paraschiv, 2015-06-17 15:12:18