Edit report at https://bugs.php.net/bug.php?id=49625&edit=1

 ID:                 49625
 Comment by:         bram048 at gmail dot com
 Reported by:        jo at feuersee dot de
 Summary:            spl_autoload and case sensitivity
 Status:             Bogus
 Type:               Bug
 Package:            SPL related
 Operating System:   Linux
 PHP Version:        5.3.0
 Block user comment: N
 Private report:     N

 New Comment:

I agree with Simon. There is absolutely no reason not to fix this, while 
keeping 
backwards compatibility.

Two years ago the reason for not fixing it was "breaking BC is not an option". 
There are plenty of alternatives, and to be honest, PHP has broken BC alot of 
times in the last few versions (which is a good thing in my opinion, as long as 
the language becomes cleaner/stricter).

Having all the files in lowercase makes them alot harder to read. Having a 
custom autoloader function is slower and more complicated to get right, and 
just 
makes code more ugly and harder to understand.

At the very least case sensitivity of the SPL autoloader should be 
configurable, 
or available by the use of an extra suffix. I would love to see this in the new 
5.4 release; shouldn't take more than a few lines of code.


Previous Comments:
------------------------------------------------------------------------
[2011-03-08 13:08:42] simon at systemparadox dot co dot uk

Why is this bug marked as bogus?
Even if spl_autoload itself isn't fixed, at the very least a version that does 
it correctly could be added (although in this case it seriously could just be 
fixed by trying the correct case first).

Implementing one in PHP is all very well, but that means that it's non-standard 
and likely incompatible with what each programmer might expect. It's also 
slower.

------------------------------------------------------------------------
[2009-09-23 07:11:47] sjo...@php.net

Trying both lowercased and original case could solve this without breaking 
backwards compatibility. However, you could as well supply your own autoload 
function defined in PHP to solve this.

------------------------------------------------------------------------
[2009-09-22 19:37:20] jo at feuersee dot de

>The reason here is that is spl_autoload becomes case
>sensitive, it will break scripts which depend on spl_autoload being
>case insensitive.

spl_autoload() was introduced in PHP 5.1.2 which is case sensitive concerning 
class names. This implies that if an operation on an unknown class is done, 
spl_autoload() is triggered and executed with the case sensitive name of the 
class.
Thus we have 4 different possibilities:

1) The class name all lower case, the file containing the class definition is 
all lower case (eg. $foo = system::bar(); system.php)

This will work independent wether spl_autoload() is lowercasing or not, since 
all is lowercased. 
Note that if the class defined in the file system.php is actually named System 
it wouldn't have ever worked because the class system is still not defined, 
which would trigger an error.

2) The class name all lower case, the file containing the class definition is 
uppercased (eg. $foo = system::bar(); System.php)

This wouldn't work anymore on file systems which are case sensitive if 
spl_autoload() would skip lowercasing.

Note that this would only have worked if the file system is case insensitive 
and the class definition in System.php would define a class "system". 

3) The class name contains upper case letters, the file containing the class 
definition is lowercased (eg. $foo = System::bar(); system.php)

This is what currently isn't working at all but would work at least for case 
insensitive file systems if lowercasing would be dropped.

Note that if the class defined in the file system.php is actually named system 
it wouldn't have ever worked because the class System is still not defined.

4) The class name contains upper case letters, the file containing the class 
definition is uppercased (eg. $foo = System::bar(); System.php)

This is what should (and would) work, but currently doesn't.


Conclusion:

The only problem might be (2):

Class name: sample
Filename: Sample.php
Class definition in Sample.php: class sample { ... }
Note: this does work on case insensitive file systems only.

I really can't see any reason for maintaining the "Worse is better" principle 
here, I really doubt that there is much code around relying on the tolowercase 
feature/bug of spl_autoload().

As a compromise I propose the following:
1) spl_autoload() additionally tries to find a file _not_ lowercased. 2) Throw 
a E_DEPRECATED in case the filename had to be lowercased to match.

Until then:
I really don't know why this lowercasing thing was introduced into 
slp_autoload() to begin with, all it ever did was preventing classes to be 
named with upper case letters on file systems which are case sensitive. In 
other words: the only compatibility issue is that code which currently works on 
platforms like Windows only would suddenly work on UN*X like platforms too.

