Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - spl_autoload and namespaces - doesn't work with capital letters

Tags:

php

I've set up a really basic autoloader in my index.php to grab a namespaced class within hello.php. My development environment is Ubuntu 12.04.

Why am I trying to do this? I'm trying to stick to the PSR-1 and PSR-2 coding standard, that includes:

Class names MUST be declared in StudlyCaps

Namespaces are as /Vendor/Class (note: capitals)

The following is my structure and code that works before making the changes to capitals.

Folder Structure

- web
  -- index.php
  -- core
    --- hello.php

Autoloader

Within index.php, I have my autoloader:

set_include_path(__DIR__);
spl_autoload_extensions('.php,.class.php');
spl_autoload_register();

Class File

Within the core folder, I have hello.php

namespace core;

class hello {
    public function __construct() {
        echo 'Constructed!';
    }
}

Code that works

If I run $obj = new \core\hello(); in my index.php, I get back "Constructed!". Great!


That which doesn't work

Renaming my core folder to 'Core' - note the uppercase C, and also the namespace in hello.php to namespace Core;.

Now let's try again with $obj = new \Core\hello();

Fatal error: Class 'Core\hello' not found in ...

So please tell me, why am I not able to use capital letters to keep inline with the PSR standards? What am I doing wrong?

like image 625
Jimbo Avatar asked Dec 21 '22 09:12

Jimbo


2 Answers

When you run your PHP code on a Linux platform, it's important to remember that Linux is case sensitive with filenames.

This affects autoloaders because they typically use the namespace and the class name when building the filename to load.

If the folder is named core, then the namespace must be core, with the same capitalisation. If you change it to Core in the namespace, then you must do the same to the folder name. (and as a result, all other core classes must be changed to Core at the same time).

On Windows, this doesn't happen because the Windows filesystem isn't case sensitive. This can cause confusion when code is tested and works on a local Windows-based dev system, and then breaks when it is copied to a Linux-based server.

[EDIT]

Okay, so I missed that you had changed the dirname as well. But nevertheless, I still think this is an issue of the filename/dirname case.

I note that you're calling spl_autoload_register() without any params. This means that the default spl_autoload() function will be used as the autoloader.

If you read the documentation for spl_autoload(), you'll note that it uses the lowercased version of the class and namespace.

In other words, using the default autoloader, your classes can be mixed case, but the folder structure and filenames must be all lower case.

So in fact, for you, you need to keep your filenames lower case.

I've personally experienced it the other way round, as per my original answer, where I had a fully lower case filename, and my mixed case class name was breaking when I moved from Windows dev box to Linux server. The reason my experience is different from yours is because I'm using a custom-written autoload function, which doesn't do an auto-lowercase conversion, so the case of my filenames has to match that of my classnames.

like image 180
SDC Avatar answered Feb 13 '23 03:02

SDC


I think you have shown us some good ambiguity.Correct me if I am wrong.

According to the specification you have to use the lowercased name of the class (and namespace) being instantiated.(http://www.php.net/manual/en/function.spl-autoload.php)

But PSR tells us to use the capital letters. If you want to stick with PSR then we have to overwrite the default spl_autoload to our own.

like image 40
kta Avatar answered Feb 13 '23 04:02

kta