29

PHP manual suggests to autoload classes like

function __autoload($class_name){
 require_once("some_dir/".$class_name.".php");
}

and this approach works fine to load class FooClass saved in the file my_dir/FooClass.php like

class FooClass{
  //some implementation
}

Question

How can I make it possible to use _autoload() function and access FooClass saved in the file my_dir/foo_class.php?

Peyman Mohamadpour
  • 17,954
  • 24
  • 89
  • 100
P.M
  • 2,880
  • 3
  • 43
  • 53

2 Answers2

74

You could convert the class name like this...

function __autoload($class_name){
    $name = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $class_name));
    require_once("some_dir/".$name.".php");
}
Rik Heywood
  • 13,816
  • 9
  • 61
  • 81
  • Would this not have issues with a class name like *myClassName*? – Corey Ballou Oct 19 '09 at 16:01
  • Thanks for the answer rikh, your magic works! @cballou, the code works in your case too. I tested it on the following class names FooClass, fooClass, myFooClass and MyFooClass. – P.M Oct 19 '09 at 17:43
  • @cballou, nope, every time there is a lower case letter followed by an upper case letter, an underscore is inserted between them. Finally, a call to strtolower is made to ensure the final name is all lower case. – Rik Heywood Oct 19 '09 at 17:47
  • 5
    Note: This will transform MyCClassName to my_cclass_name and not my_c_class_name. – DanielG Apr 09 '13 at 14:30
  • 3
    Per comment from @DanielG if you want every uppercase letter except the first to result in an underscore: `strtolower(preg_replace('/(?<!^)([A-Z])/', '_$1', $class_name))`. The only difference between this and answer provided by @rik-heywood is that MyCClassName becomes my_c_class_name instead of my_cclass_name. –  Apr 18 '14 at 17:00
  • To handle more complicated (asinine) names, like `FooBARBazAndTHeLike => foo_bar_baz_and_t_he_like`, you can use (but shouldn't!) `strtolower(preg_replace('/((?<=[a-z])[A-Z])|((?<=[A-Z])[A-Z](?=[a-z]))/', _$1$2, $class_name))`. http://www.phpliveregex.com/p/dqi – spyle Oct 29 '15 at 21:18
2

This is untested but I have used something similar before to convert the class name. I might add that my function also runs in O(n) and doesn't rely on slow backreferencing.

// lowercase first letter
$class_name[0] = strtolower($class_name[0]);

$len = strlen($class_name);
for ($i = 0; $i < $len; ++$i) {
    // see if we have an uppercase character and replace
    if (ord($class_name[$i]) > 64 && ord($class_name[$i]) < 91) {
        $class_name[$i] = '_' . strtolower($class_name[$i]);
        // increase length of class and position
        ++$len;
        ++$i;
    }
}

return $class_name;
Corey Ballou
  • 42,389
  • 8
  • 62
  • 75