问题
前几天遇到了这个问题,本地项目打不开了,百度发现是Thinkphp版本的问题,官方说把tp升级到最新版,可解决.
过程
百度搜索到[MarsWill]的文章(http://my.csdn.net/hayixia606),解释了这个问题
在使用TP5框架的时候出现了如下的异常:
Uncaught Error: Call to undefined function lang() in framework/tpl/think_exception.tpl:82
这个异常的大概意思是在framework/tpl/think_exception.tpl这个文件中的lang()是一个未定义函数。而think_exception.tpl就是tp用来显示异常的试图模板。那为什么会报这个错误呢?我在trace中查看了文件加载的顺序,是这样的:
因为框架设计的加载顺序是:
E:\mrwei\thinkfive\application\config.php ( 8.55 KB )
E:\mrwei\thinkfive\application\database.php ( 1.87 KB )
E:\mrwei\thinkfive\thinkphp\library\think\Hook.php ( 4.63 KB )
E:\mrwei\thinkfive\application\tags.php ( 0.96 KB )
E:\mrwei\thinkfive\application\common.php ( 0.60 KB )
E:\mrwei\thinkfive\thinkphp\library\think\Env.php ( 1.05 KB )
E:\mrwei\thinkfive\thinkphp\helper.php ( 17.22 KB )
E:\mrwei\thinkfive\thinkphp\library\think\Lang.php ( 6.72 KB )
E:\mrwei\thinkfive\thinkphp\library\think\Log.php ( 5.51 KB )
E:\mrwei\thinkfive\thinkphp\lang\zh-cn.php ( 3.78 KB )
也就是application的config.php是在Lang.php之前载入的,如果config.php中有错误的话错误处理模板中的>lang('xxx')函数会提示找不到lang()方法。
解决方式
由于我本地是5.0.7版本的tp,到官网下载了5.0.14把其中thinkPHP文件夹替换掉,又出现了新的问题,不识别''__PUBLIC____",原来在view.php中默认的并没有定义public,将其中的构造函数修改为以下
/**
* 构造函数
* @access public
* @param array $engine 模板引擎参数
* @param array $replace 字符串替换参数
*/
public function __construct($engine = [], $replace = [])
{
// 初始化模板引擎
$this->engine((array) $engine);
// 基础替换字符串
$request = Request::instance();
$base = $request->root();
$root = strpos($base, '.') ? ltrim(dirname($base), DS) : $base;
if ('' != $root) {
$root = '/' . ltrim($root, '/');
}
$baseReplace = [
'__ROOT__' => $root,
'__URL__' => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()),
'__STATIC__' => $root . '/static',
'__PUBLIC__' => $root.'/public',// 站点公共目录
'__CSS__' => $root . '/public/css',
'__JS__' => $root . '/public/js',
'__IMG__' => $root.'/public/img',// 站点公共目录
'__PLUG__' => $root.'/public/plugins',// 站点公共目录
];
$this->replace = array_merge($baseReplace, (array) $replace);
}
结果还是报错,遂开启找茬模式,发现fetch函数也不一样,修改之
/**
* 解析和获取模板内容 用于输出
* @param string $template 模板文件名或者内容
* @param array $vars 模板输出变量
* @param array $replace 替换内容
* @param array $config 模板参数
* @param bool $renderContent 是否渲染内容
* @return string
* @throws Exception
*/
public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false)
{
// 模板变量
$vars = array_merge(self::$var, $this->data, $vars);
// 页面缓存
ob_start();
ob_implicit_flush(0);
// 渲染输出
$method = $renderContent ? 'display' : 'fetch';
$this->engine->$method($template, $vars, $config);
// 获取并清空缓存
$content = ob_get_clean();
// 内容过滤标签
Hook::listen('view_filter', $content);
// 允许用户自定义模板的字符串替换
$replace = array_merge($this->replace, $replace);
if (!empty($replace)) {
$content = strtr($content, $replace);
}
return $content;
}
终于搞定了