5

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):

  • use create_alias
  • rename my files (customer.model.php to customermodel.php)
  • rename my classes
  • use regular expressions
  • use a bootstrap with included files (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."

Community
  • 1
  • 1
johnny
  • 19,272
  • 52
  • 157
  • 259
  • 2
    Well, yes, either make your naming simple or make your autoloader intelligent enough to deal with your complex names. You can do anything you need in your autoloader; if there is a pattern to your naming which can be expresses in code, you can implement it in your autoloader. – deceze Jun 17 '15 at 14:57
  • Your autoloader does not need to conform to PSR-4. You're not using Composer, but rather a custom function via `spl_autoload_register()`. You might consider checking both with `file_exists()` in the autoload function. – Michael Berkowski Jun 17 '15 at 14:57
  • @deceze I was hoping there was a magic PHP way to do it. I made it too hard. Thanks for help. – johnny Jun 17 '15 at 15:02
  • @MichaelBerkowski That isn't for all of PHP? – johnny Jun 17 '15 at 15:02
  • 2
    There's very little magic in PHP... ;o) – deceze Jun 17 '15 at 15:04
  • @johnny No. It is a very recent standard decided upon by the Framework Interoperability Group, which are representatives of several popular PHP open source projects. They have agreed on the PSR's for interoperability between their projects, but you needn't follow them if it doesn't work for your own situation. In the long run, if you can refactor everything, it might benefit you to use Composer and PSR-4 file layouts, but it isn't a requirement. `spl_autoload_register()` can be fully custom. – Michael Berkowski Jun 17 '15 at 15:06

1 Answers1

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

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.)

Community
  • 1
  • 1
Sergiu Paraschiv
  • 9,929
  • 5
  • 36
  • 47
  • Can you explain what you mean about the namespaces? I know what namespaces are but I'm not sure what you're saying to do. How would I name my classes, so I do not have to use string manipulation? – johnny Jun 17 '15 at 15:15
  • 1
    I was not clear. With that naming scheme and folder structure namespaces would be close to pointless. Having a `Controllers` namespace where you're dumping _all_ the controllers in your application is useless. What I meant is that I'd switch ASAP to meaningful namespaces (`Customers\\Controllers -> Customer`) and file names (`customers/controllers/customer.php`) that Composer handles "by default". – Sergiu Paraschiv Jun 17 '15 at 15:20