From 635f93dbcf15502423103f86f84def60b6562314 Mon Sep 17 00:00:00 2001 From: thinkphp Date: Mon, 19 Jan 2015 09:23:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Library/Think/Storage.php | 40 ++++++ Library/Think/Storage/Driver/File.php | 125 +++++++++++++++++ Library/Think/Storage/Driver/Sae.php | 194 ++++++++++++++++++++++++++ Mode/Sae/convention.php | 39 ++++++ Mode/common.php | 105 ++++++++++++++ Mode/sae.php | 68 +++++++++ start.php | 39 +++--- 7 files changed, 587 insertions(+), 23 deletions(-) create mode 100644 Library/Think/Storage.php create mode 100644 Library/Think/Storage/Driver/File.php create mode 100644 Library/Think/Storage/Driver/Sae.php create mode 100644 Mode/Sae/convention.php create mode 100644 Mode/common.php create mode 100644 Mode/sae.php diff --git a/Library/Think/Storage.php b/Library/Think/Storage.php new file mode 100644 index 00000000..aa62e677 --- /dev/null +++ b/Library/Think/Storage.php @@ -0,0 +1,40 @@ + +// +---------------------------------------------------------------------- +namespace Think; +// 分布式文件存储类 +class Storage { + + /** + * 操作句柄 + * @var string + * @access protected + */ + static protected $handler; + + /** + * 连接分布式文件系统 + * @access public + * @param string $type 文件类型 + * @param array $options 配置数组 + * @return void + */ + static public function connect($type='File',$options=array()) { + $class = 'Think\\Storage\\Driver\\'.ucwords($type); + self::$handler = new $class($options); + } + + static public function __callstatic($method,$args){ + //调用缓存驱动的方法 + if(method_exists(self::$handler, $method)){ + return call_user_func_array(array(self::$handler,$method), $args); + } + } +} diff --git a/Library/Think/Storage/Driver/File.php b/Library/Think/Storage/Driver/File.php new file mode 100644 index 00000000..cc8a0333 --- /dev/null +++ b/Library/Think/Storage/Driver/File.php @@ -0,0 +1,125 @@ + +// +---------------------------------------------------------------------- +namespace Think\Storage\Driver; +use Think\Storage; +// 本地文件写入存储类 +class File extends Storage{ + + private $contents=array(); + + /** + * 架构函数 + * @access public + */ + public function __construct() { + } + + /** + * 文件内容读取 + * @access public + * @param string $filename 文件名 + * @return string + */ + public function read($filename,$type=''){ + return $this->get($filename,'content',$type); + } + + /** + * 文件写入 + * @access public + * @param string $filename 文件名 + * @param string $content 文件内容 + * @return boolean + */ + public function put($filename,$content,$type=''){ + $dir = dirname($filename); + if(!is_dir($dir)){ + mkdir($dir,0777,true); + } + if(false === file_put_contents($filename,$content)){ + E(L('_STORAGE_WRITE_ERROR_').':'.$filename); + }else{ + $this->contents[$filename]=$content; + return true; + } + } + + /** + * 文件追加写入 + * @access public + * @param string $filename 文件名 + * @param string $content 追加的文件内容 + * @return boolean + */ + public function append($filename,$content,$type=''){ + if(is_file($filename)){ + $content = $this->read($filename,$type).$content; + } + return $this->put($filename,$content,$type); + } + + /** + * 加载文件 + * @access public + * @param string $filename 文件名 + * @param array $vars 传入变量 + * @return void + */ + public function load($_filename,$vars=null){ + if(!is_null($vars)){ + extract($vars, EXTR_OVERWRITE); + } + include $_filename; + } + + /** + * 文件是否存在 + * @access public + * @param string $filename 文件名 + * @return boolean + */ + public function has($filename,$type=''){ + return is_file($filename); + } + + /** + * 文件删除 + * @access public + * @param string $filename 文件名 + * @return boolean + */ + public function unlink($filename,$type=''){ + unset($this->contents[$filename]); + return is_file($filename) ? unlink($filename) : false; + } + + /** + * 读取文件信息 + * @access public + * @param string $filename 文件名 + * @param string $name 信息名 mtime或者content + * @return boolean + */ + public function get($filename,$name,$type=''){ + if(!isset($this->contents[$filename])){ + if(!is_file($filename)) { + return false; + } + $this->contents[$filename] = file_get_contents($filename); + } + $content=$this->contents[$filename]; + $info = array( + 'mtime' => filemtime($filename), + 'content' => $content + ); + return $info[$name]; + } +} diff --git a/Library/Think/Storage/Driver/Sae.php b/Library/Think/Storage/Driver/Sae.php new file mode 100644 index 00000000..98970081 --- /dev/null +++ b/Library/Think/Storage/Driver/Sae.php @@ -0,0 +1,194 @@ + +// +---------------------------------------------------------------------- +namespace Think\Storage\Driver; +use Think\Storage; +// SAE环境文件写入存储类 +class Sae extends Storage{ + + /** + * 架构函数 + * @access public + */ + private $mc; + private $kvs = array(); + private $htmls = array(); + private $contents = array(); + public function __construct() { + if(!function_exists('memcache_init')){ + header('Content-Type:text/html;charset=utf-8'); + exit('请在SAE平台上运行代码。'); + } + $this->mc = @memcache_init(); + if(!$this->mc){ + header('Content-Type:text/html;charset=utf-8'); + exit('您未开通Memcache服务,请在SAE管理平台初始化Memcache服务'); + } + } + + /** + * 获得SaeKv对象 + */ + private function getKv(){ + static $kv; + if(!$kv){ + $kv = new \SaeKV(); + if(!$kv->init()) + E('您没有初始化KVDB,请在SAE管理平台初始化KVDB服务'); + } + return $kv; + } + + + /** + * 文件内容读取 + * @access public + * @param string $filename 文件名 + * @return string + */ + public function read($filename,$type=''){ + switch(strtolower($type)){ + case 'f': + $kv = $this->getKv(); + if(!isset($this->kvs[$filename])){ + $this->kvs[$filename]=$kv->get($filename); + } + return $this->kvs[$filename]; + default: + return $this->get($filename,'content',$type); + } + } + + /** + * 文件写入 + * @access public + * @param string $filename 文件名 + * @param string $content 文件内容 + * @return boolean + */ + public function put($filename,$content,$type=''){ + switch(strtolower($type)){ + case 'f': + $kv = $this->getKv(); + $this->kvs[$filename] = $content; + return $kv->set($filename,$content); + case 'html': + $kv = $this->getKv(); + $content = time().$content; + $this->htmls[$filename] = $content; + return $kv->set($filename,$content); + default: + $content = time().$content; + if(!$this->mc->set($filename,$content,MEMCACHE_COMPRESSED,0)){ + E(L('_STORAGE_WRITE_ERROR_').':'.$filename); + }else{ + $this->contents[$filename] = $content; + return true; + } + } + } + + /** + * 文件追加写入 + * @access public + * @param string $filename 文件名 + * @param string $content 追加的文件内容 + * @return boolean + */ + public function append($filename,$content,$type=''){ + if($old_content = $this->read($filename,$type)){ + $content = $old_content.$content; + } + return $this->put($filename,$content,$type); + } + + /** + * 加载文件 + * @access public + * @param string $_filename 文件名 + * @param array $vars 传入变量 + * @return void + */ + public function load($_filename,$vars=null){ + if(!is_null($vars)){ + extract($vars, EXTR_OVERWRITE); + } + eval('?>'.$this->read($_filename)); + } + + /** + * 文件是否存在 + * @access public + * @param string $filename 文件名 + * @return boolean + */ + public function has($filename,$type=''){ + if($this->read($filename,$type)){ + return true; + }else{ + return false; + } + } + + /** + * 文件删除 + * @access public + * @param string $filename 文件名 + * @return boolean + */ + public function unlink($filename,$type=''){ + switch(strtolower($type)){ + case 'f': + $kv = $this->getKv(); + unset($this->kvs[$filename]); + return $kv->delete($filename); + case 'html': + $kv = $this->getKv(); + unset($this->htmls[$filename]); + return $kv->delete($filename); + default: + unset($this->contents[$filename]); + return $this->mc->delete($filename); + } + } + + /** + * 读取文件信息 + * @access public + * @param string $filename 文件名 + * @param string $name 信息名 mtime或者content + * @return boolean + */ + public function get($filename,$name,$type=''){ + switch(strtolower($type)){ + case 'html': + if(!isset($this->htmls[$filename])){ + $kv = $this->getKv(); + $this->htmls[$filename] = $kv->get($filename); + } + $content = $this->htmls[$filename]; + break; + default: + if(!isset($this->contents[$filename])){ + $this->contents[$filename] = $this->mc->get($filename); + } + $content = $this->contents[$filename]; + } + if(false===$content){ + return false; + } + $info = array( + 'mtime' => substr($content,0,10), + 'content' => substr($content,10) + ); + return $info[$name]; + } + +} \ No newline at end of file diff --git a/Mode/Sae/convention.php b/Mode/Sae/convention.php new file mode 100644 index 00000000..9101e436 --- /dev/null +++ b/Mode/Sae/convention.php @@ -0,0 +1,39 @@ + +// +---------------------------------------------------------------------- + +/** + * SAE模式惯例配置文件 + * 该文件请不要修改,如果要覆盖惯例配置的值,可在应用配置文件中设定和惯例不符的配置项 + * 配置名称大小写任意,系统会统一转换成小写 + * 所有配置参数都可以在生效前动态改变 + */ +defined('THINK_PATH') or exit(); +$st = new SaeStorage(); +return array( + //SAE下固定mysql配置 + 'DB_TYPE' => 'mysql', // 数据库类型 + 'DB_DEPLOY_TYPE' => 1, + 'DB_RW_SEPARATE' => true, + 'DB_HOST' => SAE_MYSQL_HOST_M.','.SAE_MYSQL_HOST_S, // 服务器地址 + 'DB_NAME' => SAE_MYSQL_DB, // 数据库名 + 'DB_USER' => SAE_MYSQL_USER, // 用户名 + 'DB_PWD' => SAE_MYSQL_PASS, // 密码 + 'DB_PORT' => SAE_MYSQL_PORT, // 端口 + //更改模板替换变量,让普通能在所有平台下显示 + 'TMPL_PARSE_STRING' => array( + // __PUBLIC__/upload --> /Public/upload -->http://appname-public.stor.sinaapp.com/upload + '/Public/upload' => $st->getUrl('public','upload') + ), + 'LOG_TYPE' => 'Sae', + 'DATA_CACHE_TYPE' => 'Memcachesae', + 'CHECK_APP_DIR' => false, + 'FILE_UPLOAD_TYPE' => 'Sae', +); diff --git a/Mode/common.php b/Mode/common.php new file mode 100644 index 00000000..7357b9af --- /dev/null +++ b/Mode/common.php @@ -0,0 +1,105 @@ + +// +---------------------------------------------------------------------- +namespace Think; +/** + * ThinkPHP 普通模式定义 + */ + +// 加载框架底层语言包 +Lang::set(include THINK_PATH.'Lang/'.strtolower(Config::get('default_lang')).EXT); + + +// 初始化操作可以在应用的公共文件中处理 下面只是示例 +//--------------------------------------------------- +// 日志初始化 +Log::init(['type'=>'File','log_path'=> LOG_PATH]); + +// 缓存初始化 +Cache::connect(['type'=>'File','temp'=> CACHE_PATH]); +//------------------------------------------------------ + +// 启动session +if(!IS_CLI) { + Session::init(['prefix'=>'think','auto_start'=>true]); +} +if(is_file(APP_PATH.'build.php')) { // 自动化创建脚本 + Create::build(include APP_PATH.'build.php'); +} + +return [ + // 配置文件 + 'config' => [ + 'app_debug' => true, // 调试模式 + 'app_status' => 'debug',// 调试模式状态 + 'var_module' => 'm', // 模块变量名 + 'var_controller' => 'c', // 控制器变量名 + 'var_action' => 'a', // 操作变量名 + 'var_pathinfo' => 's', // PATHINFO变量名 用于兼容模式 + 'pathinfo_fetch' => 'ORIG_PATH_INFO,REDIRECT_PATH_INFO,REDIRECT_URL', + 'pathinfo_depr' => '/', // pathinfo分隔符 + 'require_module' => true, // 是否显示模块 + 'default_module' => 'index', // 默认模块名 + 'require_controller' => true, // 是否显示控制器 + 'default_controller' => 'index', // 默认控制器名 + 'default_action' => 'index', // 默认操作名 + 'action_suffix' => '', // 操作方法后缀 + 'url_model' => 1, // URL模式 + 'base_url' => $_SERVER["SCRIPT_NAME"], // 基础URL路径 + 'url_html_suffix' => '.html', + 'url_params_bind' => false, // url变量绑定 + 'exception_tmpl' => THINK_PATH.'Tpl/think_exception.tpl',// 异常页面的模板文件 + 'error_tmpl' => THINK_PATH.'Tpl/dispatch_jump.tpl', // 默认错误跳转对应的模板文件 + 'success_tmpl' => THINK_PATH.'Tpl/dispatch_jump.tpl', // 默认成功跳转对应的模板文件 + 'default_ajax_return' => 'JSON', // 默认AJAX 数据返回格式,可选JSON XML ... + 'default_jsonp_handler' => 'jsonpReturn', // 默认JSONP格式返回的处理方法 + 'var_jsonp_handler' => 'callback', + 'template_engine' => 'think', + + /* 错误设置 */ + 'error_message' => '页面错误!请稍后再试~',//错误显示信息,非调试模式有效 + 'error_page' => '', // 错误定向页面 + 'show_error_msg' => false, // 显示错误信息 + + /* 数据库设置 */ + 'database' => [ + 'type' => 'mysql', // 数据库类型 + 'dsn' => '', // + 'hostname' => 'localhost', // 服务器地址 + 'database' => '', // 数据库名 + 'username' => 'root', // 用户名 + 'password' => '', // 密码 + 'hostport' => '', // 端口 + 'params' => [], // 数据库连接参数 + 'charset' => 'utf8', // 数据库编码默认采用utf8 + 'prefix' => '', // 数据库表前缀 + 'debug' => false, // 数据库调试模式 + 'deploy' => 0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) + 'rw_separate' => false, // 数据库读写是否分离 主从式有效 + 'master_num' => 1, // 读写分离后 主服务器数量 + 'slave_no' => '', // 指定从服务器序号 + ], + ], + + // 别名定义 + 'alias' => [ + 'Think\Log' => CORE_PATH . 'Log'.EXT, + 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File'.EXT, + 'Think\Exception' => CORE_PATH . 'Exception'.EXT, + 'Think\Model' => CORE_PATH . 'Model'.EXT, + 'Think\Db' => CORE_PATH . 'Db'.EXT, + 'Think\Template' => CORE_PATH . 'Template'.EXT, + 'Think\Cache' => CORE_PATH . 'Cache'.EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, + 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + ], + + 'init' => [], +]; diff --git a/Mode/sae.php b/Mode/sae.php new file mode 100644 index 00000000..2303ba9f --- /dev/null +++ b/Mode/sae.php @@ -0,0 +1,68 @@ + +// +---------------------------------------------------------------------- + +/** + * ThinkPHP SAE应用模式定义文件 + */ +return array( + // 配置文件 + 'config' => array( + THINK_PATH.'Conf/convention.php', // 系统惯例配置 + CONF_PATH.'config'.CONF_EXT, // 应用公共配置 + MODE_PATH.'Sae/convention.php',//[sae] sae的惯例配置 + ), + + // 别名定义 + 'alias' => array( + 'Think\Log' => CORE_PATH . 'Log'.EXT, + 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File'.EXT, + 'Think\Exception' => CORE_PATH . 'Exception'.EXT, + 'Think\Model' => CORE_PATH . 'Model'.EXT, + 'Think\Db' => CORE_PATH . 'Db'.EXT, + 'Think\Template' => CORE_PATH . 'Template'.EXT, + 'Think\Cache' => CORE_PATH . 'Cache'.EXT, + 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, + 'Think\Storage' => CORE_PATH . 'Storage'.EXT, + ), + + // 函数和类文件 + 'core' => array( + THINK_PATH.'Common/functions.php', + COMMON_PATH.'Common/function.php', + CORE_PATH . 'Hook'.EXT, + CORE_PATH . 'App'.EXT, + CORE_PATH . 'Dispatcher'.EXT, + //CORE_PATH . 'Log'.EXT, + CORE_PATH . 'Route'.EXT, + CORE_PATH . 'Controller'.EXT, + CORE_PATH . 'View'.EXT, + BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT, + BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT, + ), + // 行为扩展定义 + 'tags' => array( + 'app_begin' => array( + 'Behavior\ReadHtmlCacheBehavior', // 读取静态缓存 + ), + 'app_end' => array( + 'Behavior\ShowPageTraceBehavior', // 页面Trace显示 + ), + 'view_parse' => array( + 'Behavior\ParseTemplateBehavior', // 模板解析 支持PHP、内置模板引擎和第三方模板引擎 + ), + 'template_filter'=> array( + 'Behavior\ContentReplaceBehavior', // 模板输出替换 + ), + 'view_filter' => array( + 'Behavior\WriteHtmlCacheBehavior', // 写入静态缓存 + ), + ), +); diff --git a/start.php b/start.php index 69686fb0..bd248de4 100644 --- a/start.php +++ b/start.php @@ -21,36 +21,29 @@ require CORE_PATH.'Loader.php'; // 注册自动加载 Loader::register(); -// 导入系统别名 -Loader::addMap(include THINK_PATH.'alias.php'); -// 加载应用类 -//require CORE_PATH.'App.php'; -// 加载错误类 -//require CORE_PATH.'Error.php'; // 注册错误和异常处理机制 register_shutdown_function(['Think\Error','appShutdown']); set_error_handler(['Think\Error','appError']); set_exception_handler(['Think\Error','appException']); -// 导入系统惯例 -$config = Config::load(THINK_PATH.'convention.php'); +// 加载模式定义文件 +$mode = require MODE_PATH.APP_MODE.EXT; -// 初始化操作可以在应用的公共文件中处理 下面只是示例 -//--------------------------------------------------- -// 日志初始化 -Log::init(['type'=>'File','log_path'=> LOG_PATH]); - -// 缓存初始化 -Cache::connect(['type'=>'File','temp'=> CACHE_PATH]); -//------------------------------------------------------ - -// 启动session -if(!IS_CLI) { - Session::init(['prefix'=>'think','auto_start'=>true]); +// 加载模式配置文件 +if(isset($mode['config'])){ + is_array($mode['config']) ? Config::set($mode['config']) : Config::load($mode['config']); } -if(is_file(APP_PATH.'build.php')) { // 自动化创建脚本 - Create::build(include APP_PATH.'build.php'); + +// 加载模式别名定义 +if(isset($mode['alias'])){ + Loader::addMap(is_array($mode['alias']) ? $mode['alias'] : include $mode['alias']); } + +// 加载模式行为定义 +if(isset($mode['tags'])) { + Hook::import(is_array($mode['tags']) ? $mode['tags'] : include $mode['tags']); +} + // 执行应用 -App::run($config); +App::run(Config::get());