PHP魔术常量__FILE__无法识别符号链接问题解决
在PHP中,__FILE__魔术常量可以返回文件的完整路径和文件名。PHP手册中注明了它的功能:
文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。自 PHP 4.0.2 起,
__FILE__
总是包含一个绝对路径(如果是符号连接,则是解析后的绝对路径),而在此之前的版本有时会包含一个相对路径。
但这个功能在Linux系统下使用符号链接(Symlink)时却会遇到麻烦,Kaijia之前在开发@HFLS 2012时曾经遇到过使用Symlink部署代码出现Apache错误的情况,之后写了一篇《Linux下Apache使用符号链接及权限问题解决》。最近在开发IMUNC全新官方网站时遇到了与之原因结果相反的问题。
IMUNC.com是由WordPress驱动的,二次开发主要是在主题上,参考开发@HFLS 2012时的经验,为避免频繁变动代码,Kaijia将每次的主题放到不同的文件夹中并且通过Symlink链接到themes文件夹下。例如WordPress文件夹在/var/www/src/,而主题文件夹是/var/www/theme/r版本号/下,则通过运行命令
1 2 |
cd /var/www/src/wp-content/themes/ ln -s /var/www/theme/r版本号/ 主题文件夹名/ |
来是使PHP可以正常访问显示主题文件夹。不过在这过程中Kaijia遇到了麻烦,一个显示自定义CSS的PHP文件回报了500错误导致网页无法正常显示,经过检查发现是主题文件夹下的/css/custom.css.php使用了以下的代码造成的:
1 2 3 4 |
<?php $path_to_file = explode( 'wp-content', __FILE__ ); $path_to_wp = $path_to_file[0]; require_once( $path_to_wp . '/wp-load.php' ); |
此处代码试图加载wp-load.php文件,但是由于是Symlink,__FILE__实际返回的值是:
1 |
String "/var/www/theme/r版本号/css/custom.css.php" |
而不是我们期望的:
1 |
String "/var/www/src/wp-content/themes/主题文件夹/css/custom.css.php" |
所以实际返回值中不存在“wp-content”,所以最后才会出现错误。
Google之后,Kaijia在StackOverflow上找到了一个解决方案,pferate建议使用$_SERVER[“SCRIPT_FILENAME”](返回当前执行脚本的绝对路径)代替__FILE__。
最后Kaijia通过以下这段代码解决了问题:
1 2 3 |
<?php $path_to_wp = realpath(dirname(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))))); require_once( $path_to_wp . '/wp-load.php' ); |
另外如果主题中出现了这个问题,建议使用IDE的搜索功能再搜索一下其他位置,比如Kaijia使用的MetroStyle付费主题,通过NetBeans我还是出了一个文件也存在同样的问题需要修改。
[…] 详见 PHP魔术常量__FILE__无法识别符号链接问题解决 http://www.kaijia.me/2012/10/__file__-issue-with-symlink-in-php-solved/ […]