Pls confirm if this is the compatibility issue you are talking about.

------------------------------------------------------------------------
[2009-09-22 16:22:22] sjo...@php.net

Thank you for your bug report.

Wontfix means: we agree that there is a bug, but there are reasons not to fix 
it. The reason here is that is spl_autoload becomes case sensitive, it will 
break scripts which depend on spl_autoload being case insensitive.

------------------------------------------------------------------------
[2009-09-22 16:01:15] jo at feuersee dot de

Description:
------------
This is basically the same as PHP bug #48129.

Yes, I have read it "won't fix"

My opinion on this is "won't fix" is not an option because it _is_ a bug and 
not fixing bugs does not work:

1) It is common practice in OO languages (including PHP) to give classes case 
sensitive names. Even the classes of PHP itself are case sensitive and usually 
start with capital letters (eg. DateTime, Exception, ...). PHP related projects 
like PEAR, Zend Framework etc. do the same.

2) In order to get a proper 1:1 mapping from class name to the file containing 
the PHP class definition, projects like PEAR or Zend Framework use the case 
sensitive class name, eg. System.php contains the class System. Again, this is 
common practice in other OO languages like C++.

3) What happens when the file system is case sensitive?
See example: the script fails because the PEAR class System will be looked for 
in a file named system.php which does not exist because it is called System.php
The workaround is using SPL_autoload_suxx instead. But look at the code: there 
are several compatibility issues (include_path separator : vs. ;), it does work 
but is not at all convenient.

4) What would happen if spl_autoload() wouldn't lowercase the class name when 
looking for a class definition?
a) Filesystem is case sensitive
It would work!
The spl_autoload() would look for a file called System.php which exists, thus 
will be require'd

b) Filesystem is not case sensitive
It would still work!
The spl_autoload() would look for a file called System.php
Because the file system is case insensitive, it would use either System.php or 
system.php (or sYSTEM.PHP - you got the point?).
Because on case insentive filesystems both files "System.php" and "system.php" 
are not allowed in the same directory, there is _no_ issue with backward 
compatibility.

The only circumstances where it would break backwards compatibility would be on 
filesystem which is case insensitive but does not allow capital letters. Any 
real live examples of such a file system? 

Conclusion:
The current specification of spl_autoload() with implicit lowercasing is 
excactly wrong. There has been, is and never will be any gain in this 'feature' 
since the class name itself inside PHP is case sensitive.


Reproduce code:
---------------
<?php
/**
 * Demonstration of the current incompatibility 
 * Make sure you have PEAR inside your PHP include_path
 */

// this should work but doesn't
spl_autoload_register('spl_autoload');

// this does work
//spl_autoload_register('SPL_autoload_suxx');

/**
 * Does the same as spl_autoload, but without lowercasing
 */
function SPL_autoload_suxx($name)
{
        $rc = FALSE;
        
        $exts = explode(',', spl_autoload_extensions());
        $sep = (substr(PHP_OS, 0, 3) == 'Win') ? ';' : ':';
        $paths = explode($sep, ini_get('include_path'));
        foreach($paths as $path) {
                foreach($exts as $ext) {
                        $file = $path . DIRECTORY_SEPARATOR . $name . $ext;
                        if(is_readable($file)) {
                                require_once $file;
                                $rc = $file;
                                break;
                        }
                }
        }
        
        return $rc;
}

$binaries = array(
        'mysql' => System::which('mysql'),
        'mysqlbinlog' => System::which('mysqlbinlog'),
        'php' => System::which('php')
);
print_r($binaries);
                
?>

Expected result:
----------------
Array
(
    [mysql] => /usr/bin/mysql
    [mysqlbinlog] => /usr/bin/mysqlbinlog
    [php] => /usr/local/bin/php
)


Actual result:
--------------
PHP Fatal error:  Class 'System' not found in 
/srv/www/vhosts/www.easy-sew.de/ftpjung/bin/autoload.php on line 38



------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=49625&edit=1

Reply via email to