今天逛微博看到了新浪团队开发的TeamToy这样一个团队管理工具,看看功能和自己最近开发的项目中的一个模块很像,于是将源码下载下来按照他的说明进行安装。其中波折百出,进行了各种排查。从中发现了它的安装说明中的几个疏漏,及其程序中的一处BUG。
现阐明如下:
1、安装说明中的疏漏:
TeamToy需要PHP5、MySQL4以上的运行环境,依赖PHP的json/gd扩展,为支持在线升级,请将代码目录设为可写。
请将config/db.config.sample.php改名为config/db.config.php 并将里边的数据库信息修改为您空间的配置;然后将代码上传至服务器,用过浏览器访问[domain.com]/index.php?c=install 进行初始化
如上是它的安装简介,其中说明,“将请将config/db.config.sample.php改名为config/db.config.php”,即将数据库配置更改一下然后安装即可。
安装好后你却发现,正确的用户名密码却无法登陆“错误的Email地址或者密码,请重试”(数据库已初始成功,用户名存在)。原因何在?当然如果你是直接安装在网站root目录下,你不会发现这个问题,如果像我一样 http://127.0.0.1/teamtoy这样安装访问的话就会碰到。根据Firebug的XHR可以看出,点击登陆时是将参数POST提交到http://127.0.0.1/teamtoy/index.php?c=guest&a=login处理的,
找到controller/guest.class.php,打开它,找到login方法,
function login() { if( $user = login( v('email') , v('password') ) ) { foreach( $user as $key => $value ) $_SESSION[$key] = $value; return ajax_echo( '成功登入,正在转向中 ' .jsforword('?c=dashboard')); }elseif( $user === null ) { return ajax_echo( '尝试连接服务器失败,请稍后再试' ); } else { return ajax_echo( '错误的Email地址或者密码,请重试' ); } }
从if( $user = login( v('email') , v('password') ) )看出,登陆时是通过这个判断是否登陆成功。显然$user不为null,也不是个BOOLEN为true的值,return ajax_echo(login( v('email') , v('password')));发现为空,验证了我们上面的猜测。
于是我们找呀找呀,在lib/app.function.php中找到了这个login函数,
function login( $email , $password ) { if($content = file_get_contents( c('api_server') . '?c=api&a=user_get_token&email=' . u($email) . '&password=' .u($password) )) { $data = json_decode( $content , 1 ); if( ($data['err_code'] == 0) && is_array( $data['data'] ) ) return $data['data']; else return false; } return null; }
通过“$content = file_get_contents”发现,它是通过处理 file_get_contents返回内容来判断是否登陆成功信息的。
于是乎你就有了看看file_get_contents是什么内容的冲动。同样echo出来,在XHR中发现,返回的竟然是127.0.0.1的初始页面,又显然的,你知道应该是c('api_server')出了问题。
找呀找呀找朋友,在config/app.config.sample.php中我们找到了这一项配置
$GLOBALS['config']['site_name'] = 'TeamToy'; $GLOBALS['config']['site_domain'] = $_SERVER['HTTP_HOST']; $GLOBALS['config']['site_url'] = 'http://'.$GLOBALS['config']['site_domain']; $GLOBALS['config']['default_controller'] = 'guest'; $GLOBALS['config']['favicon'] = 'static/image/favicon.png'; $GLOBALS['config']['default_avatar'] = 'static/image/user.avatar.png'; $GLOBALS['config']['api_server'] = $GLOBALS['config']['site_url'] . '/index.php'; $GLOBALS['config']['api_check_new_verison'] = true; $GLOBALS['config']['teamtoy_url'] = 'http://tt2net.sinaapp.com';
坑爹哇,安装说明中没提到让我们改这个文件呀,,,,于是你将api_server配置改为如下
$GLOBALS['config']['api_server'] = $GLOBALS['config']['site_url'] . '/teamtoy/index.php';
再次登录,登录成功了!
2、程序中的BUG:
可登录成功后你又发现,头部的图标不显示了。。。不带这么坑爹的,,,
(当前) (正常)
一看HTML结构“<img title="Todo" src="static\image\tt2.menu.todo.png">”,完整URL:“http://127.0.0.1/teamtoy/static\image\tt2.menu.todo.png”,这是神马路径啊。。
再次找啊找(好累啊),在它的模板文件中,你找到了它处理图片的方式“<img src="<?=image('doing.gif')?>"/>”,于是我们又找到了lib/app.function.php,其中的:
function image( $filename ) { return 'static' . DS . 'image' . DS . $filename; }
看来,问题出在DS了,又得找这个常量了(>_<),在_lp/lp.init.php中找到了这个配置,
if( !defined('AROOT') ) die('NO AROOT!'); if( !defined('DS') ) define( 'DS' , DIRECTORY_SEPARATOR );
至于“DIRECTORY_SEPARATOR”是什么,大家自己参考这篇文章:PHP的DIRECTORY_SEPARATOR,PATH_SEPARATOR两个常量的作用 ,自然,改这个地方配置肯定不行了,动辄太大,只好修改image函数了,改成“return 'static' . '/' . 'image' . '/' . $filename;”
然后,,,问题都解决了,终于可以松一口气了。
猜测如下:
1、该程序的开发人员是在linux环境中编程的,开发完后没有在WIN环境中测试。
2、他们测试的安装环境是直接在网站root目录下的,没有建子目录安装,同样他们也没有测试过子目录安装。
【参考】: