kohana3.2部署到新浪SAE平台所需要的修改

近日学习用kohana框架,写了一个在线查字的小应用。在本地测试良好,效果图

主要实现的是按部首、按拼音查检索文字,搜索汉子查询。

主要业务逻辑很简单。预览地址请点击这里 现在部署在SAE平台上面。一些问题的参考文档来自这里

正常运行

本地测试完成代码,刚刚部署到SAE平台上时会出现这样的错误。

ErrorException [ Warning ]: Set the ini directive 'unserialize_callback_func' without permission

可以看到kohana完善的错误信息提示已经指向了APPPATH/bootstrap.php中得这一行

[code]

ini_set(‘unserialize_callback_func’, ‘spl_autoload_call’);

[/code]

这个是因为SAE平台禁用了ini_set()函数的原因,已经没有权限执行了。

解决办法就是直接注释,这个注释的影响是

“代码中使用了unserialize(),并且其解析的结果是一个对象,同时这个对象对应的类还没有定义。这种情况下就会导致一个错误。”来自上面那篇参考文章。

第二个错误则是日志、文件cache不能正常写入了。

Kohana_Exception [ 0 ]: Directory APPPATH/logs must be writable

这个是因为SAE平台禁止了程序对本地的文件进行操作,所以也就没有权限了。“唯一可以直接使用并提供了写入权限的是一个虚拟目录SAE_TMP_PATH。但是这个目录会在php脚本执行完后销毁,所以实际上并不能真正起到缓存的作用。”

解决办法 同样注释掉

[code]

Kohana::$log->attach(new Log_File(APPPATH.’logs’));

[/code]

这样则禁用了日志功能了,不过对于一般的程序来说没有太大的影响。

加入SAE的缓存目录常量

[code]

Kohana::init(array(
‘base_url’   => ‘/’,
‘index_file’ => ‘index.php’,
‘cache_dir’ => SAE_TMP_PATH // 这里
));

[/code]

至此如果你的程序不用缓存,那么配置好SAE平台的数据库连接参数等,程序就能正常访问了。

提示一下:

SAE的数据库参数hostname的常量,这个一定要注意,最好把SAE_MYSQL_PORT这个端口常量加上去,否则出现数据库连接不上的问题,但这个问题不容易被注意到,好吧,我就是好不容易才注意到的。SAE云平台的mysql端口不是默认的3306所以我刚开始时没有加上这个端口常量,想不出问题原因,最后登录sae后天,进入管理mysql数据库才看到,原来sae的mysql端口是3307

于是加上了这个端口常量,果然好了。。

[code]

‘hostname’   => SAE_MYSQL_HOST_M.’:’.SAE_MYSQL_PORT,
‘database’   => SAE_MYSQL_DB,
‘username’   => SAE_MYSQL_USER,
‘password’   => SAE_MYSQL_PASS,
‘persistent’ => FALSE,

[/code]

因为还有考虑到本地环境运行的问题;所以我再bootstrap.php中加入了SAE常量,值为true或false,true为sae,false为本地

最后bootstrap.ph的代码修改为

[code]

// 添加sae的环境控制,也能让程序在本地正常运行
define(‘SAE’, TRUE);

if( ! SAE){
define(‘SAE_TMP_PATH’, APPPATH.’/cache’);
}

/**
* 本地环境,非SAE平台的独立设置

*  注意这一段必须在 spl_autoload_register(array(‘Kohana’, ‘auto_load’)); 之后

*  否则Kohana类未加载情况下,调用$log会出错
*/
if( ! SAE ){

// SAE不支持ini_set函数的运行
ini_set(‘unserialize_callback_func’, ‘spl_autoload_call’);
// SAE暂不支持对文件夹进行文件写入,暂时关闭日志
Kohana::$log->attach(new Log_File(APPPATH.’logs’));

define(‘SAE_MYSQL_HOST_M’, ‘localhost’);
define(‘SAE_MYSQL_PORT’, ‘3306’);
define(‘SAE_MYSQL_DB’, ‘xhzd’);
define(‘SAE_MYSQL_USER’, ‘root’);
define(‘SAE_MYSQL_PASS’, ‘root’);

}

[/code]

使用SAE memcache 缓存

不过我的这个查字程序在部首;拼音列表,以及部首拼音相关的文字这些操作都用了缓存的。所以在sae上文件缓存是用不了了,但是还有memcache缓存啊。

因为SAE平台的memcache缓存启用不是原生的new memcache,而是memcache_init()所以程序还得改下。要改的地方比较简单。大致思路就是重写Kohana_Cache_Memcache的构造函数,重写初始化_memcache

modules\cache\classes\cache\memcache.php

[code]

class Cache_Memcache extends Kohana_Cache_Memcache {

public function __construct(array $config) {

parent::__construct($config);
// SAE平台则初始化sae平台memcache
if( SAE ){
$this->_memcache = memcache_init();
}

}

}

[/code]

不过还是有问题,在SAE平台上会显示 modules\cache\classes\kohana\cache\memcache.php

call undefined function   $this->_memcache->addServer() 估计也是被禁掉了。

那也好办注释掉就好了

[code]

/**
* 区别sae平台以及本地环境
*/
if( ! SAE){

// Add the memcache servers to the pool
foreach ($servers as $server)
{
// Merge the defined config with defaults
$server += $this->_default_config;

if ( ! $this->_memcache->addServer($server[‘host’], $server[‘port’], $server[‘persistent’], $server[‘weight’], $server[‘timeout’], $server[‘retry_interval’], $server[‘status’], $server[‘failure_callback’]))
{
throw new Cache_Exception(‘Memcache could not connect to host \’:host\’ using port \’:port\”, array(‘:host’ => $server[‘host’], ‘:port’ => $server[‘port’]));
}
}
}

[/code]

因为kohana默认采用的是文件缓存

所以在调用Cache::instance();前应当Cache::$default = 'memcache';

至此,memcache缓存就能正常的运行了。Kohana框架在SAE平台上的主要修改也完成,不过肯定还有一些不知道的问题,主要是对于SAE平台的不熟悉以及SAE平台处于安全考虑禁用的一些函数、方法等。

最后宣传下个人在sae上的这个应用地址欢迎访问http://xhzd.sinaapp.com/


发表评论

电子邮件地址不会被公开。 必填项已用*标注

*