Reputation: 19725
I have seen these,
How to autoload class with a different filename? 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:
/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.
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):
include
,
require_once
, etc.)?
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."
Upvotes: 5
Views: 5195
Reputation: 10153
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
CustomerController -> /controllers/customer.controller.php
You now need to use makeFileName
inside the autoloader function.
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.
(I found splitCamelCase
here.)
Upvotes: 1