PHP include() insanity



  •  I'm developing in PHP 5.1.6 (thanks CentOS) and it's not behaving itself. I have the following two files:

    Lib.php which contains:

    @Lib.php said:

        class Lib {
        }

    and test.php which contains:

    @test.php said:

      function __autoload($class_name) {
           $libPath=$class_name . '.php';
           if(file_exists($libPath)) require_once($libPath);
        }

    Both files are in the same directory. Now I do the follwoing in test.php:

        $obj=new LIB();

    which predictably fails because I'm on Linux and it's case-sensitive.

    However if I do this:

      $obj1=new Lib();

      $obj2=new LIB();

    Both objects are instantiated and it all works. What the hell is going on? Can anyone reproduce this in other PHP versions*?

     

    *Windows users need not apply obviously.

    ED: I found it easier to read with the contents of the files in [quotes] -btk



  •  ...wait... ah, never mind, I get it.

    Thanks TDWTF.



  •  erm... I don't get it... what was it?



  • I don't even do PHP and I got it.

    By calling Lib() first, the (case-sensitive) file system was able to find the library path and it got the library loaded. Then, the call to LIB() succeeded because the code is case-insensitive and treats LIB() the same as Lib(), which it now knew about.



  • @Scarlet Manuka said:

    I don't even do PHP and I got it.

    By calling Lib() first, the (case-sensitive) file system was able to find the library path and it got the library loaded. Then, the call to LIB() succeeded because the code is case-insensitive and treats LIB() the same as Lib(), which it now knew about.

    Yup, that's it. That's why it's considered a best practice to lower case all your file names, and then in autoload just do strtolower($class);



  • @ircmaxell said:

    Yup, that's it. That's why it's considered a best practice to lower case all your file names, and then in autoload just do strtolower($class);
    ... or you could just use consistent casing like a sane person.



  • @Lingerance said:

    @ircmaxell said:
    Yup, that's it. That's why it's considered a best practice to lower case all your file names, and then in autoload just do strtolower($class);
    ... or you could just use consistent casing like a sane person.

    True, but different versions of PHP treat things differently. So it's established practice (at least in most of the conventions I've used) to always lowercase the file names. Plus, it prevents stupid things like class.php and Class.php existing in the same directory...

    For example, most class references (CLASS, get_class(), etc) before php5 would return a lowercased name, PHP >= 5.0.0 return as declared. So if (like me) you've ever written code that is used on both, you just get into the habbit of doing the lowercase (although it's been some years since I've supported php4 in anything I've written).



  • @ircmaxell said:

    By calling Lib() first, the (case-sensitive) file system was able to find the library path and it got the library loaded.
     

    I'm having a chicken and egg issue.

    Lib() is inside the library file and can only be called after __autoload() is called. Lib() cannot be called successfully unless the variable $class_name was correct, the value of which is not mentioned in the OP.




  • @dhromed said:

    Filed under: fruit, subpixel, Stargate Atlantis, conjugate
     

    Start implementing that better shuffle! ;-)



  • Well... What happens is this:

    In your code (after you define __autoload), you make a call to the class Lib:

    $foo = new Lib();

    $bar = Lib::blah();

    $class = 'Lib';
    $baz = new $class();

    class_exists('lib');

    etc...

    PHP then checks to see if it knows a class by that name. If so, it uses that one. If not, it calls the autoload function with the name of the class as a parameter. Then it checks to see if the class is defined. If so, it continues as normal. If not, it fatal errors. But the key, is that the function is called from inside of php. It's not something that you normally call yourself.

    The benefit, is that if you have 1000 classes, you don't need to load each one before starting your program. You can just define the autoload function (or method in SPL), and then "lazy load" as needed...

     

    mod: fixed formatting because you're such a nice guy with your explanation. - dh



  • @b_redeker said:

    Start implementing that better shuffle! ;-)
     

    Thief!


Log in to reply