首页 > php,linux日常 > spl_autoload的linux兼容性问题

spl_autoload的linux兼容性问题

最近帮朋友写一个php的后端,使用了php的spl_autoload_register机制。 类文件名后缀为.class.php文件名命名形如 ABC.class.php

文件内部class形如:

Class ABC{

}

由于在朋友那边的开发环境一直是在win下, 周末回家从git服务器上 clone到自己本地的linux环境里发现无法正常显示运行结果。

weired...

我的自动加载代码如下:

define('CUS_CLASS_DIR', ROOT_PATH.'/classes/');
set_include_path(CO_CLASS_DIR.PATH_SEPARATOR.MODEL_CL_DIR.PATH_SEPARATOR.CUS_CLASS_DIR);
spl_autoload_extensions(".class.php");  
spl_autoload_register();

检查set_include_path, 返回值为路径字串,正常
检查spl_autoload_extensions , 返回值为类文件后缀, 正常
检查spl_autoload_register , 返回值为true, 正常

由此可见,各function运行正常,spl可以正常找到类文件夹,可以正常找到后缀文件,并能正常注册。但是类没有正常加载。说明php没有正常找到类。 于是去找了php官方关于spl_autoload的讨论。隐约可以得出的结论是:

spl_autoload会把类名转化为小写进行文件搜索,因为WINDOWS大小写不敏感,而在LINUX下区分大小写,这样就造成linux下无法正常include文件

参考原文:

Note the slashes and backslashes in the file path. On Windows this works perfectly, but on a Linux machine, the backslashes won't work and additionally the file names are case-sensitive.

That's why on Linux the quick-and-easy way would be to convert these qualified class names to slashes and to lowercase and pass them to the built-in autoloader like so:

<?php
spl_autoload_register(
  function ($pClassName) {
    spl_autoload(strtolower(str_replace("\\", "/", $pClassName)));
  }
);
?>

But this means, you have to save all your classes with lowercase file names. Otherwise, if you omit the strtolower call, you have to use the class names exactly as specified by the file name, which can be annoying for class names that are defined with non-straightforward case like e. g. XMLHttpRequest.

I prefer the lowercase approach, because it is easier to use and the file name conversion can be done automatically on deploying.

另外stackoverflow也有相关问题解答:
http://stackoverflow.com/questions/2862133/namespace-autoload-works-under-windows-but-not-on-linux
php bug:
https://bugs.php.net/bug.php?id=53065

所以,兼容的最优解决方法为:
所有需呀包含的class文件名,一律为小写,当然,文件内容中的类可以保持为大写,调用类的时候也可以保持为大写

上一篇: sudo -u xxx 用来以其他身份来执行命令

下一篇: div垂直居中的N种方法