标签 debug 下的文章

问题? 今天迁站的时候PHP突然报错:

is_readable() [function.is-readable]: open_basedir restriction in effect. File(D:\phpnow\vhosts\wordpress.com/wp-content/plugins/D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/crayon-syntax-highlighter-zh_CN.mo) is not within the allowed path(s): (D:\phpnow\vhosts\wordpress.com;C:\Windows\Temp;) in D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php on line 339 好吧,看来是crayon-syntax-highlighter插件出错了,下面我们就一起找找出错的地方吧。

如何解决

确定出错地点 根据出错提示我们找到了

D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php的第339行,代码如下:

if ( !is_readable( $mofile ) ) return false;

这个$mofile哪里来的呢?把整个函数贴出来找找看!

function load_textdomain( $domain, $mofile ) {
	global $l10n;

	$plugin_override = apply_filters( 'override_load_textdomain', false, $domain, $mofile );

	if ( true == $plugin_override ) {
		return true;
	}

	do_action( 'load_textdomain', $domain, $mofile );

	$mofile = apply_filters( 'load_textdomain_mofile', $mofile, $domain );

	if ( !is_readable( $mofile ) ) return false;

	$mo = new MO();
	if ( !$mo->import_from_file( $mofile ) ) return false;

	if ( isset( $l10n[$domain] ) )
		$mo->merge_with( $l10n[$domain] );

	$l10n[$domain] = &$mo;

	return true;
}

看来是函数传进来的一个字符串,看来我们要继续寻找调用这个函数的地方了。不过wordpress的php文件少说也有1000多个,这样找下去是个什么效率?

等等!我好像想起来在学习数据结构的时候有一个概念叫栈,stack,什么是栈呢?其实站只是一个特殊的数据结构,它只允许在一串数据的一段进行操作,比如增加数据元素(入栈),删除数据元素(出栈)。举个栗子,堆栈就好比向水杯中放乒乓球,水杯的横截面只能通过一个乒乓球,如果想要把最先放进去的球取出来,必须把他上面的乒乓球按顺序一个一个取出来才行。 为什么突然想到栈这个概念呢?因为我们的函数调用就是使用的栈这个概念。简单地说,一个函数调用另一个函数,那么在调用期间需要保存现场,将自己的数据(比如调用指针、参数等)压入一个栈中,当调用完毕后再出栈恢复数据,然后继续调用。这个过程说起来简单,其实很复杂。以下摘自wikipedia:

在计算机科学领域中,'调用栈'Call Stack)是用于存储子程序信息的一类栈,别称执行栈(execution stack)、控制栈(control stack)、运行时栈(run-time stack)与机器栈(machine stack),在英语中亦经常简称为“栈”(“the stack”)。调用栈的维护对多数软件的正常运转有着重要意义,但一般高级语言都会隐藏其细节并自动进行维护。

既然细节被隐藏了,那么就不用深究了。下面就引出今天的主角函数。

主角

debug_backtrace()和debug_print_backtrace()两兄弟。

主要功能:他们保存了函数的调用栈信息,一个不输出以数组形式保存,另一个直接输出调用栈,调试的时候一般使用debug_print_backtrace()。 知道了这两个函数,将函数加入要追溯的函数内的第一行,不要忘了加;。 debug_backtrace()使用print_r显示如下:

Array
(
    [0] => Array
        (
            [file] => D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php
            [line] => 428
            [function] => load_textdomain
            [args] => Array
                (
                    [0] => crayon-syntax-highlighter
                    [1] => D:\phpnow\vhosts\wordpress.com/wp-content/plugins/D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/crayon-syntax-highlighter-zh_CN.mo
                )

        )

定睛一看,原来是个多维数组。file是调用文件,line是函数出现的行数,function是函数名,args是参数。 直接使用debug_print_backtrace()看看:

#0  load_textdomain(crayon-syntax-highlighter, D:\phpnow\vhosts\wordpress.com/wp-content/plugins/D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/crayon-syntax-highlighter-zh_CN.mo) called at [D:\phpnow\vhosts\wordpress.com\wp-includes\l10n.php:428]
#1  load_plugin_textdomain(crayon-syntax-highlighter, , D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter/trans/) called at [D:\phpnow\vhosts\wordpress.com\wp-admin\includes\plugin.php:121]
#2  _get_plugin_data_markup_translate(D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php, Array ([Name] => Crayon Syntax Highlighter,[PluginURI] => https://github.com/aramkocharyan/crayon-syntax-highlighter,[Version] => 2.4.1,[Description] => Supports multiple languages, themes, highlighting from a URL, local file or post text.,[Author] => Aram Kocharyan,[AuthorURI] => http://aramk.com/,[TextDomain] => crayon-syntax-highlighter,[DomainPath] => /trans/,[Network] => ), 1, 1) called at [D:\phpnow\vhosts\wordpress.com\wp-admin\includes\plugin.php:99]
#3  get_plugin_data(D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php) called at [D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php:39]
#4  include_once(D:\phpnow\vhosts\wordpress.com\wp-content\plugins\crayon-syntax-highlighter\crayon_wp.class.php) called at [D:\phpnow\vhosts\wordpress.com\wp-settings.php:197]
#5  require_once(D:\phpnow\vhosts\wordpress.com\wp-settings.php) called at [D:\phpnow\vhosts\wordpress.com\wp-config.php:90]
#6  require_once(D:\phpnow\vhosts\wordpress.com\wp-config.php) called at [D:\phpnow\vhosts\wordpress.com\wp-load.php:29]
#7  require_once(D:\phpnow\vhosts\wordpress.com\wp-load.php) called at [D:\phpnow\vhosts\wordpress.com\wp-blog-header.php:12]
#8  require(D:\phpnow\vhosts\wordpress.com\wp-blog-header.php) called at [D:\phpnow\vhosts\wordpress.com\index.php:30]

所有的函数调用清晰的呈现!

BUG在哪里?

通过仔细查找,发现原来load_plugin_textdomain()的第三个参数出了问题,该参数没有返回相对路径导致最后的路径错误,导致了MO文件无法找到。修改即可!

高级应用

请参考此篇

PHP debug_backtrace的胡思乱想