Kohana的代码不适于SAE的主要有三处,需要修改才能在SAE上正常使用。

1、unserialize_callback_func

Kohaha使用unserialize_callback_func实现反序列化对象的自动加载。
目前SAE不允许使用ini_set设置unserialize_callback_func,只能注释掉application\bootstrap.php中的相关行:

<?
ini_set('unserialize_callback_func', 'spl_autoload_call');  
?>

对大多数应用来说注释掉这行不会有什么影响。
除非遇到以下情况:使用了unserialize()解析出一个对象,同时这个对象对应的类没有定义,需要动态加载。这种情况下就会导致一个错误。

2、缓存

由于SAE本地IO的实现方式与普通LAMP架构不同,因此Kohana默认的基于文件的缓存无法使用。
解决方法是修改缓存存储方式到SAE支持的IO方式。
首先修改application\bootstrap.php中的缓存目录为SAE memcache wrapper:

<?
Kohana::init(array(
	'base_url'   => '/',
	'index_file' => '',
	'cache_dir'  => "saemc://",
));
?>

然后禁用kohana核心默认的缓存目录存在性检测。
在system\classes\kohana\core.php,253行附近,注释掉以下代码:

<?
if ( ! is_dir($settings['cache_dir']))
{
	try
	{
		//Create the cache directory

		mkdir($settings['cache_dir'], 0755, TRUE);

		//Set permissions (must be manually set to fix umask issues)

		chmod($settings['cache_dir'], 0755);
	}
	catch (Exception $e)
	{
		throw new Kohana_Exception('Could not create cache directory :dir',
		array(':dir' => Debug::path($settings['cache_dir'])));
	}
}
// Set the cache directory path

Kohana::$cache_dir = realpath($settings['cache_dir']);
?>

同样位置,添加以下代码(其实是修改上述代码的最后一行):

<?
Kohana::$cache_dir = $settings['cache_dir'];
?>

3、日志

同样由于SAE本地IO的实现方式与普通LAMP架构不同,因此Kohana默认的基于文件的日志无法使用。
需要重写日志输出类。
首先添加一个类,在部署这个类的时候,需要符合Kohana的文件结构。
我把它部署在system\classes\log\saefile.php:

<?php defined('SYSPATH') or die('No direct script access.');
/**
 * File log writer. Writes out messages and stores them in a YYYY/MM directory.
 *
 * @package    Ninlands
 * @category   Logging
 * @author     shadow
 * @copyright  (c) 2011 shadow
 */
class Log_Saefile extends Log_Writer {

	/**
	 * Creates a new file logger.
	 * @return  void
	 */
	public function __construct()
	{
	}

	/**
	 * Writes each of the messages into SAE
	 *     $writer->write($messages);
	 *
	 * @param   array   messages
	 * @return  void
	 */
	public function write(array $messages)
	{

		foreach ($messages as $message)
		{
			// Write each message into the log file

			// Format: time --- level: body

			sae_debug($message['time'].' --- '.$this->_log_levels[$message['level']].': '.$message['body'].PHP_EOL);
		}
	}

} // End Log_Saefile

然后修改application\bootstrap.php中的日志输出类:

<?
/**
 * Attach the file write to logging. Multiple writers are supported.
 */
Kohana::$log->attach(new Log_Saefile());
?>

现在,我们可以使用类似如下的语句输出日志了。这些日志都会出现在应用日志的debug分类中。

<?
Kohana::$log->add(LOG_DEBUG, 'This is debug message.');
?>

日志类型的定义如下:
(在system\classes\kohana\log\writer.php)

<?
	/**
	 * Numeric log level to string lookup table.
	 * @var array
	 */
	protected $_log_levels = array(
		LOG_EMERG   => 'EMERGENCY',
		LOG_ALERT   => 'ALERT',
		LOG_CRIT    => 'CRITICAL',
		LOG_ERR     => 'ERROR',
		LOG_WARNING => 'WARNING',
		LOG_NOTICE  => 'NOTICE',
		LOG_INFO    => 'INFO',
		LOG_DEBUG   => 'DEBUG',
		8           => 'STRACE',
	);
?>

又:通常情况下,需要关闭调试信息到浏览器的输出,代码如下。

<?
ini_set('display_errors',0);
?>

:) 现在,我们可以在SAE上欢快地运行Kohana了!