getConfig('siteInfo', '', "http://www.windframework.com/") . ")" ; ?>
- -
+ * 对象方式注册:
+ * $converter = new WindGeneralConverter();
+ * Wind::registeComponent($converter,'windConverter',singleton);
+ * 定义方式注册:
+ * Wind::registeComponent(array('path' =>
+ * 'WIND:convert.WindGeneralConverter', 'scope' => 'singleton'),
+ * 'windConverter');
+ *
+ * @param object|array $componentInstance
+ * @param string $componentName
+ * @param string $scope
+ * @return bool
+ */
+ public static function registeComponent($componentInstance, $componentName, $scope = 'application')
+ {
+ if (is_array($componentInstance)) {
+ isset($componentInstance['scope']) || $componentInstance['scope'] = $scope;
+ WindFactory::_getInstance()->loadClassDefinitions(
+ array($componentName => $componentInstance));
+ } elseif (is_object($componentInstance)) {
+ WindFactory::_getInstance()->registInstance($componentInstance, $componentName, $scope);
+ } else {
+ throw new WindException('[Wind.registeComponent] registe component fail, array or object is required',
+ WindException::ERROR_PARAMETER_TYPE_ERROR);
+ }
+ }
+
+ /**
+ *
+ * @see WindFrontController::getAppName()
+ * @return string
+ */
+ public static function getAppName()
+ {
+ return self::$_front->getAppName();
+ }
+
+ /**
+ * 返回当前的app应用
+ *
+ * @param string $appName
+ * @see WindFrontController::getApp()
+ * @return WindWebApplication
+ */
+ public static function getApp()
+ {
+ return self::$_front->getApp();
+ }
+
+ /**
+ * 加载一个类或者加载一个包
+ * 如果加载的包中有子文件夹不进行循环加载
+ * 参数格式说明:'WIND:base.WFrontController'
+ * WIND 注册的应用名称,应用名称与路径信息用‘:’号分隔
+ * base.WFrontController 相对的路径信息
+ * 如果不填写应用名称 ,例如‘base.WFrontController’,那么加载路径则相对于默认的应用路径
+ * 加载一个类的参数方式:'WIND:base.WFrontController'
+ * 加载一个包的参数方式:'WIND:base.*'
+ *
+ * @param string $filePath
+ * | 文件路径信息 或者className
+ * @return string null
+ */
+ public static function import($filePath)
+ {
+ if (!$filePath) {
+ return;
+ }
+ if (isset(self::$_imports[$filePath])) {
+ return self::$_imports[$filePath];
+ }
+ if (($pos = strrpos($filePath, '.')) !== false) {
+ $fileName = substr($filePath, $pos + 1);
+ } elseif (($pos = strrpos($filePath, ':')) !== false) {
+ $fileName = substr($filePath, $pos + 1);
+ } else {
+ $fileName = $filePath;
+ }
+ $isPackage = $fileName === '*';
+ if ($isPackage) {
+ $filePath = substr($filePath, 0, $pos + 1);
+ $dirPath = self::getRealPath(trim($filePath, '.'), false);
+ self::register($dirPath, '', true);
+ } else {
+ self::_setImport($fileName, $filePath);
+ }
+
+ return $fileName;
+ }
+
+ /**
+ * 将路径信息注册到命名空间,该方法不会覆盖已经定义过的命名空间
+ *
+ * @param string $path
+ * 需要注册的路径
+ * @param string $name
+ * 路径别名
+ * @param bool $includePath
+ * | 是否同时定义includePath
+ * @param bool $reset
+ * | 是否覆盖已经存在的定义,默认false
+ * @throws Exception
+ */
+ public static function register($path, $alias = '', $includePath = false, $reset = false)
+ {
+ if (!$path) {
+ return;
+ }
+ if (!empty($alias)) {
+ $alias = strtolower($alias);
+ if (!isset(self::$_namespace[$alias]) || $reset) {
+ self::$_namespace[$alias] = rtrim(
+ $path, '\\/').DIRECTORY_SEPARATOR;
+ }
+ }
+ if ($includePath) {
+ if (empty(self::$_includePaths)) {
+ self::$_includePaths = array_unique(explode(PATH_SEPARATOR, get_include_path()));
+ if (($pos = array_search('.', self::$_includePaths, true)) !== false) {
+ unset(
+ self::$_includePaths[$pos]);
+ }
+ }
+ array_unshift(self::$_includePaths, $path);
+ if (set_include_path(
+ '.'.PATH_SEPARATOR.implode(PATH_SEPARATOR, self::$_includePaths)) === false) {
+ throw new Exception('[Wind.register] set include path error.');
+ }
+ }
+ }
+
+ /**
+ * 返回命名空间的路径信息
+ *
+ * @param string $namespace
+ * @return string Ambigous multitype:>
+ */
+ public static function getRootPath($namespace)
+ {
+ $namespace = strtolower($namespace);
+
+ return isset(self::$_namespace[$namespace]) ? self::$_namespace[$namespace] : '';
+ }
+
+ /**
+ * 类文件自动加载方法 callback
+ *
+ * @param string $className
+ * @param string $path
+ */
+ public static function autoLoad($className, $path = '')
+ {
+ $filePath = $className.'.'.self::$_extensions;
+
+ if ($path) {
+ $filePath = $path.'.'.self::$_extensions;
+ } elseif (isset(self::$_classes[$className])) {
+ $filePath = self::$_classes[$className].'.'.self::$_extensions;
+ }
+
+ if (file_exists($filePath) && is_file($filePath)) {
+ include $filePath;
+ }
+ }
+
+ /**
+ * 解析路径信息,并返回路径的详情
+ *
+ * @param string $filePath
+ * 路径信息
+ * @param bool $suffix
+ * 是否存在文件后缀true,false,default
+ * @return string array('isPackage','fileName','extension','realPath')
+ */
+ public static function getRealPath($filePath, $suffix = '', $absolut = false)
+ {
+ if (false !== strpos($filePath, DIRECTORY_SEPARATOR)) {
+ return realpath($filePath);
+ }
+ if (false !== ($pos = strpos($filePath, ':'))) {
+ $namespace = self::getRootPath(substr($filePath, 0, $pos));
+ $filePath = substr($filePath, $pos + 1);
+ } else {
+ $namespace = $absolut ? self::getRootPath(self::getAppName()) : '';
+ }
+
+ $filePath = str_replace('.', '/', $filePath);
+ $namespace && $filePath = $namespace.$filePath;
+ if ($suffix === '') {
+ return $filePath.'.'.self::$_extensions;
+ }
+ if ($suffix === true && false !== ($pos = strrpos($filePath, '/'))) {
+ $filePath[$pos] = '.';
+
+ return $filePath;
+ }
+
+ return $suffix ? $filePath.'.'.$suffix : $filePath;
+ }
+
+ /**
+ * 解析路径信息,并返回路径的详情
+ *
+ * @param string $filePath
+ * 路径信息
+ * @param bool $absolut
+ * 是否返回绝对路径
+ * @return string array('isPackage','fileName','extension','realPath')
+ */
+ public static function getRealDir($dirPath, $absolut = false)
+ {
+ if (false !== ($pos = strpos($dirPath, ':'))) {
+ $namespace = self::getRootPath(substr($dirPath, 0, $pos));
+ $dirPath = substr($dirPath, $pos + 1);
+ } else {
+ $namespace = $absolut ? self::getRootPath(self::getAppName()) : '';
+ }
+
+ return ($namespace ? $namespace : '').str_replace('.', '/', $dirPath);
+ }
+
+ /**
+ * 初始化框架
+ */
+ public static function init()
+ {
+ self::$isDebug = WIND_DEBUG;
+ function_exists('date_default_timezone_set') && date_default_timezone_set('Etc/GMT+0');
+ self::register(WIND_PATH, 'WIND', true);
+ if (!self::$_isAutoLoad) {
+ return;
+ }
+ if (function_exists('spl_autoload_register')) {
+ spl_autoload_register('Wind::autoLoad', true, false);
+ } else {
+ self::$_isAutoLoad = false;
+ }
+ }
+
+ /**
+ * 日志记录
+ *
+ * 调用WindLogger组建进行日志记录
+ * @param string $message
+ * @param string $logType
+ * @throws WindMailException
+ */
+ public static function log($message, $logType = 'wind.core')
+ {
+ if (self::$isDebug) {
+ $traces = debug_backtrace();
+ if (isset($traces[1])) {
+ $message = "\r\n".$traces[0]['file'].' ('.$traces[0]['line'].') ['.
+ $traces[1]['class'].'::'.$traces[1]['function']."]\r\n".$message;
+ }
+ Wind::getComponent('windLogger')->info($message, $logType);
+ }
+ }
+
+ /**
+ *
+ * @param string $className
+ * @param string $classPath
+ */
+ private static function _setImport($className, $classPath)
+ {
+ self::$_imports[$classPath] = $className;
+ if (!isset(self::$_classes[$className])) {
+ $_classPath = self::getRealPath($classPath, false);
+ self::$_classes[$className] = $_classPath;
+ } else {
+ $_classPath = self::$_classes[$className];
+ }
+ if (!self::$_isAutoLoad) {
+ self::autoLoad($className, $_classPath);
+ }
+ }
}
-Wind::init();
\ No newline at end of file
+Wind::init();
diff --git a/wind/base/AbstractWindApplication.php b/wind/base/AbstractWindApplication.php
new file mode 100644
index 00000000..eea05dcc
--- /dev/null
+++ b/wind/base/AbstractWindApplication.php
@@ -0,0 +1,292 @@
+run,getRequest,getResponse,getWindFactory,自定义应用类型需要实现该接口.
+ * 基础实现有WindWebApplication
+ * @author Qiong Wu
+ * controller
+ *
+ * Controller
+ *
+ * WIND:web.WindErrorHandler
+ *
+ *
+ *
+ * template
+ *
+ * htm
+ *
+ * @param string $name
+ * module名称
+ * @param array $config
+ * 配置数组
+ * @param bool $replace
+ * 如果module已经存在是否覆盖他 默认值为false不进行覆盖
+ * @return array
+ */
+ public function setModules($name, $config, $replace = false)
+ {
+ if ($replace || !isset($this->_config['modules'][$name])) {
+ $this->_config['modules'][$name] = (array) $config;
+ }
+
+ return $this->_config['modules'][$name];
+ }
+
+ /**
+ * 获得module配置,$name为空时返回当前module配置
+ *
+ * @param string $name
+ * module名称 默认为空
+ * @param bool $merge
+ * 合并默认值
+ * @return array
+ * @throws WindActionException
+ * @throws WindException
+ */
+ public function getModules($name = '')
+ {
+ if ($name === '') {
+ $name = $this->handlerAdapter->getModule();
+ }
+ if ($name === 'pattern') {
+ $name = $this->handlerAdapter->getDefaultModule();
+ }
+ $_module = $this->getConfig('modules', $name, array());
+ if (!isset($_module['_verified']) || $_module['_verified'] !== true) {
+ if (empty($_module) && !empty($this->_config['modules']['pattern'])) {
+ $_module = $this->_config['modules']['pattern'];
+ }
+ $_flag = empty($_module);
+ $_module = WindUtility::mergeArray($this->_config['modules']['default'], $_module);
+ $_module_str = implode('#', $_module);
+ if (strpos($_module_str, '{') !== false) {
+ preg_match_all('/{(\w+)}/i', $_module_str, $matches);
+ if (!empty($matches[1])) {
+ $_replace = array();
+ foreach ($matches[1] as $key => $value) {
+ if ($value === $this->handlerAdapter->getModuleKey()) {
+ $_replace['{'.$value.'}'] = $this->handlerAdapter->getModule();
+ } elseif ($value === $this->handlerAdapter->getControllerKey()) {
+ $_replace['{'.$value.'}'] = $this->handlerAdapter->getController();
+ } elseif ($value === $this->handlerAdapter->getActionKey()) {
+ $_replace['{'.$value.'}'] = $this->handlerAdapter->getAction();
+ } else {
+ $_replace['{'.$value.'}'] = $this->request->getGet($value);
+ }
+ }
+ $_module_str = strtr($_module_str, $_replace);
+ $_module = array_combine(array_keys($_module), explode('#', $_module_str));
+ }
+ } elseif ($_flag) {
+ throw new WindException('Your request was not found on this server.', 404);
+ }
+
+ $_module['_verified'] = true;
+ $this->_config['modules'][$name] = $_module;
+ }
+
+ return $_module;
+ }
+
+ /**
+ * 手动注册actionFilter
+ * 参数为数组格式:
+ *
+ * @param array $filters
+ */
+ public function registeActionFilter($filters)
+ {
+ if (!$filters) {
+ return;
+ }
+ if (empty($this->_config['filters'])) {
+ $this->_config['filters'] = $filters;
+ } else {
+ $this->_config['filters'] += $filters;
+ }
+ }
+
+ /**
+ * 解析action过滤链的配置信息
+ *
+ * @param WindSimpleController $handler
+ */
+ protected function resolveActionFilters(&$handler)
+ {
+ if (!$filters = $this->getConfig('filters')) {
+ return;
+ }
+ /* @var $cache AbstractWindCache */
+ $_filters = array();
+ if ($cache = Wind::getComponent('windCache')) {
+ $_filters = $cache->get('filters');
+ }
+ $_token = $this->handlerAdapter->getModule().'/'.$this->handlerAdapter->getController().'/'.$this->handlerAdapter->getAction();
+ if (!isset($_filters[$_token])) {
+ foreach ($filters as $_filter) {
+ if (empty($_filter['class'])) {
+ continue;
+ }
+ $_pattern = empty($_filter['pattern']) ? '' : $_filter['pattern'];
+ unset($_filter['pattern']);
+ if ($_pattern) {
+ $_pattern = str_replace(array('*', '/'), array('\w*', '\/'), $_pattern);
+ if (in_array($_pattern[0], array('~', '!'))) {
+ $_pattern = substr($_pattern, 1);
+ if (preg_match('/^'.$_pattern.'$/i', $_token)) {
+ continue;
+ }
+ } else {
+ if (!preg_match('/^'.$_pattern.'$/i', $_token)) {
+ continue;
+ }
+ }
+ }
+ $_filters[$_token][] = $_filter;
+ }
+ $cache && $cache->set('filters', $_filters);
+ }
+ if (empty($_filters[$_token])) {
+ return;
+ }
+ /* @var $proxy WindClassProxy */
+ $proxy = new WindClassProxy();
+ $proxy->registerTargetObject($handler);
+ foreach ($_filters[$_token] as $value) {
+ $proxy->registerEventListener(
+ $this->factory->createInstance(Wind::import($value['class']),
+ array($handler->getForward(), $handler->getErrorMessage(), $this->handlerAdapter, $value)),
+ 'doAction');
+ }
+ $handler = $proxy;
+ }
+
+ /**
+ *
+ * @return WindHttpRequest
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ /**
+ *
+ * @return WindHttpResponse
+ */
+ public function getResponse()
+ {
+ return $this->response;
+ }
+
+ /**
+ *
+ * @return WindFactory
+ */
+ public function getFactory()
+ {
+ return $this->factory;
+ }
+}
diff --git a/wind/base/AbstractWindBootstrap.php b/wind/base/AbstractWindBootstrap.php
new file mode 100644
index 00000000..13835d7a
--- /dev/null
+++ b/wind/base/AbstractWindBootstrap.php
@@ -0,0 +1,43 @@
+
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id$
+ * @package wind
+ */
+abstract class AbstractWindBootstrap extends WindSimpleHandlerInterceptor
+{
+ /**
+ * @var AbstractWindFrontController
+ */
+ protected $front = null;
+
+ /**
+ * @param AbstractWindFrontController $front
+ */
+ public function __construct($front = null)
+ {
+ $this->front = $front;
+ }
+
+ /**
+ * 该方法在 application 创建之前被调用
+ */
+ abstract public function onCreate();
+
+ /**
+ * 该方法在路由之后,应用启动之前被调用
+ */
+ abstract public function onStart();
+
+ /**
+ * 该方法在应用运行结束,视图输出之前被调用
+ */
+ abstract public function onResponse();
+}
diff --git a/wind/base/AbstractWindFrontController.php b/wind/base/AbstractWindFrontController.php
index b3af0ea7..7f251a29 100644
--- a/wind/base/AbstractWindFrontController.php
+++ b/wind/base/AbstractWindFrontController.php
@@ -1,401 +1,329 @@
2011-12-27
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
* @version $$Id$$
* @package base
*/
-abstract class AbstractWindFrontController {
- /**
- * request类型定义
- *
- * @var string
- */
- protected $_request = null;
- /**
- * 组件工程实例对象
- *
- * @var WindFactory
- */
- protected $_factory = null;
- /**
- * 应用配置
- *
- * @var array
- */
- protected $_config = array();
- /**
- * 当前app名称
- *
- * @var string
- */
- protected $_appName;
- /**
- * 应用对象数组
- *
- * @var WindWebApplication
- */
- private $_app = null;
- /**
- * @var WindHandlerInterceptorChain
- */
- private $_chain = null;
- /**
- * @var AbstractWindCache
- */
- private $_cache = null;
- private $_cached = false;
- protected $_errPage = 'error';
+abstract class AbstractWindFrontController
+{
+ /**
+ * 响应对象
+ *
+ * @var WindHttpResponse
+ */
+ protected $_response = null;
+ /**
+ * 请求对象
+ *
+ * @var WindHttpRequest
+ */
+ protected $_request = null;
+ /**
+ * 组件工程实例对象
+ *
+ * @var WindFactory
+ */
+ protected $_factory = null;
+ /**
+ * 应用配置
+ *
+ * @var array
+ */
+ protected $_config = array(
+ 'isclosed' => false,
+ 'web-apps' => array(
+ 'default' => array(
+ 'error-dir' => 'WIND:web.view',
+ 'compress' => true,
+ 'root-path' => '',
+ 'charset' => 'utf-8',
+ 'modules' => array(
+ 'default' => array(
+ 'controller-path' => 'controller',
+ 'controller-suffix' => 'Controller',
+ 'error-handler' => 'WindErrorHandler', ), ), ), ),
+ 'components' => array(), );
+ /**
+ * 当前app名称
+ *
+ * @var string
+ */
+ protected $_appName = 'default';
+ /**
+ * 应用对象数组
+ *
+ * @var WindWebApplication
+ */
+ protected $_app = null;
+ /**
+ *
+ * @var WindHandlerInterceptorChain
+ */
+ private $_chain = null;
- /**
- * @param string $appName 默认app名称
- * @param Array|string $config 应用配置信息,支持为空或多应用配置
- */
- public function __construct($appName, $config) {
- set_error_handler(array($this, '_errorHandle'), error_reporting());
- set_exception_handler(array($this, '_exceptionHandle'));
- $appName && $this->_appName = $appName;
- $this->_config = $config;
- }
+ /**
+ *
+ * @param string $appName
+ * 默认app名称
+ * @param Array|string $config
+ * 应用配置信息,支持为空或多应用配置
+ */
+ public function __construct($appName, $config)
+ {
+ $appName && $this->_appName = $appName;
+ $this->init($config);
+ }
- /**
- * 创建并返回应用对象实例
- *
- * @return WindWebApplication
- */
- abstract protected function _createApplication();
+ /**
+ * 预加载系统文件,返回预加载系统文件数据
+ * 预加载系统文件格式如下,键值为类名=>值为类的includePath,可以是相对的(如果includePath中已经包含了该地址)
+ * 也可以是绝对地址,但不能是wind的命名空间形式的地址+ * return array( + * 'WindController' => 'web/WindController', + * 'WindDispatcher' => 'web/WindDispatcher' + *+ * + * @return array + */ + abstract protected function _loadBaseLib(); - /** - * 预加载系统文件,返回预加载系统文件数据 - * - * 预加载系统文件格式如下,键值为类名=>值为类的includePath,可以是相对的(如果includePath中已经包含了该地址) - * 也可以是绝对地址,但不能是wind的命名空间形式的地址
- * return array( - * 'WindController' => 'web/WindController', - * 'WindDispatcher' => 'web/WindDispatcher' - *- * @return void - * @return array - */ - abstract protected function _loadBaseLib(); + /** + * 返回组建定义信息 + * 组件的配置标签说明: + * name: 组件的名字,唯一用于在应用中获取对应组件的对象实例 + * path: 该组件的实现 + * scope: 组件对象的范围: {singleton: 单例; application: 整个应用; prototype: 当前使用} + * initMethod: 在应用对象生成时执行的方法 + * destroy: 在应用结束的时候执行的操作 + * proxy: 组件是否用代理的方式调用 + * constructor-args:构造方法的参数 + * constructor-arg: + * name:参数的位置,起始位置从0开始,第一个参数为0,第二个参数为1 + * 参数的值的表示方式有一下几种: + * ref: 该属性是一个对象,ref的值对应着组件的名字 + * value: 一个字串值 + * path: path指向的类的实例将会被创建传递给该属性 + * properties: 属性的配置,表现为组件中的类属性 + * property: + * name:属性名称 + * 属性值的表示方式有以下几种: + * ref: 该属性是一个对象,ref的值对应着组件的名字,表现为在组件中获取方式为“_get+属性名()”称来获取 + * value: 一个字串值 + * path: path指向的类的实例将会被创建传递给该属性 + * config: 组件的配置-该值对应的配置会通过setConfig接口传递给组件; + * resource: 指定一个外部地址,将会去包含该文件 + * + * @return array() + */ + abstract protected function _components(); - /** - * 返回组建定义信息 - * - * 组件的配置标签说明: - * name: 组件的名字,唯一用于在应用中获取对应组件的对象实例 - * path: 该组件的实现 - * scope: 组件对象的范围: {singleton: 单例; application: 整个应用; prototype: 当前使用} - * initMethod: 在应用对象生成时执行的方法 - * destroy: 在应用结束的时候执行的操作 - * proxy: 组件是否用代理的方式调用 - * - * constructor-args:构造方法的参数 - * constructor-arg: - * name:参数的位置,起始位置从0开始,第一个参数为0,第二个参数为1 - * 参数的值的表示方式有一下几种: - * ref: 该属性是一个对象,ref的值对应着组件的名字 - * value: 一个字串值 - * path: path指向的类的实例将会被创建传递给该属性 - * - * properties: 属性的配置,表现为组件中的类属性 - * property: - * name:属性名称 - * 属性值的表示方式有以下几种: - * ref: 该属性是一个对象,ref的值对应着组件的名字,表现为在组件中获取方式为“_get+属性名()”称来获取 - * value: 一个字串值 - * path: path指向的类的实例将会被创建传递给该属性 - * - * - * config: 组件的配置-该值对应的配置会通过setConfig接口传递给组件; - * resource: 指定一个外部地址,将会去包含该文件 - * - * @return array() - */ - abstract protected function _components(); + /** + * 创建并初始化应用配置 + * + * @param array $config + * 当前应用配置信息 + * @param WindFactory $factory + * @return WindWebApplication + */ + abstract protected function createApplication($config, $factory); - /** - * 创建并返回应用实例 - * - * @deprecated - * @return WindWebApplication - */ - public function createApplication() { - if ($this->_app === null) { - $application = $this->_createApplication(); - /* @var $application WindWebApplication */ - if (!empty($this->_config['web-apps'][$this->_appName])) { - if ($this->_appName !== 'default' && isset($this->_config['web-apps']['default']) && !isset( - $this->_config['web-apps'][$this->_appName]['_merged'])) { - $this->_config['web-apps'][$this->_appName] = WindUtility::mergeArray( - $this->_config['web-apps']['default'], $this->_config['web-apps'][$this->_appName]); - $this->_config['web-apps'][$this->_appName]['_merged'] = true; - } - $application->setConfig($this->_config['web-apps'][$this->_appName]); - } - $this->_app = $application; - } - return $this->_app; - } + /** + * 初始化前端控制器 + *
- * ...
- * $object = Wind::getApp()->getFactory()->getInstance('windApplication');
- * $object->registerEventListener('runProcess', new Listener());
- *
- * @param stinrg $event 被监听的事件
- * @param object $listener 事件监听器
- * @param string $type 事件监听类型
- * @return void
- */
- public function registerEventListener($event, $listener, $type = self::EVENT_TYPE_METHOD) {
- if (!in_array($type, array(self::EVENT_TYPE_METHOD, self::EVENT_TYPE_GETTER, self::EVENT_TYPE_SETTER))) {
- throw new WindException('[base.WindClassProxy.registerEventListener] Unsupport event type:' . $type, WindException::ERROR_PARAMETER_TYPE_ERROR);
- }
- !isset($this->_listener[$type][$event]) && $this->_listener[$type][$event] = array();
- array_push($this->_listener[$type][$event], $listener);
- }
-
- /**
- * 注册目标对象,如果已经注册了不重复注册
- *
- * WindFactory中创建类代理的一段例子:
- * $instance = new Object();
- * $this->addClassDefinitions($alias, array('path' => $proxy, 'scope' => 'prototype'));
- * $proxy = $this->getInstance($alias);
- * $proxy->registerTargetObject($instance);
- * $instance->_proxy = $proxy;
- *
+ * array(
+ * 'field' => 'name', //验证的字段名
+ * 'default' => 'test', //如果字段为空
+ * 'args' => array('args1', 'args2'), //validator验证方法接受的其他参数(必须在被验证参数的后面)
+ * 'validator' => 'isEmpty', //执行的验证方法(该方法必须在$_validatorClass指向的验证类中存在并可公开访问,并且该方法返回boolean类型)
+ * 'message' => 'name is empty', //验证失败时返回的错误信息
+ * )
+ *
+ * 验证规则可以采用{@link WindUtility::buildValidateRule()}方法进行构造.
+ *
+ * @return array
+ */
+ protected function validateRules()
+ {
+ return array();
+ }
+
+ /**
+ * 验证方法
+ *
+ */
+ public function validate()
+ {
+ $rules = $this->validateRules();
+ $methods = get_class_methods($this);
+ foreach ((array) $rules as $rule) {
+ $getMethod = 'get'.ucfirst($rule['field']);
+ $_input = in_array($getMethod, $methods) ? call_user_func(array($this, $getMethod)) : '';
+ if (true === $this->check($_input, $rule)) {
+ continue;
+ }
+ $setMethod = 'set'.ucfirst($rule['field']);
+ in_array($setMethod, $methods) && call_user_func_array(array($this, $setMethod), array($rule['default']));
+ }
+ }
+
+ /**
+ * 执行rule验证
+ *
+ * @param string $input 待验证的数据
+ * @param array $rule 数据验证的规则
+ * @return bool 如果验证成功返回true,验证失败返回false
+ */
+ private function check($input, $rule)
+ {
+ $arg = (array) $rule['args'];
+ array_unshift($arg, $input);
+ if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) {
+ return true;
+ }
+ if ($rule['default'] === null) {
+ $this->_errors[$rule['field']] = $rule['message'];
- /**
- * 返回验证中产生的错误信息
- *
- * @return array $_errors
- */
- public function getErrors() {
- return $this->_errors;
- }
+ return true;
+ }
- /**
- * 返回验证出错时使用的错误errorAction
- *
- * errorAction的格式可以用/分割m,c,a三个部分:完整的方式为m/c/a
- *
- * @return string
- */
- public function getErrorAction() {
- return $this->errorAction;
- }
+ return false;
+ }
- /**
- * 返回验证规则组成的数组
- *
- * 每一个验证规则都需要如下格式:
- *
- * array(
- * 'field' => 'name', //验证的字段名
- * 'default' => 'test', //如果字段为空
- * 'args' => array('args1', 'args2'), //validator验证方法接受的其他参数(必须在被验证参数的后面)
- * 'validator' => 'isEmpty', //执行的验证方法(该方法必须在$_validatorClass指向的验证类中存在并可公开访问,并且该方法返回boolean类型)
- * 'message' => 'name is empty', //验证失败时返回的错误信息
- * )
- *
- * 验证规则可以采用{@link WindUtility::buildValidateRule()}方法进行构造.
- *
- * @return array
- */
- protected function validateRules() {
- return array();
- }
-
- /**
- * 验证方法
- *
- * @return void
- */
- public function validate() {
- $rules = $this->validateRules();
- $methods = get_class_methods($this);
- foreach ((array) $rules as $rule) {
- $getMethod = 'get' . ucfirst($rule['field']);
- $_input = in_array($getMethod, $methods) ? call_user_func(array($this, $getMethod)) : '';
- if (true === $this->check($_input, $rule)) continue;
- $setMethod = 'set' . ucfirst($rule['field']);
- in_array($setMethod, $methods) && call_user_func_array(array($this, $setMethod), array($rule['default']));
- }
- }
-
- /**
- * 执行rule验证
- *
- * @param string $input 待验证的数据
- * @param array $rule 数据验证的规则
- * @return boolean 如果验证成功返回true,验证失败返回false
- */
- private function check($input, $rule) {
- $arg = (array) $rule['args'];
- array_unshift($arg, $input);
- if (call_user_func_array(array($this->getValidator(), $rule['validator']), $arg) !== false) return true;
- if ($rule['default'] === null) {
- $this->_errors[$rule['field']] = $rule['message'];
- return true;
- }
- return false;
- }
+ /**
+ * 返回验证器
+ *
+ * @return WindValidator
+ * @throws WindException 验证器创建失败抛出异常
+ */
+ protected function getValidator()
+ {
+ if ($this->_validator === null) {
+ $_className = Wind::import($this->_validatorClass);
+ $this->_validator = WindFactory::createInstance($_className);
+ if ($this->_validator === null) {
+ throw new WindException('[base.WindEnableValidateModule.getValidator] validator', WindException::ERROR_RETURN_TYPE_ERROR);
+ }
+ }
- /**
- * 返回验证器
- *
- * @return WindValidator
- * @throws WindException 验证器创建失败抛出异常
- */
- protected function getValidator() {
- if ($this->_validator === null) {
- $_className = Wind::import($this->_validatorClass);
- $this->_validator = WindFactory::createInstance($_className);
- if ($this->_validator === null) throw new WindException('validator', WindException::ERROR_RETURN_TYPE_ERROR);
- }
- return $this->_validator;
- }
-}
\ No newline at end of file
+ return $this->_validator;
+ }
+}
diff --git a/wind/base/WindError.php b/wind/base/WindError.php
new file mode 100644
index 00000000..4607953c
--- /dev/null
+++ b/wind/base/WindError.php
@@ -0,0 +1,208 @@
+
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id$
+ * @package wind.base
+ */
+abstract class WindError extends WindModule
+{
+ protected $errorDir;
+ protected $isClosed;
+
+ /**
+ * 构造方法
+ *
+ * @param string $errorDir 错误目录地址
+ * @param bool $isClosed 站点是否关闭
+ */
+ public function __construct($errorDir, $isClosed)
+ {
+ $this->errorDir = $errorDir;
+ $this->isClosed = $isClosed;
+ }
+
+ /**
+ * 异常处理句柄
+ *
+ * @param Exception $exception
+ */
+ public function exceptionHandle($exception)
+ {
+ $trace = array();
+ $file = $line = '';
+ if (Wind::$isDebug) {
+ $trace = $exception->getTrace();
+ if (@$trace[0]['file'] == '') {
+ unset($trace[0]);
+ $trace = array_values($trace);
+ }
+ $file = @$trace[0]['file'];
+ $line = @$trace[0]['line'];
+ }
+ $this->showErrorMessage($exception->getMessage(), $file, $line, $trace,
+ $exception->getCode());
+ }
+
+ /**
+ * 错误处理句柄
+ *
+ * @param int $errno
+ * @param string $errstr
+ * @param string $errfile
+ * @param int $errline
+ */
+ public function errorHandle($errno, $errstr, $errfile, $errline)
+ {
+ $trace = array();
+ if (Wind::$isDebug) {
+ $trace = debug_backtrace();
+ unset($trace[0]['function'], $trace[0]['args']);
+ }
+ $this->showErrorMessage($this->_friendlyErrorType($errno).': '.$errstr, $errfile,
+ $errline, $trace, $errno);
+ }
+
+ /**
+ * 错误处理
+ *
+ * @param string $message
+ * @param string $file 异常文件
+ * @param int $line 错误发生的行
+ * @param array $trace
+ * @param int $errorcode 错误代码
+ * @throws WindFinalException
+ */
+ abstract protected function showErrorMessage($message, $file, $line, $trace, $errorcode);
+
+ /**
+ * 错误信息处理方法
+ *
+ * @param string $file
+ * @param string $line
+ * @param array $trace
+ */
+ protected function crash($file, $line, $trace)
+ {
+ if ($trace) {
+ $msg = '';
+ $count = count($trace);
+ $padLen = strlen($count);
+ foreach ($trace as $key => $call) {
+ if (!isset($call['file']) || $call['file'] == '') {
+ $call['file'] = '~Internal Location~';
+ $call['line'] = 'N/A';
+ }
+ $traceLine = '#'.str_pad(($count - $key), $padLen, '0', STR_PAD_LEFT).' '.$this->_getCallLine(
+ $call);
+ $trace[$key] = $traceLine;
+ }
+ }
+ $fileLines = array();
+ if (is_file($file)) {
+ $currentLine = $line - 1;
+ $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000));
+ $topLine = $currentLine - 5;
+ $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true);
+ if (($count = count($fileLines)) > 0) {
+ $padLen = strlen($count);
+ foreach ($fileLines as $line => &$fileLine) {
+ $fileLine = ' '.htmlspecialchars(
+ str_pad($line + 1, $padLen, '0', STR_PAD_LEFT).': '.str_replace("\t",
+ ' ', rtrim($fileLine)), null, 'UTF-8');
+ }
+ }
+ }
+
+ return array($fileLines, $trace);
+ }
+
+ /**
+ *
+ * @param array $call
+ * @return string
+ */
+ private function _getCallLine($call)
+ {
+ $call_signature = '';
+ if (isset($call['file'])) {
+ $call_signature .= $call['file'].' ';
+ }
+ if (isset($call['line'])) {
+ $call_signature .= '('.$call['line'].') ';
+ }
+ if (isset($call['function'])) {
+ $call_signature .= $call['function'].'(';
+ if (isset($call['args'])) {
+ foreach ($call['args'] as $arg) {
+ if (is_string($arg)) {
+ $arg = '"'.(strlen($arg) <= 64 ? $arg : substr($arg, 0, 64).'…').'"';
+ } elseif (is_object($arg)) {
+ $arg = ''.get_class($arg).'';
+ } elseif ($arg === true) {
+ $arg = 'true';
+ } elseif ($arg === false) {
+ $arg = 'false';
+ } elseif ($arg === null) {
+ $arg = 'null';
+ } elseif (is_array($arg)) {
+ $arg = WindString::varToString($arg);
+ } else {
+ $arg = strval($arg);
+ }
+ $call_signature .= $arg.',';
+ }
+ }
+ $call_signature = trim($call_signature, ',').')';
+ }
+
+ return $call_signature;
+ }
+
+ /**
+ * 返回友好的错误类型名
+ *
+ * @param int $type
+ * @return string unknown
+ */
+ private function _friendlyErrorType($type)
+ {
+ switch ($type) {
+ case E_ERROR:
+ return 'E_ERROR';
+ case E_WARNING:
+ return 'E_WARNING';
+ case E_PARSE:
+ return 'E_PARSE';
+ case E_NOTICE:
+ return 'E_NOTICE';
+ case E_CORE_ERROR:
+ return 'E_CORE_ERROR';
+ case E_CORE_WARNING:
+ return 'E_CORE_WARNING';
+ case E_CORE_ERROR:
+ return 'E_COMPILE_ERROR';
+ case E_CORE_WARNING:
+ return 'E_COMPILE_WARNING';
+ case E_USER_ERROR:
+ return 'E_USER_ERROR';
+ case E_USER_WARNING:
+ return 'E_USER_WARNING';
+ case E_USER_NOTICE:
+ return 'E_USER_NOTICE';
+ case E_STRICT:
+ return 'E_STRICT';
+ case E_RECOVERABLE_ERROR:
+ return 'E_RECOVERABLE_ERROR';
+ case E_DEPRECATED:
+ return 'E_DEPRECATED';
+ case E_USER_DEPRECATED:
+ return 'E_USER_DEPRECATED';
+ }
+
+ return $type;
+ }
+}
diff --git a/wind/base/WindErrorMessage.php b/wind/base/WindErrorMessage.php
index bb7da027..1f66e0e6 100644
--- a/wind/base/WindErrorMessage.php
+++ b/wind/base/WindErrorMessage.php
@@ -1,136 +1,146 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindErrorMessage.php 3264 2011-12-20 09:01:40Z yishuo $
* @package base
*/
-class WindErrorMessage extends WindModule implements IWindErrorMessage {
- /**
- * 用于存储错误信息
- *
- * @var array
- */
- private $error = array();
- /**
- * 用于处理当前错误的action操作
- *
- * 用于处理当前错误的action操作,当该值为空时,系统自动调用默认错误处理类,可以通过配置改变默认的错误处理类
- * @var string
- */
- private $errorAction;
+class WindErrorMessage extends WindModule implements IWindErrorMessage
+{
+ /**
+ * 用于存储错误信息
+ *
+ * @var array
+ */
+ private $error = array();
+ /**
+ * 用于处理当前错误的action操作
+ *
+ * 用于处理当前错误的action操作,当该值为空时,系统自动调用默认错误处理类,可以通过配置改变默认的错误处理类
+ * @var string
+ */
+ private $errorAction;
- /**
- * @param string $message 错误消息 默认为空
- * @param string $errorAction 用于处理当前错误的Action操作 默认为空
- */
- public function __construct($message = '', $errorAction = '') {
- $message !== '' && $this->addError($message);
- $errorAction !== '' && $this->setErrorAction($errorAction);
- }
+ /**
+ * @param string $message 错误消息 默认为空
+ * @param string $errorAction 用于处理当前错误的Action操作 默认为空
+ */
+ public function __construct($message = '', $errorAction = '')
+ {
+ $message !== '' && $this->addError($message);
+ $errorAction !== '' && $this->setErrorAction($errorAction);
+ }
- /* (non-PHPdoc)
- * @see IWindErrorMessage::sendError()
- */
- public function sendError($message = '') {
- if ($message)
- $this->addError($message);
- elseif (empty($this->error))
- return;
- throw new WindActionException($this);
- }
+ /* (non-PHPdoc)
+ * @see IWindErrorMessage::sendError()
+ */
+ public function sendError($message = '')
+ {
+ if ($message) {
+ $this->addError($message);
+ } elseif (empty($this->error)) {
+ return;
+ }
+ throw new WindActionException($this);
+ }
- /* (non-PHPdoc)
- * @see IWindErrorMessage::clearError()
- */
- public function clearError() {
- $this->error = array();
- }
+ /* (non-PHPdoc)
+ * @see IWindErrorMessage::clearError()
+ */
+ public function clearError()
+ {
+ $this->error = array();
+ }
- /* (non-PHPdoc)
- * @see IWindErrorMessage::getError()
- */
- public function getError($key = '') {
- if ($key === '') return $this->error;
- return isset($this->error[$key]) ? $this->error[$key] : '';
- }
+ /* (non-PHPdoc)
+ * @see IWindErrorMessage::getError()
+ */
+ public function getError($key = '')
+ {
+ if ($key === '') {
+ return $this->error;
+ }
- /* (non-PHPdoc)
- * @see IWindErrorMessage::addError()
- */
- public function addError($error, $key = '') {
- if ($key === '')
- $this->error[] = $error;
- else
- $this->error[$key] = $error;
- }
+ return isset($this->error[$key]) ? $this->error[$key] : '';
+ }
- /**
- * 返回用于处理当前错误的action操作
- *
- * @return string
- */
- public function getErrorAction() {
- return $this->errorAction;
- }
+ /* (non-PHPdoc)
+ * @see IWindErrorMessage::addError()
+ */
+ public function addError($error, $key = '')
+ {
+ if ($key === '') {
+ $this->error[] = $error;
+ } else {
+ $this->error[$key] = $error;
+ }
+ }
- /**
- * 设置用于处理当前错误的action操作
- *
- * $errorAction支持的输入格式/module/controller/action/?args
- * @param string $errorAction
- * @return void
- */
- public function setErrorAction($errorAction) {
- $this->errorAction = $errorAction;
- }
+ /**
+ * 返回用于处理当前错误的action操作
+ *
+ * @return string
+ */
+ public function getErrorAction()
+ {
+ return $this->errorAction;
+ }
+
+ /**
+ * 设置用于处理当前错误的action操作
+ *
+ * $errorAction支持的输入格式/module/controller/action/?args
+ * @param string $errorAction
+ */
+ public function setErrorAction($errorAction)
+ {
+ $this->errorAction = $errorAction;
+ }
}
/**
* 错误消息类接口定义
- *
+ *
* the last known user to change this file in the repository <$LastChangedBy: yishuo $>
* @author Qiong Wu ...
- * 该方法在应用结束时统一被调用.
- * @return void
- * @throws WindException
- */
- public function executeDestroyMethod() {
- try {
- foreach ($this->destories as $call)
- call_user_func_array($call, array());
- $this->instances = array();
- $this->destories = array();
- } catch (Exception $e) {
- throw new WindException($e->getMessage());
- }
- }
+ /**
+ * 注册组件对象,如果已经存在则覆盖原有值
+ *
+ * @param object $instance
+ * @param string $alias
+ * @param string $scope
+ * 对象作用域 默认为'singleton'
+ * @return bool
+ */
+ public function registInstance($instance, $alias, $scope = 'singleton')
+ {
+ return $this->setScope($alias, $scope, $instance);
+ }
- /**
- * 解析组件对象构造方法参数信息,并返回参数列表
- *
- * 该方法解析组件对象构造方法的参数信息,相关的组件配置
- *
- *
- * 相关定义同properties相同.'name'为参数位置,生成的参数列表按照'name'一次排序.
- * @param array $constructors
- * @param array $args
- * @return void
- */
- protected function buildArgs($constructors, &$args) {
- foreach ((array) $constructors as $key => $_var) {
- $key = intval($key);
- if (isset($_var['value'])) {
- $args[$key] = $_var['value'];
- } elseif (isset($_var['ref']))
- $args[$key] = $this->getInstance($_var['ref']);
- elseif (isset($_var['path'])) {
- $_className = Wind::import($_var['path']);
- $args[$key] = $this->createInstance($_className);
- }
- }
- ksort($args);
- }
+ /**
+ * 动态添加组件定义
+ *
+ * @param string $alias
+ * @param array $classDefinition
+ * @throws WindException
+ */
+ public function addClassDefinitions($alias, $classDefinition)
+ {
+ if (is_string($alias) && !empty($alias)) {
+ if (!isset($this->classDefinitions[$alias])) {
+ $this->classDefinitions[$alias] = $classDefinition;
+ }
+ } else {
+ throw new WindException('[base.WindFactory.addClassDefinitions] class alias is empty.',
+ WindException::ERROR_PARAMETER_TYPE_ERROR);
+ }
+ }
- /**
- * 组件对象的作用域解析
- *
- * 组件对象的作用域解析,目前支持的属性作用于为'prototype','application','singleton',默认为'application'.
- * 相关组件定义方式...
- * @param string $alias
- * @param string $scope
- * @param WindModule $instance
- * @return boolean
- */
- protected function setScope($alias, $scope, $instance) {
- switch ($scope) {
- case 'prototype':
- $this->prototype[$alias] = clone $instance;
- break;
- case 'application':
- $this->instances[$alias] = $instance;
- break;
- case 'singleton':
- $this->singleton[$alias] = $instance;
- break;
- default:
- break;
- }
- return true;
- }
+ /**
+ * 加载类定义
+ * 调用该方法加载组件定义,如果merge为true,则覆盖原有配置信息.
+ *
+ * @param array $classDefinitions
+ * @param bool $merge
+ * 是否进行merge操作,默认为true
+ */
+ public function loadClassDefinitions($classDefinitions, $merge = true)
+ {
+ foreach ((array) $classDefinitions as $alias => $definition) {
+ if (!is_array($definition)) {
+ continue;
+ }
+ if (isset($this->instances[$alias]) || isset($this->prototype[$alias])) {
+ continue;
+ }
+ if (!isset($this->classDefinitions[$alias]) || $merge === false) {
+ $this->classDefinitions[$alias] = $definition;
+ } else {
+ $this->classDefinitions[$alias] = WindUtility::mergeArray($this->classDefinitions[$alias], $definition);
+ }
+ }
+ }
- /**
- * 解析组件配置
- *
- * 解析组件配置并将配置信息设置进组件,默认调用windCache组件对进行配置缓存处理,可以通过配置'isCache'开启或关闭系统缓存.
- * 组件配置定义... ,
- * 可以通过配置'resource'引入外部配置(支持命名空间方式定义路径地址),也可以直接将配置定义到config标签下.
- * @param array|string $config
- * @param string $alias
- * @param WindModule $instance
- * @return void
- */
- protected function resolveConfig($config, $alias, $instance) {
- if (!empty($config['resource'])) {
- $_configPath = Wind::getRealPath($config['resource'], true, true);
- $config = $this->getInstance('configParser')->parse($_configPath, $alias, 'components_config',
- (!empty($this->instances['windCache']) ? $this->instances['windCache'] : null));
- }
- if ($config && method_exists($instance, 'setConfig')) $instance->setConfig($config);
- }
+ /**
+ * 设置类定义
+ * 通过该方法设置会覆盖原有类定义,请注意该方法于{@see loadClassDefinitions}的区别
+ *
+ * @param array $classDefinitions
+ */
+ public function setClassDefinitions($classDefinitions)
+ {
+ $this->classDefinitions = $classDefinitions;
+ }
- /**
- * 执行类的初始化方法
- *
- * 类的初始化方法的组件定义...
- * @param string $initMethod
- * @param object $instance
- * @return mixed
- * @throws WindException
- */
- protected function executeInitMethod($initMethod, $instance) {
- try {
- return call_user_func_array(array($instance, $initMethod), array());
- } catch (Exception $e) {
- throw new WindException(
- '[base.WindFactory.executeInitMethod] (' . $initMethod . ', ' . $e->getMessage() . ')',
- WindException::ERROR_CLASS_METHOD_NOT_EXIST);
- }
- }
+ /**
+ * 组件定义检查
+ * 检查类定义是否已经存在,或者是否已经被创建.避免重复注册组件定义
+ *
+ * @param string $alias
+ * @return bool
+ */
+ public function checkAlias($alias)
+ {
+ if (isset($this->prototype[$alias])) {
+ return true;
+ } elseif (isset($this->instances[$alias])) {
+ return true;
+ }
- /**
- * 设置类代理对象,并返回代理类对象
- *
- * 代理类同当前类拥有同样的职责和功能,可以通过访问代理类对象访问当前类.
- * 类的代理信息对应的组件配置为... 当'proxy'设置为false时返回该类的代理类型,
- * 类默认的代理类型为WindClassProxy,不可以通过配置进行修改.
- * @param string $proxy
- * @param WindModule $instance
- * @return WindClassProxy
- */
- protected function setProxyForClass($proxy, $instance) {
- if (!$proxy) return $instance;
- if (true === $proxy) $proxy = $this->proxyType;
- $proxy = self::createInstance(Wind::import($proxy));
- $proxy->registerTargetObject($instance);
- $instance->_proxy = $proxy;
- return $proxy;
- }
+ return false;
+ }
- /**
- * 构建类的属性信息
- *
- * 类的属性信息对应的组件配置为
- * 他支持的标签为'delay','property-name','ref','value','path'.
- * 当'delay'设置为true时该属性延迟加载.'property-name'设置了属性名称.'ref','value','path'是定义属性值的三种方式,'ref'指向另外的组件定义名称,
- * 'value'直接输入属性的值,'path'定义一个属性对象的路径,系统会自动创建该属性的对象.
- * @param string $properties 属性定义
- * @param WindModule $instance 类对象
- * @return void
- */
- protected function buildProperties($properties, $instance) {
- isset($properties['delay']) || $properties['delay'] = true;
- if ($properties['delay'] === 'false' || $properties['delay'] === false) {
- foreach ($properties as $key => $subDefinition) {
- $_value = '';
- if (isset($subDefinition['value']))
- $_value = $subDefinition['value'];
- elseif (isset($subDefinition['ref']))
- $_value = $this->getInstance($subDefinition['ref']);
- elseif (isset($subDefinition['path'])) {
- $_className = Wind::import($subDefinition['path']);
- $_value = $this->createInstance($_className);
- }
- $_setter = 'set' . ucfirst(trim($key, '_'));
- if (method_exists($instance, $_setter)) call_user_func_array(array($instance, $_setter), array($_value));
- }
- } else
- $instance->setDelayAttributes($properties);
- }
-}
\ No newline at end of file
+ /**
+ * 执行组件定义的注销方法
+ * 调用全部组件的注销方法,按照组件的定义顺序依次调用,相关组件的定义方法...
+ * 该方法在应用结束时统一被调用.
+ *
+ * @throws WindException
+ */
+ public function executeDestroyMethod()
+ {
+ try {
+ foreach ($this->destories as $call) {
+ call_user_func_array($call, array());
+ }
+ $this->instances = array();
+ $this->destories = array();
+ } catch (Exception $e) {
+ throw new WindException($e->getMessage());
+ }
+ }
+
+ /**
+ * 解析组件对象构造方法参数信息,并返回参数列表
+ * 该方法解析组件对象构造方法的参数信息,相关的组件配置
+ *
+ *
+ * 相关定义同properties相同.'name'为参数位置,生成的参数列表按照'name'一次排序.
+ *
+ * @param array $constructors
+ * @param array $args
+ */
+ protected function buildArgs($constructors, &$args)
+ {
+ foreach ((array) $constructors as $key => $_var) {
+ $key = intval($key);
+ if (isset($_var['value'])) {
+ $args[$key] = $_var['value'];
+ } elseif (isset($_var['ref'])) {
+ $args[$key] = $this->getInstance($_var['ref']);
+ } elseif (isset($_var['path'])) {
+ $_className = Wind::import($_var['path']);
+ $args[$key] = $this->createInstance($_className);
+ }
+ }
+ ksort($args);
+ }
+
+ /**
+ * 组件对象的作用域解析
+ * 组件对象的作用域解析,目前支持的属性作用于为'prototype','application','singleton',默认为'application'.
+ * 相关组件定义方式...
+ *
+ * @param string $alias
+ * @param string $scope
+ * @param WindModule $instance
+ * @return bool
+ */
+ protected function setScope($alias, $scope, $instance)
+ {
+ switch ($scope) {
+ case 'prototype':
+ $this->prototype[$alias] = clone $instance;
+ break;
+ case 'application':
+ $this->instances[$alias] = $instance;
+ break;
+ case 'singleton':
+ $this->singleton[$alias] = $instance;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * 解析组件配置
+ * 解析组件配置并将配置信息设置进组件,默认调用windCache组件对进行配置缓存处理,可以通过配置'isCache'开启或关闭系统缓存.
+ * 组件配置定义... ,
+ * 可以通过配置'resource'引入外部配置(支持命名空间方式定义路径地址),也可以直接将配置定义到config标签下.
+ *
+ * @param array|string $config
+ * @param string $alias
+ * @param WindModule $instance
+ */
+ protected function resolveConfig($config, $alias, $instance)
+ {
+ if (!empty($config['resource'])) {
+ $_configPath = Wind::getRealPath($config['resource'], true, true);
+ $config = $this->getInstance('configParser')->parse($_configPath, $alias, 'components_config',
+ (!empty($this->instances['windCache']) ? $this->instances['windCache'] : null));
+ }
+ if ($config && method_exists($instance, 'setConfig')) {
+ $instance->setConfig($config);
+ }
+ }
+
+ /**
+ * 执行类的初始化方法
+ * 类的初始化方法的组件定义...
+ *
+ * @param string $initMethod
+ * @param object $instance
+ * @return mixed
+ * @throws WindException
+ */
+ protected function executeInitMethod($initMethod, $instance)
+ {
+ try {
+ return $instance->$initMethod();
+ // return call_user_func_array(array($instance, $initMethod),
+ // array());
+ } catch (Exception $e) {
+ throw new WindException(
+ '[base.WindFactory.executeInitMethod] ('.$initMethod.', '.$e->getMessage().')',
+ WindException::ERROR_CLASS_METHOD_NOT_EXIST);
+ }
+ }
+
+ /**
+ * 设置类代理对象,并返回代理类对象
+ * 代理类同当前类拥有同样的职责和功能,可以通过访问代理类对象访问当前类.
+ * 类的代理信息对应的组件配置为... 当'proxy'设置为false时返回该类的代理类型,
+ * 类默认的代理类型为WindClassProxy,不可以通过配置进行修改.
+ *
+ * @param string $proxy
+ * @param WindModule $instance
+ * @return WindClassProxy
+ */
+ protected function setProxyForClass($proxy, $listeners, $instance)
+ {
+ if (!$proxy) {
+ return $instance;
+ }
+ if (true === $proxy) {
+ $proxy = $this->proxyType;
+ }
+ /* @var $proxy WindClassProxy */
+ $proxy = self::createInstance(Wind::import($proxy));
+ $proxy->registerTargetObject($instance);
+ foreach ($listeners as $key => $value) {
+ $listener = WindFactory::createInstance(Wind::import($value));
+ $proxy->registerEventListener($listener, $key);
+ }
+ // $instance->_proxy = $proxy;
+ return $proxy;
+ }
+
+ /**
+ * 构建类的属性信息
+ * 类的属性信息对应的组件配置为
+ * 他支持的标签为'delay','property-name','ref','value','path'.
+ * 当'delay'设置为true时该属性延迟加载.'property-name'设置了属性名称.'ref','value','path'是定义属性值的三种方式,'ref'指向另外的组件定义名称,
+ * 'value'直接输入属性的值,'path'定义一个属性对象的路径,系统会自动创建该属性的对象.
+ *
+ * @param string $properties
+ * 属性定义
+ * @param WindModule $instance
+ * 类对象
+ */
+ protected function buildProperties($properties, $instance)
+ {
+ isset($properties['delay']) || $properties['delay'] = true;
+ if ($properties['delay'] === 'false' || $properties['delay'] === false) {
+ foreach ($properties as $key => $subDefinition) {
+ $_value = '';
+ if (isset($subDefinition['value'])) {
+ $_value = $subDefinition['value'];
+ } elseif (isset($subDefinition['ref'])) {
+ $_value = $this->getInstance($subDefinition['ref']);
+ } elseif (isset($subDefinition['path'])) {
+ $_className = Wind::import($subDefinition['path']);
+ $_value = $this->createInstance($_className);
+ }
+ $_setter = 'set'.ucfirst(trim($key, '_'));
+ if (method_exists($instance, $_setter)) {
+ call_user_func_array(array($instance, $_setter), array($_value));
+ }
+ }
+ } else {
+ $instance->setDelayAttributes($properties);
+ }
+ }
+
+ /**
+ * 返回组建工厂单例对象
+ *
+ * @return WindFactory
+ */
+ public static function _getInstance()
+ {
+ if (!(self::$_instance instanceof self)) {
+ self::$_instance = new self();
+ }
+
+ return self::$_instance;
+ }
+}
diff --git a/wind/base/WindFinalException.php b/wind/base/WindFinalException.php
index fc86a941..140867c6 100644
--- a/wind/base/WindFinalException.php
+++ b/wind/base/WindFinalException.php
@@ -1,23 +1,22 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindFinalException.php 2973 2011-10-15 19:22:48Z yishuo $
* @package base
*/
-class WindFinalException extends Exception {
-
- /**
- * @param string $message 异常信息
- */
- public function __construct($message = '') {
- $message || $message = 'system error~';
- parent::__construct($message, 500);
- }
+class WindFinalException extends Exception
+{
+ /**
+ * @param string $message 异常信息
+ */
+ public function __construct($message = '')
+ {
+ $message || $message = 'system error~';
+ parent::__construct($message, 500);
+ }
}
-
-?>
\ No newline at end of file
diff --git a/wind/base/WindForwardException.php b/wind/base/WindForwardException.php
index 7601f299..b3689073 100644
--- a/wind/base/WindForwardException.php
+++ b/wind/base/WindForwardException.php
@@ -1,43 +1,44 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindForwardException.php 2973 2011-10-15 19:22:48Z yishuo $
* @package base
*/
-class WindForwardException extends WindException {
- /**
- * @var WindForward
- */
- private $forward;
-
- /**
- * @param WindForward $forward
- */
- public function __construct($forward) {
- $this->forward = $forward;
- }
+class WindForwardException extends WindException
+{
+ /**
+ * @var WindForward
+ */
+ private $forward;
- /**
- * @return WindForward
- */
- public function getForward() {
- return $this->forward;
- }
+ /**
+ * @param WindForward $forward
+ */
+ public function __construct($forward)
+ {
+ $this->forward = $forward;
+ }
- /**
- * @param WindForward $forward
- */
- public function setForward($forward) {
- $this->forward = $forward;
- }
+ /**
+ * @return WindForward
+ */
+ public function getForward()
+ {
+ return $this->forward;
+ }
+ /**
+ * @param WindForward $forward
+ */
+ public function setForward($forward)
+ {
+ $this->forward = $forward;
+ }
}
-
-?>
\ No newline at end of file
diff --git a/wind/base/WindModule.php b/wind/base/WindModule.php
index 5dcf4c07..3b02d927 100644
--- a/wind/base/WindModule.php
+++ b/wind/base/WindModule.php
@@ -1,182 +1,201 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindModule.php 3850 2012-12-04 07:30:02Z yishuo $
* @package base
*/
-class WindModule {
- /**
- * 代理类对象
- *
- * @var WindClassProxy
- */
- public $_proxy = null;
- /**
- * 配置数据
- *
- * @var array
- */
- protected $_config = array();
- /**
- * 在延迟加载策略中使用,保存需要延迟加载的属性配置信息
- *
- * @var array
- */
- protected $_delayAttributes = array();
+class WindModule
+{
+ /**
+ * 代理类对象
+ *
+ * @var WindClassProxy
+ */
+ public $_proxy = null;
+ /**
+ * 配置数据
+ *
+ * @var array
+ */
+ protected $_config = array();
+ /**
+ * 在延迟加载策略中使用,保存需要延迟加载的属性配置信息
+ *
+ * @var array
+ */
+ protected $_delayAttributes = array();
- /**
- * 重载了魔术方法__set
- *
- * 当属性访问不到时该方法被调用,该方法会尝试去访问对应属性的setter设置器,如果不存在则什么也不做
- * @param string $propertyName
- * @param mixed $value
- * @return void
- */
- public function __set($propertyName, $value) {
- $_setter = 'set' . ucfirst($propertyName);
- if (method_exists($this, $_setter)) $this->$_setter($value);
- }
+ /**
+ * 重载了魔术方法__set
+ * 当属性访问不到时该方法被调用,该方法会尝试去访问对应属性的setter设置器,如果不存在则什么也不做
+ *
+ * @param string $propertyName
+ * @param mixed $value
+ */
+ public function __set($propertyName, $value)
+ {
+ $_setter = 'set'.ucfirst($propertyName);
+ if (method_exists($this, $_setter)) {
+ $this->$_setter($value);
+ }
+ }
- /**
- * 重载了魔术方法__get
- *
- * 当属性访问不到时该方法被调用,该方法会尝试去访问对应属性的getter并返回对应的值,如果不存在则什么也不做
- * @param string $propertyName
- * @return mixed
- */
- public function __get($propertyName) {
- $_getter = 'get' . ucfirst($propertyName);
- if (method_exists($this, $_getter)) return $this->$_getter();
- }
+ /**
+ * 重载了魔术方法__get
+ * 当属性访问不到时该方法被调用,该方法会尝试去访问对应属性的getter并返回对应的值,如果不存在则什么也不做
+ *
+ * @param string $propertyName
+ * @return mixed
+ */
+ public function __get($propertyName)
+ {
+ $_getter = 'get'.ucfirst($propertyName);
+ if (method_exists($this, $_getter)) {
+ return $this->$_getter();
+ }
+ }
- /**
- * 重载了魔术方法__call
- *
- * 当类的方法访问不到时调用该方法,在这里的实现是配置类属性对象的延迟加载策略
- *
- * //延迟访问某个属性,当使用这种方式调用时该方法被调用,并访问该类中的$_delayAttributes属性,并创建该属性对象并返回
- * $this->_getMethodName();
- *
- * @param string $methodName
- * @param array $args
- * @return mixed
- */
- public function __call($methodName, $args) {
- $_prefix = substr($methodName, 0, 4);
- $_propertyName = substr($methodName, 4);
- $_propertyName = WindUtility::lcfirst($_propertyName);
- if ($_prefix == '_get') {
- if (!$this->$_propertyName && isset($this->_delayAttributes[$_propertyName])) {
- $_property = $this->_delayAttributes[$_propertyName];
- $_value = null;
- if (isset($_property['value'])) {
- $_value = $_property['value'];
- } elseif (isset($_property['ref'])) {
- $_value = Wind::getApp()->getWindFactory()->getInstance($_property['ref'],
- $args);
- } elseif (isset($_property['path'])) {
- $_className = Wind::import($_property['path']);
- $_value = WindFactory::createInstance($_className, $args);
- }
- $this->$_propertyName = $_value;
-
- /*unset($this->delayAttributes[$_propertyName]);*/
- }
- return $this->$_propertyName;
- } elseif ($_prefix == '_set') {
- $this->$_propertyName = $args[0];
- }
- }
+ /**
+ * 重载了魔术方法__call
+ * 当类的方法访问不到时调用该方法,在这里的实现是配置类属性对象的延迟加载策略
+ *
+ * //延迟访问某个属性,当使用这种方式调用时该方法被调用,并访问该类中的$_delayAttributes属性,并创建该属性对象并返回
+ * $this->_getMethodName();
+ *
+ *
+ * @param string $methodName
+ * @param array $args
+ * @return mixed
+ */
+ public function __call($methodName, $args)
+ {
+ $_prefix = substr($methodName, 0, 4);
+ $_propertyName = substr($methodName, 4);
+ $_propertyName = WindUtility::lcfirst($_propertyName);
+ if ($_prefix == '_get') {
+ if (!$this->$_propertyName && isset($this->_delayAttributes[$_propertyName])) {
+ $_property = $this->_delayAttributes[$_propertyName];
+ $_value = null;
+ if (isset($_property['value'])) {
+ $_value = $_property['value'];
+ } elseif (isset($_property['ref'])) {
+ $_value = Wind::getComponent($_property['ref'], $args);
+ } elseif (isset($_property['path'])) {
+ $_className = Wind::import($_property['path']);
+ $_value = WindFactory::createInstance($_className, $args);
+ }
+ $this->$_propertyName = $_value;
+ }
- /**
- * 返回该对象的数组类型
- *
- * @return array
- */
- public function toArray() {
- $reflection = new ReflectionClass(get_class($this));
- $properties = $reflection->getProperties();
- $_result = array();
- foreach ($properties as $property) {
- $_propertyName = $property->name;
- $_result[$_propertyName] = $this->$_propertyName;
- }
- return $_result;
- }
+ return $this->$_propertyName;
+ } elseif ($_prefix == '_set') {
+ $this->$_propertyName = $args[0];
+ }
+ }
- /**
- * 根据配置名取得相应的配置
- *
- * 当configName为空时则返回整个配置.当配置值不存在时返回默认值.默认值默认为空
- * @param string $configName 键名
- * @param string $subConfigName 二级键名
- * @param string $default 默认值
- * @param array $config 外部配置
- * @return mixed
- */
- public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array()) {
- if (empty($config)) $config = $this->_config;
- if ($configName === '') return $config;
- if (!isset($config[$configName])) return $default;
- if ($subConfigName === '') return $config[$configName];
- if (!isset($config[$configName][$subConfigName])) return $default;
- return $config[$configName][$subConfigName];
- }
+ /**
+ * 返回该对象的数组类型
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ $reflection = new ReflectionClass(get_class($this));
+ $properties = $reflection->getProperties();
+ $_result = array();
+ foreach ($properties as $property) {
+ $_propertyName = $property->name;
+ $_result[$_propertyName] = $this->$_propertyName;
+ }
- /**
- * 设置类配置
- *
- * 设置类配置信息,如果配置已经存在,则将以存在配置和输入配置进行合并. 重复配置后者将覆盖前者.
- * 支持配置路径解析,当输入值为配置路径时则会调用配置解析器进行解析并自动缓存当前配置值.(缓存是由wind_config中的isCache配置值决定是否开启)
- * @param string|array $config
- * @return void
- */
- public function setConfig($config) {
- if ($config) {
- if (is_string($config)) {
- $config = Wind::getApp()->getComponent('configParser')->parse($config,
- get_class($this), false, Wind::getApp()->getComponent('windCache'));
- }
- if (!empty($this->_config)) {
- $this->_config = array_merge($this->_config, (array) $config);
- } else
- $this->_config = $config;
- }
- }
+ return $_result;
+ }
- /**
- * 返回当前应用的WindHttpRequest对象
- *
- * @return WindHttpRequest
- */
- protected function getRequest() {
- return Wind::getApp()->getRequest();
- }
+ /**
+ * 根据配置名取得相应的配置
+ * 当configName为空时则返回整个配置.当配置值不存在时返回默认值.默认值默认为空
+ *
+ * @param string $configName 键名
+ * @param string $subConfigName 二级键名
+ * @param string $default 默认值
+ * @param array $config 外部配置
+ * @return mixed
+ */
+ public function getConfig($configName = '', $subConfigName = '', $default = '', $config = array())
+ {
+ if ($configName === '') {
+ return $this->_config;
+ }
+ if (!isset($this->_config[$configName])) {
+ return $default;
+ }
+ if ($subConfigName === '') {
+ return $this->_config[$configName];
+ }
+ if (!isset($this->_config[$configName][$subConfigName])) {
+ return $default;
+ }
- /**
- * 返回当前应用的WindHttpResponse对象
- *
- * @return WindHttpResponse
- */
- protected function getResponse() {
- return Wind::getApp()->getResponse();
- }
+ return $this->_config[$configName][$subConfigName];
+ }
- /**
- * 设置延迟加载类属性相关组件配置信息
- *
- * @param array $delayAttributes
- * @return void
- */
- public function setDelayAttributes($delayAttributes) {
- $this->_delayAttributes = array_merge($this->_delayAttributes, $delayAttributes);
- }
+ /**
+ * 设置类配置
+ * 设置类配置信息,如果配置已经存在,则将以存在配置和输入配置进行合并.
+ * 重复配置后者将覆盖前者.
+ * 支持配置路径解析,当输入值为配置路径时则会调用配置解析器进行解析并自动缓存当前配置值.(缓存是由wind_config中的isCache配置值决定是否开启)
+ *
+ * @param string|array $config
+ */
+ public function setConfig($config)
+ {
+ if ($config) {
+ if (is_string($config)) {
+ $config = Wind::getComponent('configParser')->parse($config, get_class($this), false,
+ Wind::getComponent('windCache'));
+ }
+ if (!empty($this->_config)) {
+ $this->_config = array_merge($this->_config, (array) $config);
+ } else {
+ $this->_config = $config;
+ }
+ }
+ }
-}
\ No newline at end of file
+ /**
+ * 返回当前应用的WindHttpRequest对象
+ *
+ * @return WindHttpRequest
+ */
+ protected function getRequest()
+ {
+ return Wind::getComponent('request');
+ }
+
+ /**
+ * 返回当前应用的WindHttpResponse对象
+ *
+ * @return WindHttpResponse
+ */
+ protected function getResponse()
+ {
+ return Wind::getComponent('response');
+ }
+
+ /**
+ * 设置延迟加载类属性相关组件配置信息
+ *
+ * @param array $delayAttributes
+ */
+ public function setDelayAttributes($delayAttributes)
+ {
+ $this->_delayAttributes = array_merge($this->_delayAttributes, $delayAttributes);
+ }
+}
diff --git a/wind/cache/AbstractWindCache.php b/wind/cache/AbstractWindCache.php
index 390cdc79..97b0ca8c 100644
--- a/wind/cache/AbstractWindCache.php
+++ b/wind/cache/AbstractWindCache.php
@@ -1,9 +1,10 @@
*
- * Wind::import('WIND:cache.strategy.WindApcCache');
+ *
* $cache = new WindApcCache();
* $cache->set('name', 'windframework');
*
- *
+ *
* 2、同时作为组件,WindApcCache也允许用户通过组件配置得方式,通过框架的组件机制来获得该缓存对象进行操作.
* 在应用配置中的组件配置块(components),配置使用该组件如下:
*
@@ -36,7 +37,7 @@
* 'path' => 'WIND:cache.strategy.WindApcCache',
* 'scope' => 'singleton',
* 'config' => array(
- * 'security-code' => '',
+ * 'security-code' => '',
* 'key-prefix' => '',
* 'expires' => '0',
* ),
@@ -44,54 +45,59 @@
*
* 在应用中通过如下方式使用:
*
- * $cache = Wind::getApp()->getComponent('apcCache'); //注意这里的apcCache组件名称和配置的组件名称需要对应
+ * $cache = Wind::getComponent('apcCache'); //注意这里的apcCache组件名称和配置的组件名称需要对应
* $cache->set('name', 'wf');
*
* 关于组件配置的相关说明请参考组件配置一章.
- *
+ *
*
* array(
- * 'table-name' => 'pw_cache', //缓存的表名
+ * 'table-name' => 'cache', //缓存的表名
* 'field-key' => 'key', //缓存key的字段名,唯一键值
* 'field-value' => 'value', //缓存数据存储的字段名
* 'field-expire' => 'expire', //缓存数据的过期时间字段名,为int类型,默认为0
@@ -29,7 +30,7 @@
* Db缓存的使用:
* 1、像使用普通类库一样使用该组件:
*
- * Wind::import('WIND:cache.strategy.WindDbCache');
+ *
* $cache = new WindDbCache($dbHandler, array('table-name' => 'pw_cache', 'field-key' => 'key', 'field-value' => 'value', 'field-expire' => '0'));
* $cache->set('name', 'windDbTest');
*
@@ -44,11 +45,11 @@
* 'connection' => array('ref' => 'db');
* ),
* 'config' => array(
- * 'table-name' => 'pw_cache',
+ * 'table-name' => 'cache',
* 'field-key' => 'key',
* 'field-value' => 'value',
* 'field-expire' => 'expire',
- * 'security-code' => '',
+ * 'security-code' => '',
* 'key-prefix' => '',
* 'expires' => '0',
* ),
@@ -56,204 +57,247 @@
*
* 在应用中可以通过如下方式获得dbCache对象:
*
- * $cache = Wind::getApp()->getComponent('dbCache'); //dbCache的名字来自于组件配置中的名字
+ * $cache = Wind::getComponent('dbCache'); //dbCache的名字来自于组件配置中的名字
* $cache->set('name', 'test');
*
* 注意: 组件配置需要配置属性(preperties),connection其值为db组件的一个引用
- *
+ *
* the last known user to change this file in the repository
* @author xiaoxiao
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindDbCache.php 3791 2012-10-30 04:01:29Z liusanbian $
* @package strategy
*/
-class WindDbCache extends AbstractWindCache {
-
- /**
- * 链接句柄
- *
- * @var WindConnection
- */
- protected $connection;
-
- /**
- * 缓存表名
- *
- * @var string
- */
- private $table = 'pw_cache';
-
- /**
- * 缓存表的键字段
- *
- * @var string
- */
- private $keyField = 'key';
-
- /**
- * 缓存表的值字段
- *
- * @var string
- */
- private $valueField = 'value';
-
- /**
- * 缓存表过期时间字段
- *
- * @var string
- */
- private $expireField = 'expire';
+class WindDbCache extends AbstractWindCache
+{
+ /**
+ * 链接句柄
+ *
+ * @var WindConnection
+ */
+ protected $connection;
+
+ /**
+ * 缓存表名
+ *
+ * @var string
+ */
+ private $table = 'cache';
+
+ /**
+ * 缓存表的键字段
+ *
+ * @var string
+ */
+ private $keyField = 'key';
+
+ /**
+ * 缓存表的值字段
+ *
+ * @var string
+ */
+ private $valueField = 'value';
+
+ /**
+ * 缓存表过期时间字段
+ *
+ * @var string
+ */
+ private $expireField = 'expire';
+
+ /**
+ * 构造函数
+ *
+ * 初始化数据
+ *
+ * @param WindConnection $connection 数据库链接对象,缺省值为null
+ * @param array $config 缓存的配置文件,缺省值为array()
+ */
+ public function __construct(WindConnection $connection = null, $config = array())
+ {
+ $connection && $this->setConnection($connection);
+ $config && $this->setConfig($config);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return $this->store($key, $value, $expire);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expire = 0)
+ {
+ return $this->store($key, $value, $expire, 'add');
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ $sql = 'SELECT * FROM '.$this->getTableName().' WHERE `'.$this->keyField.'` =? ';
+ $data = $this->getConnection()->createStatement($sql)->getOne(array($key));
+ if (!$data) {
+ return false;
+ }
+
+ return $this->_checkExpire($data[$this->expireField], time()) ? false : $data[$this->valueField];
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::batchGet()
+ */
+ public function batchGet(array $keys)
+ {
+ if (!$keys) {
+ return array();
+ }
+ $_temp = $result = array();
+ foreach ($keys as $value) {
+ $_temp[$value] = $this->buildSecurityKey($value);
+ }
+ $sql = 'SELECT * FROM '.$this->getTableName().' WHERE `'.$this->keyField.'` IN '.$this->getConnection()->quoteArray($_temp);
+ $data = $this->getConnection()->createStatement($sql)->queryAll(array(), $this->keyField);
+ $_now = time();
+ foreach ($_temp as $key => $cacheKey) {
+ $result[$key] = false;
+ if (!isset($data[$cacheKey])) {
+ continue;
+ }
+ $tmp = $data[$cacheKey];
+ $result[$key] = $this->_checkExpire($tmp[$this->expireField], $_now) ? false : $this->formatData($key, $tmp[$this->valueField]);
+ }
+
+ return $result;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ $sql = 'DELETE FROM '.$this->getTableName().' WHERE `'.$this->keyField.'` = ? ';
+
+ return $this->getConnection()->createStatement($sql)->update(array($key));
+ }
- /**
- * 构造函数
- *
- * 初始化数据
- *
- * @param WindConnection $connection 数据库链接对象,缺省值为null
- * @param array $config 缓存的配置文件,缺省值为array()
- */
- public function __construct(WindConnection $connection = null, $config = array()) {
- $connection && $this->setConnection($connection);
- $config && $this->setConfig($config);
- }
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::batchDelete()
+ */
+ public function batchDelete(array $keys)
+ {
+ array_walk($keys, array($this, 'buildSecurityKey'));
+ $sql = 'DELETE FROM '.$this->getTableName().' WHERE `'.$this->keyField.'` IN '.$this->getConnection()->quoteArray($keys);
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return $this->store($key, $value, $expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expire = 0) {
- return $this->store($key, $value, $expire, 'add');
- }
+ return $this->getConnection()->execute($sql);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::getValue()
- */
- protected function getValue($key) {
- $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` =? AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)';
- $data = $this->getConnection()->createStatement($sql)->getOne(array($key, time()));
- return $data[$this->valueField];
- }
+ /**
+ * 清除缓存数据
+ *
+ * - 如果$expireOnly=true,则将只删除过期的数据。
+ * - 如果$expireOnly=false,则将删除所有缓存数据。
+ *
+ *
+ * @param bool $expireOnly 如果删除过期数据则设置为true,如果全部缓存都删除则为false,缺省值为true
+ * @return int
+ */
+ public function clear($expireOnly = true)
+ {
+ $sql = sprintf('DELETE FROM `%s`', $this->getTableName());
+ if ($expireOnly) {
+ $sql = sprintf('DELETE FROM `%s` WHERE `%s` < ', $this->getTableName(), $this->expireField).$this->getConnection()->quote(time());
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::batchGet()
- */
- public function batchGet(array $keys) {
- $_temp = array();
- foreach ($keys as $value) {
- $_temp[$value] = $this->buildSecurityKey($value);
- }
- list($sql, $result) = array('', array());
- $sql = 'SELECT * FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray(
- $_temp) . ' AND (`' . $this->expireField . '`=0 OR `' . $this->expireField . '`>?)';
- $data = $this->getConnection()->createStatement($sql)->queryAll(array(time()));
- $_keys = array_flip($_temp);
- foreach ($data as $tmp) {
- $result[$_keys[$tmp[$this->keyField]]] = $this->formatData($_keys[$tmp[$this->keyField]], $tmp[$this->valueField]);
- }
- return $result;
- }
+ return $this->getConnection()->execute($sql);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` = ? ';
- return $this->getConnection()->createStatement($sql)->update(array($key));
- }
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ $this->table = $this->getConfig('table-name', '', 'cache', $config);
+ $this->keyField = $this->getConfig('field-key', '', 'key', $config);
+ $this->valueField = $this->getConfig('field-value', '', 'value', $config);
+ $this->expireField = $this->getConfig('field-expire', '', 'expire', $config);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::batchDelete()
- */
- public function batchDelete(array $keys) {
- foreach ($keys as $key => $value) {
- $keys[$key] = $this->buildSecurityKey($value);
- }
- $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE `' . $this->keyField . '` IN ' . $this->getConnection()->quoteArray(
- $keys);
- return $this->getConnection()->execute($sql);
- }
+ /**
+ * 设置链接对象
+ *
+ * @param WindConnection $connection
+ */
+ public function setConnection($connection)
+ {
+ if ($connection instanceof WindConnection) {
+ $this->connection = $connection;
+ }
+ }
- /**
- * 清除缓存数据
- *
- * - 如果$expireOnly=true,则将只删除过期的数据。
- * - 如果$expireOnly=false,则将删除所有缓存数据。
- *
- *
- * @param boolean $expireOnly 如果删除过期数据则设置为true,如果全部缓存都删除则为false,缺省值为true
- * @return int
- */
- public function clear($expireOnly = true) {
- $sql = sprintf('DELETE FROM `%s`', $this->getTableName());
- if ($expireOnly) {
- $sql = sprintf('DELETE FROM `%s` WHERE `%s` < ', $this->getTableName(), $this->expireField) . $this->getConnection()->quote(
- time());
- }
- return $this->getConnection()->execute($sql);
- }
+ /**
+ * 返回缓存表名
+ *
+ * @return string
+ */
+ private function getTableName()
+ {
+ return $this->getConnection()->getTablePrefix().$this->table;
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- $this->table = $this->getConfig('table-name', '', 'pw_cache', $config);
- $this->keyField = $this->getConfig('field-key', '', 'key', $config);
- $this->valueField = $this->getConfig('field-value', '', 'value', $config);
- $this->expireField = $this->getConfig('field-expire', '', 'expire', $config);
- }
+ /**
+ * 存储数据
+ *
+ * @param string $key 保存的缓存key,
+ * @param string $value 保存的缓存数据
+ * @param int $expires 缓存保存的时间,如果为0则永不过期,默认为0
+ * @param string $type 缓存的保存方式,默认为set将使用replace方式保存
+ * @return int
+ */
+ private function store($key, $value, $expires = 0, $type = 'set')
+ {
+ ($expires > 0) ? $expires += time() : $expire = 0;
+ $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires);
+ if ($type == 'add') {
+ $sql = 'INSERT INTO '.$this->getTableName().' SET '.$this->getConnection()->sqlSingle($db);
+ } else {
+ $sql = 'REPLACE INTO '.$this->getTableName().' SET '.$this->getConnection()->sqlSingle($db);
+ }
- /**
- * 设置链接对象
- *
- * @param WindConnection $connection
- */
- public function setConnection($connection) {
- if ($connection instanceof WindConnection) $this->connection = $connection;
- }
+ return $this->getConnection()->createStatement($sql)->update();
+ }
- /**
- * 返回缓存表名
- *
- * @return string
- */
- private function getTableName() {
- return $this->table;
- }
+ /**
+ * 判断是否过期
+ * 过期则返回true/否则返回false
+ *
+ * @param int $endTime
+ * @param int $nowTime
+ * @return bool
+ */
+ private function _checkExpire($endTime, $nowTime)
+ {
+ if ($endTime == 0) {
+ return false;
+ }
- /**
- * 存储数据
- *
- * @param string $key 保存的缓存key,
- * @param string $value 保存的缓存数据
- * @param int $expires 缓存保存的时间,如果为0则永不过期,默认为0
- * @param string $type 缓存的保存方式,默认为set将使用replace方式保存
- * @return int
- */
- private function store($key, $value, $expires = 0, $type="set") {
- ($expires > 0) ? $expires += time() : $expire = 0;
- $db = array($this->keyField => $key, $this->valueField => $value, $this->expireField => $expires);
- if ($type == 'add') {
- $sql = 'INSERT INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db);
- } else {
- $sql = 'REPLACE INTO ' . $this->getTableName() . ' SET ' . $this->getConnection()->sqlSingle($db);
- }
- return $this->getConnection()->createStatement($sql)->update();
- }
+ return $endTime <= $nowTime;
+ }
- /**
- * 获得链接对象
- *
- * @return WindConnection
- */
- private function getConnection() {
- return $this->_getConnection();
- }
-}
\ No newline at end of file
+ /**
+ * 获得链接对象
+ *
+ * @return WindConnection
+ */
+ private function getConnection()
+ {
+ return $this->_getConnection();
+ }
+}
diff --git a/wind/cache/strategy/WindEacceleratorCache.php b/wind/cache/strategy/WindEacceleratorCache.php
index 1658998d..8c7f472d 100644
--- a/wind/cache/strategy/WindEacceleratorCache.php
+++ b/wind/cache/strategy/WindEacceleratorCache.php
@@ -1,108 +1,115 @@
-
- * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
- * get($key): 继承自{@link AbstractWindCache::get()}.
- * delete($key): 继承自{@link AbstractWindCache::delete()}.
- * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
- * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
- * setConfig($config): 继承自{@link AbstractWindCache::setConfig()}.
- *
- * 该缓存策略从AbstractWindCache类中继承三个配置项:
- *
- * array(
- * 'security-code' => '', //继承自AbstractWindCache,安全码配置
- * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
- * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
- * )
- *
- * 使用方式:
- * 1、您可以像使用普通类库一样使用该组件:
- *
- * Wind::import('WIND:cache.strategy.WindEacceleratorCache');
- * $cache = new WindEacceleratorCache();
- * $cache->set('name', 'xxx');
- *
- * 2、同时您也可以使用组件配置的方式实现调用,在应用配置中的组件配置块(components),配置该组件命名为eacceleratorCache如下:
- *
- * 'eacceleratorCache' => array(
- * 'path' => 'WIND:cache.strategy.WindEacceleratorCache',
- * 'scope' => 'singleton',
- * 'config' => array(
- * 'security-code' => '',
- * 'key-prefix' => '',
- * 'expires' => '0',
- * ),
- * ),
- *
- * 在应用中可以通过如下方式实现访问:
- *
- * $cache = Wind::getApp()->getComponent('eacceleratorCache');
- * $cache->set('name', 'cacheTest');
- *
- * 关于组件配置的相关说明请参考组件配置一章.
- *
- * 注意:要使用EacceleratorCache组件,需要安装eaccelerator扩展支持。
- *
- * the last known user to change this file in the repository
- * @author xiaoxiao
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package strategy
- */
-class WindEacceleratorCache extends AbstractWindCache {
-
- /**
- * 构造函数
- *
- * 判断是否有安装eaccelerator扩展,如果没有安装则会抛出WindCacheException异常
- *
- * @throws WindCacheException
- */
- public function __construct() {
- if (!function_exists('eaccelerator_get')) {
- throw new WindCacheException('The eaccelerator extension must be loaded !');
- }
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return eaccelerator_put($key, $value, $expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expire = 0) {
- return eaccelerator_put($key,$value,$expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::get()
- */
- protected function getValue($key) {
- return eaccelerator_get($key);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return eaccelerator_rm($key);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- return eaccelerator_gc();
- }
-}
\ No newline at end of file
+
+ * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
+ * get($key): 继承自{@link AbstractWindCache::get()}.
+ * delete($key): 继承自{@link AbstractWindCache::delete()}.
+ * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
+ * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
+ * setConfig($config): 继承自{@link AbstractWindCache::setConfig()}.
+ *
+ * 该缓存策略从AbstractWindCache类中继承三个配置项:
+ *
+ * array(
+ * 'security-code' => '', //继承自AbstractWindCache,安全码配置
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
+ * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
+ * )
+ *
+ * 使用方式:
+ * 1、您可以像使用普通类库一样使用该组件:
+ *
+ *
+ * $cache = new WindEacceleratorCache();
+ * $cache->set('name', 'xxx');
+ *
+ * 2、同时您也可以使用组件配置的方式实现调用,在应用配置中的组件配置块(components),配置该组件命名为eacceleratorCache如下:
+ *
+ * 'eacceleratorCache' => array(
+ * 'path' => 'WIND:cache.strategy.WindEacceleratorCache',
+ * 'scope' => 'singleton',
+ * 'config' => array(
+ * 'security-code' => '',
+ * 'key-prefix' => '',
+ * 'expires' => '0',
+ * ),
+ * ),
+ *
+ * 在应用中可以通过如下方式实现访问:
+ *
+ * $cache = Wind::getComponent('eacceleratorCache');
+ * $cache->set('name', 'cacheTest');
+ *
+ * 关于组件配置的相关说明请参考组件配置一章.
+ *
+ * 注意:要使用EacceleratorCache组件,需要安装eaccelerator扩展支持。
+ *
+ * the last known user to change this file in the repository
+ * @author xiaoxiao
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindEacceleratorCache.php 3904 2013-01-08 07:01:26Z yishuo $
+ * @package strategy
+ */
+class WindEacceleratorCache extends AbstractWindCache
+{
+ /**
+ * 构造函数
+ *
+ * 判断是否有安装eaccelerator扩展,如果没有安装则会抛出WindCacheException异常
+ *
+ * @throws WindCacheException
+ */
+ public function __construct()
+ {
+ if (!function_exists('eaccelerator_get')) {
+ throw new WindCacheException('[cache.strategy.WindEacceleratorCache] The eaccelerator extension must be loaded !');
+ }
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return eaccelerator_put($key, $value, $expire);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expire = 0)
+ {
+ return eaccelerator_put($key, $value, $expire);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::get()
+ */
+ protected function getValue($key)
+ {
+ return eaccelerator_get($key);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return eaccelerator_rm($key);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ return eaccelerator_gc();
+ }
+}
diff --git a/wind/cache/strategy/WindFileCache.php b/wind/cache/strategy/WindFileCache.php
index 36e08d1a..3d654419 100644
--- a/wind/cache/strategy/WindFileCache.php
+++ b/wind/cache/strategy/WindFileCache.php
@@ -1,9 +1,9 @@
* set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
@@ -11,7 +11,8 @@
* delete($key): 继承自{@link AbstractWindCache::delete()}.
* batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
* batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
- * {@link setConfig($config)}: 重写了父类的{@link AbstractWindCache::setConfig()}.
+ * {@link setConfig($config)}: 重写了父类的{@link
+ * AbstractWindCache::setConfig()}.
*
* 它接收如下配置:
*
@@ -20,14 +21,14 @@
* 'suffix' => 'txt', //缓存文件的后缀,默认为txt后缀
* 'dir-level' => '0', //缓存文件存放目录的子目录长度,默认为0不分子目录
* 'security-code' => '', //继承自AbstractWindCache,安全码配置
- * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
* 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
* )
*
* 使用方法:
* 1、您可以像使用普通类库一样使用该组件:
*
- * Wind::import('WIND:cache.strategy.WindFileCache');
+ *
* $cache = new WindFileCache();
* $cache->setConfig(array('dir' => 'data', 'suffix' => 'php'));
* $cache->set('name', 'fileCacheTest');
@@ -42,7 +43,7 @@
* 'dir' => 'data',
* 'suffix' => 'txt',
* 'dir-level' => '0',
- * 'security-code' => '',
+ * 'security-code' => '',
* 'key-prefix' => '',
* 'expires' => '0',
* ),
@@ -50,200 +51,218 @@
*
* 在应用中可以通过如下方式获得dbCache对象:
*
- * $fileCache = Wind::getApp()->getComponent('fileCache'); //dbCache的名字来自于组件配置中的名字
+ * $fileCache = Wind::getComponent('fileCache'); //dbCache的名字来自于组件配置中的名字
*
- *
- * the last known user to change this file in the repository
+ * the last known user to change this file in the repository
+ *
* @author xiaoxiao
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindFileCache.php 3791 2012-10-30 04:01:29Z liusanbian $
* @package strategy
*/
-class WindFileCache extends AbstractWindCache {
-
- /**
- * 缓存目录
- *
- * @var string
- */
- private $cacheDir;
-
- /**
- * 缓存后缀
- *
- * @var string
- */
- private $cacheFileSuffix = 'txt';
-
- /**
- * 缓存子目录的长度
- *
- * @var int
- */
- private $cacheDirectoryLevel = 0;
-
- /**
- * 保存缓存目录列表
- *
- * 如果用户已经访问过统一个缓存,则会直接从该列表中获取该具体值而不重新计算。
- *
- * @var array
- */
- private $cacheFileList = array();
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return WindFile::write($key, $value) == strlen($value);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expire = 0) {
- return WindFile::write($key, $value) == strlen($value);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::get()
- */
- protected function getValue($key) {
- if (!is_file($key)) return null;
- return WindFile::read($key);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return WindFile::write($key, '');
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- return WindFolder::clearRecur($this->getCacheDir());
- }
-
- /**
- * 根据用户key计算获取真是缓存文件
- *
- * 缓存key在安全处理之后,判断该key是否已经被访问过
- *
- * - 如果被访问过,则直接返回该真实缓存文件
- * - 没有访问过,则将会进入计算流程.
- *
- * - 如果用该组件配置了缓存子目录的长度n:
- *
- * - 获得缓存key的md5值的0~n的子字串作为子缓存目录;
- * - 将缓存文件存放在该缓存子目录下.同时将该缓存文件的新路径保存到已访问的缓存路径列表中,供下次直接调用.
- *
- *
- * - 如果没有配置缓存子目录长度,则直接将该文件缓存在缓存根目录下,同时也将该缓存文件路径保存在已访问的缓存路径列表中.
- *
- *
- *
- *
- * @param string $key 用户的缓存文件key
- * @return string 真实的缓存文件
- */
- protected function buildSecurityKey($key) {
- $key = parent::buildSecurityKey($key);
- if (false !== ($dir = $this->checkCacheDir($key))) return $dir;
- $_dir = $this->getCacheDir();
- if (0 < ($level = $this->getCacheDirectoryLevel())) {
- $_subdir = substr(md5($key), 0, $level);
- $_dir .= '/' . $_subdir;
- WindFolder::mk($_dir);
- }
- $filename = $key . '.' . $this->getCacheFileSuffix();
- $this->cacheFileList[$key] = ($_dir ? $_dir . '/' . $filename : $filename);
- return $this->cacheFileList[$key];
- }
-
- /**
- * 是否缓存key已经存在缓存访问列表中
- *
- *
- * - 如果缓存key已经在缓存访问列表中,则将会直接返回存在的值
- * - 如果不存在则返回false.
- *
- *
- * @param string $key 待检查的缓存key
- * @return string|boolean 如果存在则返回被保存的值,如果不存在则返回false;
- */
- private function checkCacheDir($key) {
- return isset($this->cacheFileList[$key]) ? $this->cacheFileList[$key] : false;
- }
-
- /**
- * 设置缓存目录
- *
- * @param string $dir 缓存目录,必须是可写可读权限
- */
- public function setCacheDir($dir) {
- $_dir = Wind::getRealPath($dir, false, true);
- WindFolder::mkRecur($_dir);
- $this->cacheDir = realpath($_dir);
- }
-
- /**
- * 获得缓存目录
- *
- * @return string $cacheDir 返回配置的缓存目录
- */
- private function getCacheDir() {
- return $this->cacheDir;
- }
-
- /**
- * 设置缓存文件的后缀
- *
- * @param string $cacheFileSuffix 缓存文件的后缀,默认为txt
- */
- public function setCacheFileSuffix($cacheFileSuffix) {
- $this->cacheFileSuffix = $cacheFileSuffix;
- }
-
- /**
- * 获得缓存文件的后缀
- *
- * @return string $cacheFileSuffix 缓存文件的后缀
- */
- private function getCacheFileSuffix() {
- return $this->cacheFileSuffix;
- }
-
- /**
- * 设置缓存存放的目录下子目录的长度
- *
- * @param int $cacheDirectoryLevel 该值将会决定缓存目录下子缓存目录的长度,最小为0(不建子目录),最大为32(md5值最长32),缺省为0
- */
- public function setCacheDirectoryLevel($cacheDirectoryLevel) {
- $this->cacheDirectoryLevel = $cacheDirectoryLevel;
- }
-
- /**
- * 返回缓存存放的目录下子目录的长度
- *
- * 该值将会决定缓存目录下子缓存目录的长度,最小为0(不建子目录),最大为32(md5值最长32),缺省为0
- *
- * @return int $cacheDirectoryLevel
- */
- public function getCacheDirectoryLevel() {
- return $this->cacheDirectoryLevel;
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- $this->setCacheDir($this->getConfig('dir'));
- $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt'));
- $this->setCacheDirectoryLevel($this->getConfig('dir-level', '', 0));
- }
-}
\ No newline at end of file
+class WindFileCache extends AbstractWindCache
+{
+ /**
+ * 缓存目录
+ *
+ * @var string
+ */
+ private $cacheDir;
+
+ /**
+ * 缓存后缀
+ *
+ * @var string
+ */
+ private $cacheFileSuffix = 'txt';
+
+ /**
+ * 缓存子目录的长度
+ *
+ * @var int
+ */
+ private $cacheDirectoryLevel = 0;
+
+ /**
+ * 保存缓存目录列表
+ * 如果用户已经访问过统一个缓存,则会直接从该列表中获取该具体值而不重新计算。
+ *
+ * @var array
+ */
+ private $cacheFileList = array();
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return WindFile::write($key, $value) == strlen($value);
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expire = 0)
+ {
+ return WindFile::write($key, $value) == strlen($value);
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::get()
+ */
+ protected function getValue($key)
+ {
+ if (!is_file($key)) {
+ return null;
+ }
+
+ return WindFile::read($key);
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return WindFile::write($key, '');
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ return WindFolder::clearRecur($this->getCacheDir());
+ }
+
+ /**
+ * 根据用户key计算获取真是缓存文件
+ * 缓存key在安全处理之后,判断该key是否已经被访问过
+ *
+ * - 如果被访问过,则直接返回该真实缓存文件
+ * - 没有访问过,则将会进入计算流程.
+ *
+ * - 如果用该组件配置了缓存子目录的长度n:
+ *
+ * - 获得缓存key的md5值的0~n的子字串作为子缓存目录;
+ * - 将缓存文件存放在该缓存子目录下.同时将该缓存文件的新路径保存到已访问的缓存路径列表中,供下次直接调用.
+ *
+ *
+ * - 如果没有配置缓存子目录长度,则直接将该文件缓存在缓存根目录下,同时也将该缓存文件路径保存在已访问的缓存路径列表中.
+ *
+ *
+ *
+ *
+ * @param string $key 用户的缓存文件key
+ * @return string 真实的缓存文件
+ */
+ protected function buildSecurityKey($key)
+ {
+ $key = parent::buildSecurityKey($key);
+ if (false !== ($dir = $this->checkCacheDir($key))) {
+ return $dir;
+ }
+ $_dir = $this->getCacheDir();
+ if (0 < ($level = $this->getCacheDirectoryLevel())) {
+ $_subdir = substr(md5($key), 0, $level);
+ $_dir .= '/'.$_subdir;
+ WindFolder::isDir($_dir) || WindFolder::mk($_dir);
+ }
+ $filename = $key.'.'.$this->getCacheFileSuffix();
+ $this->cacheFileList[$key] = ($_dir ? $_dir.'/'.$filename : $filename);
+
+ return $this->cacheFileList[$key];
+ }
+
+ /**
+ * 是否缓存key已经存在缓存访问列表中
+ *
+ * - 如果缓存key已经在缓存访问列表中,则将会直接返回存在的值
+ * - 如果不存在则返回false.
+ *
+ *
+ * @param string $key 待检查的缓存key
+ * @return string boolean
+ */
+ private function checkCacheDir($key)
+ {
+ return isset($this->cacheFileList[$key]) ? $this->cacheFileList[$key] : false;
+ }
+
+ /**
+ * 设置缓存目录
+ *
+ * @param string $dir 缓存目录,必须是可写可读权限
+ */
+ public function setCacheDir($dir)
+ {
+ $_dir = Wind::getRealPath($dir, false, true);
+ WindFolder::mkRecur($_dir);
+ $this->cacheDir = realpath($_dir);
+ }
+
+ /**
+ * 获得缓存目录
+ *
+ * @return string $cacheDir 返回配置的缓存目录
+ */
+ private function getCacheDir()
+ {
+ return $this->cacheDir;
+ }
+
+ /**
+ * 设置缓存文件的后缀
+ *
+ * @param string $cacheFileSuffix 缓存文件的后缀,默认为txt
+ */
+ public function setCacheFileSuffix($cacheFileSuffix)
+ {
+ $this->cacheFileSuffix = $cacheFileSuffix;
+ }
+
+ /**
+ * 获得缓存文件的后缀
+ *
+ * @return string $cacheFileSuffix 缓存文件的后缀
+ */
+ private function getCacheFileSuffix()
+ {
+ return $this->cacheFileSuffix;
+ }
+
+ /**
+ * 设置缓存存放的目录下子目录的长度
+ *
+ * @param int $cacheDirectoryLevel
+ * 该值将会决定缓存目录下子缓存目录的长度,最小为0(不建子目录),最大为32(md5值最长32),缺省为0
+ */
+ public function setCacheDirectoryLevel($cacheDirectoryLevel)
+ {
+ $this->cacheDirectoryLevel = $cacheDirectoryLevel;
+ }
+
+ /**
+ * 返回缓存存放的目录下子目录的长度
+ * 该值将会决定缓存目录下子缓存目录的长度,最小为0(不建子目录),最大为32(md5值最长32),缺省为0
+ *
+ * @return int $cacheDirectoryLevel
+ */
+ public function getCacheDirectoryLevel()
+ {
+ return $this->cacheDirectoryLevel;
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ $this->setCacheDir($this->getConfig('dir'));
+ $this->setCacheFileSuffix($this->getConfig('suffix', '', 'txt'));
+ $this->setCacheDirectoryLevel($this->getConfig('dir-level', '', 0));
+ }
+}
diff --git a/wind/cache/strategy/WindMemCache.php b/wind/cache/strategy/WindMemCache.php
index 963dba09..8bad1423 100644
--- a/wind/cache/strategy/WindMemCache.php
+++ b/wind/cache/strategy/WindMemCache.php
@@ -1,8 +1,9 @@
@@ -13,7 +14,7 @@
* batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
* {@link setConfig($config)}: 重写了父类的{@link AbstractWindCache::setConfig()}.
*
- *
+ *
* 它接收如下配置:
*
* array(
@@ -48,7 +49,7 @@
*
* 'memCache' => array(
* 'path' => 'WIND:cache.strategy.WindMemCache',
- 'scope' => 'singleton',
+ 'scope' => 'singleton',
* 'config' = array(
* 'security-code' => '',
* 'key-prefix' => '',
@@ -70,104 +71,162 @@
* ),
*
* 如果含有多个memCache主机,可以设置多组host在config中,如host1,host2,其key值也可以自定义.
- *
+ *
* 注意:要使用该组件需要安装memcache扩展库.
- *
+ *
* the last known user to change this file in the repository
* @author xiaoxiao
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindMemCache.php 3904 2013-01-08 07:01:26Z yishuo $
* @package strategy
*/
-class WindMemCache extends AbstractWindCache {
-
- /**
- * memcache缓存操作句柄
- *
- * @var WindMemcache
- */
- protected $memcache = null;
- /**
- * 是否对缓存采取压缩存储
- *
- * @var int
- */
- protected $compress = 0;
-
- /**
- * 构造函数
- *
- * 判断是否有支持memCache,如果没有安装扩展库将会抛出异常,
- * 首先尝试使用memcached扩展,如果然后尝试创建memcache
- *
- * @throws WindCacheException 如果没有安装memcache扩展则抛出异常
- */
- public function __construct() {
- $this->memcache = new Memcached();
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return $this->memcache->set($key, $value, (int) $expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expires = 0) {
- return $this->memcache->add($key, $value, (int) $expires);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::getValue()
- */
- protected function getValue($key) {
- return $this->memcache->get($key);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return $this->memcache->delete($key);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- return $this->memcache->flush();
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::increment()
- */
- public function increment($key, $step = 1) {
- return $this->memcache->increment($this->buildSecurityKey($key), $step);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::decrement()
- */
- public function decrement($key, $step = 1) {
- return $this->memcache->decrement($this->buildSecurityKey($key), $step);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- $servers = $this->getConfig('servers', '', array());
- foreach ((array) $servers as $server) {
- if (!is_array($server)) throw new WindException('The memcache config is incorrect');
- if (!isset($server['host'])) throw new WindException('The memcache server ip address is not exist');
- if (!isset($server['port'])) throw new WindException('The memcache server port is not exist');
- $this->memcache->addServer($server['host'], $server['port'],
- isset($server['weight']) ? $server['weight'] : null);
- }
- }
-}
\ No newline at end of file
+class WindMemCache extends AbstractWindCache
+{
+ /**
+ * memcache缓存操作句柄
+ *
+ * @var WindMemcache
+ */
+ protected $memcache = null;
+
+ /**
+ * 是否对缓存采取压缩存储
+ *
+ * @var int
+ */
+ protected $compress = 0;
+
+ /**
+ * 构造函数
+ *
+ * 判断是否有支持memCache,如果没有安装扩展库将会抛出异常,
+ * 首先尝试使用memcached扩展,如果然后尝试创建memcache
+ *
+ * @throws WindCacheException 如果没有安装memcache扩展则抛出异常
+ */
+ public function __construct()
+ {
+ $this->memcache = new Memcache();
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return $this->memcache->set($key, $value, $this->compress, (int) $expire);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expires = 0)
+ {
+ return $this->memcache->add($key, $value, $this->compress, (int) $expires);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ return $this->memcache->get($key, $this->compress);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return $this->memcache->delete($key);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ return $this->memcache->flush();
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::increment()
+ */
+ public function increment($key, $step = 1)
+ {
+ return $this->memcache->increment($this->buildSecurityKey($key), $step);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::decrement()
+ */
+ public function decrement($key, $step = 1)
+ {
+ return $this->memcache->decrement($this->buildSecurityKey($key), $step);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::batchGet()
+ */
+ public function batchGet(array $keys)
+ {
+ $_keys = array_map(array($this, 'buildSecurityKey'), $keys);
+ $tags = array_fill(0, count($_keys), $this->compress);
+ $_datas = $this->memcache->get($_keys, $tags);
+ $_return = array();
+ foreach ($keys as $_i => $key) {
+ $_return[$key] = isset($_datas[$_keys[$_i]]) ? $this->formatData($key, $_datas[$_keys[$_i]]) : false;
+ }
+
+ return $_return;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::buildData()
+ */
+ protected function buildData($value, $expires = 0, IWindCacheDependency $dependency = null)
+ {
+ return $value;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::formatData()
+ */
+ protected function formatData($key, $value)
+ {
+ return $value;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ $this->compress = $this->getConfig('compress', '', '0');
+ $servers = $this->getConfig('servers', '', array());
+ $defaultServer = array(
+ 'host' => '',
+ 'port' => '',
+ 'pconn' => true,
+ 'weight' => 1,
+ 'timeout' => 1,
+ 'retry' => 15,
+ 'status' => true,
+ 'fcallback' => null, );
+ foreach ((array) $servers as $server) {
+ if (!is_array($server)) {
+ throw new WindCacheException('[cache.strategy.WindMemCache.setConfig] The memcache config is incorrect');
+ }
+ $args = array_merge($defaultServer, $server);
+ if (empty($server['host'])) {
+ throw new WindCacheException('[cache.strategy.WindMemCache.setConfig] The memcache server ip address is not exist');
+ }
+ if (empty($server['port'])) {
+ throw new WindCacheException('[cache.strategy.WindMemCache.setConfig] The memcache server port is not exist');
+ }
+ $this->memcache->addServer($args['host'], $args['port'], $args['pconn'], $args['weight'], $args['timeout'], $args['retry'], $args['status'], $args['fcallback']);
+ }
+ }
+}
diff --git a/wind/cache/strategy/WindMemCached.php b/wind/cache/strategy/WindMemCached.php
new file mode 100644
index 00000000..629ededa
--- /dev/null
+++ b/wind/cache/strategy/WindMemCached.php
@@ -0,0 +1,204 @@
+
+ * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
+ * get($key): 继承自{@link AbstractWindCache::get()}.
+ * delete($key): 继承自{@link AbstractWindCache::delete()}.
+ * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
+ * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
+ * {@link setConfig($config)}: 重写了父类的{@link AbstractWindCache::setConfig()}.
+ *
+ *
+ * 它接收如下配置:
+ *
+ * array(
+ * 'security-code' => '', //继承自AbstractWindCache,安全码配置.
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀.
+ * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置.
+ * 'compress' => '0', //压缩等级,默认为0
+ * 'servers' => array(
+ * 'host' => array(
+ * 'host'=>'localhost', //要连接的memcached服务端监听的主机位置.
+ * 'port'=>11211, //要连接的memcached服务端监听的端口.
+ * 'weight' => 1, //为此服务器创建的桶的数量,用来控制此服务器被选中的权重,单个服务器被选中的概率是相对于所有服务器weight总和而言的.
+ * ),
+ * ),
+ * )
+ *
+ * 使用方法:
+ * 1、按照普通的调用类库的方式去调用:
+ *
+ * Wind::import("WIND:cache.strategy.WindMemCached");
+ * $cache = new WindMemCached();
+ * $cache->setConfig(array('host' => 'localhost', 'port' => 11211));
+ * $cache->set('name', 'test');
+ *
+ * 2、采用组件配置的方式,通过组件机制调用
+ * 在应用配置的components组件配置块中,配置memCache(该名字将决定调用的时候使用的组件名字):
+ *
+ * 'memCache' => array(
+ * 'path' => 'WIND:cache.strategy.WindMemCached',
+ 'scope' => 'singleton',
+ * 'config' = array(
+ * 'security-code' => '',
+ * 'key-prefix' => '',
+ * 'expires' => '0',
+ * 'compress' => '0',
+ * 'servers' => array(
+ * 'host1' => array(
+ * 'host'=>'localhost',
+ * 'port'=>11211,
+ * 'pconn'=>true,
+ * 'weight' => 1,
+ * ),
+ * ),
+ * ),
+ * ),
+ *
+ * 如果含有多个memCache主机,可以设置多组host在config中,如host1,host2,其key值也可以自定义.
+ *
+ * 注意:要使用该组件需要安装memcache扩展库.
+ *
+ * the last known user to change this file in the repository
+ * @author xiaoxiao
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindMemCached.php 3891 2013-01-08 03:44:46Z xiaoxia.xuxx $
+ * @package strategy
+ */
+class WindMemCached extends AbstractWindCache
+{
+ /**
+ * memcache缓存操作句柄
+ *
+ * @var WindMemcache
+ */
+ protected $memcache = null;
+
+ /**
+ * 构造函数
+ *
+ * 判断是否有支持memCache,如果没有安装扩展库将会抛出异常,
+ * 首先尝试使用memcached扩展,如果然后尝试创建memcache
+ *
+ * @throws WindCacheException 如果没有安装memcache扩展则抛出异常
+ */
+ public function __construct()
+ {
+ $this->memcache = new Memcached();
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return $this->memcache->set($key, $value, (int) $expire);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expires = 0)
+ {
+ return $this->memcache->add($key, $value, (int) $expires);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ return $this->memcache->get($key);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return $this->memcache->delete($key);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ return $this->memcache->flush();
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::increment()
+ */
+ public function increment($key, $step = 1)
+ {
+ return $this->memcache->increment($this->buildSecurityKey($key), $step);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::decrement()
+ */
+ public function decrement($key, $step = 1)
+ {
+ return $this->memcache->decrement($this->buildSecurityKey($key), $step);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::batchGet()
+ */
+ public function batchGet(array $keys)
+ {
+ $_keys = array_map(array($this, 'buildSecurityKey'), $keys);
+ $_datas = $this->memcache->getMulti($_keys);
+ $_return = array();
+ foreach ($keys as $_i => $key) {
+ $_return[$key] = isset($_datas[$_keys[$_i]]) ? $this->formatData($key, $_datas[$_keys[$_i]]) : false;
+ }
+
+ return $_return;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::buildData()
+ */
+ protected function buildData($value, $expires = 0, IWindCacheDependency $dependency = null)
+ {
+ return $value;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::formatData()
+ */
+ protected function formatData($key, $value)
+ {
+ return $value;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindCache::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ $servers = $this->getConfig('servers', '', array());
+ foreach ((array) $servers as $server) {
+ if (!is_array($server)) {
+ throw new WindCacheException('[cache.strategy.WindMemCached.setConfig] The memcache config is incorrect');
+ }
+ if (!isset($server['host'])) {
+ throw new WindCacheException('[cache.strategy.WindMemCached.setConfig] The memcache server ip address is not exist');
+ }
+ if (!isset($server['port'])) {
+ throw new WindCacheException('[cache.strategy.WindMemCached.setConfig] The memcache server port is not exist');
+ }
+ $this->memcache->addServer($server['host'], $server['port'], isset($server['weight']) ? $server['weight'] : null);
+ }
+ }
+}
diff --git a/wind/cache/strategy/WindRedisCache.php b/wind/cache/strategy/WindRedisCache.php
index 42ff24d6..6543a351 100644
--- a/wind/cache/strategy/WindRedisCache.php
+++ b/wind/cache/strategy/WindRedisCache.php
@@ -1,27 +1,26 @@
注意:使用该类型的缓存,需要安装phpredis扩展
- *
* 配置文件格式:
*
* array(
- * 'security-code' => '', //继承自AbstractWindCache,安全码配置.
- * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀.
- * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置.
- * 'auth' => '', //链接认证密码,redis->auth
- * 'servers' => array(
- * array(
- * 'host'=>'127.0.0.1', //要连接的redis服务端监听的主机位置.
- * 'port'=>6379, //要连接的redis服务端监听的端口.
- * 'timeout' => 0, //连接持续(超时)时间(单位秒),默认值0.不限制
- * 'pconn'=>true, //控制是否使用持久化连接,默认true.
- * ),
- * ),
+ * 'security-code' => '', //继承自AbstractWindCache,安全码配置.
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀.
+ * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置.
+ * 'auth' => '', //链接认证密码,redis->auth
+ * 'servers' => array(
+ * array(
+ * 'host'=>'127.0.0.1', //要连接的redis服务端监听的主机位置.
+ * 'port'=>6379, //要连接的redis服务端监听的端口.
+ * 'timeout' => 0, //连接持续(超时)时间(单位秒),默认值0.不限制
+ * 'pconn'=>true, //控制是否使用持久化连接,默认true.
+ * ),
+ * ),
* )
*
- *
* 1、按照普通的调用类库的方式去调用:
*
* Wind::import("WIND:cache.strategy.WindRedisCache");
@@ -30,141 +29,153 @@
* $cache->set('name', 'test');
* echo $cache->get('name');
*
- *
* 2、采用组件配置的方式,通过组件机制调用
* 在应用配置的components组件配置块中,配置redisCache(该名字将决定调用的时候使用的组件名字):
*
* //配置组件
* 'redisCache' => array(
- * 'path' => 'WIND:cache.strategy.WindRedisCache',
- * 'scope' => 'singleton',
- * 'config' = array(
- * 'security-code' => '',
- * 'key-prefix' => '',
- * 'expires' => '0',
- * 'auth' => '',
- * 'servers' => array(
- * 'host1' => array(
- * 'host' => '127.0.0.1',
- * 'port' => 6379,
- * 'pconn' => true,
- * 'timeout' => 0,
- * ),
- * ),
- * ),
+ * 'path' => 'WIND:cache.strategy.WindRedisCache',
+ * 'scope' => 'singleton',
+ * 'config' = array(
+ * 'security-code' => '',
+ * 'key-prefix' => '',
+ * 'expires' => '0',
+ * 'auth' => '',
+ * 'servers' => array(
+ * 'host1' => array(
+ * 'host' => '127.0.0.1',
+ * 'port' => 6379,
+ * 'pconn' => true,
+ * 'timeout' => 0,
+ * ),
+ * ),
+ * ),
* ),
* //使用:
- * $redis = Wind::getApp()->getComponent('redisCache');
+ * $redis = Wind::getComponent('redisCache');
* $redis->set('name', 'windFramework');
* echo $redis->get('name');
*
- *
+ *
* @author xiaoxia.xu
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindRedisCache.php 3904 2013-01-08 07:01:26Z yishuo $
* @package wind.cache.strategy
*/
-class WindRedisCache extends AbstractWindCache {
- /**
- * redis缓存操作句柄
- *
- * @var Redis
- */
- protected $redis = null;
-
- /**
- * redis链接使用的认证密码
- *
- * @var string
- */
- protected $auth = '';
+class WindRedisCache extends AbstractWindCache
+{
+ /**
+ * redis缓存操作句柄
+ *
+ * @var Redis
+ */
+ protected $redis = null;
+
+ /**
+ * redis链接使用的认证密码
+ *
+ * @var string
+ */
+ protected $auth = '';
+
+ /**
+ * 构造函数
+ *
+ * @throws WindCacheException
+ */
+ public function __construct()
+ {
+ $this->redis = new Redis();
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expires = 0)
+ {
+ $r = $this->redis->set($key, $value);
+ if ($r && $expires) {
+ $this->redis->setTimeout($key, $expires);
+ }
+
+ return $r;
+ }
- /**
- * 构造函数
- *
- * @throws WindCacheException
- */
- public function __construct() {
- $this->redis = new Redis();
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expires = 0)
+ {
+ $r = $this->redis->setnx($key, $value);
+ if ($r && $expires) {
+ $this->redis->setTimeout($key, $expires);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expires = 0) {
- $r = $this->redis->set($key, $value);
- if ($r && $expires) $this->redis->setTimeout($key, $expires);
- return $r;
- }
+ return $r;
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expires = 0) {
- $r = $this->redis->setnx($key, $value);
- if ($r && $expires) {
- $this->redis->setTimeout($key, $expires);
- }
- return $r;
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ return $this->redis->get($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::getValue()
- */
- protected function getValue($key) {
- return $this->redis->get($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return $this->redis->delete($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return $this->redis->delete($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ $this->redis->flushAll();
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- $this->redis->flushAll();
- }
+ /*
+ * //TODO 调用其他方法开放调用,重构 @see WindModule::__call()
+ */
+ public function __call($methodName, $args)
+ {
+ if (!method_exists($this->redis, $methodName)) {
+ throw new WindCacheException('[cache.strategy.WindRedisCache] The method "'.$methodName.'" is no in redis');
+ }
- /* //TODO 调用其他方法开放调用,重构
- * @see WindModule::__call()
- */
- public function __call($methodName, $args) {
- if (!method_exists($this->redis, $methodName)) throw new WindCacheException(
- 'The method "' . $methodName . '" is no in redis');
- return call_user_func_array(array($this->redis, $methodName), $args);
- }
+ return call_user_func_array(array($this->redis, $methodName), $args);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- $auth = $this->getConfig('auth', '', '');
- if ($auth && (true !== $this->redis->auth($auth))) {
- throw new WindCacheException('Authenticate the redis connection error');
- }
- $servers = $this->getConfig('servers', '', array());
- $defaultServer = array(
- 'host' => '',
- 'port' => 6379,
- 'timeout' => 0,
- 'pconn' => false,
- 'persistent_id' => '');
- foreach ((array) $servers as $server) {
- if (!is_array($server)) throw new WindCacheException('The redis config is incorrect');
- $args = array_merge($defaultServer, $server);
- if (!isset($server['host'])) throw new WindCacheException(
- 'The redis server ip address is not exist');
- $method = $args['pconn'] === true ? 'pconnect' : 'connect';
- $m_args = array($args['host'], $args['port'], $args['timeout']);
- //如果是长链接,则会存在一个长链接的ID号
- ($args['pconn'] === true && $args['persistent_id']) && $m_args[] = $args['persistent_id'];
- call_user_func_array(array($this->redis, $method), $m_args);
- }
- }
-}
\ No newline at end of file
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ $auth = $this->getConfig('auth', '', '');
+ if ($auth && (true !== $this->redis->auth($auth))) {
+ throw new WindCacheException('[cache.strategy.WindRedisCache.setConfig] Authenticate the redis connection error');
+ }
+ $servers = $this->getConfig('servers', '', array());
+ $defaultServer = array('host' => '', 'port' => 6379, 'timeout' => 0, 'pconn' => false, 'persistent_id' => '');
+ foreach ((array) $servers as $server) {
+ if (!is_array($server)) {
+ throw new WindCacheException('[cache.strategy.WindRedisCache.setConfig] The redis config is incorrect');
+ }
+ $args = array_merge($defaultServer, $server);
+ if (!isset($server['host'])) {
+ throw new WindCacheException('[cache.strategy.WindRedisCache.setConfig] The redis server ip address is not exist');
+ }
+ $method = $args['pconn'] === true ? 'pconnect' : 'connect';
+ $m_args = array($args['host'], $args['port'], $args['timeout']);
+ // 如果是长链接,则会存在一个长链接的ID号
+ ($args['pconn'] === true && $args['persistent_id']) && $m_args[] = $args['persistent_id'];
+ call_user_func_array(array($this->redis, $method), $m_args);
+ }
+ }
+}
diff --git a/wind/cache/strategy/WindWinCache.php b/wind/cache/strategy/WindWinCache.php
index 6ecfd0fd..7b17922c 100644
--- a/wind/cache/strategy/WindWinCache.php
+++ b/wind/cache/strategy/WindWinCache.php
@@ -1,97 +1,101 @@
- * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
- * get($key): 继承自{@link AbstractWindCache::get()}.
- * delete($key): 继承自{@link AbstractWindCache::delete()}.
- * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
- * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
- * setConfig($config): 继承自{@link AbstractWindCache::setConfig()}.
+ * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
+ * get($key): 继承自{@link AbstractWindCache::get()}.
+ * delete($key): 继承自{@link AbstractWindCache::delete()}.
+ * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
+ * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
+ * setConfig($config): 继承自{@link AbstractWindCache::setConfig()}.
*
* 该缓存策略从AbstractWindCache类中继承三个配置项:
*
- * array(
- * 'security-code' => '', //继承自AbstractWindCache,安全码配置
- * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
- * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
- * )
+ * array(
+ * 'security-code' => '', //继承自AbstractWindCache,安全码配置
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
+ * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
+ * )
*
- * 使用方式:
+ * 使用方式:
* 1、您可以像使用普通的类一样使用该组件,如下:
*
- * Wind::import('WIND:cache.strategy.WindWinCache');
+ *
* $cache = new WindWinCache();
* $cache->set('name', 'windframework');
*
- *
* 2、同时作为组件,WindWinCache也允许用户通过组件配置得方式,通过框架的组件机制来获得该缓存对象进行操作.
* 在应用配置中的组件配置块(components),配置使用该组件为winCache如下:
*
- * 'winCache' => array(
- * 'path' => 'WIND:cache.strategy.WindwinCache',
- * 'scope' => 'singleton',
- * 'config' => array(
- * 'security-code' => '',
- * 'key-prefix' => '',
- * 'expires' => '0',
- * ),
- * ),
+ * 'winCache' => array(
+ * 'path' => 'WIND:cache.strategy.WindwinCache',
+ * 'scope' => 'singleton',
+ * 'config' => array(
+ * 'security-code' => '',
+ * 'key-prefix' => '',
+ * 'expires' => '0',
+ * ),
+ * ),
*
* 在应用中通过如下方式使用:
*
- * $cache = Wind::getApp()->getComponent('winCache'); //注意这里的winCache组件名称和配置的组件名称需要对应
+ * $cache = Wind::getComponent('winCache'); //注意这里的winCache组件名称和配置的组件名称需要对应
* $cache->set('name', 'wf');
*
* 关于组件配置的相关说明请参考组件配置一章.
- *
* 注意: 要使用WindWinCache组件,需要安装wincache扩展支持.
- *
- * the last known user to change this file in the repository
+ * the last known user to change this file in the repository
+ *
* @author xiaoxiao
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindWinCache.php 3791 2012-10-30 04:01:29Z liusanbian $
* @package strategy
*/
-class WindWinCache extends AbstractWindCache {
+class WindWinCache extends AbstractWindCache
+{
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return wincache_ucache_set($key, $value, $expire);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return wincache_ucache_set($key, $value, $expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expire = 0) {
- return wincache_ucache_add($key, $value, $expire);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expire = 0)
+ {
+ return wincache_ucache_add($key, $value, $expire);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::getValue()
- */
- protected function getValue($key) {
- return wincache_ucache_get($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ return wincache_ucache_get($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return wincache_ucache_delete($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return wincache_ucache_delete($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- return wincache_ucache_clear();
- }
-}
\ No newline at end of file
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ return wincache_ucache_clear();
+ }
+}
diff --git a/wind/cache/strategy/WindXCache.php b/wind/cache/strategy/WindXCache.php
index a9b9921c..a32b0964 100644
--- a/wind/cache/strategy/WindXCache.php
+++ b/wind/cache/strategy/WindXCache.php
@@ -1,138 +1,146 @@
- * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
- * get($key): 继承自{@link AbstractWindCache::get()}.
- * delete($key): 继承自{@link AbstractWindCache::delete()}.
- * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
- * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
- * {@link setConfig($config)}: 重写了父类的{@link AbstractWindCache::setConfig()}.
+ * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
+ * get($key): 继承自{@link AbstractWindCache::get()}.
+ * delete($key): 继承自{@link AbstractWindCache::delete()}.
+ * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
+ * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
+ * {@link setConfig($config)}: 重写了父类的{@link
+ * AbstractWindCache::setConfig()}.
*
- *
* 它接收如下配置:
*
- * array(
- * 'user' => '', //拥有清空xcache数据的权限用户
- * 'pwd' => '', //拥有清空xcache数据的权限用户的密码
- * 'security-code' => '', //继承自AbstractWindCache,安全码配置
- * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
- * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
- * )
+ * array(
+ * 'user' => '', //拥有清空xcache数据的权限用户
+ * 'pwd' => '', //拥有清空xcache数据的权限用户的密码
+ * 'security-code' => '', //继承自AbstractWindCache,安全码配置
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
+ * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
+ * )
*
* xcache缓存的使用:
* 1、像使用普通类库一样使用该组件:
*
- * Wind::import('WIND:cache.strategy.WindXCache');
- * $cache = new WindxCache();
- * $cache->set('name', 'windDbTest');
+ *
+ * $cache = new WindxCache();
+ * $cache->set('name', 'windDbTest');
*
* 2、采用组件配置的方式,通过组件机制调用
* 在应用配置的components组件配置块中,配置xCache(该名字将决定调用的时候使用的组件名字):
*
- * 'xCache' => array(
- * 'path' => 'WIND:cache.strategy.WindXCache',
- * 'scope' => 'singleton',
- * 'config' => array(
- * 'user' => '',
- * 'pwd' => '',
- * 'security-code' => '',
- * 'key-prefix' => '',
- * 'expires' => '0',
- * ),
- * ),
+ * 'xCache' => array(
+ * 'path' => 'WIND:cache.strategy.WindXCache',
+ * 'scope' => 'singleton',
+ * 'config' => array(
+ * 'user' => '',
+ * 'pwd' => '',
+ * 'security-code' => '',
+ * 'key-prefix' => '',
+ * 'expires' => '0',
+ * ),
+ * ),
*
* 在应用中可以通过如下方式获得xCache对象:
*
- * $cache = Wind::getApp()->getComponent('xCache'); //xCache的名字来自于组件配置中的名字
+ * $cache = Wind::getComponent('xCache'); //xCache的名字来自于组件配置中的名字
* $cache->set('name', 'test');
*
* 注意: 该组件需要安装扩展xcache.
- *
- * the last known user to change this file in the repository
+ * the last known user to change this file in the repository
+ *
* @author xiaoxiao
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindXCache.php 3791 2012-10-30 04:01:29Z liusanbian $
* @package strategy
*/
-class WindXCache extends AbstractWindCache {
- /**
- * 拥有删除数据的权限用户
- *
- * xcache清空缓存的时候需要获得有权限的用户
- *
- * @var string
- */
- private $authUser = '';
- /**
- * 拥有删除数据的权限用户的密码
- *
- * xcache清空缓存的时候需要获得有权限的用户
- *
- * @var string
- */
- private $authPwd = '';
+class WindXCache extends AbstractWindCache
+{
+ /**
+ * 拥有删除数据的权限用户
+ * xcache清空缓存的时候需要获得有权限的用户
+ *
+ * @var string
+ */
+ private $authUser = '';
+ /**
+ * 拥有删除数据的权限用户的密码
+ * xcache清空缓存的时候需要获得有权限的用户
+ *
+ * @var string
+ */
+ private $authPwd = '';
+
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return xcache_set($key, $value, $expire);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return xcache_set($key, $value, $expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expire = 0) {
- return xcache_set($key, $value, $expire);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expire = 0)
+ {
+ return xcache_set($key, $value, $expire);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::getValue()
- */
- protected function getValue($key) {
- return xcache_get($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ return xcache_get($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return xcache_unset($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return xcache_unset($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- //xcache_clear_cache需要验证权限
- $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER'];
- $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW'];
- $_SERVER['PHP_AUTH_USER'] = $this->authUser;
- $_SERVER['PHP_AUTH_PW'] = $this->authPwd;
- //如果配置中xcache.var_count > 0 则不能用xcache_clear_cache(XC_TYPE_VAR, 0)的方式删除
- $max = xcache_count(XC_TYPE_VAR);
- for ($i = 0; $i < $max; $i++) {
- xcache_clear_cache(XC_TYPE_VAR, $i);
- }
- //恢复之前的权限
- $_SERVER['PHP_AUTH_USER'] = $tmp['user'];
- $_SERVER['PHP_AUTH_PW'] = $tmp['pwd'];
- return true;
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ // xcache_clear_cache需要验证权限
+ $tmp['user'] = isset($_SERVER['PHP_AUTH_USER']) ? null : $_SERVER['PHP_AUTH_USER'];
+ $tmp['pwd'] = isset($_SERVER['PHP_AUTH_PW']) ? null : $_SERVER['PHP_AUTH_PW'];
+ $_SERVER['PHP_AUTH_USER'] = $this->authUser;
+ $_SERVER['PHP_AUTH_PW'] = $this->authPwd;
+ // 如果配置中xcache.var_count > 0 则不能用xcache_clear_cache(XC_TYPE_VAR, 0)的方式删除
+ $max = xcache_count(XC_TYPE_VAR);
+ for ($i = 0; $i < $max; $i++) {
+ xcache_clear_cache(XC_TYPE_VAR, $i);
+ }
+ // 恢复之前的权限
+ $_SERVER['PHP_AUTH_USER'] = $tmp['user'];
+ $_SERVER['PHP_AUTH_PW'] = $tmp['pwd'];
- /* (non-PHPdoc)
- * @see AbstractWindCache::setConfig()
- */
- public function setConfig($config = array()) {
- if (!$config) return false;
- parent::setConfig($config);
- $this->authUser = $this->getConfig('user');
- $this->authPwd = $this->getConfig('pwd');
- }
+ return true;
+ }
-}
\ No newline at end of file
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setConfig()
+ */
+ public function setConfig($config = array())
+ {
+ if (!$config) {
+ return false;
+ }
+ parent::setConfig($config);
+ $this->authUser = $this->getConfig('user');
+ $this->authPwd = $this->getConfig('pwd');
+ }
+}
diff --git a/wind/cache/strategy/WindZendCache.php b/wind/cache/strategy/WindZendCache.php
index dd6971cd..663ce9c2 100644
--- a/wind/cache/strategy/WindZendCache.php
+++ b/wind/cache/strategy/WindZendCache.php
@@ -1,97 +1,101 @@
- * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
- * get($key): 继承自{@link AbstractWindCache::get()}.
- * delete($key): 继承自{@link AbstractWindCache::delete()}.
- * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
- * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
- * setConfig($config): 继承自{@link AbstractWindCache::setConfig()}.
+ * set($key, $value, $expire): 继承自{@link AbstractWindCache::set()}.
+ * get($key): 继承自{@link AbstractWindCache::get()}.
+ * delete($key): 继承自{@link AbstractWindCache::delete()}.
+ * batchGet($keys): 继承自{@link AbstractWindCache::batchGet()}.
+ * batchDelete($keys): 继承自{@link AbstractWindCache::batchDelete()}.
+ * setConfig($config): 继承自{@link AbstractWindCache::setConfig()}.
*
* 该缓存策略从AbstractWindCache类中继承三个配置项:
*
- * array(
- * 'security-code' => '', //继承自AbstractWindCache,安全码配置
- * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
- * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
- * )
+ * array(
+ * 'security-code' => '', //继承自AbstractWindCache,安全码配置
+ * 'key-prefix' => '', //继承自AbstractWindCache,缓存key前缀
+ * 'expires' => '0', //继承自AbstractWindCache,缓存过期时间配置
+ * )
*
* 使用方式:
* 1、您可以像使用普通的类一样使用该组件,如下:
*
- * Wind::import('WIND:cache.strategy.WindZendCache');
+ *
* $cache = new WindZendCache();
* $cache->set('name', 'windframework');
*
- *
* 2、同时作为组件,WindZendCache也允许用户通过组件配置得方式,通过框架的组件机制来获得该缓存对象进行操作.
* 在应用配置中的组件配置块(components),配置使用该组件如下:
*
- * 'zendCache' => array(
- * 'path' => 'WIND:cache.strategy.WindZendCache',
- * 'scope' => 'singleton',
- * 'config' => array(
- * 'security-code' => '',
- * 'key-prefix' => '',
- * 'expires' => '0',
- * ),
- * ),
+ * 'zendCache' => array(
+ * 'path' => 'WIND:cache.strategy.WindZendCache',
+ * 'scope' => 'singleton',
+ * 'config' => array(
+ * 'security-code' => '',
+ * 'key-prefix' => '',
+ * 'expires' => '0',
+ * ),
+ * ),
*
* 在应用中通过如下方式使用:
*
- * $cache = Wind::getApp()->getComponent('zendCache'); //注意这里的zendCache组件名称和配置的组件名称需要对应
+ * $cache = Wind::getComponent('zendCache'); //注意这里的zendCache组件名称和配置的组件名称需要对应
* $cache->set('name', 'wf');
*
* 关于组件配置的相关说明请参考组件配置一章.
- *
* 注意: 要使用WindZendCache组件,需要安装zend_cache扩展支持.
- *
- * the last known user to change this file in the repository
+ * the last known user to change this file in the repository
+ *
* @author xiaoxiao
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindZendCache.php 3791 2012-10-30 04:01:29Z liusanbian $
* @package strategy
*/
-class WindZendCache extends AbstractWindCache {
+class WindZendCache extends AbstractWindCache
+{
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::setValue()
+ */
+ protected function setValue($key, $value, $expire = 0)
+ {
+ return zend_shm_cache_store($key, $value, $expire);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::setValue()
- */
- protected function setValue($key, $value, $expire = 0) {
- return zend_shm_cache_store($key, $value, $expire);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindCache::addValue()
- */
- protected function addValue($key, $value, $expire = 0) {
- return zend_shm_cache_store($key, $value, $expire);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::addValue()
+ */
+ protected function addValue($key, $value, $expire = 0)
+ {
+ return zend_shm_cache_store($key, $value, $expire);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::getValue()
- */
- protected function getValue($key) {
- return zend_shm_cache_fetch($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::getValue()
+ */
+ protected function getValue($key)
+ {
+ return zend_shm_cache_fetch($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::deleteValue()
- */
- protected function deleteValue($key) {
- return zend_shm_cache_delete($key);
- }
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::deleteValue()
+ */
+ protected function deleteValue($key)
+ {
+ return zend_shm_cache_delete($key);
+ }
- /* (non-PHPdoc)
- * @see AbstractWindCache::clear()
- */
- public function clear() {
- return zend_shm_cache_clear();
- }
-}
\ No newline at end of file
+ /*
+ * (non-PHPdoc) @see AbstractWindCache::clear()
+ */
+ public function clear()
+ {
+ return zend_shm_cache_clear();
+ }
+}
diff --git a/wind/command/WindCommandApplication.php b/wind/command/WindCommandApplication.php
index 52e61c86..95126f18 100644
--- a/wind/command/WindCommandApplication.php
+++ b/wind/command/WindCommandApplication.php
@@ -5,222 +5,64 @@
* @author Shi Long
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindCommandApplication.php 3859 2012-12-18 09:25:51Z yishuo $
* @package command
*/
-class WindCommandApplication extends WindModule implements IWindApplication {
-
- /**
- * @var WindCommandView
- */
- protected $windView = null;
-
- /**
- * @var WindCommandRouter
- */
- protected $handlerAdapter = null;
- /**
- * @var WindCommandRequest
- */
- protected $request;
- /**
- * @var WindCommandResponse
- */
- protected $response;
- /**
- * @var WindFactory
- */
- protected $windFactory = null;
- protected $defaultModule = array(
- 'controller-path' => 'controller',
- 'controller-suffix' => 'Controller',
- 'error-handler' => 'WIND:command.WindCommandErrorHandler');
+class WindCommandApplication extends AbstractWindApplication
+{
+ /**
+ * 显示帮助信息
+ *
+ * @param string $className
+ * @param WindException $e
+ */
+ protected function help($className, $e = null)
+ {
+ $helps = array();
+ $helps[10] = 'usage: command [options] [args]';
+ $helps[11] = 'Valid options:';
+ $helps[12] = $this->handlerAdapter->getModuleKey().' routing information,the name of application module';
+ $helps[13] = $this->handlerAdapter->getControllerKey().' routing information,the name of controller';
+ $helps[14] = $this->handlerAdapter->getActionKey().' routing information,the name of action';
+ $helps[15] = $this->handlerAdapter->getParamKey().' the parameters of the method [action]';
+ if (class_exists($className)) {
+ /* @var $handler WindCommandController */
+ $handler = new $className();
+ $action = $this->handlerAdapter->getAction();
+ if ($action !== 'run') {
+ $action = $handler->resolvedActionName(
+ $this->handlerAdapter->getAction());
+ }
+ if (!method_exists($handler, $action)) {
+ return;
+ }
+ $method = new ReflectionMethod($handler, $action);
+ $helps[20] = "\r\nlist -p [paraments] of '$className::$action' \r\n";
+ $method = $method->getParameters();
+ $i = 21;
+ foreach ($method as $value) {
+ $helps[$i++] = $value;
+ }
+ }
+ if ($e !== null) {
+ $helps[0] = $e->getMessage()."\r\n";
+ }
+ exit(implode("\r\n", $helps));
+ }
- /**
- * 应用初始化操作
- *
- * @param WindCommandRequest $request
- * @param WindCommandResponse $response
- * @param WindFactory $factory
- */
- public function __construct($request, $factory) {
- $this->request = $request;
- $this->response = $request->getResponse();
- $this->windFactory = $factory;
- }
-
- /* (non-PHPdoc)
- * @see IWindApplication::run()
- */
- public function run() {
- $module = $this->getModules($this->_getHandlerAdapter()->getModule());
- $handlerPath = $module['controller-path'] . '.' . ucfirst($this->handlerAdapter->getController()) . $module['controller-suffix'];
- $className = Wind::import($handlerPath);
- if ($this->handlerAdapter->isHelp()) {
- $this->help($className);
- }
- if (!class_exists($className)) throw new WindException(
- "Your requested '$handlerPath' was not found on this server.");
-
- try {
- $handler = new $className();
- $handler->setDelayAttributes(
- array('errorMessage' => array('ref' => 'errorMessage'), 'forward' => array('ref' => 'forward')));
- $handler->doAction($this->handlerAdapter);
- } catch (WindException $e) {
- $this->help($className, $e);
- }
- }
+ /* (non-PHPdoc)
+ * @see AbstractWindApplication::doDispatch()
+ */
+ public function doDispatch($forward)
+ {
+ // TODO Auto-generated method stub
+ }
- /**
- * 显示帮助信息
- *
- * @param string $className
- * @param WindException $e
- */
- protected function help($className, $e = null) {
- $helps = array();
- $helps[10] = 'usage: command [options] [args]';
- $helps[11] = 'Valid options:';
- $helps[12] = $this->handlerAdapter->getModuleKey() . ' routing information,the name of application module';
- $helps[13] = $this->handlerAdapter->getControllerKey() . ' routing information,the name of controller';
- $helps[14] = $this->handlerAdapter->getActionKey() . ' routing information,the name of action';
- $helps[15] = $this->handlerAdapter->getParamKey() . ' the parameters of the method [action]';
- if (class_exists($className)) {
- /*@var $handler WindCommandController */
- $handler = new $className();
- $action = $this->handlerAdapter->getAction();
- if ($action !== 'run') $action = $handler->resolvedActionName($this->handlerAdapter->getAction());
- if (!method_exists($handler, $action)) return;
- $method = new ReflectionMethod($handler, $action);
- $helps[20] = "\r\nlist -p [paraments] of '$className::$action' \r\n";
- $method = $method->getParameters();
- $i = 21;
- foreach ($method as $value) {
- $helps[$i++] = $value;
- }
- }
- if ($e !== null) $helps[0] = $e->getMessage() . "\r\n";
- exit(implode("\r\n", $helps));
- }
-
- /* (non-PHPdoc)
- * @see WindModule::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- if ($default = $this->getModules('default')) {
- $this->defaultModule = WindUtility::mergeArray($this->defaultModule, $default);
- }
- }
-
- /**
- * 添加module配置
- *
- * controller
- *
- * Controller
- *
- * WIND:command.WindCommandErrorHandler
- *
- *
- * @param string $name module名称
- * @param array $config 配置数组
- * @param boolean $replace 如果module已经存在是否覆盖他 默认值为false不进行覆盖
- * @return array
- */
- public function setModules($name, $config, $replace = false) {
- if ($replace || !isset($this->_config['modules'][$name])) {
- $this->_config['modules'][$name] = WindUtility::mergeArray($this->defaultModule, (array) $config);
- }
- return $this->_config['modules'][$name];
- }
-
- /**
- * 获得module配置,$name为空时返回当前module配置
- *
- * @param string $name module名称 默认为空
- * @return array
- * @throws WindActionException
- * @throws WindException
- */
- public function getModules($name = '') {
- if ($name === '') $name = $this->handlerAdapter->getModule();
- $_module = $this->getConfig('modules', $name, array());
- if (!isset($_module['_verified'])) {
- $_module = WindUtility::mergeArray($this->defaultModule, $_module);
- $_module['_verified'] = true;
- $this->_config['modules'][$name] = $_module;
- }
- return $_module;
- }
-
- /**
- * 获得组件对象
- *
- * @param string $componentName 组件名称呢个
- * @return object
- */
- public function getComponent($componentName, $args = array()) {
- return $this->windFactory->getInstance($componentName, $args);
- }
-
- /**
- * 处理错误请求
- *
- * 根据错误请求的相关信息,将程序转向到错误处理句柄进行错误处理
- * @param WindActionException actionException
- * @return void
- * @throws WindFinalException
- */
- protected function sendErrorMessage($exception) {
- $moduleName = $this->handlerAdapter->getModule();
- if ($moduleName === 'error') throw new WindFinalException($exception->getMessage());
- $errorMessage = null;
- if ($exception instanceof WindActionException) $errorMessage = $exception->getError();
- if (!$errorMessage) {
- $errorMessage = $this->getComponent('errorMessage');
- $errorMessage->addError($exception->getMessage());
- }
- if (!$_errorAction = $errorMessage->getErrorAction()) {
- $module = $this->getModules($moduleName);
- if (empty($module)) $module = $this->getModules('default');
- preg_match("/([a-zA-Z]*)$/", @$module['error-handler'], $matchs);
- $_errorHandler = trim(substr(@$module['error-handler'], 0, -(strlen(@$matchs[0]) + 1)));
- $_errorAction = 'error/' . @$matchs[0] . '/run/';
- $this->setModules('error',
- array('controller-path' => $_errorHandler, 'controller-suffix' => '', 'error-handler' => ''));
- }
- $this->handlerAdapter->setModule('error');
- $this->handlerAdapter->setController($matchs[0]);
- Wind::getApp()->getRequest()->setAttribute(array($errorMessage->getError(), $exception->getCode()), 'argv');
- Wind::getApp()->run();
- }
-
- /**
- * @return WindFactory
- */
- public function getWindFactory() {
- return $this->windFactory;
- }
-
- /**
- * 返回WindCommandRequest
- *
- * @return WindCommandRequest $request
- */
- public function getRequest() {
- return $this->request;
- }
-
- /**
- * 返回WindCommandResponse
- *
- * @return WindCommandResponse $response
- */
- public function getResponse() {
- return $this->response;
- }
+ /* (non-PHPdoc)
+ * @see AbstractWindApplication::sendErrorMessage()
+ */
+ protected function sendErrorMessage($errorMessage, $errorcode)
+ {
+ // TODO Auto-generated method stub
+ }
}
-
-?>
\ No newline at end of file
diff --git a/wind/command/WindCommandController.php b/wind/command/WindCommandController.php
index 8afb3199..fd45acca 100644
--- a/wind/command/WindCommandController.php
+++ b/wind/command/WindCommandController.php
@@ -5,98 +5,177 @@
* @author Shi Long
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindCommandController.php 3859 2012-12-18 09:25:51Z yishuo $
* @package command
*/
-abstract class WindCommandController extends WindModule {
-
- /**
- * 默认的操作处理方法
- *
- * @return void
- */
- abstract public function run();
-
- /**
- * action操作开始前调用
- *
- * @param AbstractWindRouter $handlerAdapter
- */
- protected function beforeAction($handlerAdapter) {}
-
- /**
- * action操作结束后调用
- *
- * @param AbstractWindRouter $handlerAdapter
- */
- protected function afterAction($handlerAdapter) {}
-
- /* (non-PHPdoc)
- * @see IWindController::doAction()
- */
- public function doAction($handlerAdapter) {
- $this->beforeAction($handlerAdapter);
- $action = $handlerAdapter->getAction();
- if ($action !== 'run') $action = $this->resolvedActionName($action);
- if (in_array($action, array('doAction', 'beforeAction', 'afterAction', 'resolvedActionName')) || !method_exists(
- $this, $action)) {
- throw new WindException('[command.WindCommandController.doAction] ',
- WindException::ERROR_CLASS_METHOD_NOT_EXIST);
- }
- $method = new ReflectionMethod($this, $action);
- if ($method->isProtected()) throw new WindException('[command.WindCommandController.doAction] ',
- WindException::ERROR_CLASS_METHOD_NOT_EXIST);
- $args = $this->getRequest()->getRequest('argv');
- call_user_func_array(array($this, $action), $args);
- $this->afterAction($handlerAdapter);
- }
-
- /**
- * 显示错误信息
- *
- * @param string $error
- */
- protected function showError($error) {
- echo "Error: " . $error . "\r\n";
- echo "Try: command help -m someModule -c someController -a someAction";
- exit();
- }
-
- /**
- * 显示信息
- *
- * @param string $message 默认为空字符串
- * @return void
- */
- protected function showMessage($message) {
- if (is_array($message)) {
- foreach ($message as $key => $value)
- echo "'" . $key . "' => '" . $value . "',\r\n";
- } else
- echo $message, "\r\n";
- }
-
- /**
- * 解析action操作方法名称
- *
- * 默认解析规则,在请求的action名称后加'Action'后缀
- * 请求的action为 'add',则对应的处理方法名为 'addAction',可以通过覆盖本方法,修改解析规则
- * @param string $action
- * @return void
- */
- public function resolvedActionName($action) {
- return $action . 'Action';
- }
-
- /**
- * 读取输入行
- *
- * @return string
- */
- protected function getLine($message) {
- echo $message;
- return trim(fgets(STDIN));
- }
-}
+abstract class WindCommandController extends WindModule implements IWindController
+{
+ /**
+ * 默认的操作处理方法
+ *
+ */
+ abstract public function run();
+
+ /**
+ * action操作开始前调用
+ *
+ * @param AbstractWindRouter $handlerAdapter
+ */
+ protected function beforeAction($handlerAdapter)
+ {
+ }
+
+ /**
+ * action操作结束后调用
+ *
+ * @param AbstractWindRouter $handlerAdapter
+ */
+ protected function afterAction($handlerAdapter)
+ {
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindController::doAction()
+ */
+ public function doAction($handlerAdapter)
+ {
+ $this->beforeAction($handlerAdapter);
+ $action = $handlerAdapter->getAction();
+ if ($action !== 'run') {
+ $action = $this->resolvedActionName($action);
+ }
+ $args = $this->getRequest()->getRequest('argv');
+ call_user_func_array(array($this, $action), $args);
+ print_r($args);
+ if ($this->errorMessage !== null) {
+ $this->getErrorMessage()->sendError();
+ }
+ $this->afterAction($handlerAdapter);
+
+ return $this->forward;
+ }
+
+ /**
+ * 设置模板数据
+ *
+ * @param string|array|object $data
+ * @param string $key
+ */
+ protected function setOutput($data, $key = '')
+ {
+ $this->getForward()->setVars($data, $key);
+ }
+
+ /* 错误处理 */
+ /**
+ * 添加错误信息
+ *
+ * @param string $message
+ * @param string $key 默认为空字符串
+ */
+ protected function addMessage($message, $key = '')
+ {
+ $this->getErrorMessage()->addError($message, $key);
+ }
+
+ /**
+ * 发送一个错误请求
+ *
+ * @param string $message 默认为空字符串
+ * @param string $key 默认为空字符串
+ * @param string $errorAction 默认为空字符串
+ */
+ protected function showMessage($message = '', $key = '', $errorAction = '')
+ {
+ $this->addMessage($message, $key);
+ $errorAction && $this->getErrorMessage()->setErrorAction($errorAction);
+ $this->getErrorMessage()->sendError();
+ }
+
+ // /**
+ // * 显示错误信息
+ // *
+ // * @param string $error
+ // */
+ // protected function showError($error) {
+ // echo "Error: " . $error . "\r\n";
+ // echo "Try: command help -m someModule -c someController -a someAction";
+ // exit();
+ // }
+
-?>
\ No newline at end of file
+ // /**
+ // * 显示信息
+ // *
+ // * @param string $message 默认为空字符串
+ // * @return void
+ // */
+ // protected function showMessage($message) {
+ // if (is_array($message)) {
+ // foreach ($message as $key => $value)
+ // echo "'" . $key . "' => '" . $value . "',\r\n";
+ // } else
+ // echo $message, "\r\n";
+ // }
+
+
+ /**
+ * 解析action操作方法名称
+ *
+ * 默认解析规则,在请求的action名称后加'Action'后缀
+ * 请求的action为 'add',则对应的处理方法名为 'addAction',可以通过覆盖本方法,修改解析规则
+ * @param string $action
+ */
+ protected function resolvedActionName($action)
+ {
+ return $action.'Action';
+ }
+
+ /**
+ * 读取输入行
+ *
+ * @return string
+ */
+ protected function getLine($message)
+ {
+ echo $message;
+
+ return trim(fgets(STDIN));
+ }
+
+ /**
+ *
+ * @return WindForward
+ */
+ public function getForward()
+ {
+ return $this->_getForward();
+ }
+
+ /**
+ *
+ * @return WindErrorMessage
+ */
+ public function getErrorMessage()
+ {
+ return $this->_getErrorMessage();
+ }
+
+ /**
+ *
+ * @param WindForward $forward
+ */
+ public function setForward($forward)
+ {
+ $this->forward = $forward;
+ }
+
+ /**
+ *
+ * @param WindErrorMessage $errorMessage
+ */
+ public function setErrorMessage($errorMessage)
+ {
+ $this->errorMessage = $errorMessage;
+ }
+}
diff --git a/wind/command/WindCommandError.php b/wind/command/WindCommandError.php
new file mode 100644
index 00000000..78e4f78e
--- /dev/null
+++ b/wind/command/WindCommandError.php
@@ -0,0 +1,21 @@
+
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: codetemplates(windframework_docs_zend_8.0).xml 2781 2011-09-22
+ * 03:59:17Z yishuo $
+ * @package wind
+ */
+class WindCommandError extends WindError
+{
+ /*
+ * (non-PHPdoc) @see WindError::showErrorMessage()
+ */
+ protected function showErrorMessage($message, $file, $line, $trace, $errorcode)
+ {
+ // TODO
+ }
+}
diff --git a/wind/command/WindCommandFrontController.php b/wind/command/WindCommandFrontController.php
index fc43e576..54c42464 100644
--- a/wind/command/WindCommandFrontController.php
+++ b/wind/command/WindCommandFrontController.php
@@ -1,110 +1,95 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindCommandFrontController.php 3859 2012-12-18 09:25:51Z yishuo $
* @package command
*/
-class WindCommandFrontController extends AbstractWindFrontController {
-
- /* (non-PHPdoc)
- * @see AbstractWindFrontController::run()
- */
- public function run() {
- parent::run();
- exit("Completely Done~\r\n");
- }
+class WindCommandFrontController extends AbstractWindFrontController
+{
+ /*
+ * (non-PHPdoc) @see AbstractWindFrontController::createApplication()
+ */
+ public function createApplication($config, $factory)
+ {
+ $request = $factory->getInstance('request');
+ $response = $factory->getInstance('response');
+ $application = new WindCommandApplication($request, $response, $factory);
+ $application->setConfig($config);
+
+ return $application;
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindFrontController::_components()
+ */
+ protected function _components()
+ {
+ return array(
+ 'request' => array(
+ 'path' => 'WindCommandRequest',
+ 'scope' => 'application', ),
+ 'response' => array(
+ 'path' => 'WindCommandResponse',
+ 'scope' => 'application', ),
+ 'router' => array('path' => 'WindCommandRouter', 'scope' => 'application'),
+ 'windView' => array('path' => 'WindCommandView', 'scope' => 'prototype'),
+ 'db' => array('path' => 'WindConnection', 'scope' => 'singleton'),
+ 'configParser' => array(
+ 'path' => 'WindConfigParser',
+ 'scope' => 'singleton', ),
+ 'error' => array('path' => 'WIND:command.WindCommandError', 'scope' => 'application'),
+ 'errorMessage' => array('path' => 'WindErrorMessage', 'scope' => 'prototype'),
+ 'windLogger' => array(
+ 'path' => 'WindLogger',
+ 'scope' => 'singleton',
+ 'destroy' => 'flush',
+ 'constructor-args' => array(
+ '0' => array('value' => 'DATA:log'),
+ '1' => array('value' => '2'), ), ),
+ 'i18n' => array(
+ 'path' => 'WindLangResource',
+ 'scope' => 'singleton',
+ 'config' => array('path' => 'i18n'), ), );
+ }
+
+ /*
+ * (non-PHPdoc) @see AbstractWindFrontController::_loadBaseLib()
+ */
+ protected function _loadBaseLib()
+ {
+ Wind::$_imports += array(
+ 'WIND:i18n.WindLangResource' => 'WindLangResource',
+ 'WIND:log.WindLogger' => 'WindLogger',
+ 'WIND:base.WindErrorMessage' => 'WindErrorMessage',
+ 'WIND:parser.WindConfigParser' => 'WindConfigParser',
+ 'WIND:db.WindConnection' => 'WindConnection',
+ 'WIND:router.WindCommandRouter' => 'WindCommandRouter',
+
+ 'WIND:command.WindCommandView' => 'WindCommandView',
+ 'WIND:command.WindCommandErrorHandler' => 'WindCommandErrorHandler',
+ 'WIND:command.WindCmmandRequest' => 'WindCommandRequest',
+ 'WIND:command.WindCommandResponse' => 'WindCommandResponse',
+ 'WIND:command.WindCommandController' => 'WindCommandController',
+ 'WIND:command.WindCommandApplication' => 'WindCommandApplication', );
- /**
- * @return WindHttpRequest
- */
- public function getRequest() {
- if ($this->_request === null) {
- $this->_request = WindFactory::createInstance('WindCommandRequest');
- }
- return $this->_request;
- }
+ Wind::$_classes += array(
+ 'WindLangResource' => 'i18n/WindLangResource',
+ 'WindLogger' => 'log/WindLogger',
+ 'WindErrorMessage' => 'base/WindErrorMessage',
+ 'WindConfigParser' => 'parser/WindConfigParser',
+ 'WindConnection' => 'db/WindConnection',
+ 'WindCommandRouter' => 'router/WindCommandRouter',
- /**
- * 创建并返回应用
- *
- * @return WindCommandApplication
- */
- protected function _createApplication() {
- $application = new WindCommandApplication($this->getRequest(), $this->getFactory());
- $application->setDelayAttributes(
- array('windView' => array('ref' => 'windView'), 'handlerAdapter' => array('ref' => 'router')));
- return $application;
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindFrontController::showErrorMessage()
- */
- protected function showErrorMessage($message, $file, $line, $trace, $errorcode) {
- $log = $message . "\r\n" . $file . ":" . $line . "\r\n";
- list($fileLines, $trace) = WindUtility::crash($file, $line, $trace);
- foreach ($trace as $key => $value) {
- $log .= $value . "\r\n";
- }
- if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->error($log, 'error', true);
- exit($log);
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindFrontController::_components()
- */
- protected function _components() {
- return array(
- 'router' => array('path' => 'WIND:command.WindCommandRouter', 'scope' => 'application'),
- 'windView' => array('path' => 'WIND:command.WindCommandView', 'scope' => 'prototype'),
- 'db' => array('path' => 'WIND:db.WindConnection', 'scope' => 'singleton'),
- 'configParser' => array('path' => 'WIND:parser.WindConfigParser', 'scope' => 'singleton'),
- 'errorMessage' => array('path' => 'WIND:base.WindErrorMessage', 'scope' => 'prototype'),
- 'windLogger' => array(
- 'path' => 'WIND:log.WindLogger',
- 'scope' => 'singleton',
- 'destroy' => 'flush',
- 'constructor-args' => array('0' => array('value' => 'DATA:log'), '1' => array('value' => '2'))),
- 'i18n' => array(
- 'path' => 'WIND:i18n.WindLangResource',
- 'scope' => 'singleton',
- 'config' => array('path' => 'i18n')));
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindFrontController::_loadBaseLib()
- */
- protected function _loadBaseLib() {
- Wind::$_imports += array(
- 'WIND:i18n.WindLangResource' => 'WindLangResource',
- 'WIND:log.WindLogger' => 'WindLogger',
- 'WIND:base.WindErrorMessage' => 'WindErrorMessage',
- 'WIND:parser.WindConfigParser' => 'WindConfigParser',
- 'WIND:db.WindConnection' => 'WindConnection',
- 'WIND:command.WindCommandView' => 'WindCommandView',
- 'WIND:command.WindCommandRouter' => 'WindCommandRouter',
- 'WIND:command.WindCommandErrorHandler' => 'WindCommandErrorHandler',
- 'WIND:command.WindCmmandRequest' => 'WindCommandRequest',
- 'WIND:command.WindCommandResponse' => 'WindCommandResponse',
- 'WIND:command.WindCommandController' => 'WindCommandController',
- 'WIND:command.WindCommandApplication' => 'WindCommandApplication');
-
- Wind::$_classes += array(
- 'WindLangResource' => 'i18n/WindLangResource',
- 'WindLogger' => 'log/WindLogger',
- 'WindErrorMessage' => 'base/WindErrorMessage',
- 'WindConfigParser' => 'parser/WindConfigParser',
- 'WindConnection' => 'db/WindConnection',
- 'WindCommandView' => 'command/WindCommandView',
- 'WindCommandRouter' => 'command/WindCommandRouter',
- 'WindCommandApplication' => 'command/WindCommandApplication',
- 'WindCommandController' => 'command/WindCommandController',
- 'WindCommandErrorHandler' => 'command/WindCommandErrorHandler',
- 'WindCommandRequest' => 'command/WindCommandRequest',
- 'WindCommandResponse' => 'command/WindCommandResponse');
- }
+ 'WindCommandView' => 'command/WindCommandView',
+ 'WindCommandApplication' => 'command/WindCommandApplication',
+ 'WindCommandController' => 'command/WindCommandController',
+ 'WindCommandErrorHandler' => 'command/WindCommandErrorHandler',
+ 'WindCommandRequest' => 'command/WindCommandRequest',
+ 'WindCommandResponse' => 'command/WindCommandResponse', );
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/command/WindCommandRequest.php b/wind/command/WindCommandRequest.php
index db90e53b..68646293 100644
--- a/wind/command/WindCommandRequest.php
+++ b/wind/command/WindCommandRequest.php
@@ -5,126 +5,146 @@
* @author Shi Long
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindCommandRequest.php 3668 2012-06-12 03:36:18Z yishuo $
* @package command
*/
-class WindCommandRequest implements IWindRequest {
- /**
- * 请求参数信息
- *
- * @var array
- */
- private $_attribute = array();
-
- /**
- * 应答对象
- *
- * @var WindCommandResponse
- */
- private $_response = null;
+class WindCommandRequest implements IWindRequest
+{
+ /**
+ * 请求参数信息
+ *
+ * @var array
+ */
+ private $_attribute = array();
- /**
- * 获得用户请求的数据
- *
- * @param string $key 获取的参数name,默认为null将获得$_GET和$_POST两个数组的所有值
- * @param mixed $defaultValue 当获取值失败的时候返回缺省值,默认值为null
- * @return mixed
- */
- public function getRequest($key, $defaultValue = null) {
- if (isset($_SERVER[$key])) return $_SERVER[$key];
- if (isset($_ENV[$key])) return $_ENV[$key];
- return $defaultValue;
- }
+ /**
+ * 应答对象
+ *
+ * @var WindCommandResponse
+ */
+ private $_response = null;
- /**
- * 根据名称获得服务器和执行环境信息
- *
- * 主要获取的依次顺序为:_attribute、$_SERVER、$_ENV
- *
- * @param string $name 获取数据的key值
- * @param string $defaultValue 设置缺省值,当获取值失败的时候返回缺省值,默认该值为空字串
- * @return string|object|array 返回获得值
- */
- public function getAttribute($key, $defaultValue = '') {
- if (isset($this->_attribute[$key]))
- return $this->_attribute[$key];
- else if (isset($_SERVER[$key]))
- return $_SERVER[$key];
- else if (isset($_ENV[$key]))
- return $_ENV[$key];
- else
- return $defaultValue;
- }
+ /**
+ * 获得用户请求的数据
+ *
+ * @param string $key 获取的参数name,默认为null将获得$_GET和$_POST两个数组的所有值
+ * @param mixed $defaultValue 当获取值失败的时候返回缺省值,默认值为null
+ * @return mixed
+ */
+ public function getRequest($key, $defaultValue = null)
+ {
+ if (isset($_SERVER[$key])) {
+ return $_SERVER[$key];
+ }
+ if (isset($_ENV[$key])) {
+ return $_ENV[$key];
+ }
- /**
- * 设置属性数据
- *
- * @param string|array|object $data 需要设置的数据
- * @param string $key 设置的数据保存用的key,默认为空,当数组和object类型的时候将会执行array_merge操作
- * @return void
- */
- public function setAttribute($data, $key = '') {
- if ($key) {
- $this->_attribute[$key] = $data;
- return;
- }
- if (is_object($data)) $data = get_object_vars($data);
- if (is_array($data)) $this->_attribute = array_merge($this->_attribute, $data);
- }
+ return $defaultValue;
+ }
- /**
- * 获得请求类型
- *
- * @return string
- */
- public function getRequestType() {
- return 'command';
- }
-
- /* (non-PHPdoc)
- * @see IWindRequest::getPathInfo()
- */
- public function getPathInfo() {
- return '';
- }
-
- /* (non-PHPdoc)
- * @see IWindRequest::getHostInfo()
- */
- public function getHostInfo() {
- return '';
- }
-
- /* (non-PHPdoc)
- * @see IWindRequest::getServerName()
- */
- public function getServerName() {
- return '';
- }
-
- /* (non-PHPdoc)
- * @see IWindRequest::getServerPort()
- */
- public function getServerPort() {
- return '';
- }
-
- /* (non-PHPdoc)
- * @see IWindRequest::getResponse()
- */
- public function getResponse() {
- if ($this->_response === null) {
- $this->_response = new WindCommandResponse();
- }
- return $this->_response;
- }
-
- /* (non-PHPdoc)
- * @see IWindRequest::getAcceptLanguage()
- */
- public function getAcceptLanguage() {
- return '';
- }
-}
+ /**
+ * 根据名称获得服务器和执行环境信息
+ *
+ * 主要获取的依次顺序为:_attribute、$_SERVER、$_ENV
+ *
+ * @param string $name 获取数据的key值
+ * @param string $defaultValue 设置缺省值,当获取值失败的时候返回缺省值,默认该值为空字串
+ * @return string|object|array 返回获得值
+ */
+ public function getAttribute($key, $defaultValue = '')
+ {
+ if (isset($this->_attribute[$key])) {
+ return $this->_attribute[$key];
+ } elseif (isset($_SERVER[$key])) {
+ return $_SERVER[$key];
+ } elseif (isset($_ENV[$key])) {
+ return $_ENV[$key];
+ } else {
+ return $defaultValue;
+ }
+ }
+
+ /**
+ * 设置属性数据
+ *
+ * @param string|array|object $data 需要设置的数据
+ * @param string $key 设置的数据保存用的key,默认为空,当数组和object类型的时候将会执行array_merge操作
+ */
+ public function setAttribute($data, $key = '')
+ {
+ if ($key) {
+ $this->_attribute[$key] = $data;
+
+ return;
+ }
+ if (is_object($data)) {
+ $data = get_object_vars($data);
+ }
+ if (is_array($data)) {
+ $this->_attribute = array_merge($this->_attribute, $data);
+ }
+ }
+
+ /**
+ * 获得请求类型
+ *
+ * @return string
+ */
+ public function getRequestType()
+ {
+ return 'command';
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindRequest::getPathInfo()
+ */
+ public function getPathInfo()
+ {
+ return '';
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindRequest::getHostInfo()
+ */
+ public function getHostInfo()
+ {
+ return '';
+ }
-?>
\ No newline at end of file
+ /* (non-PHPdoc)
+ * @see IWindRequest::getServerName()
+ */
+ public function getServerName()
+ {
+ return '';
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindRequest::getServerPort()
+ */
+ public function getServerPort()
+ {
+ return '';
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindRequest::getResponse()
+ */
+ public function getResponse()
+ {
+ if ($this->_response === null) {
+ $this->_response = new WindCommandResponse();
+ }
+
+ return $this->_response;
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindRequest::getAcceptLanguage()
+ */
+ public function getAcceptLanguage()
+ {
+ return '';
+ }
+}
diff --git a/wind/command/WindCommandResponse.php b/wind/command/WindCommandResponse.php
index 44612cff..0ed45799 100644
--- a/wind/command/WindCommandResponse.php
+++ b/wind/command/WindCommandResponse.php
@@ -5,93 +5,102 @@
* @author Shi Long
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindCommandResponse.php 3668 2012-06-12 03:36:18Z yishuo $
* @package command
*/
-class WindCommandResponse implements IWindResponse {
- private $_output = '';
- private $charset = 'utf-8';
+class WindCommandResponse implements IWindResponse
+{
+ private $_output = '';
+ private $charset = 'utf-8';
- /**
- * 发送响应信息
- *
- * @return void
- */
- public function sendResponse() {
- echo $this->_output;
- }
+ /**
+ * 发送响应信息
+ *
+ */
+ public function sendResponse()
+ {
+ echo $this->_output;
+ }
- /**
- * 设置输出信息
- *
- * @param string $output
- */
- public function setOutput($output) {
- $this->_output = $output;
- }
+ /**
+ * 设置输出信息
+ *
+ * @param string $output
+ */
+ public function setOutput($output)
+ {
+ $this->_output = $output;
+ }
- /**
- * @return array
- */
- public function getHeaders() {
- return array();
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::getData()
- */
- public function getData() {
- return array();
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::setData()
- */
- public function setData($data, $key = '') {
- return false;
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::getCharset()
- */
- public function getCharset() {
- return $this->charset;
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::setCharset()
- */
- public function setCharset($_charset) {
- return $this->charset = $_charset;
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::setBody()
- */
- public function setBody($content, $name = 'default') {
- return false;
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::sendError()
- */
- public function sendError($status = self::W_NOT_FOUND, $message = '') {
- return false;
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::sendBody()
- */
- public function sendBody() {
- return false;
- }
-
- /* (non-PHPdoc)
- * @see IWindResponse::sendHeaders()
- */
- public function sendHeaders() {
- return false;
- }
-}
+ /**
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return array();
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::getData()
+ */
+ public function getData()
+ {
+ return array();
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::setData()
+ */
+ public function setData($data, $key = '')
+ {
+ return false;
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::getCharset()
+ */
+ public function getCharset()
+ {
+ return $this->charset;
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::setCharset()
+ */
+ public function setCharset($_charset)
+ {
+ return $this->charset = $_charset;
+ }
-?>
\ No newline at end of file
+ /* (non-PHPdoc)
+ * @see IWindResponse::setBody()
+ */
+ public function setBody($content, $name = 'default')
+ {
+ return false;
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::sendError()
+ */
+ public function sendError($status = self::W_NOT_FOUND, $message = '')
+ {
+ return false;
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::sendBody()
+ */
+ public function sendBody()
+ {
+ return false;
+ }
+
+ /* (non-PHPdoc)
+ * @see IWindResponse::sendHeaders()
+ */
+ public function sendHeaders()
+ {
+ return false;
+ }
+}
diff --git a/wind/command/WindCommandRouter.php b/wind/command/WindCommandRouter.php
deleted file mode 100644
index 1bd6761f..00000000
--- a/wind/command/WindCommandRouter.php
+++ /dev/null
@@ -1,101 +0,0 @@
-
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package command
- */
-class WindCommandRouter extends AbstractWindRouter {
- protected $moduleKey = '-m,module,--module';
- protected $controllerKey = '-c,controller,--controller';
- protected $actionKey = '-a,action,--action';
- protected $helpKey = '-h,help,--help';
- protected $paramKey = '-p,param,--param';
- protected $help = false;
- protected $cmd = '';
- /**
- * @var WindCommandRequest
- */
- private $request = null;
-
- /* (non-PHPdoc)
- * @see AbstractWindRouter::route()
- */
- public function route($request) {
- $this->request = $request;
- $this->_action = $this->action;
- $this->_controller = $this->controller;
- $this->_module = $this->module;
- if (!empty($this->_config['routes'])) {
- $params = $this->getHandler()->handle($request);
- $this->setParams($params, $request);
- } else {
- $args = $request->getRequest('argv', array());
- $this->cmd = $args[0];
- $_count = count($args);
- for ($i = 1; $i < $_count; $i++) {
- if (in_array($args[$i], explode(',', $this->helpKey))) {
- $this->help = true;
- } elseif (in_array($args[$i], explode(',', $this->moduleKey))) {
- $this->module = $args[++$i];
- } elseif (in_array($args[$i], explode(',', $this->controllerKey))) {
- $this->controller = $args[++$i];
- } elseif (in_array($args[$i], explode(',', $this->actionKey))) {
- $this->action = $args[++$i];
- } elseif (in_array($args[$i], explode(',', $this->paramKey))) {
- $_SERVER['argv'] = array_slice($args, $i + 1);
- break;
- }
- }
- }
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindRouter::assemble()
- */
- public function assemble($action, $args = array(), $route = '') {
- return '';
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindRouter::setParams()
- */
- protected function setParams($params, $request) {
- /* @var $request WindCommandRequest */
- $_SERVER['argv'] = isset($params[$this->paramKey]) ? $params[$this->paramKey] : array();
- isset($params[$this->moduleKey]) && $this->setModule($params[$this->moduleKey]);
- isset($params[$this->controllerKey]) && $this->setController($params[$this->controllerKey]);
- isset($params[$this->actionKey]) && $this->setAction($params[$this->actionKey]);
- }
-
- /**
- * 是否是请求帮助
- *
- * @return boolean
- */
- public function isHelp() {
- return $this->help;
- }
-
- /**
- * 返回当前命令
- *
- * @return string
- */
- public function getCmd() {
- return $this->cmd;
- }
-
- /**
- * @return string
- */
- public function getParamKey() {
- return $this->paramKey;
- }
-}
-
-?>
\ No newline at end of file
diff --git a/wind/convert/IWindConverter.php b/wind/convert/IWindConverter.php
index 98411b0d..8d2060df 100644
--- a/wind/convert/IWindConverter.php
+++ b/wind/convert/IWindConverter.php
@@ -1,23 +1,21 @@
2011-10-19
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: IWindConverter.php 3016 2011-10-20 02:23:08Z yishuo $
* @package convert
*/
-interface IWindConverter {
-
- /**
- * 编码转化
- *
- * 对输入的字符串进行从原编码到目标编码的转化,请确定原编码与目标编码
- * @param string $srcText
- * @return string 转化后的编码
- */
- public function convert($str);
+interface IWindConverter
+{
+ /**
+ * 编码转化
+ *
+ * 对输入的字符串进行从原编码到目标编码的转化,请确定原编码与目标编码
+ * @param string $srcText
+ * @return string 转化后的编码
+ */
+ public function convert($str);
}
-
-?>
\ No newline at end of file
diff --git a/wind/convert/WindGeneralConverter.php b/wind/convert/WindGeneralConverter.php
index b0901e67..3547b230 100644
--- a/wind/convert/WindGeneralConverter.php
+++ b/wind/convert/WindGeneralConverter.php
@@ -1,330 +1,354 @@
2011-10-19
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindGeneralConverter.php 3016 2011-10-20 02:23:08Z yishuo $
* @package convert
*/
-class WindGeneralConverter extends WindModule implements IWindConverter {
- protected $tableName = './encode/encode.table';
- protected $tableHandle = 0;
- protected $encodeLang = '';
- protected $iconvEnabled = false;
- protected $tableIndex = array();
- protected $tableEncode = array();
-
- protected $IndexPoint = array(
- 'GBKtoUTF8' => 0,
- 'GBKtoUNICODE' => 0,
- 'BIG5toUTF8' => 1024,
- 'BIG5toUNICODE' => 1024,
- 'UTF8toGBK' => 512,
- 'UTF8toBIG5' => 1536);
+class WindGeneralConverter extends WindModule implements IWindConverter
+{
+ protected $tableName = './encode/encode.table';
+ protected $tableHandle = 0;
+ protected $encodeLang = '';
+ protected $iconvEnabled = false;
+ protected $tableIndex = array();
+ protected $tableEncode = array();
+
+ protected $IndexPoint = array(
+ 'GBKtoUTF8' => 0,
+ 'GBKtoUNICODE' => 0,
+ 'BIG5toUTF8' => 1024,
+ 'BIG5toUNICODE' => 1024,
+ 'UTF8toGBK' => 512,
+ 'UTF8toBIG5' => 1536, );
+
+ /**
+ * @param string $SourceLang
+ * @param string $TargetLang
+ * @param bool $ForceTable
+ */
+ public function WindGeneralConverter($sourceLang = '', $targetLang = '', $forceTable = false)
+ {
+ if ($sourceLang && $targetLang) {
+ $this->initConvert($sourceLang, $targetLang, $forceTable);
+ }
+ }
+
+ /**
+ * 编码转化
+ *
+ * 对输入的字符串进行从原编码到目标编码的转化,请确定原编码与目标编码
+ * @param string $srcText
+ * @param string $SourceLang
+ * @param string $TargetLang
+ * @param bool $ForceTable
+ * @return Ambigous |string|unknown
+ */
+ public function convert($srcText, $sourceLang = '', $targetLang = '', $forceTable = false)
+ {
+ if ($sourceLang && $targetLang) {
+ $this->initConvert($sourceLang, $targetLang, $forceTable);
+ }
+
+ if ($this->encodeLang) {
+ switch ($this->encodeLang) {
+ case 'GBKtoUTF8':
+ return $this->iconvEnabled ? iconv('GBK', 'UTF-8', $srcText) : $this->chstoUTF8($srcText);
+ break;
+ case 'BIG5toUTF8':
+ return $this->iconvEnabled ? iconv('BIG5', 'UTF-8', $srcText) : $this->chstoUTF8($srcText);
+ break;
+ case 'UTF8toGBK':
+ return $this->iconvEnabled ? iconv('UTF-8', 'GBK', $srcText) : $this->utf8toCHS($srcText);
+ break;
+ case 'UTF8toBIG5':
+ return $this->utf8toCHS($srcText);
+ break;
+ case 'GBKtoUNICODE':
+ return $this->chstoUNICODE($srcText, 'GBK');
+ break;
+ case 'BIG5toUNICODE':
+ return $this->chstoUNICODE($srcText, 'BIG5');
+ break;
+ case 'GBKtoBIG5':
+ case 'BIG5toGBK':
+ return $this->chsConvert($srcText, $this->encodeLang);
+ break;
+ }
+ }
+
+ return $srcText;
+ }
+
+ /**
+ * 初始化类
+ *
+ * @param string $SourceLang
+ * @param string $TargetLang
+ * @param bool $ForceTable
+ */
+ protected function initConvert($SourceLang, $targetLang, $forceTable)
+ {
+ if (($SourceLang = $this->_getCharset($SourceLang)) && ($targetLang = $this->_getCharset($targetLang)) && $SourceLang != $targetLang) {
+ $this->encodeLang = $SourceLang.'to'.$targetLang;
+ $this->iconvEnabled = (function_exists('iconv') && $targetLang != 'BIG5' && !$forceTable) ? true : false;
+ $this->iconvEnabled || is_resource($this->tableHandle) || $this->tableHandle = fopen($this->tableName, 'r');
+ }
+ }
+
+ /**
+ * unicode to utf8
+ *
+ * @param string $c
+ * @return string
+ */
+ protected function unicodeToUTF8($c)
+ {
+ if ($c < 0x80) {
+ $c = chr($c);
+ } elseif ($c < 0x800) {
+ $c = chr(0xC0 | $c >> 6).chr(0x80 | $c & 0x3F);
+ } elseif ($c < 0x10000) {
+ $c = chr(0xE0 | $c >> 12).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ } elseif ($c < 0x200000) {
+ $c = chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ } elseif ($c < 0x4000000) {
+ $c = chr(0xF8 | $c >> 24).chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(0x80 | $c >> 6 & 0x3F).chr(
+ 0x80 | $c & 0x3F);
+ } else {
+ $c = chr(0xF8 | $c >> 30).chr(0xF8 | $c >> 24).chr(0xF0 | $c >> 18).chr(0x80 | $c >> 12 & 0x3F).chr(
+ 0x80 | $c >> 6 & 0x3F).chr(0x80 | $c & 0x3F);
+ }
+
+ return $c;
+ }
+
+ /**
+ * BIG5,GBK to Unicode
+ *
+ * @param string $c
+ * @return string
+ */
+ protected function chsUTF8toU($c)
+ {
+ switch (strlen($c)) {
+ case 1:
+ return ord($c);
+ case 2:
+ return ((ord($c[0]) & 0x3F) << 6) + (ord($c[1]) & 0x3F);
+ case 3:
+ return ((ord($c[0]) & 0x1F) << 12) + ((ord($c[1]) & 0x3F) << 6) + (ord($c[2]) & 0x3F);
+ case 4:
+ return ((ord($c[0]) & 0x0F) << 18) + ((ord($c[1]) & 0x3F) << 12) + ((ord($c[2]) & 0x3F) << 6) + (ord(
+ $c[3]) & 0x3F);
+ }
+ }
- /**
- * @param string $SourceLang
- * @param string $TargetLang
- * @param boolean $ForceTable
- */
- public function WindGeneralConverter($sourceLang = '', $targetLang = '', $forceTable = false) {
- if ($sourceLang && $targetLang) $this->initConvert($sourceLang, $targetLang, $forceTable);
- }
+ /**
+ * BIG5,GBK to UTF8
+ *
+ * @param string $srcText
+ * @return Ambigous
+ */
+ protected function chstoUTF8($srcText)
+ {
+ $this->_getTableIndex();
+ $tarText = '';
+ for ($i = 0; $i < strlen($srcText); $i += 2) {
+ $h = ord($srcText[$i]);
+ if ($h > 127 && isset($this->tableIndex[$this->encodeLang][$h])) {
+ $l = ord($srcText[$i + 1]);
+ if (!isset($this->tableEncode[$this->encodeLang][$h][$l])) {
+ fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
+ $this->tableEncode[$this->encodeLang][$h][$l] = $this->unicodeToUTF8(
+ hexdec(bin2hex(fread($this->tableHandle, 2))));
+ }
+ $tarText .= $this->tableEncode[$this->encodeLang][$h][$l];
+ } elseif ($h < 128) {
+ $tarText .= $srcText[$i];
+ $i--;
+ }
+ }
- /**
- * 编码转化
- *
- * 对输入的字符串进行从原编码到目标编码的转化,请确定原编码与目标编码
- * @param string $srcText
- * @param string $SourceLang
- * @param string $TargetLang
- * @param boolean $ForceTable
- * @return Ambigous |string|unknown
- */
- public function convert($srcText, $sourceLang = '', $targetLang = '', $forceTable = false) {
- if ($sourceLang && $targetLang) $this->initConvert($sourceLang, $targetLang, $forceTable);
-
- if ($this->encodeLang) {
- switch ($this->encodeLang) {
- case 'GBKtoUTF8':
- return $this->iconvEnabled ? iconv('GBK', 'UTF-8', $srcText) : $this->chstoUTF8($srcText);
- break;
- case 'BIG5toUTF8':
- return $this->iconvEnabled ? iconv('BIG5', 'UTF-8', $srcText) : $this->chstoUTF8($srcText);
- break;
- case 'UTF8toGBK':
- return $this->iconvEnabled ? iconv('UTF-8', 'GBK', $srcText) : $this->utf8toCHS($srcText);
- break;
- case 'UTF8toBIG5':
- return $this->utf8toCHS($srcText);
- break;
- case 'GBKtoUNICODE':
- return $this->chstoUNICODE($srcText, 'GBK');
- break;
- case 'BIG5toUNICODE':
- return $this->chstoUNICODE($srcText, 'BIG5');
- break;
- case 'GBKtoBIG5':
- case 'BIG5toGBK':
- return $this->chsConvert($srcText, $this->encodeLang);
- break;
- }
- }
- return $srcText;
- }
+ return $tarText;
+ }
- /**
- * 初始化类
- *
- * @param string $SourceLang
- * @param string $TargetLang
- * @param boolean $ForceTable
- */
- protected function initConvert($SourceLang, $targetLang, $forceTable) {
- if (($SourceLang = $this->_getCharset($SourceLang)) && ($targetLang = $this->_getCharset($targetLang)) && $SourceLang != $targetLang) {
- $this->encodeLang = $SourceLang . 'to' . $targetLang;
- $this->iconvEnabled = (function_exists('iconv') && $targetLang != 'BIG5' && !$forceTable) ? true : false;
- $this->iconvEnabled || is_resource($this->tableHandle) || $this->tableHandle = fopen($this->tableName, "r");
- }
- }
+ /**
+ * UTF8 to GBK,BIG5
+ *
+ * @param string $srcText
+ * @return string
+ */
+ protected function utf8toCHS($srcText)
+ {
+ $this->_getTableIndex();
+ $tarText = '';
+ $i = 0;
+ while ($i < strlen($srcText)) {
+ $c = ord($srcText[$i++]);
+ switch ($c >> 4) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ $tarText .= chr($c);
+ break;
+ case 12:
+ case 13:
+ $c = (($c & 0x1F) << 6) | (ord($srcText[$i++]) & 0x3F);
+ $h = $c >> 8;
+ if (isset($this->tableIndex[$this->encodeLang][$h])) {
+ $l = $c & 0xFF;
+ if (!isset($this->tableEncode[$this->encodeLang][$h][$l])) {
+ fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
+ $this->tableEncode[$this->encodeLang][$h][$l] = fread($this->tableHandle, 2);
+ }
+ $tarText .= $this->tableEncode[$this->encodeLang][$h][$l];
+ }
+ break;
+ case 14:
+ $c = (($c & 0x0F) << 12) | ((ord($srcText[$i++]) & 0x3F) << 6) | ((ord($srcText[$i++]) & 0x3F));
+ $h = $c >> 8;
+ if (isset($this->tableIndex[$this->encodeLang][$h])) {
+ $l = $c & 0xFF;
+ if (!isset($this->tableEncode[$h][$l])) {
+ fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
+ $this->tableEncode[$h][$l] = fread($this->tableHandle, 2);
+ }
+ $tarText .= $this->tableEncode[$h][$l];
+ }
+ break;
+ }
+ }
- /**
- * unicode to utf8
- *
- * @param string $c
- * @return string
- */
- protected function unicodeToUTF8($c) {
- if ($c < 0x80) {
- $c = chr($c);
- } elseif ($c < 0x800) {
- $c = chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F);
- } elseif ($c < 0x10000) {
- $c = chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F) . chr(0x80 | $c & 0x3F);
- } elseif ($c < 0x200000) {
- $c = chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) . chr(0x80 | $c >> 6 & 0x3F) . chr(0x80 | $c & 0x3F);
- } elseif ($c < 0x4000000) {
- $c = chr(0xF8 | $c >> 24) . chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) . chr(0x80 | $c >> 6 & 0x3F) . chr(
- 0x80 | $c & 0x3F);
- } else {
- $c = chr(0xF8 | $c >> 30) . chr(0xF8 | $c >> 24) . chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) . chr(
- 0x80 | $c >> 6 & 0x3F) . chr(0x80 | $c & 0x3F);
- }
- return $c;
- }
+ return $tarText;
+ }
- /**
- * BIG5,GBK to Unicode
- *
- * @param string $c
- * @return string
- */
- protected function chsUTF8toU($c) {
- switch (strlen($c)) {
- case 1:
- return ord($c);
- case 2:
- return ((ord($c[0]) & 0x3F) << 6) + (ord($c[1]) & 0x3F);
- case 3:
- return ((ord($c[0]) & 0x1F) << 12) + ((ord($c[1]) & 0x3F) << 6) + (ord($c[2]) & 0x3F);
- case 4:
- return ((ord($c[0]) & 0x0F) << 18) + ((ord($c[1]) & 0x3F) << 12) + ((ord($c[2]) & 0x3F) << 6) + (ord(
- $c[3]) & 0x3F);
- }
- }
+ /**
+ * GBK,BIG5 to UNICODE
+ *
+ * @param string $srcText
+ * @param string $SourceLang
+ * @return Ambigous
+ */
+ protected function chstoUNICODE($srcText, $SourceLang = '')
+ {
+ $tarText = '';
+ if ($this->iconvEnabled && isset($SourceLang)) {
+ for ($i = 0; $i < strlen($srcText); $i += 2) {
+ if (ord($srcText[$i]) > 127) {
+ $tarText .= ''.dechex(
+ $this->Utf8_Unicode(iconv($SourceLang, 'UTF-8', $srcText[$i].$srcText[$i + 1]))).';';
+ } else {
+ $tarText .= $srcText[$i--];
+ }
+ }
+ } else {
+ $this->_getTableIndex();
+ for ($i = 0; $i < strlen($srcText); $i += 2) {
+ $h = ord($srcText[$i]);
+ if ($h > 127 && isset($this->tableIndex[$this->encodeLang][$h])) {
+ $l = ord($srcText[$i + 1]);
+ if (!isset($this->tableEncode[$this->encodeLang][$h][$l])) {
+ fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
+ $this->tableEncode[$this->encodeLang][$h][$l] = ''.bin2hex(fread($this->tableHandle, 2)).';';
+ }
+ $tarText .= $this->tableEncode[$this->encodeLang][$h][$l];
+ } elseif ($h < 128) {
+ $tarText .= $srcText[$i--];
+ }
+ }
+ }
- /**
- * BIG5,GBK to UTF8
- *
- * @param string $srcText
- * @return Ambigous
- */
- protected function chstoUTF8($srcText) {
- $this->_getTableIndex();
- $tarText = '';
- for ($i = 0; $i < strlen($srcText); $i += 2) {
- $h = ord($srcText[$i]);
- if ($h > 127 && isset($this->tableIndex[$this->encodeLang][$h])) {
- $l = ord($srcText[$i + 1]);
- if (!isset($this->tableEncode[$this->encodeLang][$h][$l])) {
- fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
- $this->tableEncode[$this->encodeLang][$h][$l] = $this->unicodeToUTF8(
- hexdec(bin2hex(fread($this->tableHandle, 2))));
- }
- $tarText .= $this->tableEncode[$this->encodeLang][$h][$l];
- } elseif ($h < 128) {
- $tarText .= $srcText[$i];
- $i--;
- }
- }
- return $tarText;
- }
+ return $tarText;
+ }
- /**
- * UTF8 to GBK,BIG5
- *
- * @param string $srcText
- * @return string
- */
- protected function utf8toCHS($srcText) {
- $this->_getTableIndex();
- $tarText = '';
- $i = 0;
- while ($i < strlen($srcText)) {
- $c = ord($srcText[$i++]);
- switch ($c >> 4) {
- case 0:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- $tarText .= chr($c);
- break;
- case 12:
- case 13:
- $c = (($c & 0x1F) << 6) | (ord($srcText[$i++]) & 0x3F);
- $h = $c >> 8;
- if (isset($this->tableIndex[$this->encodeLang][$h])) {
- $l = $c & 0xFF;
- if (!isset($this->tableEncode[$this->encodeLang][$h][$l])) {
- fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
- $this->tableEncode[$this->encodeLang][$h][$l] = fread($this->tableHandle, 2);
- }
- $tarText .= $this->tableEncode[$this->encodeLang][$h][$l];
- }
- break;
- case 14:
- $c = (($c & 0x0F) << 12) | ((ord($srcText[$i++]) & 0x3F) << 6) | ((ord($srcText[$i++]) & 0x3F));
- $h = $c >> 8;
- if (isset($this->tableIndex[$this->encodeLang][$h])) {
- $l = $c & 0xFF;
- if (!isset($this->tableEncode[$h][$l])) {
- fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
- $this->tableEncode[$h][$l] = fread($this->tableHandle, 2);
- }
- $tarText .= $this->tableEncode[$h][$l];
- }
- break;
- }
- }
- return $tarText;
- }
+ /**
+ * BIG5toGBK
+ *
+ * @param string $srcText
+ * @param string $SourceLang
+ * @return mixed
+ */
+ protected function chsConvert($srcText, $SourceLang = 'GBK')
+ {
+ if (strtoupper(substr($SourceLang, 0, 3)) == 'GBK') {
+ $handle = fopen('./encode/gb-big5.table', 'r');
+ } else {
+ $handle = fopen('./encode/big5-gb.table', 'r');
+ }
+ $encode = array();
+ for ($i = 0; $i < strlen($srcText) - 1; $i++) {
+ $h = ord($srcText[$i]);
+ if ($h >= 160) {
+ $l = ord($srcText[$i + 1]);
+ if (!isset($encode[$h][$l])) {
+ fseek($handle, ($h - 160) * 510 + ($l - 1) * 2);
+ $encode[$h][$l] = fread($handle, 2);
+ }
+ $srcText[$i++] = $encode[$h][$l][0];
+ $srcText[$i] = $encode[$h][$l][1];
+ }
+ }
+ fclose($handle);
- /**
- * GBK,BIG5 to UNICODE
- *
- * @param string $srcText
- * @param string $SourceLang
- * @return Ambigous
- */
- protected function chstoUNICODE($srcText, $SourceLang = '') {
- $tarText = '';
- if ($this->iconvEnabled && isset($SourceLang)) {
- for ($i = 0; $i < strlen($srcText); $i += 2) {
- if (ord($srcText[$i]) > 127) {
- $tarText .= "" . dechex(
- $this->Utf8_Unicode(iconv($SourceLang, "UTF-8", $srcText[$i] . $srcText[$i + 1]))) . ";";
- } else {
- $tarText .= $srcText[$i--];
- }
- }
- } else {
- $this->_getTableIndex();
- for ($i = 0; $i < strlen($srcText); $i += 2) {
- $h = ord($srcText[$i]);
- if ($h > 127 && isset($this->tableIndex[$this->encodeLang][$h])) {
- $l = ord($srcText[$i + 1]);
- if (!isset($this->tableEncode[$this->encodeLang][$h][$l])) {
- fseek($this->tableHandle, $l * 2 + $this->tableIndex[$this->encodeLang][$h]);
- $this->tableEncode[$this->encodeLang][$h][$l] = '' . bin2hex(fread($this->tableHandle, 2)) . ';';
- }
- $tarText .= $this->tableEncode[$this->encodeLang][$h][$l];
- } elseif ($h < 128) {
- $tarText .= $srcText[$i--];
- }
- }
- }
- return $tarText;
- }
+ return $srcText;
+ }
- /**
- * BIG5toGBK
- *
- * @param string $srcText
- * @param string $SourceLang
- * @return mixed
- */
- protected function chsConvert($srcText, $SourceLang = 'GBK') {
- if (strtoupper(substr($SourceLang, 0, 3)) == 'GBK') {
- $handle = fopen('./encode/gb-big5.table', "r");
- } else {
- $handle = fopen('./encode/big5-gb.table', "r");
- }
- $encode = array();
- for ($i = 0; $i < strlen($srcText) - 1; $i++) {
- $h = ord($srcText[$i]);
- if ($h >= 160) {
- $l = ord($srcText[$i + 1]);
- if (!isset($encode[$h][$l])) {
- fseek($handle, ($h - 160) * 510 + ($l - 1) * 2);
- $encode[$h][$l] = fread($handle, 2);
- }
- $srcText[$i++] = $encode[$h][$l][0];
- $srcText[$i] = $encode[$h][$l][1];
- }
- }
- fclose($handle);
- return $srcText;
- }
+ /**
+ * 解析编码表
+ *
+ */
+ private function _getTableIndex()
+ {
+ if (!isset($this->tableIndex[$this->encodeLang])) {
+ fseek($this->tableHandle, $this->IndexPoint[$this->encodeLang]);
+ $tmpData = fread($this->tableHandle, 512);
+ $pFirstEncode = hexdec(bin2hex(substr($tmpData, 4, 4)));
+ for ($i = 8; $i < 512; $i += 4) {
+ $item = unpack('nkey/nvalue', substr($tmpData, $i, 4));
+ if (isset($this->tableIndex[$this->encodeLang][$item['key']])) {
+ break;
+ }
+ $this->tableIndex[$this->encodeLang][$item['key']] = $pFirstEncode + $item['value'];
+ }
+ }
+ }
- /**
- * 解析编码表
- *
- * @return void
- */
- private function _getTableIndex() {
- if (!isset($this->tableIndex[$this->encodeLang])) {
- fseek($this->tableHandle, $this->IndexPoint[$this->encodeLang]);
- $tmpData = fread($this->tableHandle, 512);
- $pFirstEncode = hexdec(bin2hex(substr($tmpData, 4, 4)));
- for ($i = 8; $i < 512; $i += 4) {
- $item = unpack('nkey/nvalue', substr($tmpData, $i, 4));
- if (isset($this->tableIndex[$this->encodeLang][$item['key']])) break;
- $this->tableIndex[$this->encodeLang][$item['key']] = $pFirstEncode + $item['value'];
- }
- }
- }
+ /**
+ * 获得编码类型
+ *
+ * @param string $lang
+ * @return string
+ */
+ private function _getCharset($lang)
+ {
+ switch (strtoupper(substr($lang, 0, 2))) {
+ case 'GB':
+ $lang = 'GBK';
+ break;
+ case 'UT':
+ $lang = 'UTF8';
+ break;
+ case 'UN':
+ $lang = 'UNICODE';
+ break;
+ case 'BI':
+ $lang = 'BIG5';
+ break;
+ default:
+ $lang = '';
+ }
- /**
- * 获得编码类型
- *
- * @param string $lang
- * @return string
- */
- private function _getCharset($lang) {
- switch (strtoupper(substr($lang, 0, 2))) {
- case 'GB':
- $lang = 'GBK';
- break;
- case 'UT':
- $lang = 'UTF8';
- break;
- case 'UN':
- $lang = 'UNICODE';
- break;
- case 'BI':
- $lang = 'BIG5';
- break;
- default:
- $lang = '';
- }
- return $lang;
- }
+ return $lang;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/dao/WindDao.php b/wind/dao/WindDao.php
index 47beb2d8..4fc20b3f 100644
--- a/wind/dao/WindDao.php
+++ b/wind/dao/WindDao.php
@@ -1,39 +1,41 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindDao.php 2973 2011-10-15 19:22:48Z yishuo $
* @package dao
*/
-class WindDao extends WindModule {
- /**
- * 链接句柄
- *
- * @var WindConnection
- */
- protected $connection = null;
+class WindDao extends WindModule
+{
+ /**
+ * 链接句柄
+ *
+ * @var WindConnection
+ */
+ protected $connection = null;
- /**
- * 获得链接对象
- *
- * 根据用户配置决定配置是采用配置链接管理
- *
- * @return WindConnection
- */
- public function getConnection() {
- return $this->_getConnection();
- }
+ /**
+ * 获得链接对象
+ *
+ * 根据用户配置决定配置是采用配置链接管理
+ *
+ * @return WindConnection
+ */
+ public function getConnection()
+ {
+ return $this->_getConnection();
+ }
- /**
- * 设置链接对象
- *
- * @param WindConnection $connection 链接对象
- */
- public function setConnection($connection) {
- $this->connection = $connection;
- }
+ /**
+ * 设置链接对象
+ *
+ * @param WindConnection $connection 链接对象
+ */
+ public function setConnection($connection)
+ {
+ $this->connection = $connection;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/dao/WindDaoFactory.php b/wind/dao/WindDaoFactory.php
index 11a7553e..9227344b 100644
--- a/wind/dao/WindDaoFactory.php
+++ b/wind/dao/WindDaoFactory.php
@@ -1,8 +1,8 @@
* 创建DAO实例
@@ -13,63 +13,66 @@
* @author Qiong Wu
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindDaoFactory.php 3904 2013-01-08 07:01:26Z yishuo $
* @package dao
*/
-class WindDaoFactory extends WindModule {
- /**
- * dao路径信息
- *
- * @var string
- */
- protected $daoResource = '';
+class WindDaoFactory extends WindModule
+{
+ /**
+ * dao路径信息
+ *
+ * @var string
+ */
+ protected $daoResource = '';
+
+ /**
+ * 返回Dao类实例
+ * $className接受两种形式呃参数如下
+ *
+ * - 'namespace:path'
+ * - 'className'
+ *
+ *
+ * @param string $className
+ * Dao名字
+ * @return WindDao
+ * @throws WindDaoException 如果获取实例错误抛出异常
+ */
+ public function getDao($className)
+ {
+ try {
+ if (strpos($className, ':') === false) {
+ $className = $this->getDaoResource().'.'.$className;
+ }
+ Wind::registeComponent(array('path' => $className, 'scope' => 'application'), $className);
+ $daoInstance = Wind::getComponent($className);
+ $daoInstance->setDelayAttributes(array('connection' => array('ref' => 'db')));
- /**
- * 返回Dao类实例
- *
- * $className接受两种形式呃参数如下
- *
- * - 'namespace:path'
- * - 'className'
- *
- *
- * @param string $className Dao名字
- * @return WindDao
- * @throws WindDaoException 如果获取实例错误抛出异常
- */
- public function getDao($className) {
- try {
- if (strpos($className, ":") === false)
- $className = $this->getDaoResource() . '.' . $className;
- Wind::getApp()->getWindFactory()->addClassDefinitions($className,
- array('path' => $className, 'scope' => 'application'));
- $daoInstance = Wind::getApp()->getWindFactory()->getInstance($className);
- $daoInstance->setDelayAttributes(array('connection' => array('ref' => 'db')));
- return $daoInstance;
- } catch (Exception $exception) {
- throw new WindDaoException(
- '[dao.WindDaoFactory] create dao ' . $className . ' fail.' . $exception->getMessage());
- }
- }
+ return $daoInstance;
+ } catch (Exception $exception) {
+ throw new WindDaoException('[dao.WindDaoFactory.getDao] create dao '.$className.' fail.'.$exception->getMessage());
+ }
+ }
- /**
- * 获得dao存放的目录
- *
- * @return string $daoResource Dao目录
- */
- public function getDaoResource() {
- return $this->daoResource;
- }
+ /**
+ * 获得dao存放的目录
+ *
+ * @return string $daoResource Dao目录
+ */
+ public function getDaoResource()
+ {
+ return $this->daoResource;
+ }
- /**
- * 设置dao的获取目录
- *
- * 以框架的命名空间方式设置比如:WIND:dao来设置路径信息,WIND的位置为注册过的命名空间名字.
- *
- * @param string $daoResource Dao目录
- */
- public function setDaoResource($daoResource) {
- $this->daoResource = $daoResource;
- }
+ /**
+ * 设置dao的获取目录
+ * 以框架的命名空间方式设置比如:WIND:dao来设置路径信息,WIND的位置为注册过的命名空间名字.
+ *
+ * @param string $daoResource
+ * Dao目录
+ */
+ public function setDaoResource($daoResource)
+ {
+ $this->daoResource = $daoResource;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/dao/exception/WindDaoException.php b/wind/dao/exception/WindDaoException.php
index 2c907da7..2c84d61a 100644
--- a/wind/dao/exception/WindDaoException.php
+++ b/wind/dao/exception/WindDaoException.php
@@ -1,25 +1,26 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindDaoException.php 2973 2011-10-15 19:22:48Z yishuo $
* @package dao
* @subpackage exception
*/
-class WindDaoException extends WindException {
+class WindDaoException extends WindException
+{
+ /* (non-PHPdoc)
+ * @see WindException::messageMapper()
+ */
+ protected function messageMapper($code)
+ {
+ $messages = array();
- /* (non-PHPdoc)
- * @see WindException::messageMapper()
- */
- protected function messageMapper($code) {
- $messages = array();
- return isset($messages[$code]) ? $messages[$code] : '$message';
- }
+ return isset($messages[$code]) ? $messages[$code] : '$message';
+ }
}
-
-?>
\ No newline at end of file
diff --git a/wind/dao/listener/WindDaoCacheListener.php b/wind/dao/listener/WindDaoCacheListener.php
index 438ef26f..f96b6c6e 100644
--- a/wind/dao/listener/WindDaoCacheListener.php
+++ b/wind/dao/listener/WindDaoCacheListener.php
@@ -1,65 +1,69 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindDaoCacheListener.php 2973 2011-10-15 19:22:48Z yishuo $
* @package dao
* @subpackage listener
*/
-class WindDaoCacheListener extends WindHandlerInterceptor {
+class WindDaoCacheListener extends WindHandlerInterceptor
+{
+ /**
+ * dao实例对象
+ *
+ * @var WindDao
+ */
+ private $daoObject = null;
- /**
- * dao实例对象
- *
- * @var WindDao
- */
- private $daoObject = null;
+ /**
+ * 构造函数
+ *
+ * 设置需要监听的dao实例对象
+ *
+ * @param WindDao $instance
+ */
+ public function __construct($instance)
+ {
+ $this->daoObject = $instance;
+ }
- /**
- * 构造函数
- *
- * 设置需要监听的dao实例对象
- *
- * @param WindDao $instance
- */
- public function __construct($instance) {
- $this->daoObject = $instance;
- }
+ /* (non-PHPdoc)
+ * @see WindHandlerInterceptor::preHandle()
+ */
+ public function preHandle()
+ {
+ /* @var $cacheHandler AbstractWindCache */
+ $cacheHandler = $this->daoObject->getCacheHandler();
+ $key = $this->generateKey(func_get_args());
+ $result = $cacheHandler->get($key);
- /* (non-PHPdoc)
- * @see WindHandlerInterceptor::preHandle()
- */
- public function preHandle() {
- /* @var $cacheHandler AbstractWindCache */
- $cacheHandler = $this->daoObject->getCacheHandler();
- $key = $this->generateKey(func_get_args());
- $result = $cacheHandler->get($key);
- return empty($result) ? null : $result;
- }
+ return empty($result) ? null : $result;
+ }
- /* (non-PHPdoc)
- * @see WindHandlerInterceptor::postHandle()
- */
- public function postHandle() {
- /* @var $cacheHandler AbstractWindCache */
- $cacheHandler = $this->daoObject->getCacheHandler();
- $key = $this->generateKey(func_get_args());
- $cacheHandler->set($key, $this->result);
- }
+ /* (non-PHPdoc)
+ * @see WindHandlerInterceptor::postHandle()
+ */
+ public function postHandle()
+ {
+ /* @var $cacheHandler AbstractWindCache */
+ $cacheHandler = $this->daoObject->getCacheHandler();
+ $key = $this->generateKey(func_get_args());
+ $cacheHandler->set($key, $this->result);
+ }
- /**
- * 返回缓存键值
- *
- * @param array $args 被监听方法的传递参数
- * @return string 计算生成保存的缓存键值
- */
- private function generateKey($args) {
- return $this->event[0] . '_' . $this->event[1] . '_' . (is_array($args[0]) ? $args[0][0] : $args[0]);
- }
+ /**
+ * 返回缓存键值
+ *
+ * @param array $args 被监听方法的传递参数
+ * @return string 计算生成保存的缓存键值
+ */
+ private function generateKey($args)
+ {
+ return $this->event[0].'_'.$this->event[1].'_'.(is_array($args[0]) ? $args[0][0] : $args[0]);
+ }
}
-
-?>
\ No newline at end of file
diff --git a/wind/db/AbstractWindPdoAdapter.php b/wind/db/AbstractWindPdoAdapter.php
index e10b4da3..3a170a1d 100644
--- a/wind/db/AbstractWindPdoAdapter.php
+++ b/wind/db/AbstractWindPdoAdapter.php
@@ -1,89 +1,92 @@
2011-9-22
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: AbstractWindPdoAdapter.php 3113 2011-11-11 07:28:09Z yishuo $
* @package db
*/
-abstract class AbstractWindPdoAdapter extends PDO {
- private $_typeMap = array(
- 'boolean' => PDO::PARAM_BOOL,
- 'integer' => PDO::PARAM_INT,
- 'string' => PDO::PARAM_STR,
- 'NULL' => PDO::PARAM_NULL);
+abstract class AbstractWindPdoAdapter extends PDO
+{
+ private $_typeMap = array(
+ 'boolean' => PDO::PARAM_BOOL,
+ 'integer' => PDO::PARAM_INT,
+ 'string' => PDO::PARAM_STR,
+ 'NULL' => PDO::PARAM_NULL, );
- /**
- * 获得绑定参数的类型
- *
- * @param string $variable
- * @return int
- */
- protected function _getPdoDataType($variable) {
- return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR;
- }
+ /**
+ * 获得绑定参数的类型
+ *
+ * @param string $variable
+ * @return int
+ */
+ protected function _getPdoDataType($variable)
+ {
+ return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR;
+ }
- /* (non-PHPdoc)
- * @see PDO::quote()
- */
- public function quote($value, $type = null) {
- if (is_array($value) || is_object($value)) return "''";
- return parent::quote($value, $type ? $type : $this->_getPdoDataType(gettype($value)));
- }
+ /* (non-PHPdoc)
+ * @see PDO::quote()
+ */
+ public function quote($value, $type = null)
+ {
+ if (is_array($value) || is_object($value)) {
+ return "''";
+ }
- /**
- * 过滤SQL元数据,数据库对象(如表名字,字段等)
- *
- * @param array $data
- * @return string
- */
- abstract public function fieldMeta($data);
+ return parent::quote($value, $type ? $type : $this->_getPdoDataType(gettype($value)));
+ }
- /**
- * 过滤数组并组装单条 key=value 形式的SQL查询语句值(insert/update)
- *
- * @param array $array
- * @return string
- */
- abstract public function sqlSingle($array);
-
- /**
- * 过滤数组并将数组变量转换为sql字符串
- *
- * @param array $variable 需要组装的数据
- * @return string
- */
- abstract public function quoteArray($variable);
-
- /**
- * 过滤二维数组将数组变量转换为多组的sql字符串
- *
- * @param array $var
- * @return string
- */
- abstract public function quoteMultiArray($var);
+ /**
+ * 过滤SQL元数据,数据库对象(如表名字,字段等)
+ *
+ * @param array $data
+ * @return string
+ */
+ abstract public function fieldMeta($data);
- /**
- * 添加数据表
- *
- * 添加数据表注意:最后一个参数'$replace',有两个取值'true,false',当值为false时表示如果数据表存在不创建新表,
- * 值为true时则删除已经存在的数据表并创建新表
- * @param string $tableName 数据表名称
- * @param string|array $values 数据表字段信息
- * @param boolean $replace 如果表已经存在是否覆盖,接收两个值true|false
- * @return boolean
- */
- abstract public function createTable($tableName, $values, $replace = false);
+ /**
+ * 过滤数组并组装单条 key=value 形式的SQL查询语句值(insert/update)
+ *
+ * @param array $array
+ * @return string
+ */
+ abstract public function sqlSingle($array);
- /**
- * 设置连接数据库是所用的编码方式
- *
- * @param string $charset 编码格式
- */
- abstract public function setCharset($charset);
+ /**
+ * 过滤数组并将数组变量转换为sql字符串
+ *
+ * @param array $variable 需要组装的数据
+ * @return string
+ */
+ abstract public function quoteArray($variable);
-}
+ /**
+ * 过滤二维数组将数组变量转换为多组的sql字符串
+ *
+ * @param array $var
+ * @return string
+ */
+ abstract public function quoteMultiArray($var);
+
+ /**
+ * 添加数据表
+ *
+ * 添加数据表注意:最后一个参数'$replace',有两个取值'true,false',当值为false时表示如果数据表存在不创建新表,
+ * 值为true时则删除已经存在的数据表并创建新表
+ * @param string $tableName 数据表名称
+ * @param string|array $values 数据表字段信息
+ * @param bool $replace 如果表已经存在是否覆盖,接收两个值true|false
+ * @return bool
+ */
+ abstract public function createTable($tableName, $values, $replace = false);
-?>
\ No newline at end of file
+ /**
+ * 设置连接数据库是所用的编码方式
+ *
+ * @param string $charset 编码格式
+ */
+ abstract public function setCharset($charset);
+}
diff --git a/wind/db/WindConnection.php b/wind/db/WindConnection.php
index 709fb71d..2d184b5f 100644
--- a/wind/db/WindConnection.php
+++ b/wind/db/WindConnection.php
@@ -1,10 +1,11 @@
* $connection = new WindConnection('mysql:host=localhost;dbname=test', 'root', 'root');
* $stm = $connection->createStatement('SELECT * FROM {members} WHERE uid<=:uid', true);
@@ -25,337 +26,367 @@
*
*
* @author Qiong Wu 2011-9-23
- * @copyright ©2003-2103 phpwind.com
+ * @copyright (c)2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindConnection.php 3904 2013-01-08 07:01:26Z yishuo $
* @package db
*/
-class WindConnection extends WindModule {
- /**
- * 链接字符串,携带数据驱动类型,主机信息,库名等
- *
- * mysql:host=localhost;dbname=test
- * @var string
- */
- protected $_dsn;
- /**
- * 驱动名
- *
- * @var string
- */
- protected $_driverName;
- /**
- * 用户名
- *
- * @var string
- */
- protected $_user;
- /**
- * 数据密码
- *
- * @var string
- */
- protected $_pwd;
- /**
- * 数据表前缀
- *
- * @var string
- */
- protected $_tablePrefix;
- /**
- * 数据连接编码方式
- *
- * @var string
- */
- protected $_charset;
- /**
- * 属性值
- *
- * @var array
- */
- protected $_attributes = array();
- /**
- * 数据连接句柄
- *
- * @var PDO
- */
- protected $_dbHandle = null;
-
- /**
- * @param string $dsn
- * @param string $username
- * @param string $password
- */
- public function __construct($dsn = '', $username = '', $password = '') {
- $this->_dsn = $dsn;
- $this->_user = $username;
- $this->_pwd = $password;
- }
-
- /**
- * 接受一条sql语句,并返回sqlStatement对象
- *
- * @param string $sql sql语句
- * @return WindSqlStatement
- */
- public function createStatement($sql = null) {
- return new WindSqlStatement($this, $this->parseQueryString($sql));
- }
-
- /**
- * 返回数据库链接对象
- *
- * @return AbstractWindPdoAdapter
- */
- public function getDbHandle() {
- $this->init();
- return $this->_dbHandle;
- }
-
- /**
- * 获得链接相关属性设置
- *
- * @param string $attribute
- * @return string
- * */
- public function getAttribute($attribute) {
- if ($this->_dbHandle !== null) {
- return $this->_dbHandle->getAttribute($attribute);
- } else
- return isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : '';
- }
-
- /**
- * 设置链接相关属性
- *
- * @param string $attribute
- * @param string $value 默认值为null
- * @return void
- */
- public function setAttribute($attribute, $value = null) {
- if (!$attribute) return;
- if ($this->_dbHandle !== null) {
- $this->_dbHandle->setAttribute($attribute, $value);
- } else
- $this->_attributes[$attribute] = $value;
- }
-
- /**
- * 返回DB驱动类型
- *
- * @return string
- */
- public function getDriverName() {
- if ($this->_driverName) return $this->_driverName;
- if ($this->_dbHandle !== null) {
- $this->_driverName = $this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME);
- } elseif (($pos = strpos($this->_dsn, ':')) !== false) {
- $this->_driverName = strtolower(substr($this->_dsn, 0, $pos));
- }
- return $this->_driverName;
- }
-
- /**
- * 执行一条sql语句 同时返回影响行数
- *
- * @param string $sql sql语句
- * @return int
- */
- public function execute($sql) {
- try {
- $result = $this->getDbHandle()->exec($this->parseQueryString($sql));
- if (WIND_DEBUG & 2) {
- Wind::getApp()->getComponent('windLogger')->info(
- "[db.WindConnection.execute] \r\n\tSQL: " . $sql . " \r\n\tResult:" . WindString::varToString(
- $result));
- }
- return $result;
- } catch (PDOException $e) {
- $this->close();
- throw new WindDbException($e->getMessage());
- }
- }
-
- /**
- * 执行一条查询同时返回结果集
- *
- * @param string $sql sql语句
- * @return WindResultSet
- */
- public function query($sql) {
- try {
- $sql = $this->parseQueryString($sql);
- return new WindResultSet($this->getDbHandle()->query($sql));
- } catch (PDOException $e) {
- throw new WindDbException($e->getMessage(), WindDbException::DB_QUERY_ERROR);
- }
- }
-
- /**
- * 过滤SQL元数据,数据库对象(如表名字,字段等)
- *
- * @param string $data
- * @throws WindDbException
- */
- public function sqlMetadata($data) {
- return $this->getDbHandle()->fieldMeta($data);
- }
-
- /**
- * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组
- *
- * @param array $array
- * @return string
- */
- public function quoteArray($array) {
- return $this->getDbHandle()->quoteArray($array);
- }
-
- /**
- * 过滤二维数组将数组变量转换为多组的sql字符串
- *
- * @param array $array
- * @return string
- */
- public function quoteMultiArray($array) {
- return $this->getDbHandle()->quoteMultiArray($array);
- }
-
- /**
- * sql元数据安全过滤,并返回过滤后值
- *
- * @param string $string
- * @return string
- */
- public function quote($string) {
- return $this->getDbHandle()->quote($string);
- }
-
- /**
- * 过滤数组值并返回(insert/update)sql语句形式
- *
- * 该方法接收一个数组变量,进行安全过滤,并返回组装单条 key=value 形式的SQL查询语句值 (适用于insert/update value值组装).
- * 该方法的具体实现根据数据库的链接类型不同有所不同.
- * @param array $array
- * @return string
- * @see AbstractWindPdoAdapter::sqlSingle()
- */
- public function sqlSingle($array) {
- return $this->getDbHandle()->sqlSingle($array);
- }
-
- /**
- * 创建表,返回是否创建成功
- *
- * 创建表并返回是否创建成功'$values'为字段信息.该方法的具体实现根据数据库的链接类型不同有所不同.
- * @param string $tableName 表名称
- * @param array $values 字段值信息
- * @param boolean $replace 是否覆盖
- * @return boolean
- * @see AbstractWindPdoAdapter::createTable()
- */
- public function createTable($tableName, $values, $replace = false) {
- return $this->getDbHandle()->createTable($tableName, $values, $replace);
- }
-
- /**
- * 返回最后一条插入的数据值,当传一个'name'给该方法,则返回'name'对应的列值
- *
- * @param string $name 默认为空字符串
- * @return int
- */
- public function lastInsertId($name = '') {
- if ($name)
- return $this->getDbHandle()->lastInsertId($name);
- else
- return $this->getDbHandle()->lastInsertId();
- }
-
- /**
- * 关闭数据库连接
- *
- * @return void
- */
- public function close() {
- $this->_dbHandle = null;
- }
-
- /**
- * 初始化DB句柄
- *
- * @return void
- * @throws WindDbException
- */
- public function init() {
- try {
- if ($this->_dbHandle !== null) return;
- $driverName = $this->getDriverName();
- $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter";
- $dbHandleClass = Wind::import($dbHandleClass);
- $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes);
- $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- $this->_dbHandle->setCharset($this->_charset);
- if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info(
- "[db.WindConnection.init] Initialize db connection success. \r\n\tDSN:" . $this->_dsn . "\r\n\tUser:" . $this->_user . "\r\n\tCharset:" . $this->_charset . "\r\n\tTablePrefix:" . $this->_tablePrefix . "\r\n\tDriverName:" . $this->_driverName,
- 'db');
- } catch (PDOException $e) {
- $this->close();
- throw new WindDbException($e->getMessage());
- }
- }
-
- /**
- * (non-PHPdoc)
- * @see WindModule::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- $this->_initConfig();
- $this->_attributes = array();
- }
-
- /**
- * 根据配置信息,初始化当前连接对象
- *
- * @param array $config 连接配置,默认为空数组
- */
- protected function _initConfig($config = array()) {
- $this->_dsn = $this->getConfig('dsn', '', '', $config);
- $this->_user = $this->getConfig('user', '', '', $config);
- $this->_pwd = $this->getConfig('pwd', '', '', $config);
- $this->_charset = $this->getConfig('charset', '', '', $config);
- $this->_tablePrefix = $this->getConfig('tableprefix', '', '', $config);
- }
-
- /**
- * 解析当前查询语句,并返回解析后结果
- *
- * @param string $sql
- */
- protected function parseQueryString($sql) {
- if ($_prefix = $this->getTablePrefix()) {
- list($new, $old) = explode('|', $_prefix . '|');
- $sql = preg_replace('/{{(' . $old . ')?(.*?)}}/', $new . '\2', $sql);
- }
- return $sql;
- }
-
- /**
- * 获得表前缀
- *
- * @return string $tablePrefix
- */
- public function getTablePrefix() {
- return $this->_tablePrefix;
- }
-
- /**
- * 设置表前缀
- *
- * @param string $tablePrefix
- */
- public function setTablePrefix($tablePrefix) {
- $this->_tablePrefix = $tablePrefix;
- }
+class WindConnection extends WindModule
+{
+ /**
+ * 链接字符串,携带数据驱动类型,主机信息,库名等
+ *
+ * mysql:host=localhost;dbname=test
+ * @var string
+ */
+ protected $_dsn;
+ /**
+ * 驱动名
+ *
+ * @var string
+ */
+ protected $_driverName;
+ /**
+ * 用户名
+ *
+ * @var string
+ */
+ protected $_user;
+ /**
+ * 数据密码
+ *
+ * @var string
+ */
+ protected $_pwd;
+ /**
+ * 数据表前缀
+ *
+ * @var string
+ */
+ protected $_tablePrefix;
+ /**
+ * 数据连接编码方式
+ *
+ * @var string
+ */
+ protected $_charset;
+ /**
+ * 属性值
+ *
+ * @var array
+ */
+ protected $_attributes = array();
+ /**
+ * 数据连接句柄
+ *
+ * @var PDO
+ */
+ protected $_dbHandle = null;
+
+ /**
+ * @param string $dsn
+ * @param string $username
+ * @param string $password
+ */
+ public function __construct($dsn = '', $username = '', $password = '')
+ {
+ $this->_dsn = $dsn;
+ $this->_user = $username;
+ $this->_pwd = $password;
+ }
+
+ /**
+ * 接受一条sql语句,并返回sqlStatement对象
+ *
+ * @param string $sql sql语句
+ * @return WindSqlStatement
+ */
+ public function createStatement($sql = null)
+ {
+ /* @var $statement WindSqlStatement */
+ $statement = Wind::getComponent('sqlStatement');
+ $statement->setConnection($this);
+ $statement->setQueryString($this->parseQueryString($sql));
+
+ return $statement;
+ }
+
+ /**
+ * 返回数据库链接对象
+ *
+ * @return AbstractWindPdoAdapter
+ */
+ public function getDbHandle()
+ {
+ $this->init();
+
+ return $this->_dbHandle;
+ }
+
+ /**
+ * 获得链接相关属性设置
+ *
+ * @param string $attribute
+ * @return string
+ * */
+ public function getAttribute($attribute)
+ {
+ if ($this->_dbHandle !== null) {
+ return $this->_dbHandle->getAttribute($attribute);
+ } else {
+ return isset($this->_attributes[$attribute]) ? $this->_attributes[$attribute] : '';
+ }
+ }
+
+ /**
+ * 设置链接相关属性
+ *
+ * @param string $attribute
+ * @param string $value 默认值为null
+ */
+ public function setAttribute($attribute, $value = null)
+ {
+ if (!$attribute) {
+ return;
+ }
+ if ($this->_dbHandle !== null) {
+ $this->_dbHandle->setAttribute($attribute, $value);
+ } else {
+ $this->_attributes[$attribute] = $value;
+ }
+ }
+
+ /**
+ * 返回DB驱动类型
+ *
+ * @return string
+ */
+ public function getDriverName()
+ {
+ if ($this->_driverName) {
+ return $this->_driverName;
+ }
+ if ($this->_dbHandle !== null) {
+ $this->_driverName = $this->_dbHandle->getAttribute(PDO::ATTR_DRIVER_NAME);
+ } elseif (($pos = strpos($this->_dsn, ':')) !== false) {
+ $this->_driverName = strtolower(substr($this->_dsn, 0, $pos));
+ }
+
+ return $this->_driverName;
+ }
+
+ /**
+ * 执行一条sql语句 同时返回影响行数
+ *
+ * @param string $sql sql语句
+ * @return int
+ */
+ public function execute($sql)
+ {
+ try {
+ $statement = $this->createStatement($sql);
+
+ return $statement->execute();
+ } catch (PDOException $e) {
+ $this->close();
+ throw new WindDbException('[db.WindConnection.execute] '.$e->getMessage()."\r\nSQL:$sql", WindDbException::DB_QUERY_ERROR);
+ }
+ }
+
+ /**
+ * 执行一条查询同时返回结果集
+ * @param string $sql sql语句
+ * @return WindResultSet
+ */
+ public function query($sql)
+ {
+ try {
+ $sql = $this->parseQueryString($sql);
+
+ return new WindResultSet($this->getDbHandle()->query($sql));
+ } catch (PDOException $e) {
+ throw new WindDbException('[db.WindConnection.query] '.$e->getMessage()."\r\nSQL:$sql", WindDbException::DB_QUERY_ERROR);
+ }
+ }
+
+ /**
+ * 过滤SQL元数据,数据库对象(如表名字,字段等)
+ *
+ * @param string $data
+ * @throws WindDbException
+ */
+ public function sqlMetadata($data)
+ {
+ return $this->getDbHandle()->fieldMeta($data);
+ }
+
+ /**
+ * 过滤数组变量,将数组变量转换为字符串,并用逗号分隔每个数组元素支持多维数组
+ *
+ * @param array $array
+ * @return string
+ */
+ public function quoteArray($array)
+ {
+ return $this->getDbHandle()->quoteArray($array);
+ }
+
+ /**
+ * 过滤二维数组将数组变量转换为多组的sql字符串
+ *
+ * @param array $array
+ * @return string
+ */
+ public function quoteMultiArray($array)
+ {
+ return $this->getDbHandle()->quoteMultiArray($array);
+ }
+
+ /**
+ * sql元数据安全过滤,并返回过滤后值
+ *
+ * @param string $string
+ * @return string
+ */
+ public function quote($string)
+ {
+ return $this->getDbHandle()->quote($string);
+ }
+
+ /**
+ * 过滤数组值并返回(insert/update)sql语句形式
+ *
+ * 该方法接收一个数组变量,进行安全过滤,并返回组装单条 key=value 形式的SQL查询语句值 (适用于insert/update value值组装).
+ * 该方法的具体实现根据数据库的链接类型不同有所不同.
+ * @param array $array
+ * @return string
+ * @see AbstractWindPdoAdapter::sqlSingle()
+ */
+ public function sqlSingle($array)
+ {
+ return $this->getDbHandle()->sqlSingle($array);
+ }
+
+ /**
+ * 创建表,返回是否创建成功
+ *
+ * 创建表并返回是否创建成功'$values'为字段信息.该方法的具体实现根据数据库的链接类型不同有所不同.
+ * @param string $tableName 表名称
+ * @param array $values 字段值信息
+ * @param bool $replace 是否覆盖
+ * @return bool
+ * @see AbstractWindPdoAdapter::createTable()
+ */
+ public function createTable($tableName, $values, $replace = false)
+ {
+ return $this->getDbHandle()->createTable($tableName, $values, $replace);
+ }
+
+ /**
+ * 返回最后一条插入的数据值,当传一个'name'给该方法,则返回'name'对应的列值
+ *
+ * @param string $name 默认为空字符串
+ * @return int
+ */
+ public function lastInsertId($name = '')
+ {
+ if ($name) {
+ return $this->getDbHandle()->lastInsertId($name);
+ } else {
+ return $this->getDbHandle()->lastInsertId();
+ }
+ }
+
+ /**
+ * 关闭数据库连接
+ *
+ */
+ public function close()
+ {
+ $this->_dbHandle = null;
+ }
+
+ /**
+ * 初始化DB句柄
+ *
+ * @throws WindDbException
+ */
+ public function init()
+ {
+ try {
+ if ($this->_dbHandle !== null) {
+ return;
+ }
+ $driverName = $this->getDriverName();
+ $dbHandleClass = 'WIND:db.'.$driverName.'.Wind'.ucfirst($driverName).'PdoAdapter';
+ $dbHandleClass = Wind::import($dbHandleClass);
+ $this->_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd, (array) $this->_attributes);
+ $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+ $this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
+ $this->_dbHandle->setCharset($this->_charset);
+ } catch (PDOException $e) {
+ $this->close();
+ throw new WindDbException('[db.WindConnection.init] '.$e->getMessage());
+ }
+ }
+
+ /**
+ * (non-PHPdoc)
+ * @see WindModule::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ $this->_initConfig();
+ $this->_attributes = array();
+ }
+
+ /**
+ * 根据配置信息,初始化当前连接对象
+ *
+ * @param array $config 连接配置,默认为空数组
+ */
+ protected function _initConfig($config = array())
+ {
+ $this->_dsn = $this->getConfig('dsn', '', '', $config);
+ $this->_user = $this->getConfig('user', '', '', $config);
+ $this->_pwd = $this->getConfig('pwd', '', '', $config);
+ $this->_charset = $this->getConfig('charset', '', '', $config);
+ $this->_tablePrefix = $this->getConfig('tableprefix', '', '', $config);
+ }
+
+ /**
+ * 解析当前查询语句,并返回解析后结果
+ *
+ * @param string $sql
+ */
+ protected function parseQueryString($sql)
+ {
+ if ($_prefix = $this->getTablePrefix()) {
+ list($new, $old) = explode('|', $_prefix.'|');
+ $sql = preg_replace('/{{('.$old.')?(.*?)}}/', $new.'\2', $sql);
+ }
+
+ return $sql;
+ }
+
+ /**
+ * 获得表前缀
+ *
+ * @return string $tablePrefix
+ */
+ public function getTablePrefix()
+ {
+ return $this->_tablePrefix;
+ }
+
+ /**
+ * 设置表前缀
+ *
+ * @param string $tablePrefix
+ */
+ public function setTablePrefix($tablePrefix)
+ {
+ $this->_tablePrefix = $tablePrefix;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/db/WindConnectionManager.php b/wind/db/WindConnectionManager.php
index 46344d2d..e952cd60 100644
--- a/wind/db/WindConnectionManager.php
+++ b/wind/db/WindConnectionManager.php
@@ -1,8 +1,8 @@
* 1. 当没有任何策略部署时 ,默认返回当前配置中的第一个链接句柄
* 2. 当没有任何策略部署时,如果在sql语句中有链接句柄指定时则返回指定的链接句柄
@@ -31,224 +31,239 @@
* @author Qiong Wu 2011-9-23
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindConnectionManager.php 3904 2013-01-08 07:01:26Z yishuo $
* @package db
*/
-class WindConnectionManager extends WindConnection {
- /**
- * 通配符设置
- *
- * @var string
- */
- private $wildcard = '*';
- /**
- * 数据链接池,临时保存当前所有数据库连接句柄
- *
- * @var array
- */
- private $pool = array();
- /**
- * 当前数据表名称
- *
- * @var string
- */
- private $tableName;
- /**
- * 当前的sql语句查询类型
- *
- * @var string
- */
- private $sqlType;
- /**
- * 数据库连接池策略部署配置信息
- *
- * @var array
- */
- private $except = array('_current' => '', '_default' => array(), '_except' => array(), '_db' => array());
-
- /**
- * 是否强制主链接,默认为false
- *
- * @var boolean
- */
- private $forceMaster = false;
-
- /*
- * (non-PHPdoc) @see WindConnection::createStatement()
- */
- public function createStatement($sql = null, $forceMaster = false) {
- $this->forceMaster = $forceMaster;
- return parent::createStatement($sql);
- }
-
- /*
- * (non-PHPdoc) @see WindConnection::getDbHandle()
- */
- public function getDbHandle() {
- $this->init();
- return $this->_dbHandle;
- }
-
- /*
- * (non-PHPdoc) @see WindConnection::init()
- */
- public function init() {
- try {
- if (!isset($this->pool[$this->except['_current']])) {
- $driverName = $this->getDriverName();
- $dbHandleClass = "WIND:db." . $driverName . ".Wind" . ucfirst($driverName) . "PdoAdapter";
- $dbHandleClass = Wind::import($dbHandleClass);
- $_dbHandle = new $dbHandleClass($this->_dsn, $this->_user, $this->_pwd,
- (array) $this->_attributes);
- $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- $_dbHandle->setCharset($this->_charset);
- $this->pool[$this->except['_current']] = $_dbHandle;
- }
- $this->_dbHandle = $this->pool[$this->except['_current']];
- if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info(
- "db.WindConnectionManager.init() Initialize db connection successful. use '" . $this->except['_current'] . "'",
- 'db');
- } catch (PDOException $e) {
- $this->close();
- throw new WindDbException($e->getMessage());
- }
- }
-
- /*
- * (non-PHPdoc) @see WindConnection::parseQueryString()
- */
- protected function parseQueryString($sql) {
- $sql = preg_replace_callback(
- '/^([a-zA-Z]*)\s[\w\*\s]+(\{\{([\w]+\:)?([\w]+\.)?([\w]+)\}\})?[\w\s\<\=\:]*/i',
- array($this, '_pregQueryString'), $sql);
- if (!$this->except['_current']) {
- if (!isset($this->except['_db'][$this->tableName])) {
- foreach ((array) $this->except['_except'] as $value) {
- preg_match('/' . str_replace($this->wildcard, '\w*', $value) . '/i',
- $this->tableName, $matchs);
- if (!empty($matchs)) {
- $_c = $this->except['_db'][$value];
- break;
- }
- }
- $_c || $_c = $this->except['_default'];
- } else
- $_c = $this->except['_db'][$this->tableName];
- $this->_resolveCurrentDb($_c);
- }
- if ($this->except['_current']) {
- $_config = $this->getConfig($this->except['_current']);
- if (!$_config) throw new WindDbException(
- '[db.WindConnectionManager.parseQueryString] db connection ' . $this->except['_current'] . ' is not exist.');
- parent::_initConfig($_config);
- }
- return parent::parseQueryString($sql);
- }
-
- /**
- * 根据当前sql语句类型,从一条数据连接配置中解析出主从信息,并设置当前db链接名
- *
- * @param array $_c
- * @return void
- */
- private function _resolveCurrentDb($_c) {
- if (empty($_c) || empty($_c['_m'])) throw new WindDbException(
- '[db.WindConnectionManager._resolveCurrentDb] db error.',
- WindDbException::DB_BUILDER_NOT_EXIST);
-
- switch ($this->sqlType) {
- case 'SELECT':
- if (!$this->forceMaster && !empty($_c['_s'])) {
- $_count = count($_c['_s']);
- $_index = $_count > 1 ? mt_rand(0, $_count - 1) : 0;
- $this->except['_current'] = $_c['_s'][$_index];
- break;
- }
- default:
- $this->except['_current'] = $_c['_m'];
- break;
- }
- }
-
- /**
- * 解析sql语句
- *
- * 解析sql语句,在sql语句中提取数据库连接信息,返回解析后的sql语句
- * Array(
- * [0] => SELECT * FROM {db1:database.members} WHERE uid<=:uid | 匹配到的完整str
- * [1] => SELECT | 当前的sql类型
- * [2] => {db1:database.members} | 当前table
- * [3] => db1: | 当前table自定义链接
- * [4] => database. | 当前database
- * [5] => members | 当前表名
- * )
- *
- * @param array $matchs
- * @return string
- */
- private function _pregQueryString($matchs) {
- $this->sqlType = $matchs[1];
- if (isset($matchs[2])) {
- $this->tableName = $matchs[5];
- $this->except['_current'] = trim($matchs[3], ':');
- $matchs[0] = str_replace($matchs[3] . $matchs[4], '', $matchs[0]);
- } else
- $this->except['_current'] = $this->tableName = '';
- return $matchs[0];
- }
-
- /*
- * (non-PHPdoc) @see WindConnection::_initConfig()
- */
- protected function _initConfig() {
- $_except = $this->getConfig('connections', 'except');
- unset($this->_config['connections']['except']);
- $this->_config = $this->_config['connections'];
- $_dbNames = array_keys($this->_config);
- if (empty($_dbNames)) throw new WindDbException(
- '[db.WindConnectionManager._initConfig] db config is required.');
- $this->_resetConnection($_dbNames[0]);
- $this->except['_default']['_m'] = $_dbNames[0];
- if ($_except) preg_replace_callback('/([\w\*\,]+):([\w]+)\|*([\w\,]+)*/i',
- array($this, '_pregExcept'), $_except);
- }
-
- /**
- * 重置链接信息
- *
- * @param string $db
- * @return void
- */
- private function _resetConnection($db) {
- $_config = $this->getConfig($db);
- if (!$_config) throw new WindDbException(
- '[db.WindConnectionManager._initConfig] db connection ' . $db . ' is not exist.');
- parent::_initConfig($_config);
- }
-
- /**
- * 解析链接管理链接策略
- *
- * db链接管理配置信息如下:except='*:(db1);user*,tablename2:(db1|db2);'
- * 一组'*:(db1);'代表一组数据配置,格式如:'tableName1,tableName2,tableName3:(db1|db2,db3,db4)'.
- * 数据表名称与策略用':'隔开,':'前面表示一组数据表,可以是多个也可以是一个,多个表名用','隔开.
- * ':'后面'()'中表示一组数据策略,例子中策略的意思是'db1'是主链接(master),'db2,db3,db4'为从属链接(slaves).
- * 该方法解析这段数据库链接配置,并将解析结果存储到 'except' 属性中.
- *
- * @param array $matchs
- * @return void
- */
- private function _pregExcept($matchs) {
- $_keys = explode(',', $matchs[1]);
- foreach ($_keys as $_v) {
- if ($_v === $this->wildcard) {
- $this->except['_default']['_m'] = $matchs[2];
- $this->except['_default']['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array();
- break;
- }
- if (strpos($_v, $this->wildcard) !== false) $this->except['_except'][] = $_v;
- $this->except['_db'][$_v]['_m'] = $matchs[2];
- $this->except['_db'][$_v]['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array();
- }
- }
-}
\ No newline at end of file
+class WindConnectionManager extends WindConnection
+{
+ /**
+ * 通配符设置
+ *
+ * @var string
+ */
+ private $wildcard = '*';
+ /**
+ * 数据链接池,临时保存当前所有数据库连接句柄
+ *
+ * @var array
+ */
+ private $pool = array();
+ /**
+ * 当前数据表名称
+ *
+ * @var string
+ */
+ private $tableName;
+ /**
+ * 当前的sql语句查询类型
+ *
+ * @var string
+ */
+ private $sqlType;
+ /**
+ * 数据库连接池策略部署配置信息
+ *
+ * @var array
+ */
+ private $except = array('_current' => '', '_default' => array(), '_except' => array(), '_db' => array());
+
+ /**
+ * 是否强制主链接,默认为false
+ *
+ * @var bool
+ */
+ private $forceMaster = false;
+
+ /*
+ * (non-PHPdoc) @see WindConnection::createStatement()
+ */
+ public function createStatement($sql = null, $forceMaster = false)
+ {
+ $this->forceMaster = $forceMaster;
+
+ return parent::createStatement($sql);
+ }
+
+ /*
+ * (non-PHPdoc) @see WindConnection::getDbHandle()
+ */
+ public function getDbHandle()
+ {
+ $this->init();
+
+ return $this->_dbHandle;
+ }
+
+ /*
+ * (non-PHPdoc) @see WindConnection::init()
+ */
+ public function init()
+ {
+ try {
+ if (!isset($this->pool[$this->except['_current']])) {
+ parent::init();
+ $this->pool[$this->except['_current']] = $this->_dbHandle;
+ } else {
+ $this->_dbHandle = $this->pool[$this->except['_current']];
+ }
+ } catch (PDOException $e) {
+ $this->close();
+ throw new WindDbException('[db.WindConnectionManager.init] '.$e->getMessage());
+ }
+ }
+
+ /*
+ * (non-PHPdoc) @see WindConnection::parseQueryString()
+ */
+ protected function parseQueryString($sql)
+ {
+ $sql = preg_replace_callback(
+ '/^([a-zA-Z]*)\s[\w\*\s]+(\{\{([\w]+\:)?([\w]+\.)?([\w]+)\}\})?[\w\s\<\=\:]*/i',
+ array($this, '_pregQueryString'), $sql);
+ if (!$this->except['_current']) {
+ if (!isset($this->except['_db'][$this->tableName])) {
+ foreach ((array) $this->except['_except'] as $value) {
+ preg_match('/'.str_replace($this->wildcard, '\w*', $value).'/i',
+ $this->tableName, $matchs);
+ if (!empty($matchs)) {
+ $_c = $this->except['_db'][$value];
+ break;
+ }
+ }
+ $_c || $_c = $this->except['_default'];
+ } else {
+ $_c = $this->except['_db'][$this->tableName];
+ }
+ $this->_resolveCurrentDb($_c);
+ }
+ if ($this->except['_current']) {
+ $_config = $this->getConfig($this->except['_current']);
+ if (!$_config) {
+ throw new WindDbException(
+ '[db.WindConnectionManager.parseQueryString] db connection '.$this->except['_current'].' is not exist.');
+ }
+ parent::_initConfig($_config);
+ }
+
+ return parent::parseQueryString($sql);
+ }
+
+ /**
+ * 根据当前sql语句类型,从一条数据连接配置中解析出主从信息,并设置当前db链接名
+ *
+ * @param array $_c
+ */
+ private function _resolveCurrentDb($_c)
+ {
+ if (empty($_c) || empty($_c['_m'])) {
+ throw new WindDbException(
+ '[db.WindConnectionManager._resolveCurrentDb] db error.',
+ WindDbException::DB_BUILDER_NOT_EXIST);
+ }
+
+ switch ($this->sqlType) {
+ case 'SELECT':
+ if (!$this->forceMaster && !empty($_c['_s'])) {
+ $_count = count($_c['_s']);
+ $_index = $_count > 1 ? mt_rand(0, $_count - 1) : 0;
+ $this->except['_current'] = $_c['_s'][$_index];
+ break;
+ }
+ default:
+ $this->except['_current'] = $_c['_m'];
+ break;
+ }
+ }
+
+ /**
+ * 解析sql语句
+ * 解析sql语句,在sql语句中提取数据库连接信息,返回解析后的sql语句
+ * Array(
+ * [0] => SELECT * FROM {db1:database.members} WHERE uid<=:uid | 匹配到的完整str
+ * [1] => SELECT | 当前的sql类型
+ * [2] => {db1:database.members} | 当前table
+ * [3] => db1: | 当前table自定义链接
+ * [4] => database. | 当前database
+ * [5] => members | 当前表名
+ * )
+ *
+ * @param array $matchs
+ * @return string
+ */
+ private function _pregQueryString($matchs)
+ {
+ $this->sqlType = $matchs[1];
+ if (isset($matchs[2])) {
+ $this->tableName = $matchs[5];
+ $this->except['_current'] = trim($matchs[3], ':');
+ $matchs[0] = str_replace($matchs[3].$matchs[4], '', $matchs[0]);
+ } else {
+ $this->except['_current'] = $this->tableName = '';
+ }
+
+ return $matchs[0];
+ }
+
+ /*
+ * (non-PHPdoc) @see WindConnection::_initConfig()
+ */
+ protected function _initConfig()
+ {
+ $_except = $this->getConfig('connections', 'except');
+ unset($this->_config['connections']['except']);
+ $this->_config = $this->_config['connections'];
+ $_dbNames = array_keys($this->_config);
+ if (empty($_dbNames)) {
+ throw new WindDbException(
+ '[db.WindConnectionManager._initConfig] db config is required.');
+ }
+ $this->_resetConnection($_dbNames[0]);
+ $this->except['_default']['_m'] = $_dbNames[0];
+ if ($_except) {
+ preg_replace_callback('/([\w\*\,]+):([\w]+)\|*([\w\,]+)*/i',
+ array($this, '_pregExcept'), $_except);
+ }
+ }
+
+ /**
+ * 重置链接信息
+ *
+ * @param string $db
+ */
+ private function _resetConnection($db)
+ {
+ $_config = $this->getConfig($db);
+ if (!$_config) {
+ throw new WindDbException(
+ '[db.WindConnectionManager._initConfig] db connection '.$db.' is not exist.');
+ }
+ parent::_initConfig($_config);
+ }
+
+ /**
+ * 解析链接管理链接策略
+ * db链接管理配置信息如下:except='*:(db1);user*,tablename2:(db1|db2);'
+ * 一组'*:(db1);'代表一组数据配置,格式如:'tableName1,tableName2,tableName3:(db1|db2,db3,db4)'.
+ * 数据表名称与策略用':'隔开,':'前面表示一组数据表,可以是多个也可以是一个,多个表名用','隔开.
+ * ':'后面'()'中表示一组数据策略,例子中策略的意思是'db1'是主链接(master),'db2,db3,db4'为从属链接(slaves).
+ * 该方法解析这段数据库链接配置,并将解析结果存储到 'except' 属性中.
+ *
+ * @param array $matchs
+ */
+ private function _pregExcept($matchs)
+ {
+ $_keys = explode(',', $matchs[1]);
+ foreach ($_keys as $_v) {
+ if ($_v === $this->wildcard) {
+ $this->except['_default']['_m'] = $matchs[2];
+ $this->except['_default']['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array();
+ break;
+ }
+ if (strpos($_v, $this->wildcard) !== false) {
+ $this->except['_except'][] = $_v;
+ }
+ $this->except['_db'][$_v]['_m'] = $matchs[2];
+ $this->except['_db'][$_v]['_s'] = isset($matchs[3]) ? explode(',', $matchs[3]) : array();
+ }
+ }
+}
diff --git a/wind/db/WindResultSet.php b/wind/db/WindResultSet.php
index c8b9507d..f63f109c 100644
--- a/wind/db/WindResultSet.php
+++ b/wind/db/WindResultSet.php
@@ -5,153 +5,194 @@
* @author Qiong Wu 2011-9-23
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindResultSet.php 3829 2012-11-19 11:13:22Z yishuo $
* @package db
*/
-class WindResultSet {
- /**
- * @var PDOStatement
- */
- private $_statement = null;
- /**
- * PDO fetchMode, default fetchMode PDO::FETCH_ASSOC
- *
- * @var number
- */
- private $_fetchMode = PDO::FETCH_ASSOC;
- /**
- * PDO fetchType, default fetchType PDO::FETCH_ORI_FIRST
- *
- * @var number
- */
- private $_fetchType = PDO::FETCH_ORI_FIRST;
- private $_columns = array();
+class WindResultSet
+{
+ /**
+ *
+ * @var PDOStatement
+ */
+ private $_statement = null;
+ /**
+ * PDO fetchMode, default fetchMode PDO::FETCH_ASSOC
+ *
+ * @var number
+ */
+ private $_fetchMode = PDO::FETCH_ASSOC;
+ /**
+ * PDO fetchType, default fetchType PDO::FETCH_ORI_FIRST
+ *
+ * @var number
+ */
+ private $_fetchType = PDO::FETCH_ORI_FIRST;
+ private $_columns = array();
- /**
- * @param WindSqlStatement $sqlStatement 预处理对象
- * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
- * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
- */
- public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0) {
- if ($sqlStatement instanceof WindSqlStatement) {
- $this->_statement = $sqlStatement->getStatement();
- $this->_columns = $sqlStatement->getColumns();
- } else
- $this->_statement = $sqlStatement;
- if ($fetchMode != 0) $this->_fetchMode = $fetchMode;
- if ($fetchType != 0) $this->_fetchType = $fetchType;
- }
+ /**
+ *
+ * @param WindSqlStatement $sqlStatement
+ * 预处理对象
+ * @param int $fetchMode
+ * 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
+ * @param int $fetchType
+ * 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,
+ * 必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
+ */
+ public function __construct($sqlStatement, $fetchMode = 0, $fetchType = 0)
+ {
+ if ($sqlStatement instanceof WindSqlStatement) {
+ $this->_statement = $sqlStatement->getStatement();
+ $this->_columns = $sqlStatement->getColumns();
+ } else {
+ $this->_statement = $sqlStatement;
+ }
+ if ($fetchMode != 0) {
+ $this->_fetchMode = $fetchMode;
+ }
+ if ($fetchType != 0) {
+ $this->_fetchType = $fetchType;
+ }
+ }
- /**
- * 设置获取模式
- *
- * @param int $fetchMode 设置获取的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM...
- * @param boolean $flush 是否统一设置所有PDOStatement中的获取方式
- */
- public function setFetchMode($fetchMode, $flush = false) {
- $this->_fetchMode = $fetchMode;
- if ($flush) {
- $fetchMode = func_get_args();
- call_user_func_array(array($this->_statement, 'setFetchMode'), $fetchMode);
- }
- }
+ /**
+ * 设置获取模式
+ *
+ * @param int $fetchMode
+ * 设置获取的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM...
+ * @param bool $flush
+ * 是否统一设置所有PDOStatement中的获取方式
+ */
+ public function setFetchMode($fetchMode, $flush = false)
+ {
+ $this->_fetchMode = $fetchMode;
+ $flush && $this->_statement->setFetchMode($fetchMode);
+ }
- /**
- * 返回最后一条Sql语句的影响行数
- *
- * @return int
- */
- public function rowCount() {
- return $this->_statement->rowCount();
- }
+ /**
+ * 返回最后一条Sql语句的影响行数
+ *
+ * @return int
+ */
+ public function rowCount()
+ {
+ return $this->_statement->rowCount();
+ }
- /**
- * 返回结果集中的列数
- *
- * @return number
- */
- public function columnCount() {
- return $this->_statement->columnCount();
- }
+ /**
+ * 返回结果集中的列数
+ *
+ * @return number
+ */
+ public function columnCount()
+ {
+ return $this->_statement->columnCount();
+ }
- /**
- * 获得结果集的下一行
- *
- * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
- * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,设置Statement的属性设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
- * @return array
- */
- public function fetch($fetchMode = 0, $fetchType = 0) {
- if ($fetchMode === 0) $fetchMode = $this->_fetchMode;
- if ($fetchType === 0) $fetchType = $this->_fetchType;
- return $this->_fetch($fetchMode, $fetchType);
- }
+ /**
+ * 获得结果集的下一行
+ *
+ * @param int $fetchMode
+ * 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
+ * @param int $fetchType
+ * 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,
+ * 设置Statement的属性设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
+ * @return array
+ */
+ public function fetch($fetchMode = 0, $fetchType = 0)
+ {
+ if ($fetchMode === 0) {
+ $fetchMode = $this->_fetchMode;
+ }
+ if ($fetchType === 0) {
+ $fetchType = $this->_fetchType;
+ }
- /**
- * @param string $fetchMode
- * @param string $fetchType
- */
- private function _fetch($fetchMode, $fetchType) {
- if (!empty($this->_columns)) $fetchMode = PDO::FETCH_BOUND;
- $result = array();
- if ($row = $this->_statement->fetch($fetchMode, $fetchType)) {
- if (empty($this->_columns))
- $result = $row;
- else
- foreach ($this->_columns as $key => $value) {
- $result[$key] = $value;
- }
- }
- return $result;
- }
+ return $this->_fetch($fetchMode, $fetchType);
+ }
- /**
- * 返回所有的查询结果
- *
- * @param string $index 输出数组下标
- * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
- * @return array
- */
- public function fetchAll($index = '', $fetchMode = 0) {
- if ($fetchMode === 0) $fetchMode = $this->_fetchMode;
- $result = array();
- if (!$index)
- while ($row = $this->fetch($fetchMode))
- $result[] = $row;
- else
- while ($row = $this->fetch($fetchMode)) {
- if (!isset($row[$index])) continue;
- $result[$row[$index]] = $row;
- }
- return $result;
- }
+ /**
+ *
+ * @param string $fetchMode
+ * @param string $fetchType
+ */
+ private function _fetch($fetchMode, $fetchType)
+ {
+ if (!empty($this->_columns)) {
+ $fetchMode = PDO::FETCH_BOUND;
+ }
+ $result = array();
+ if ($row = $this->_statement->fetch($fetchMode, $fetchType)) {
+ if (empty($this->_columns)) {
+ $result = $row;
+ } else {
+ foreach ($this->_columns as $key => $value) {
+ $result[$key] = $value;
+ }
+ }
+ }
- /**
- * 从下一行记录中获得下标是$index的值,如果获取失败则返回false
- *
- * @param int $index 列下标
- * @return string|bool
- */
- public function fetchColumn($index = 0) {
- $result = $this->_statement->fetchColumn($index);
- if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info(
- "[component.db.WindResultSet.fetchColumn] \r\n\tResult:" . WindString::varToString(
- $result));
- return $result;
- }
+ return $result;
+ }
- /**
- * 获得结果集中的下一行,同时根据设置的类返回如果没有设置则返回的使StdClass对象
- *
- * @param string $className 使用的类
- * @param array $ctor_args 初始化参数
- * @return object
- */
- public function fetchObject($className = '', $ctor_args = array()) {
- if ($className === '')
- return $this->_statement->fetchObject();
- else
- return $this->_statement->fetchObject($className, $ctor_args);
- }
+ /**
+ * 返回所有的查询结果
+ *
+ * @param string $index
+ * 输出数组下标
+ * @param int $fetchMode
+ * 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
+ * @return array
+ */
+ public function fetchAll($index = '', $fetchMode = 0)
+ {
+ if ($fetchMode === 0) {
+ $fetchMode = $this->_fetchMode;
+ }
+ $result = array();
+ if (!$index) {
+ while ($row = $this->fetch($fetchMode)) {
+ $result[] = $row;
+ }
+ } else {
+ while ($row = $this->fetch($fetchMode)) {
+ if (!isset($row[$index])) {
+ continue;
+ }
+ $result[$row[$index]] = $row;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * 从下一行记录中获得下标是$index的值,如果获取失败则返回false
+ *
+ * @param int $index
+ * 列下标
+ * @return string bool
+ */
+ public function fetchColumn($index = 0)
+ {
+ return $this->_statement->fetchColumn($index);
+ }
+
+ /**
+ * 获得结果集中的下一行,同时根据设置的类返回如果没有设置则返回的使StdClass对象
+ *
+ * @param string $className
+ * 使用的类
+ * @param array $ctor_args
+ * 初始化参数
+ * @return object
+ */
+ public function fetchObject($className = '', $ctor_args = array())
+ {
+ if ($className === '') {
+ return $this->_statement->fetchObject();
+ } else {
+ return $this->_statement->fetchObject($className, $ctor_args);
+ }
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/db/WindSqlStatement.php b/wind/db/WindSqlStatement.php
index da5007f6..e2131922 100644
--- a/wind/db/WindSqlStatement.php
+++ b/wind/db/WindSqlStatement.php
@@ -1,363 +1,412 @@
2011-9-23
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindSqlStatement.php 3904 2013-01-08 07:01:26Z yishuo $
* @package db
*/
-class WindSqlStatement {
- /**
- * @var WindConnection
- */
- private $_connection;
- /**
- * @var PDOStatement
- */
- private $_statement = null;
- /**
- * @var string
- */
- private $_queryString;
- /**
- * PDO类型映射
- *
- * @var array
- */
- private $_typeMap = array(
- 'boolean' => PDO::PARAM_BOOL,
- 'integer' => PDO::PARAM_INT,
- 'string' => PDO::PARAM_STR,
- 'NULL' => PDO::PARAM_NULL);
- /**
- * @var array
- */
- private $_columns = array();
-
- /**
- * @param WindConnection $connection WindConnection对象
- * @param string $query 预定义语句
- */
- public function __construct($connection, $query) {
- $this->_connection = $connection;
- $this->_queryString = $query;
- }
-
- /**
- * 参数绑定
- *
- * @param mixed $parameter 预定义语句的待绑定的位置
- * @param mixed &$variable 绑定的值
- * @param int $dataType 值的类型(PDO::PARAM_STR/PDO::PARAM_INT...)
- * @param int $length 绑定值的长度
- * @param mixed $driverOptions
- * @return WindSqlStatement
- * @see PDOStatement::bindParam()
- * @throws WindDbException
- */
- public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null) {
- try {
- $this->init();
- if ($dataType === null) {
- $dataType = $this->_getPdoDataType($variable);
- }
- if ($length === null)
- $this->getStatement()->bindParam($parameter, $variable, $dataType);
- else
- $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, $driverOptions);
- return $this;
- } catch (PDOException $e) {
- throw new WindDbException($e->getMessage());
- }
- }
-
- /**
- * 批量绑定变量
- *
- * 如果是一维数组,则使用key=>value的形式,key代表变量位置,value代表替换的值,而替换值需要的类型则通过该值的类型来判断---不准确
- * 如果是一个二维数组,则允许,key=>array(0=>value, 1=>data_type, 2=>length, 3=>driver_options)的方式来传递变量。
- *
- * @param array $parameters
- * @return WindSqlStatement
- * @see PDOStatement::bindParam()
- * @throws WindDbException
- */
- public function bindParams(&$parameters) {
- if (!is_array($parameters)) throw new WindDbException(
- '[component.db.WindSqlStatement.bindParams] Error unexpected paraments type ' . gettype($parameters));
-
- $keied = (array_keys($parameters) !== range(0, sizeof($parameters) - 1));
- foreach ($parameters as $key => $value) {
- $_key = $keied ? $key : $key + 1;
- if (is_array($value)) {
- $dataType = isset($value[1]) ? $value[1] : $this->_getPdoDataType($value[0]);
- $length = isset($value[2]) ? $value[2] : null;
- $driverOptions = isset($value[3]) ? $value[3] : null;
- $this->bindParam($_key, $parameters[$key][0], $dataType, $length, $driverOptions);
- } else
- $this->bindParam($_key, $parameters[$key], $this->_getPdoDataType($value));
- }
- return $this;
- }
-
- /**
- * 参数绑定
- *
- * @param string $parameter 预定义语句的待绑定的位置
- * @param string $value 绑定的值
- * @param int $data_type 值的类型
- * @return WindSqlStatement
- * @see PDOStatement::bindValue()
- * @throws WindDbException
- */
- public function bindValue($parameter, $value, $data_type = null) {
- try {
- $this->init();
- if ($data_type === null) $data_type = $this->_getPdoDataType($value);
- $this->getStatement()->bindValue($parameter, $value, $data_type);
- return $this;
- } catch (PDOException $e) {
- throw new WindDbException($e->getMessage());
- }
- }
-
- /**
- * 调用bindValue的批量绑定参数
- *
- * @param array $values 待绑定的参数值
- * @return WindSqlStatement
- * @see PDOStatement::bindValue()
- * @throws WindDbException
- */
- public function bindValues($values) {
- if (!is_array($values)) throw new WindDbException(
- '[component.db.WindSqlStatement.bindValues] Error unexpected paraments type \'' . gettype($values) . '\'');
-
- $keied = (array_keys($values) !== range(0, sizeof($values) - 1));
- foreach ($values as $key => $value) {
- if (!$keied) $key = $key + 1;
- $this->bindValue($key, $value, $this->_getPdoDataType($value));
- }
- return $this;
- }
-
- /**
- * 绑定输出结果集的列到PHP变量
- *
- * @param mixed $column 需要被绑定的字段列表,可以是字段名,也可以是字段的对应的下标
- * @param mixed &$param 需要被绑定的php变量
- * @param int $type 参数的数据类型 PDO::PARAM_*
- * @param int $maxlen A hint for pre-allocation.
- * @param mixed $driverdata Optional parameter(s) for the driver.
- * @return WindSqlStatement
- * @see PDOStatement::bindColumn()
- * @throws WindDbException
- */
- public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null) {
- try {
- $this->init();
- if ($type == null) $type = $this->_getPdoDataType($param);
- if ($type == null)
- $this->getStatement()->bindColumn($column, $param);
- elseif ($maxlen == null)
- $this->getStatement()->bindColumn($column, $param, $type);
- else
- $this->getStatement()->bindColumn($column, $param, $type, $maxlen, $driverdata);
- $this->_columns[$column] = & $param;
- return $this;
- } catch (PDOException $e) {
- throw new WindDbException($e->getMessage());
- }
- }
-
- /**
- * 批量绑定输出结果集的列到PHP变量
- *
- * @param array $columns 待绑定的列
- * @param array &$param 需要绑定的php变量
- * @see PDOStatement::bindColumn()
- * @return WindSqlStatement
- */
- public function bindColumns($columns, &$param = array()) {
- $int = 0;
- foreach ($columns as $value) {
- $this->bindColumn($value, $param[$int++]);
- }
- return $this;
- }
-
- /**
- * 绑定参数,执行SQL语句,并返回更新影响行数
- *
- * @param array $params 预定义语句中需要绑定的参数
- * @param boolean $rowCount 是否返回影响行数
- * @return int|boolean
- * @throws WindDbException
- */
- public function update($params = array(), $rowCount = false) {
- return $this->execute($params, $rowCount);
- }
-
- /**
- * 绑定参数,执行SQL语句,并返回查询结果
- *
- * @param array $params 预定义语句中需要绑定的参数
- * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
- * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
- * @return WindResultSet
- */
- public function query($params = array(), $fetchMode = 0, $fetchType = 0) {
- $this->execute($params, false);
- return new WindResultSet($this, $fetchMode, $fetchType);
- }
-
- /**
- * 绑定参数,执行SQL语句,并返回查询结果
- *
- * @param array $params 预定义语句中需要绑定的参数
- * @param string $index 返回的数组的下标对应的字段
- * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
- * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
- * @return array 返回处理后的结果
- */
- public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0) {
- $this->execute($params, false);
- $rs = new WindResultSet($this, $fetchMode, $fetchType);
- return $rs->fetchAll($index);
- }
-
- /**
- * 绑定参数,执行SQL语句,并返回查询到的结果集中某一个列的值
- *
- * @param array $params 预定义语句中需要绑定的参数
- * @param int $column 列的下标,默认为0即第一列
- * @return string
- */
- public function getValue($params = array(), $column = 0) {
- $this->execute($params, false);
- $rs = new WindResultSet($this, PDO::FETCH_NUM, 0);
- return $rs->fetchColumn($column);
- }
-
- /**
- * 绑定参数,执行SQL语句,并返回一行查询结果
- *
- * @param array $params 预定义语句中需要绑定的参数
- * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
- * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
- * @return array
- */
- public function getOne($params = array(), $fetchMode = 0, $fetchType = 0) {
- $this->execute($params, false);
- $rs = new WindResultSet($this, $fetchMode, $fetchType);
- return $rs->fetch();
- }
-
- /* (non-PHPdoc)
- * @see WindConnection::lastInsterId()
- */
- public function lastInsertId($name = '') {
- return $this->getConnection()->lastInsertId($name);
- }
-
- /**
- * 绑定参数,执行SQL语句,并返回影响行数
- *
- * @param array $params -- 绑定的参数和bindValues的参数一样
- * @param boolean $rowCount 是否返回受印象行数
- * @return rowCount
- */
- public function execute($params = array(), $rowCount = true) {
- try {
- if (WIND_DEBUG & 2) {
- Wind::getApp()->getComponent('windLogger')->profileBegin('SQL:execute sql statement.', 'db');
- Wind::getApp()->getComponent('windLogger')->info(
- "[component.db.WindSqlStatement.execute] \r\n\tSQL:" . $this->getQueryString(), 'db');
- }
- $this->init();
- $this->bindValues($params);
- $this->getStatement()->execute();
- $_result = $rowCount ? $this->getStatement()->rowCount() : true;
- if (WIND_DEBUG & 2) {
- Wind::getApp()->getComponent('windLogger')->profileEnd('SQL:execute sql statement.', 'db');
- Wind::getApp()->getComponent('windLogger')->info(
- "[component.db.WindSqlStatement.execute] execute sql statement success.\r\n", 'db');
- }
- return $_result;
- } catch (PDOException $e) {
- throw new WindDbException('[component.db.WindSqlStatement.execute]' . $e->getMessage());
- }
- }
-
- /**
- * 获得查询的预定义语句
- *
- * @return string
- */
- public function getQueryString() {
- return $this->_queryString;
- }
-
- /**
- * 获得PDO链接对象
- *
- * @return WindConnection
- */
- public function getConnection() {
- return $this->_connection;
- }
-
- /**
- * 获得PDOStatement对象
- *
- * @return PDOStatement
- */
- public function getStatement() {
- return $this->_statement;
- }
-
- /**
- * 获得需要绑定的结果输出的列值
- *
- * @return array
- */
- public function getColumns() {
- return $this->_columns;
- }
-
- /**
- * 初始化数据库链接信息
- *
- * @return void
- * @throws WindDbException
- */
- public function init() {
- if ($this->_statement === null) {
- try {
- $this->_statement = $this->getConnection()->getDbHandle()->prepare($this->getQueryString());
- if (WIND_DEBUG & 2) Wind::getApp()->getComponent('windLogger')->info(
- "[component.db.WindSqlStatement.init] Initialize statement success.", 'db');
- } catch (PDOException $e) {
- throw new WindDbException("Initialization WindSqlStatement failed." . $e->getMessage());
- }
- }
- }
-
- /**
- * 获得绑定参数的类型
- *
- * @param string $variable
- * @return int
- */
- private function _getPdoDataType($variable) {
- return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR;
- }
+class WindSqlStatement
+{
+ /**
+ * @var WindConnection
+ */
+ private $_connection;
+ /**
+ * @var PDOStatement
+ */
+ private $_statement = null;
+ /**
+ * @var string
+ */
+ private $_queryString;
+ /**
+ * PDO类型映射
+ *
+ * @var array
+ */
+ private $_typeMap = array(
+ 'boolean' => PDO::PARAM_BOOL,
+ 'integer' => PDO::PARAM_INT,
+ 'string' => PDO::PARAM_STR,
+ 'NULL' => PDO::PARAM_NULL, );
+ /**
+ * @var array
+ */
+ private $_columns = array();
+ /**
+ * @var array
+ */
+ private $_param = array();
+
+ /**
+ * @param WindConnection $connection WindConnection对象
+ * @param string $query 预定义语句
+ */
+ public function __construct($connection = null, $query = '')
+ {
+ $connection && $this->_connection = $connection;
+ $query && $this->setQueryString($query);
+ }
+
+ /**
+ * 参数绑定
+ *
+ * @param mixed $parameter 预定义语句的待绑定的位置
+ * @param mixed &$variable 绑定的值
+ * @param int $dataType 值的类型(PDO::PARAM_STR/PDO::PARAM_INT...)
+ * @param int $length 绑定值的长度
+ * @param mixed $driverOptions
+ * @return WindSqlStatement
+ * @see PDOStatement::bindParam()
+ * @throws WindDbException
+ */
+ public function bindParam($parameter, &$variable, $dataType = null, $length = null, $driverOptions = null)
+ {
+ try {
+ if ($dataType === null) {
+ $dataType = $this->_getPdoDataType($variable);
+ }
+ if ($length === null) {
+ $this->getStatement()->bindParam($parameter, $variable, $dataType);
+ } else {
+ $this->getStatement()->bindParam($parameter, $variable, $dataType, $length, $driverOptions);
+ }
+ $this->_param[$parameter] = $variable;
+
+ return $this;
+ } catch (PDOException $e) {
+ throw new WindDbException('[db.WindSqlStatement.bindParam] '.$e->getMessage());
+ }
+ }
+
+ /**
+ * 批量绑定变量
+ *
+ * 如果是一维数组,则使用key=>value的形式,key代表变量位置,value代表替换的值,而替换值需要的类型则通过该值的类型来判断---不准确
+ * 如果是一个二维数组,则允许,key=>array(0=>value, 1=>data_type, 2=>length, 3=>driver_options)的方式来传递变量。
+ *
+ * @param array $parameters
+ * @return WindSqlStatement
+ * @see PDOStatement::bindParam()
+ * @throws WindDbException
+ */
+ public function bindParams(&$parameters)
+ {
+ if (!is_array($parameters)) {
+ throw new WindDbException(
+ '[db.WindSqlStatement.bindParams] Error unexpected paraments type '.gettype($parameters));
+ }
+
+ $keied = (array_keys($parameters) !== range(0, count($parameters) - 1));
+ foreach ($parameters as $key => $value) {
+ $_key = $keied ? $key : $key + 1;
+ if (is_array($value)) {
+ $dataType = isset($value[1]) ? $value[1] : $this->_getPdoDataType($value[0]);
+ $length = isset($value[2]) ? $value[2] : null;
+ $driverOptions = isset($value[3]) ? $value[3] : null;
+ $this->bindParam($_key, $parameters[$key][0], $dataType, $length, $driverOptions);
+ } else {
+ $this->bindParam($_key, $parameters[$key], $this->_getPdoDataType($value));
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * 参数绑定
+ *
+ * @param string $parameter 预定义语句的待绑定的位置
+ * @param string $value 绑定的值
+ * @param int $data_type 值的类型
+ * @return WindSqlStatement
+ * @see PDOStatement::bindValue()
+ * @throws WindDbException
+ */
+ public function bindValue($parameter, $value, $data_type = null)
+ {
+ try {
+ if ($data_type === null) {
+ $data_type = $this->_getPdoDataType($value);
+ }
+ $this->getStatement()->bindValue($parameter, $value, $data_type);
+ $this->_param[$parameter] = $value;
+
+ return $this;
+ } catch (PDOException $e) {
+ throw new WindDbException('[db.WindSqlStatement.bindValue] '.$e->getMessage());
+ }
+ }
+
+ /**
+ * 调用bindValue的批量绑定参数
+ *
+ * @param array $values 待绑定的参数值
+ * @return WindSqlStatement
+ * @see PDOStatement::bindValue()
+ * @throws WindDbException
+ */
+ public function bindValues($values)
+ {
+ if (!is_array($values)) {
+ throw new WindDbException(
+ '[db.WindSqlStatement.bindValues] Error unexpected paraments type \''.gettype($values).'\'');
+ }
+
+ $keied = (array_keys($values) !== range(0, count($values) - 1));
+ foreach ($values as $key => $value) {
+ if (!$keied) {
+ $key = $key + 1;
+ }
+ $this->bindValue($key, $value, $this->_getPdoDataType($value));
+ }
+
+ return $this;
+ }
+
+ /**
+ * 绑定输出结果集的列到PHP变量
+ *
+ * @param mixed $column 需要被绑定的字段列表,可以是字段名,也可以是字段的对应的下标
+ * @param mixed &$param 需要被绑定的php变量
+ * @param int $type 参数的数据类型 PDO::PARAM_*
+ * @param int $maxlen A hint for pre-allocation.
+ * @param mixed $driverdata Optional parameter(s) for the driver.
+ * @return WindSqlStatement
+ * @see PDOStatement::bindColumn()
+ * @throws WindDbException
+ */
+ public function bindColumn($column, &$param = '', $type = null, $maxlen = null, $driverdata = null)
+ {
+ try {
+ if ($type == null) {
+ $type = $this->_getPdoDataType($param);
+ }
+ if ($type == null) {
+ $this->getStatement()->bindColumn($column, $param);
+ } elseif ($maxlen == null) {
+ $this->getStatement()->bindColumn($column, $param, $type);
+ } else {
+ $this->getStatement()->bindColumn($column, $param, $type, $maxlen, $driverdata);
+ }
+ $this->_columns[$column] = & $param;
+
+ return $this;
+ } catch (PDOException $e) {
+ throw new WindDbException('[db.WindSqlStatement.bindColumn] '.$e->getMessage());
+ }
+ }
+
+ /**
+ * 批量绑定输出结果集的列到PHP变量
+ *
+ * @param array $columns 待绑定的列
+ * @param array &$param 需要绑定的php变量
+ * @see PDOStatement::bindColumn()
+ * @return WindSqlStatement
+ */
+ public function bindColumns($columns, &$param = array())
+ {
+ $int = 0;
+ foreach ($columns as $value) {
+ $this->bindColumn($value, $param[$int++]);
+ }
+
+ return $this;
+ }
+
+ /**
+ * 绑定参数,执行SQL语句,并返回更新影响行数
+ *
+ * @param array $params 预定义语句中需要绑定的参数
+ * @param bool $rowCount 是否返回影响行数
+ * @return int|bool
+ * @throws WindDbException
+ */
+ public function update($params = array(), $rowCount = false)
+ {
+ return $this->execute($params, $rowCount);
+ }
+
+ /**
+ * 绑定参数,执行SQL语句,并返回查询结果
+ *
+ * @param array $params 预定义语句中需要绑定的参数
+ * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
+ * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
+ * @return WindResultSet
+ */
+ public function query($params = array(), $fetchMode = 0, $fetchType = 0)
+ {
+ $this->execute($params, false);
+
+ return new WindResultSet($this, $fetchMode, $fetchType);
+ }
+
+ /**
+ * 绑定参数,执行SQL语句,并返回查询结果
+ *
+ * @param array $params 预定义语句中需要绑定的参数
+ * @param string $index 返回的数组的下标对应的字段
+ * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
+ * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
+ * @return array 返回处理后的结果
+ */
+ public function queryAll($params = array(), $index = '', $fetchMode = 0, $fetchType = 0)
+ {
+ $this->execute($params, false);
+ $rs = new WindResultSet($this, $fetchMode, $fetchType);
+
+ return $rs->fetchAll($index);
+ }
+
+ /**
+ * 绑定参数,执行SQL语句,并返回查询到的结果集中某一个列的值
+ *
+ * @param array $params 预定义语句中需要绑定的参数
+ * @param int $column 列的下标,默认为0即第一列
+ * @return string
+ */
+ public function getValue($params = array(), $column = 0)
+ {
+ $this->execute($params, false);
+ $rs = new WindResultSet($this, PDO::FETCH_NUM, 0);
+
+ return $rs->fetchColumn($column);
+ }
+
+ /**
+ * 绑定参数,执行SQL语句,并返回一行查询结果
+ *
+ * @param array $params 预定义语句中需要绑定的参数
+ * @param int $fetchMode 获得结果集的模式PDO::FETCH_BOTH/PDO::FETCH_ASSOC/PDO::FETCH_NUM
+ * @param int $fetchType 设置结果集的读取方式,PDO::FETCH_ORI_NEXT/PDO::FETCH_ORI_PRE,注意要使用该属性,必须通过setAttribute设置PDO::ATTR_CURSOR=PDO::CURSOR_SCROLL
+ * @return array
+ */
+ public function getOne($params = array(), $fetchMode = 0, $fetchType = 0)
+ {
+ $this->execute($params, false);
+ $rs = new WindResultSet($this, $fetchMode, $fetchType);
+
+ return $rs->fetch();
+ }
+
+ /* (non-PHPdoc)
+ * @see WindConnection::lastInsterId()
+ */
+ public function lastInsertId($name = '')
+ {
+ return $this->getConnection()->lastInsertId($name);
+ }
+
+ /**
+ * 绑定参数,执行SQL语句,并返回影响行数
+ *
+ * @param array $params -- 绑定的参数和bindValues的参数一样
+ * @param bool $rowCount 是否返回受印象行数
+ * @return rowCount
+ */
+ public function execute($params = array(), $rowCount = true)
+ {
+ try {
+ $this->bindValues($params);
+ $this->getStatement()->execute();
+ $_result = $rowCount ? $this->getStatement()->rowCount() : true;
+
+ return $_result;
+ } catch (PDOException $e) {
+ throw new WindDbException('[db.WindSqlStatement.execute] '.$e->getMessage()."\r\nSQL:".$this->getQueryString());
+ }
+ }
+
+ /**
+ * @param string $sql
+ */
+ public function setQueryString($sql)
+ {
+ try {
+ $this->_queryString = $sql;
+ $this->_statement = $this->getConnection()->getDbHandle()->prepare($sql);
+ } catch (PDOException $e) {
+ throw new WindDbException('[db.WindSqlStatement.setQueryString] Initialization WindSqlStatement failed.'.$e->getMessage());
+ }
+ }
+
+ /**
+ * 获得查询的预定义语句
+ *
+ * @return string
+ */
+ public function getQueryString()
+ {
+ return $this->_queryString;
+ }
+
+ /**
+ * @param WindConnection $connection
+ */
+ public function setConnection($connection)
+ {
+ $this->_connection = $connection;
+ }
+
+ /**
+ * 获得PDO链接对象
+ *
+ * @return WindConnection
+ */
+ public function getConnection()
+ {
+ return $this->_connection;
+ }
+
+ /**
+ * 获得PDOStatement对象
+ *
+ * @return PDOStatement
+ */
+ public function getStatement()
+ {
+ return $this->_statement;
+ }
+
+ /**
+ * 获取参数绑定列表
+ *
+ * @return array
+ */
+ public function getParams()
+ {
+ return $this->_param;
+ }
+
+ /**
+ * 获得需要绑定的结果输出的列值
+ *
+ * @return array
+ */
+ public function getColumns()
+ {
+ return $this->_columns;
+ }
+
+ /**
+ * 获得绑定参数的类型
+ *
+ * @param string $variable
+ * @return int
+ */
+ private function _getPdoDataType($variable)
+ {
+ return isset($this->_typeMap[gettype($variable)]) ? $this->_typeMap[gettype($variable)] : PDO::PARAM_STR;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/db/exception/WindDbException.php b/wind/db/exception/WindDbException.php
index d3c0ae2e..1e493354 100644
--- a/wind/db/exception/WindDbException.php
+++ b/wind/db/exception/WindDbException.php
@@ -1,123 +1,125 @@
2011-9-22
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindDbException.php 3871 2012-12-25 07:14:59Z yishuo $
* @package db
* @subpackage exception
*/
-class WindDbException extends WindException {
- /**
- * 连接相关的异常
- */
- const DB_CONN_EMPTY = 200;
-
- const DB_CONN_FORMAT = 201;
-
- const DB_CONN_NOT_EXIST = 202;
-
- const DB_CONN_EXIST = 203;
-
- const DB_CONNECT_NOT_EXIST = 204;
-
- /**
- * 查讯 相关的异常
- */
- const DB_QUERY_EMPTY = 210;
-
- const DB_QUERY_LINK_EMPTY = 211;
-
- const DB_QUERY_FIELD_EMPTY = 212;
-
- const DB_QUERY_FIELD_EXIST = 213;
-
- const DB_QUERY_FIELD_FORMAT = 214;
-
- const DB_QUERY_INSERT_DATA = 215;
-
- const DB_QUERY_UPDATE_DATA = 216;
-
- const DB_QUERY_CONDTTION_FORMAT = 217;
-
- const DB_QUERY_GROUP_MATCH = 218;
-
- const DB_QUERY_LOGIC_MATCH = 219;
-
- const DB_QUERY_FETCH_ERROR = 220;
-
- const DB_QUERY_TRAN_BEGIN = 221;
-
- const DB_QUERY_COMPARESS_ERROR = 222;
-
- const DB_QUERY_COMPARESS_EXIST = 223;
-
- const DB_QUERY_WHERE_ERROR = 224;
-
- const DB_QUERY_JOIN_TYPE_ERROR = 225;
-
- const DB_QUERY_ERROR = 226;
-
- /**
- * 字段异常
- */
- const DB_TABLE_EMPTY = 240;
-
- const DB_EMPTY = 241;
-
- const DB_DRIVER_NOT_EXIST = 242;
-
- const DB_DRIVER_EXIST = 243;
-
- const DB_BUILDER_NOT_EXIST = 250;
-
- const DB_BUILDER_EXIST = 251;
-
- const DB_DRIVER_BUILDER_NOT_MATCH = 252;
-
- const DB_ADAPTER_NOT_EXIST = 260;
-
- const DB_ADAPTER_EXIST = 261;
-
- /* (non-PHPdoc)
- * @see WindException::messageMapper()
- */
- protected function messageMapper($code) {
- $messages = array(
- self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ',
- self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ',
- self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ',
- self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.',
- self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.',
- self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'',
- self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.',
- self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.',
- self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.',
- self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'',
- self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'',
- self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'',
- self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'',
- self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.',
- self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.',
- self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'',
- self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'',
- self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'',
- self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'',
- self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'',
- self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'',
- self::DB_QUERY_ERROR => 'Query error. \'$message\'',
- self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'',
- self::DB_EMPTY => 'Database is empty. \'$message\'',
- self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'',
- self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'',
- self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'',
- self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'',
- self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'',
- self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'',
- self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. ');
- return isset($messages[$code]) ? $messages[$code] : '$message';
- }
+class WindDbException extends WindException
+{
+ /**
+ * 连接相关的异常
+ */
+ const DB_CONN_EMPTY = 1200;
+
+ const DB_CONN_FORMAT = 1201;
+
+ const DB_CONN_NOT_EXIST = 1202;
+
+ const DB_CONN_EXIST = 1203;
+
+ const DB_CONNECT_NOT_EXIST = 1204;
+
+ /**
+ * 查讯 相关的异常
+ */
+ const DB_QUERY_EMPTY = 1210;
+
+ const DB_QUERY_LINK_EMPTY = 1211;
+
+ const DB_QUERY_FIELD_EMPTY = 1212;
+
+ const DB_QUERY_FIELD_EXIST = 1213;
+
+ const DB_QUERY_FIELD_FORMAT = 1214;
+
+ const DB_QUERY_INSERT_DATA = 1215;
+
+ const DB_QUERY_UPDATE_DATA = 1216;
+
+ const DB_QUERY_CONDTTION_FORMAT = 1217;
+
+ const DB_QUERY_GROUP_MATCH = 1218;
+
+ const DB_QUERY_LOGIC_MATCH = 1219;
+
+ const DB_QUERY_FETCH_ERROR = 1220;
+
+ const DB_QUERY_TRAN_BEGIN = 1221;
+
+ const DB_QUERY_COMPARESS_ERROR = 1222;
+
+ const DB_QUERY_COMPARESS_EXIST = 1223;
+
+ const DB_QUERY_WHERE_ERROR = 1224;
+
+ const DB_QUERY_JOIN_TYPE_ERROR = 1225;
+
+ const DB_QUERY_ERROR = 126;
+
+ /**
+ * 字段异常
+ */
+ const DB_TABLE_EMPTY = 1240;
+
+ const DB_EMPTY = 1241;
+
+ const DB_DRIVER_NOT_EXIST = 1242;
+
+ const DB_DRIVER_EXIST = 1243;
+
+ const DB_BUILDER_NOT_EXIST = 1250;
+
+ const DB_BUILDER_EXIST = 1251;
+
+ const DB_DRIVER_BUILDER_NOT_MATCH = 1252;
+
+ const DB_ADAPTER_NOT_EXIST = 1260;
+
+ const DB_ADAPTER_EXIST = 1261;
+
+ /* (non-PHPdoc)
+ * @see WindException::messageMapper()
+ */
+ protected function messageMapper($code)
+ {
+ $messages = array(
+ self::DB_CONN_EMPTY => 'Database configuration is empty. \'$message\' ',
+ self::DB_CONN_FORMAT => 'Database configuration format is incorrect. \'$message\' ',
+ self::DB_CONN_NOT_EXIST => '\'$message\' The identify of the database connection does not exist. ',
+ self::DB_CONN_EXIST => '\'$message\' The identify of the database connection is aleady exist.',
+ self::DB_CONNECT_NOT_EXIST => '\'$message\' The database connection does not exist.',
+ self::DB_QUERY_EMPTY => 'Query is empty. \'$message\'',
+ self::DB_QUERY_LINK_EMPTY => '\'$message\' Query link is not a validate resource.',
+ self::DB_QUERY_FIELD_EMPTY => '\'$message\' Query field is empty.',
+ self::DB_QUERY_FIELD_EXIST => '\'$message\' Query field is not exist.',
+ self::DB_QUERY_FIELD_FORMAT => 'Inside the field in the query not formatted correctly. \'$message\'',
+ self::DB_QUERY_INSERT_DATA => 'The new data is empty. \'$message\'',
+ self::DB_QUERY_UPDATE_DATA => 'The Updated data is empty. \'$message\'',
+ self::DB_QUERY_CONDTTION_FORMAT => 'The conditions of query are not right. \'$message\'',
+ self::DB_QUERY_GROUP_MATCH => '\'$message\' Query group does not match.',
+ self::DB_QUERY_LOGIC_MATCH => '\'$message\' Query logic does not match.',
+ self::DB_QUERY_FETCH_ERROR => 'The wrong way to obtain the result set. \'$message\'',
+ self::DB_QUERY_TRAN_BEGIN => 'Transaction has not started. \'$message\'',
+ self::DB_QUERY_COMPARESS_ERROR => 'Query comparison is incorrect conversion or assembly. \'$message\'',
+ self::DB_QUERY_COMPARESS_EXIST => 'Comparison does not exist query. \'$message\'',
+ self::DB_QUERY_WHERE_ERROR => 'Query where is Error. \'$message\'',
+ self::DB_QUERY_JOIN_TYPE_ERROR => 'The database is wrong type of join query. \'$message\'',
+ self::DB_QUERY_ERROR => 'Query error. \'$message\'',
+ self::DB_TABLE_EMPTY => 'Table is empty. \'$message\'',
+ self::DB_EMPTY => 'Database is empty. \'$message\'',
+ self::DB_DRIVER_NOT_EXIST => 'The database driver does not exist. \'$message\'',
+ self::DB_DRIVER_EXIST => 'The database driver is aleady exist. \'$message\'',
+ self::DB_BUILDER_NOT_EXIST => 'The database builder does not exist. \'$message\'',
+ self::DB_BUILDER_EXIST => 'The database builder is aleady exist. \'$message\'',
+ self::DB_ADAPTER_NOT_EXIST => 'The database adapter does not exist. \'$message\'',
+ self::DB_ADAPTER_EXIST => 'The database adapter is aleady exist. \'$message\'',
+ self::DB_DRIVER_BUILDER_NOT_MATCH => '\'$message\' The database driver does not match with the builder. ', );
+
+ return isset($messages[$code]) ? $messages[$code] : '$message';
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/db/mysql/WindMysqlPdoAdapter.php b/wind/db/mysql/WindMysqlPdoAdapter.php
index 7e054f4d..f4c1f15c 100644
--- a/wind/db/mysql/WindMysqlPdoAdapter.php
+++ b/wind/db/mysql/WindMysqlPdoAdapter.php
@@ -1,128 +1,153 @@
* mysql:host=localhost;dbname=test
* //':'前面部分标明了链接类型为mysql.
*
* @author Qiong Wu 2011-9-22
- * @copyright ©2003-2103 phpwind.com
+ * @copyright (c)2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindMysqlPdoAdapter.php 3941 2013-05-31 05:41:07Z long.shi $
* @package db
* @subpackage mysql
*/
-class WindMysqlPdoAdapter extends AbstractWindPdoAdapter {
+class WindMysqlPdoAdapter extends AbstractWindPdoAdapter
+{
+ /* (non-PHPdoc)
+ * @see AbstractWindPdoAdapter::setCharset()
+ */
+ public function setCharset($charset)
+ {
+ if ($charset) {
+ $charset = $this->quote($charset);
+ $this->query(sprintf("set character_set_connection= %s, character_set_results= %s, character_set_client=binary, sql_mode='';", $charset, $charset));
+ $this->query("set names {$charset}");
+ }
+ }
+
+ /**
+ * 创建数据表
+ *
+ * 添加数据表,支持三个参数'数据表明,字段定义,是否覆盖已存在表'.'$values'举例如下,当数据表名称未定义,或者当'fields'字段未定义,或者为空时抛出异常:
+ *
+ * $values = array(
+ * 'fields' => "`id` smallint(5) unsigned NOT NULL auto_increment,
+ * `name` varchar(30) NOT NULL default '',PRIMARY KEY (`id`)",
+ * 'charset' => "utf-8",
+ * 'autoIncrement' => 'id',
+ * 'engine' => 'InnerDB');
+ *
+ * 注意:最后一个参数'$replace',有两个取值'true,false',当值为false时表示如果数据表存在不创建新表,
+ * 值为true时则删除已经存在的数据表并创建新表
+ *
+ * @param string $tableName 数据表名称
+ * @param string|array $values 数据表字段信息
+ * @param bool $replace 如果表已经存在是否覆盖,接收两个值true|false
+ * @see AbstractWindPdoAdapter::createTable()
+ * @return bool
+ * @throws WindDbException
+ */
+ public function createTable($tableName, $values, $replace = false)
+ {
+ if (empty($values['fields']) || !$tableName) {
+ throw new WindDbException(
+ '[db.mysql.WindMysqlPdoAdapter.createTable] create table file. ');
+ }
+
+ if ($replace) {
+ $_sql = 'DROP TABLE IF EXISTS '.$tableName.';';
+ }
+ $_sql .= 'CREATE TABLE IF NOT EXISTS '.$tableName;
+ $_sql .= '('.$values['fields'].')ENGINE='.(isset($values['engine']) ? $values['engine'] : 'MyISAM');
+ $_sql .= isset($values['charset']) ? ' DEFAULT CHARSET='.$values['charset'] : '';
+ $_sql .= isset($values['autoIncrement']) ? ' AUTO_INCREMENT='.$values['autoIncrement'] : '';
+
+ return $this->query($_sql);
+ }
+
+ /**
+ * 过滤数组并将数组变量转换为sql字符串
+ *
+ * 对数组中的值进行安全过滤,并转化为mysql支持的values的格式,如下例子:
+ *
+ * $variable = array('a','b','c');
+ * quoteArray($variable);
+ * //return string: ('a','b','c')
+ *
+ *
+ * @see AbstractWindPdoAdapter::quoteArray()
+ */
+ public function quoteArray($variable)
+ {
+ if (empty($variable) || !is_array($variable)) {
+ return '';
+ }
+ $_returns = array();
+ foreach ($variable as $value) {
+ $_returns[] = $this->quote($value);
+ }
+
+ return '('.implode(', ', $_returns).')';
+ }
+
+ /**
+ * 过滤二维数组将数组变量转换为多组的sql字符串
+ *
+ *
+ * $var = array(array('a1','b1','c1'),array('a2','b2','c2'));
+ * quoteMultiArrray($var);
+ * //return string: ('a1','b1','c1'),('a2','b2','c2')
+ *
+ *
+ * @see AbstractWindPdoAdapter::quoteMultiArray()
+ */
+ public function quoteMultiArray($var)
+ {
+ if (empty($var) || !is_array($var)) {
+ return '';
+ }
+ $_returns = array();
+ foreach ($var as $val) {
+ if (!empty($val) && is_array($val)) {
+ $_returns[] = $this->quoteArray($val);
+ }
+ }
- /* (non-PHPdoc)
- * @see AbstractWindPdoAdapter::setCharset()
- */
- public function setCharset($charset) {
- $charset && $this->query("set names " . $this->quote($charset) . ";");
- }
+ return implode(', ', $_returns);
+ }
- /**
- * 创建数据表
- *
- * 添加数据表,支持三个参数'数据表明,字段定义,是否覆盖已存在表'.'$values'举例如下,当数据表名称未定义,或者当'fields'字段未定义,或者为空时抛出异常:
- *
- * $values = array(
- * 'fields' => "`id` smallint(5) unsigned NOT NULL auto_increment,
- * `name` varchar(30) NOT NULL default '',PRIMARY KEY (`id`)",
- * 'charset' => "utf-8",
- * 'autoIncrement' => 'id',
- * 'engine' => 'InnerDB');
- *
- * 注意:最后一个参数'$replace',有两个取值'true,false',当值为false时表示如果数据表存在不创建新表,
- * 值为true时则删除已经存在的数据表并创建新表
- *
- * @param string $tableName 数据表名称
- * @param string|array $values 数据表字段信息
- * @param boolean $replace 如果表已经存在是否覆盖,接收两个值true|false
- * @see AbstractWindPdoAdapter::createTable()
- * @return boolean
- * @throws WindDbException
- */
- public function createTable($tableName, $values, $replace = false) {
- if (empty($values['fields']) || !$tableName) throw new WindDbException(
- '[db.mysql.WindMysqlPdoAdapter.createTable] create table file. ');
-
- if ($replace) $_sql = 'DROP TABLE IF EXISTS ' . $tableName . ';';
- $_sql .= 'CREATE TABLE IF NOT EXISTS ' . $tableName;
- $_sql .= "(" . $values['fields'] . ")ENGINE=" . (isset($values['engine']) ? $values['engine'] : 'MyISAM');
- $_sql .= isset($values['charset']) ? " DEFAULT CHARSET=" . $values['charset'] : '';
- $_sql .= isset($values['autoIncrement']) ? " AUTO_INCREMENT=" . $values['autoIncrement'] : '';
- return $this->query($_sql);
- }
+ /**
+ * 组装单条 key=value 形式的SQL查询语句值 insert/update
+ *
+ * @param array $array
+ * @return string
+ * @see AbstractWindPdoAdapter
+ */
+ public function sqlSingle($array)
+ {
+ if (!is_array($array)) {
+ return '';
+ }
+ $str = array();
+ foreach ($array as $key => $val) {
+ $str[] = $this->fieldMeta($key).'='.$this->quote($val);
+ }
- /**
- * 过滤数组并将数组变量转换为sql字符串
- *
- * 对数组中的值进行安全过滤,并转化为mysql支持的values的格式,如下例子:
- *
- * $variable = array('a','b','c');
- * quoteArray($variable);
- * //return string: ('a','b','c')
- *
- *
- * @see AbstractWindPdoAdapter::quoteArray()
- */
- public function quoteArray($variable) {
- if (empty($variable) || !is_array($variable)) return '';
- $_returns = array();
- foreach ($variable as $value) {
- $_returns[] = $this->quote($value);
- }
- return '(' . implode(', ', $_returns) . ')';
- }
-
- /**
- * 过滤二维数组将数组变量转换为多组的sql字符串
- *
- *
- * $var = array(array('a1','b1','c1'),array('a2','b2','c2'));
- * quoteMultiArrray($var);
- * //return string: ('a1','b1','c1'),('a2','b2','c2')
- *
- *
- * @see AbstractWindPdoAdapter::quoteMultiArray()
- */
- public function quoteMultiArray($var) {
- if (empty($var) || !is_array($var)) return '';
- $_returns = array();
- foreach ($var as $val) {
- if (!empty($val) && is_array($val)) {
- $_returns[] = $this->quoteArray($val);
- }
- }
- return implode(', ', $_returns);
- }
+ return $str ? implode(',', $str) : '';
+ }
- /**
- * 组装单条 key=value 形式的SQL查询语句值 insert/update
- *
- * @param array $array
- * @return string
- * @see AbstractWindPdoAdapter
- */
- public function sqlSingle($array) {
- if (!is_array($array)) return '';
- $str = array();
- foreach ($array as $key => $val) {
- $str[] = $this->fieldMeta($key) . '=' . $this->quote($val);
- }
- return $str ? implode(',', $str) : '';
- }
+ /* (non-PHPdoc)
+ * @see AbstractWindPdoAdapter::fieldMeta()
+ */
+ public function fieldMeta($data)
+ {
+ $data = str_replace(array('`', ' '), '', $data);
- /* (non-PHPdoc)
- * @see AbstractWindPdoAdapter::fieldMeta()
- */
- public function fieldMeta($data) {
- $data = str_replace(array('`', ' '), '', $data);
- return ' `' . $data . '` ';
- }
+ return ' `'.$data.'` ';
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/filter/WindActionFilter.php b/wind/filter/WindActionFilter.php
index 82526ec0..3a8a7323 100644
--- a/wind/filter/WindActionFilter.php
+++ b/wind/filter/WindActionFilter.php
@@ -1,15 +1,16 @@
* 'filters' => array(
* 'class' => 'WIND:filter.WindFilterChain', //设置使用的拦截链实现
* 'filter1' => array(
- * 'class' => 'MYAPP:filter.MyFilter', //设置设置实现的MyFilter类路径,MYAPP必须是一个有效的经过注册的命名空间
+ * 'class' =>
+ * 'MYAPP:filter.MyFilter', //设置设置实现的MyFilter类路径,MYAPP必须是一个有效的经过注册的命名空间
* 'pattern' => '*', //此处设置该拦截规则应用的范围,*意味着所有的action都将会应用该拦截规则
* )
* )
@@ -24,119 +25,117 @@
* 用户可以在filter中添加自己的特殊配置:比如:
*
* 'filters' => array(
- * 'class' => 'WIND:filter.WindFilterChain',
+ * 'class' => 'WIND:filter.WindFilterChain',
* 'filter1' => array(
- * 'class' => 'MYAPP:filter.TestFilter',
- * 'pattern' => '*',
+ * 'class' => 'MYAPP:filter.TestFilter',
+ * 'pattern' => '*',
* 'isOpen' => '1', //添加的配置
* )
* )
*
* 则在自己的TestFilter中设置一个属性名为isOpen同时设置该属性为protected权限,那么在使用的时候该配置的值将会赋值给该属性.
- *
+ *
* @author Qiong Wu
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindActionFilter.php 3829 2012-11-19 11:13:22Z yishuo $
* @package filter
*/
-abstract class WindActionFilter extends WindHandlerInterceptor {
- /**
- * action跳转类
- *
- * @var WindForward
- */
- protected $forward = null;
- /**
- * 错误处理类
- *
- * @var WindErrorMessage
- */
- protected $errorMessage = null;
- /**
- * 路由对象
- *
- * @var AbstractWindRouter
- */
- protected $router = null;
+abstract class WindActionFilter extends WindHandlerInterceptor
+{
+ /**
+ * action跳转类
+ *
+ * @var WindForward
+ */
+ protected $forward = null;
+ /**
+ * 错误处理类
+ *
+ * @var WindErrorMessage
+ */
+ protected $errorMessage = null;
+ /**
+ * 路由对象
+ *
+ * @var AbstractWindRouter
+ */
+ protected $router = null;
- /**
- * 构造函数
- *
- * 初始化类属性
- *
- * @param WindForward $forward 设置当前的forward对象
- * @param WindErrorMessage $errorMessage 设置错误处理的errorMessage
- * @param AbstractWindRouter $router 路由对象
- * @param array $args 接受数组传递,数组以关联数组的方式给出,如果存在属性和关联数组中的key相同则将该key对应值设置给该属性.
- */
- public function __construct($forward, $errorMessage, $router, $args = array()) {
- $this->forward = $forward;
- $this->errorMessage = $errorMessage;
- $this->router = $router;
- foreach ($args as $key => $value)
- property_exists($this, $key) && $this->$key = $value;
- }
+ /**
+ * 构造函数
+ * 初始化类属性
+ *
+ * @param WindForward $forward
+ * 设置当前的forward对象
+ * @param WindErrorMessage $errorMessage
+ * 设置错误处理的errorMessage
+ * @param AbstractWindRouter $router
+ * 路由对象
+ * @param array $args
+ * 接受数组传递,数组以关联数组的方式给出,如果存在属性和关联数组中的key相同则将该key对应值设置给该属性.
+ */
+ public function __construct($forward, $errorMessage, $router, $args = array())
+ {
+ $this->forward = $forward;
+ $this->errorMessage = $errorMessage;
+ $this->router = $router;
+ foreach ($args as $key => $value) {
+ property_exists($this, $key) && $this->$key = $value;
+ }
+ }
- /**
- * 设置模板数据
- *
- * 此方法设置的参数,作用域仅仅只是在当前模板中可用,调用的方法为{$varName}
- *
- * @param string|array|object $data 需要设置输出的参数
- * @param string $key 参数的名字,默认为空,如果key为空,并且$data是数组或是对象的时候,则$data中的元素将会作为单独的参数保存到输出数据中.
- */
- protected function setOutput($data, $key = '') {
- $this->forward->setVars($data, $key);
- }
+ /**
+ * 设置模板数据
+ * 此方法设置的参数,作用域仅仅只是在当前模板中可用,调用的方法为{$varName}
+ *
+ * @param string|array|object $data
+ * 需要设置输出的参数
+ * @param string $key
+ * 参数的名字,默认为空,如果key为空,并且$data是数组或是对象的时候,则$data中的元素将会作为单独的参数保存到输出数据中.
+ */
+ protected function setOutput($data, $key = '')
+ {
+ $this->forward->setVars($data, $key);
+ }
- /**
- * 设置全局模板数据
- *
- * 设置为Global的参数数据,将可以在所有子模板中共用,在模板中的通过{@G:varName}的方式去获取变量
- *
- * @param string|array|object $data 需要设置的数据
- * @param string $key 参数的名字,默认为空,如果key为空,并且$data是数组或是对象的时候,则$data中的元素将会作为单独的参数保存到Global数据中.
- */
- protected function setGlobal($data, $key = '') {
- Wind::getApp()->setGlobal($data, $key);
- }
+ /**
+ * 从指定源中根据输入的参数名获得输入数据
+ *
+ * @param string $name
+ * 需要获取的值的key
+ * @param string $type
+ * 获取数据源,可以是(GET POST COOKIE)中的一个,每种都将从各自的源中去获取对应的数值:
+ *
+ * - GET: 将从$_GET中去获取数据
+ * - POST: 将从$_POST中去获取数据
+ * - COOKIE: 将从$_COOKIE中去获取数据
+ * - 其他值:
+ * 将依次从request对象的attribute,$_GET,$_POST,$_COOKIE,$_REQUEST,$_ENV,$_SERVER中去尝试获取该值.
+ *
+ * 该参数默认为空
+ * @return array string
+ * - 第一个元素: 获得的用户输入的值
+ * - 第二个元素:执行$callback之后返回的值
+ *
+ */
+ protected function getInput($name, $type = '')
+ {
+ $value = '';
+ switch (strtolower($type)) {
+ case 'get':
+ $value = $this->getRequest()->getGet($name);
+ break;
+ case 'post':
+ $value = $this->getRequest()->getPost($name);
+ break;
+ case 'cookie':
+ $value = $this->getRequest()->getCookie($name);
+ break;
+ default:
+ $value = $this->getRequest()->getRequest($name);
+ }
- /**
- * 从指定源中根据输入的参数名获得输入数据
- *
- * @param string $name 需要获取的值的key
- * @param string $type 获取数据源,可以是(GET POST COOKIE)中的一个,每种都将从各自的源中去获取对应的数值:
- *
- * - GET: 将从$_GET中去获取数据
- * - POST: 将从$_POST中去获取数据
- * - COOKIE: 将从$_COOKIE中去获取数据
- * - 其他值: 将依次从request对象的attribute,$_GET,$_POST,$_COOKIE,$_REQUEST,$_ENV,$_SERVER中去尝试获取该值.
- *
- * 该参数默认为空
- * @param string $callback 回调函数,缺省值为空数组,该回调函数支持数组格式,即可以是调用类中的方法
- * @return array|string 当有$callback的时候返回一个数组,其有两个元素:
- *
- * - 第一个元素: 获得的用户输入的值
- * - 第二个元素:执行$callback之后返回的值
- *
- */
- protected function getInput($name, $type = '', $callback = array()) {
- $value = '';
- switch (strtolower($type)) {
- case 'get':
- $value = $this->getRequest()->getGet($name, null);
- break;
- case 'post':
- $value = $this->getRequest()->getPost($name, null);
- break;
- case 'cookie':
- $value = $this->getRequest()->getCookie($name, null);
- break;
- default:
- $value = $this->getRequest()->getAttribute($name, null);
- }
- return $callback ? array($value, call_user_func_array($callback, array($value))) : $value;
- }
+ return $value;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/filter/WindEnhancedListener.php b/wind/filter/WindEnhancedListener.php
new file mode 100644
index 00000000..5be4070e
--- /dev/null
+++ b/wind/filter/WindEnhancedListener.php
@@ -0,0 +1,76 @@
+
+ * {@link preHandle()}: 抽象接口,前置操作,需要子类实现
+ * {@link postHandle()}: 抽象接口,后置操作,需要子类实现
+ * {@link handle()}: 入口接口,调用拦截器的实现.
+ *
+ * 该拦截器需要配合拦截链WindHandlerInterceptorChain实现真正的拦截链.
+ *
+ * the last known user to change this file in the repository <$LastChangedBy: yishuo $>
+ * @author Qiong Wu
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindHandlerInterceptor.php 3107 2011-11-11 03:40:09Z yishuo $
+ * @package filter
+ */
+abstract class WindEnhancedListener extends WindModule
+{
+ protected $targetObject = null;
+ /**
+ * 保存执行的结果
+ *
+ * @var mixed
+ */
+ protected $result = null;
+ /**
+ * 保存拦截链
+ *
+ * 用以传递控制到下一个拦截器
+ *
+ * @var WindHandlerInterceptorChain
+ */
+ protected $interceptorChain = null;
+
+ /**
+ * 拦截器的执行入口
+ *
+ * @param mixed $var=.. 该接口接受任意参数,并将依次传递给拦截器的前置和后置操作
+ * @return mixed 返回拦截链执行的最终结果
+ */
+ public function handle($event, $targetObject = null)
+ {
+ $args = func_get_args();
+ $_args = array_slice($args, 2);
+ $this->targetObject = $targetObject;
+ if (method_exists($this, 'pre'.$event)) {
+ $this->result = call_user_func_array(array($this, 'pre'.$event), $_args);
+ if (null !== $this->result) {
+ return $this->result;
+ }
+ }
+ if (null !== ($handler = $this->interceptorChain->getHandler())) {
+ $this->result = call_user_func_array(array($handler, 'handle'), $args);
+ } else {
+ $this->result = call_user_func_array(array($this->interceptorChain, 'handle'), $_args);
+ }
+ if (method_exists($this, 'post'.$event)) {
+ call_user_func_array(array($this, 'post'.$event), $_args);
+ }
+
+ return $this->result;
+ }
+
+ /**
+ * 设置拦截链对象
+ *
+ * @param WindHandlerInterceptorChain $interceptorChain
+ */
+ public function setHandlerInterceptorChain($interceptorChain)
+ {
+ $this->interceptorChain = $interceptorChain;
+ }
+}
diff --git a/wind/filter/WindHandlerInterceptor.php b/wind/filter/WindHandlerInterceptor.php
index b287b658..503c03ee 100644
--- a/wind/filter/WindHandlerInterceptor.php
+++ b/wind/filter/WindHandlerInterceptor.php
@@ -1,7 +1,7 @@
* {@link preHandle()}: 抽象接口,前置操作,需要子类实现
@@ -14,68 +14,71 @@
* @author Qiong Wu
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindHandlerInterceptor.php 3113 2011-11-11 07:28:09Z yishuo $
* @package filter
*/
-abstract class WindHandlerInterceptor extends WindModule {
- /**
- * 保存执行的结果
- *
- * @var mixed
- */
- protected $result = null;
- /**
- * 保存拦截链
- *
- * 用以传递控制到下一个拦截器
- *
- * @var WindHandlerInterceptorChain
- */
- protected $interceptorChain = null;
+abstract class WindHandlerInterceptor extends WindModule
+{
+ /**
+ * 保存执行的结果
+ *
+ * @var mixed
+ */
+ protected $result = null;
+ /**
+ * 保存拦截链
+ *
+ * 用以传递控制到下一个拦截器
+ *
+ * @var WindHandlerInterceptorChain
+ */
+ protected $interceptorChain = null;
+
+ /**
+ * 拦截器的前置操作
+ *
+ * @param mixed $var=.. 参数列表将会从handle接口中传递继承
+ * @return null|mixed 如果返回为null则将会继续执行下一个拦截器,如果返回不为null则会中断拦截链的执行
+ */
+ abstract public function preHandle();
- /**
- * 拦截器的前置操作
- *
- * @param mixed $var=.. 参数列表将会从handle接口中传递继承
- * @return null|mixed 如果返回为null则将会继续执行下一个拦截器,如果返回不为null则会中断拦截链的执行
- */
- abstract public function preHandle();
+ /**
+ * 拦截器的后置操作
+ *
+ * @param mixed $var=.. 参数列表将会从handle接口中传递继承
+ */
+ abstract public function postHandle();
- /**
- * 拦截器的后置操作
- *
- * @param mixed $var=.. 参数列表将会从handle接口中传递继承
- */
- abstract public function postHandle();
+ /**
+ * 拦截器的执行入口
+ *
+ * @param mixed $var=.. 该接口接受任意参数,并将依次传递给拦截器的前置和后置操作
+ * @return mixed 返回拦截链执行的最终结果
+ */
+ public function handle()
+ {
+ $args = func_get_args();
+ $this->result = call_user_func_array(array($this, 'preHandle'), $args);
+ if ($this->result !== null) {
+ return $this->result;
+ }
+ if (null !== ($handler = $this->interceptorChain->getHandler())) {
+ $this->result = call_user_func_array(array($handler, 'handle'), $args);
+ } else {
+ $this->result = call_user_func_array(array($this->interceptorChain, 'handle'), $args);
+ }
+ call_user_func_array(array($this, 'postHandle'), $args);
- /**
- * 拦截器的执行入口
- *
- * @param mixed $var=.. 该接口接受任意参数,并将依次传递给拦截器的前置和后置操作
- * @return mixed 返回拦截链执行的最终结果
- */
- public function handle() {
- $args = func_get_args();
- $this->result = call_user_func_array(array($this, 'preHandle'), $args);
- if ($this->result !== null) {
- return $this->result;
- }
- if (null !== ($handler = $this->interceptorChain->getHandler())) {
- $this->result = call_user_func_array(array($handler, 'handle'), $args);
- } else {
- $this->result = call_user_func_array(array($this->interceptorChain, 'handle'), $args);
- }
- call_user_func_array(array($this, 'postHandle'), $args);
- return $this->result;
- }
+ return $this->result;
+ }
- /**
- * 设置拦截链对象
- *
- * @param WindHandlerInterceptorChain $interceptorChain
- */
- public function setHandlerInterceptorChain($interceptorChain) {
- $this->interceptorChain = $interceptorChain;
- }
+ /**
+ * 设置拦截链对象
+ *
+ * @param WindHandlerInterceptorChain $interceptorChain
+ */
+ public function setHandlerInterceptorChain($interceptorChain)
+ {
+ $this->interceptorChain = $interceptorChain;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/filter/WindHandlerInterceptorChain.php b/wind/filter/WindHandlerInterceptorChain.php
index 71a042c5..faea8537 100644
--- a/wind/filter/WindHandlerInterceptorChain.php
+++ b/wind/filter/WindHandlerInterceptorChain.php
@@ -1,109 +1,125 @@
*
- * the last known user to change this file in the repository <$LastChangedBy: yishuo $>
* @author Qiong Wu
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindHandlerInterceptorChain.php 3776 2012-10-23 09:30:30Z
+ * yishuo $
* @package filter
*/
-class WindHandlerInterceptorChain extends WindModule {
- /**
- * 拦截器
- *
- * @var array
- */
- protected $_interceptors = array('_Na' => null);
- /**
- * 设置拦截链的回调函数
- *
- * @var string|array
- */
- protected $_callBack = null;
- /**
- * 拦截链回调函数的参数
- *
- * @var array
- */
- protected $_args = array();
+class WindHandlerInterceptorChain extends WindModule
+{
+ /**
+ * 拦截器
+ *
+ * @var array
+ */
+ protected $_interceptors = array('_Na' => null);
+ /**
+ * 设置拦截链的回调函数
+ *
+ * @var string array
+ */
+ protected $_callBack = null;
+ /**
+ * 拦截链回调函数的参数
+ *
+ * @var array
+ */
+ protected $_args = array();
- /**
- * 设置回调方法
- *
- * @param string|array $callBack 回调方法,可以是字符串: 函数;也可以是数组: 类中的方法
- * @param array $args 回调函数的参数列表
- */
- public function setCallBack($callBack, $args = array()) {
- $this->_callBack = $callBack;
- $this->_args = $args;
- }
+ /**
+ * 设置回调方法
+ *
+ * @param string|array $callBack
+ * 回调方法,可以是字符串: 函数;也可以是数组: 类中的方法
+ * @param array $args
+ * 回调函数的参数列表
+ */
+ public function setCallBack($callBack, $args = array())
+ {
+ $this->_callBack = $callBack;
+ $this->_args = $args;
+ }
- /**
- * 执行callback方法
- *
- * @return mixed $var=.. 如果callBack没有被设置则返回null,否则返回回调函数的结果
- * @throws WindException 如果回调函数调用失败则抛出异常
- */
- public function handle() {
- reset($this->_interceptors);
- if ($this->_callBack === null) return null;
- if (is_string($this->_callBack) && !function_exists($this->_callBack)) {
- throw new WindException('[filter.WindHandlerInterceptorChain.execute]' . $this->_callBack,
- WindException::ERROR_FUNCTION_NOT_EXIST);
- }
- $this->_args || $this->_args = func_get_args();
- return call_user_func_array($this->_callBack, (array) $this->_args);
- }
+ /**
+ * 执行callback方法
+ *
+ * @return mixed $var=.. 如果callBack没有被设置则返回null,否则返回回调函数的结果
+ * @throws WindException 如果回调函数调用失败则抛出异常
+ */
+ public function handle()
+ {
+ reset($this->_interceptors);
+ if ($this->_callBack === null) {
+ return null;
+ }
+ if (is_string($this->_callBack) && !function_exists($this->_callBack)) {
+ throw new WindException('[filter.WindHandlerInterceptorChain.handle] '.$this->_callBack,
+ WindException::ERROR_FUNCTION_NOT_EXIST);
+ }
+ $this->_args || $this->_args = func_get_args();
- /**
- * 返回拦截链中的下一个拦截器
- *
- * @return WindHandlerInterceptor
- */
- public function getHandler() {
- if (count($this->_interceptors) <= 1) {
- return $this;
- }
- $handler = next($this->_interceptors);
- if ($handler === false) {
- return null;
- }
- if (method_exists($handler, 'handle')) {
- $handler->setHandlerInterceptorChain($this);
- return $handler;
- }
- return $this->getHandler();
- }
+ return call_user_func_array($this->_callBack, (array) $this->_args);
+ }
- /**
- * 添加拦截连中的拦截器对象
- *
- * 支持数组和对象两种类型,如果是数组则进行array_merge操作,如果不是数组则直接进行追加操作
- *
- * @param array|WindHandlerInterceptor $interceptors 拦截器数组或是单个拦截器
- */
- public function addInterceptors($interceptors) {
- if (is_array($interceptors))
- $this->_interceptors = array_merge($this->_interceptors, $interceptors);
- else
- $this->_interceptors[] = $interceptors;
- }
+ /**
+ * 返回拦截链中的下一个拦截器
+ *
+ * @return WindHandlerInterceptor
+ */
+ public function getHandler()
+ {
+ if (count($this->_interceptors) <= 1) {
+ return $this;
+ }
+ $handler = next($this->_interceptors);
+ if ($handler === false) {
+ reset($this->_interceptors);
- /**
- * 重置拦截链初始化信息
- *
- * @return boolean
- */
- public function reset() {
- $this->_interceptors = array('_Na' => null);
- $this->_callBack = null;
- $this->_args = array();
- return true;
- }
+ return null;
+ }
+ if (method_exists($handler, 'handle')) {
+ $handler->setHandlerInterceptorChain($this);
+
+ return $handler;
+ }
+
+ return $this->getHandler();
+ }
+
+ /**
+ * 添加拦截连中的拦截器对象
+ * 支持数组和对象两种类型,如果是数组则进行array_merge操作,如果不是数组则直接进行追加操作
+ *
+ * @param array|WindHandlerInterceptor $interceptors
+ * 拦截器数组或是单个拦截器
+ */
+ public function addInterceptors($interceptors)
+ {
+ if (is_array($interceptors)) {
+ $this->_interceptors = array_merge($this->_interceptors, $interceptors);
+ } else {
+ $this->_interceptors[] = $interceptors;
+ }
+ }
+
+ /**
+ * 重置拦截链初始化信息
+ *
+ * @return bool
+ */
+ public function reset()
+ {
+ $this->_interceptors = array('_Na' => null);
+ $this->_callBack = null;
+ $this->_args = array();
+
+ return true;
+ }
}
-?>
\ No newline at end of file
diff --git a/wind/filter/WindSimpleHandlerInterceptor.php b/wind/filter/WindSimpleHandlerInterceptor.php
new file mode 100644
index 00000000..fb3de9ac
--- /dev/null
+++ b/wind/filter/WindSimpleHandlerInterceptor.php
@@ -0,0 +1,51 @@
+
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id$
+ * @package wind
+ */
+class WindSimpleHandlerInterceptor
+{
+ /**
+ * 保存拦截链
+ * 用以传递控制到下一个拦截器
+ *
+ * @var WindHandlerInterceptorChain
+ */
+ protected $interceptorChain = null;
+
+ /**
+ * 拦截器的执行入口
+ *
+ * @param mixed $var=..
+ * 该接口接受任意参数,并将依次传递给拦截器的前置和后置操作
+ * @return mixed 返回拦截链执行的最终结果
+ */
+ public function handle($method)
+ {
+ if (method_exists($this, $method)) {
+ $this->$method();
+ }
+ $handler = $this->interceptorChain->getHandler();
+ if (null !== $handler) {
+ $handler->handle($method);
+ }
+
+ return;
+ }
+
+ /**
+ * 设置拦截链对象
+ *
+ * @param WindHandlerInterceptorChain $interceptorChain
+ */
+ public function setHandlerInterceptorChain($interceptorChain)
+ {
+ $this->interceptorChain = $interceptorChain;
+ }
+}
diff --git a/wind/filter/proxy/WindClassProxy.php b/wind/filter/proxy/WindClassProxy.php
new file mode 100644
index 00000000..adc947b4
--- /dev/null
+++ b/wind/filter/proxy/WindClassProxy.php
@@ -0,0 +1,178 @@
+
+ * //相关组件配置,只需设置 proxy为true,就可以通过组件工厂创建一个具有代理功能的类实例对象.
+ *
+ *
+ *
+ *
+ *
+ *
+ * $object = Wind::getComponents('windApplication');
+ * $object->registerEventListener('runProcess', new Listener());
+ *
+ * @author Qiong Wu
+ * ...
+ * $object = Wind::getComponents('windApplication');
+ * $object->registerEventListener('runProcess', new Listener());
+ *
+ * @param object $listener 事件监听器
+ * @param stinrg $event 被监听的事件
+ */
+ public function registerEventListener($listener, $event)
+ {
+ $this->_listener[$event][] = $listener;
+ }
+
+ /**
+ * 注册目标对象,如果已经注册了不重复注册
+ *
+ * WindFactory中创建类代理的一段例子:
+ * $instance = new Object();
+ * $this->addClassDefinitions($alias, array('path' => $proxy, 'scope' => 'prototype'));
+ * $proxy = $this->getInstance($alias);
+ * $proxy->registerTargetObject($instance);
+ * $instance->_proxy = $proxy;
+ *
+ * ...
+ * $object = Wind::getComponents('windApplication');
+ * $object->registerEventListener('runProcess', new Listener());
+ *
+ * @param stinrg $event 被监听的事件
+ * @param object $listener 事件监听器
+ */
+ public function registerEventListener($listener)
+ {
+ $this->_listener[] = $listener;
+ }
+
+ /**
+ * 注册目标对象,如果已经注册了不重复注册
+ *
+ * WindFactory中创建类代理的一段例子:
+ * $instance = new Object();
+ * $this->addClassDefinitions($alias, array('path' => $proxy, 'scope' => 'prototype'));
+ * $proxy = $this->getInstance($alias);
+ * $proxy->registerTargetObject($instance);
+ * $instance->_proxy = $proxy;
+ *
- * $session = Wind::getApp()->getComponent('WindSession');
- *
+ * $session = Wind::getComponent('WindSession');
+ *
* $session->set('name', 'test'); //等同:$_SESSION['name'] = 'test';
* echo $session->get('name'); //等同:echo $_SESSION['name'];
- *
+ *
* $session->delete('name'); //等同: unset($_SESSION['name');
* echo $session->getCurrentName(); //等同: echo session_name();
* echo $session->getCurrentId(); //等同: echo session_id();
@@ -36,151 +37,160 @@
* 'destroy' => 'commit',
* ),
*
- *
+ *
*
* @author xiaoxia.xu
- * INFO! Message: $msg
- *
- *
- * @param string $msg 输出的信息
- * @return string
- */
- private function _buildInfo($msg) {
- return "INFO! Message: " . $msg;
- }
-
- /**
- * 组装堆栈trace的信息输出格式
- *
- *
- * TRACE! Message: $msg
- * #1 trace1
- * #2 trace2
- *
- *
- * @param string $msg 输出的信息
- * @return string
- */
- private function _buildTrace($msg) {
- return "TRACE! Message: " . $msg . implode("\r\n", $this->_getTrace());
- }
-
- /**
- * 组装debug信息输出
- *
- *
- * DEBUG! Message: $msg
- * #1 trace1
- * #2 trace2
- *
- *
- * @param string $msg 输出的信息
- * @return string
- */
- private function _buildDebug($msg) {
- return 'DEBUG! Message: ' . $msg . implode("\r\n", $this->_getTrace());
- }
-
- /**
- *组装Error信息输出
- *
- *
- * ERROR! Message: $msg
- * #1 trace1
- * #2 trace2
- *
- *
- * @param string $msg 输出的错误信息
- * @return string
- */
- private function _buildError($msg) {
- return 'ERROR! Message: ' . $msg;
- }
-
- /**
- * 错误堆栈信息的获取及组装输出
- *
- *
- * #1 trace
- * #2 trace
- *
- *
- * @return string
- */
- private function _getTrace() {
- $num = 0;
- $info[] = 'Stack trace:';
- $traces = debug_backtrace();
- foreach ($traces as $traceKey => $trace) {
- if ($num >= 7) break;
- if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos($trace['file'], __CLASS__ . '.php') !== false) continue;
- $file = isset($trace['file']) ? $trace['file'] . '(' . $trace['line'] . '): ' : '[internal function]: ';
- $function = isset($trace['class']) ? $trace['class'] . $trace['type'] . $trace['function'] : $trace['function'];
- if ($function == 'WindBase::log') continue;
- $args = array_map(array($this, '_buildArg'), $trace['args']);
- $info[] = '#' . ($num++) . ' ' . $file . $function . '(' . implode(',', $args) . ')';
- }
- return $info;
- }
-
- /**
- * 组装输出的trace中的参数组装
- *
- * @param mixed $arg 需要组装的信息
- * @return string 返回组装好的信息
- *
+ * INFO! Message: $msg
+ *
+ *
+ * @param string $msg 输出的信息
+ * @return string
+ */
+ private function _buildInfo($msg)
+ {
+ return 'INFO! Message: '.$msg;
+ }
+
+ /**
+ * 组装堆栈trace的信息输出格式
+ *
+ *
+ * TRACE! Message: $msg
+ * #1 trace1
+ * #2 trace2
+ *
+ *
+ * @param string $msg 输出的信息
+ * @return string
+ */
+ private function _buildTrace($msg)
+ {
+ return 'TRACE! Message: '.$msg.implode("\r\n", $this->_getTrace());
+ }
+
+ /**
+ * 组装debug信息输出
+ *
+ *
+ * DEBUG! Message: $msg
+ * #1 trace1
+ * #2 trace2
+ *
+ *
+ * @param string $msg 输出的信息
+ * @return string
+ */
+ private function _buildDebug($msg)
+ {
+ return 'DEBUG! Message: '.$msg.implode("\r\n", $this->_getTrace());
+ }
+
+ /**
+ *组装Error信息输出
+ *
+ *
+ * ERROR! Message: $msg
+ * #1 trace1
+ * #2 trace2
+ *
+ *
+ * @param string $msg 输出的错误信息
+ * @return string
+ */
+ private function _buildError($msg)
+ {
+ return 'ERROR! Message: '.$msg;
+ }
+
+ /**
+ * 错误堆栈信息的获取及组装输出
+ *
+ *
+ * #1 trace
+ * #2 trace
+ *
+ *
+ * @return string
+ */
+ private function _getTrace()
+ {
+ $num = 0;
+ $info[] = 'Stack trace:';
+ $traces = debug_backtrace();
+ foreach ($traces as $traceKey => $trace) {
+ if ($num >= 7) {
+ break;
+ }
+ if ((isset($trace['class']) && $trace['class'] == __CLASS__) || isset($trace['file']) && strrpos(
+ $trace['file'], __CLASS__.'.php') !== false) {
+ continue;
+ }
+ $file = isset($trace['file']) ? $trace['file'].'('.$trace['line'].'): ' : '[internal function]: ';
+ $function = isset($trace['class']) ? $trace['class'].$trace['type'].$trace['function'] : $trace['function'];
+ if ($function == 'WindBase::log') {
+ continue;
+ }
+ $args = array_map(array($this, '_buildArg'), $trace['args']);
+ $info[] = '#'.($num++).' '.$file.$function.'('.implode(',', $args).')';
+ }
+
+ return $info;
+ }
+
+ /**
+ * 组装输出的trace中的参数组装
+ *
+ * @param mixed $arg 需要组装的信息
+ * @return string 返回组装好的信息
+ *
+ * 数组中key为数值型时,则转为- value
+ * 普通string或其他基本类型,则转为- string
+ *
+ *
+ * @param mixed $source 待转换的数据
+ * @param string $charset 待转换数据的编码
+ * @return string
+ */
+ public function parseToXml($source, $charset = 'utf8')
+ {
+ switch (gettype($source)) {
+ case 'object':
+ $source = get_object_vars($source);
+ case 'array':
+ $this->arrayToXml($source, $charset, $this->dom);
+ break;
+ case 'string':
+ $source = WindConvert::convert($source, 'utf8', $charset);
+ default:
+ $item = $this->dom->createElement('item');
+ $text = $this->dom->createTextNode($source);
+ $item->appendChild($text);
+ $this->dom->appendChild($item);
+ break;
+ }
+
+ return $this->dom->saveXML();
+ }
+
+ /**
+ * 获得节点的所有子节点
+ *
+ * 子节点包括属性和子节点(及文本节点),
+ * 子节点的属性将会根据作为该节点的一个属性元素存放,如果该子节点中含有标签列表,则会进行一次合并。
+ * 每个被合并的列表项都作为一个单独的数组元素存在。
+ *
+ * @param DOMElement $node 要解析的XMLDOM节点
+ * @return array 返回解析后该节点的数组
+ */
+ public function getChilds($node)
+ {
+ if (!$node instanceof DOMElement) {
+ return array();
+ }
+ $childs = array();
+ foreach ($node->childNodes as $_node) {
+ $tempChilds = $attributes = array();
+ $_node->hasAttributes() && $attributes = $this->getAttributes($_node);
+ if (3 == $_node->nodeType) {
+ $value = trim($_node->nodeValue);
+ (is_numeric($value) || $value) && $childs['__value'] = $value; //值为0的情况
+ $__tmp = strtolower($value);
+ ('false' === $__tmp) && $childs['__value'] = false; //为false的配置值
+ ('true' === $__tmp) && $childs['__value'] = true; //为false的配置值
+ }
+ if (1 !== $_node->nodeType) {
+ continue;
+ }
+
+ $tempChilds = $this->getChilds($_node);
+ $tempChilds = array_merge($attributes, $tempChilds);
+
+ if (empty($tempChilds)) {
+ $tempChilds = '';
+ } else {
+ $tempChilds = (isset($tempChilds['__value']) && count($tempChilds) == 1) ? $tempChilds['__value'] : $tempChilds;
+ }
+
+ $nodeName = '' !== ($name = $_node->getAttribute(self::NAME)) ? $name : $_node->nodeName;
+ if (!isset($childs[$nodeName])) {
+ $childs[$nodeName] = $tempChilds;
+ } else {
+ $element = $childs[$nodeName];
+ $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(
+ array($element), array($tempChilds)) : array_merge((array) $element, array($tempChilds));
+ }
+ }
+
+ return $childs;
+ }
+
+ /**
+ * 获得节点的属性
+ *
+ * 该属性将不包含属性为name的值--规则(name的值将作为解析后数组的key值索引存在)
+ *
+ * @param DOMElement $node 节点
+ * @return array 返回属性数组
+ */
+ public function getAttributes($node)
+ {
+ if (!$node instanceof DOMElement || !$node->hasAttributes()) {
+ return array();
+ }
+ $attributes = array();
+ foreach ($node->attributes as $attribute) {
+ if (self::NAME != $attribute->nodeName) {
+ $value = (string) $attribute->nodeValue;
+ $__tmp = strtolower($value);
+ $attributes[$attribute->nodeName] = 'false' === $__tmp ? false : ('true' === $__tmp ? true : $value);
+ }
+ }
+
+ return $attributes;
+ }
+
+ /**
+ * 将一个数组转换为xml
+ *
+ * @param array $arr 待转换的数组
+ * @param string $charset 编码
+ * @param DOMDocument $dom 根节点
+ * @return DOMDocument
*/
- public function parseXmlStream($stream, $option = 0) {
- if (!$stream) return array();
- $this->dom->loadXML($stream, $option);
- return $this->getChilds($this->dom->documentElement);
+ protected function arrayToXml($arr, $charset, $dom = null)
+ {
+ foreach ($arr as $key => $val) {
+ if (is_numeric($key)) {
+ $itemx = $this->dom->createElement('item');
+ $id = $this->dom->createAttribute('id');
+ $id->appendChild($this->dom->createTextNode($key));
+ $itemx->appendChild($id);
+ } else {
+ $itemx = $this->dom->createElement($key);
+ }
+ $dom->appendChild($itemx);
+ if (is_string($val)) {
+ $val = WindConvert::convert($val, 'utf8', $charset);
+ $itemx->appendChild($this->dom->createTextNode($val));
+ } elseif (is_object($val)) {
+ $this->arrayToXml(get_object_vars($val), $charset, $itemx);
+ } else {
+ $this->arrayToXml($val, $charset, $itemx);
+ }
+ }
}
-
- /**
- * 将数据转换成xml格式
- *
- *
- * 数组中key为数值型时,则转为- value
- * 普通string或其他基本类型,则转为- string
- *
- *
- * @param mixed $source 待转换的数据
- * @param string $charset 待转换数据的编码
- * @return string
- */
- public function parseToXml($source, $charset = 'utf8') {
- switch (gettype($source)) {
- case 'object':
- $source = get_object_vars($source);
- case 'array':
- $this->arrayToXml($source, $charset, $this->dom);
- break;
- case 'string':
- $source = WindConvert::convert($source, 'utf8', $charset);
- default:
- $item = $this->dom->createElement("item");
- $text = $this->dom->createTextNode($source);
- $item->appendChild($text);
- $this->dom->appendChild($item);
- break;
- }
- return $this->dom->saveXML();
- }
-
- /**
- * 获得节点的所有子节点
- *
- * 子节点包括属性和子节点(及文本节点),
- * 子节点的属性将会根据作为该节点的一个属性元素存放,如果该子节点中含有标签列表,则会进行一次合并。
- * 每个被合并的列表项都作为一个单独的数组元素存在。
- *
- * @param DOMElement $node 要解析的XMLDOM节点
- * @return array 返回解析后该节点的数组
- */
- public function getChilds($node) {
- if (!$node instanceof DOMElement) return array();
- $childs = array();
- foreach ($node->childNodes as $_node) {
- $tempChilds = $attributes = array();
- $_node->hasAttributes() && $attributes = $this->getAttributes($_node);
- if (3 == $_node->nodeType) {
- $value = trim($_node->nodeValue);
- (is_numeric($value) || $value) && $childs['__value'] = $value; //值为0的情况
- $__tmp = strtolower($value);
- ('false' === $__tmp) && $childs['__value'] = false; //为false的配置值
- ('true' === $__tmp) && $childs['__value'] = true; //为false的配置值
- }
- if (1 !== $_node->nodeType) continue;
-
- $tempChilds = $this->getChilds($_node);
- $tempChilds = array_merge($attributes, $tempChilds);
-
- if (empty($tempChilds))
- $tempChilds = '';
- else
- $tempChilds = (isset($tempChilds['__value']) && count($tempChilds) == 1) ? $tempChilds['__value'] : $tempChilds;
-
- $nodeName = "" !== ($name = $_node->getAttribute(self::NAME)) ? $name : $_node->nodeName;
- if (!isset($childs[$nodeName]))
- $childs[$nodeName] = $tempChilds;
- else {
- $element = $childs[$nodeName];
- $childs[$nodeName] = (is_array($element) && !is_numeric(implode('', array_keys($element)))) ? array_merge(
- array($element), array($tempChilds)) : array_merge((array) $element, array($tempChilds));
- }
- }
- return $childs;
- }
-
- /**
- * 获得节点的属性
- *
- * 该属性将不包含属性为name的值--规则(name的值将作为解析后数组的key值索引存在)
- *
- * @param DOMElement $node 节点
- * @return array 返回属性数组
- */
- public function getAttributes($node) {
- if (!$node instanceof DOMElement || !$node->hasAttributes()) return array();
- $attributes = array();
- foreach ($node->attributes as $attribute) {
- if (self::NAME != $attribute->nodeName) {
- $value = (string) $attribute->nodeValue;
- $__tmp = strtolower($value);
- $attributes[$attribute->nodeName] = 'false' === $__tmp ? false : ('true' === $__tmp ? true : $value);
- }
- }
- return $attributes;
- }
-
- /**
- * 将一个数组转换为xml
- *
- * @param array $arr 待转换的数组
- * @param string $charset 编码
- * @param DOMDocument $dom 根节点
- * @return DOMDocument
- */
- protected function arrayToXml($arr, $charset, $dom = null) {
- foreach ($arr as $key => $val) {
- if (is_numeric($key)) {
- $itemx = $this->dom->createElement("item");
- $id = $this->dom->createAttribute("id");
- $id->appendChild($this->dom->createTextNode($key));
- $itemx->appendChild($id);
- } else {
- $itemx = $this->dom->createElement($key);
- }
- $dom->appendChild($itemx);
- if (is_string($val)) {
- $val = WindConvert::convert($val, 'utf8', $charset);
- $itemx->appendChild($this->dom->createTextNode($val));
- } elseif (is_object($val)) {
- $this->arrayToXml(get_object_vars($val), $charset, $itemx);
- } else {
- $this->arrayToXml($val, $charset, $itemx);
- }
- }
- }
-
-}
\ No newline at end of file
+}
diff --git a/wind/router/AbstractWindRouter.php b/wind/router/AbstractWindRouter.php
index 3eae5f1b..5c87a174 100644
--- a/wind/router/AbstractWindRouter.php
+++ b/wind/router/AbstractWindRouter.php
@@ -1,227 +1,277 @@
2011-9-23
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: AbstractWindRouter.php 3928 2013-01-29 10:21:53Z yishuo $
* @package router
*/
-abstract class AbstractWindRouter extends WindHandlerInterceptorChain {
- protected $moduleKey = 'm';
- protected $controllerKey = 'c';
- protected $actionKey = 'a';
- protected $module = 'default';
- protected $controller = 'index';
- protected $action = 'run';
- protected $defaultRoute = '';
- protected $_action;
- protected $_controller;
- protected $_module;
-
- /**
- * 路由解析
- *
- * @param WindHttpRequest $request
- * @return string
- */
- abstract public function route($request);
-
- /**
- * 创建Url,并返回构建好的Url值
- *
- * @param string $action 操作信息
- * @param array $args 参数信息
- * @param string $route 路由协议别名
- * @return string
- */
- abstract public function assemble($action, $args = array(), $route = '');
-
- /* (non-PHPdoc)
- * @see WindModule::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- if ($this->_config) {
- $this->module = $this->getConfig('module', 'default-value', $this->module);
- $this->controller = $this->getConfig('controller', 'default-value', $this->controller);
- $this->action = $this->getConfig('action', 'default-value', $this->action);
- $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey);
- $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey);
- $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey);
- foreach ($this->getConfig('routes', '', array()) as $routeName => $route) {
- if (!isset($route['class'])) continue;
- $instance = WindFactory::createInstance(Wind::import($route['class']));
- $instance->setConfig($route);
- $this->addRoute($routeName, $instance, (isset($route['default']) && $route['default'] === true));
- }
- }
- }
-
- /**
- * 将路由解析到的url参数信息保存早系统变量中
- *
- * @param string $params
- * @param WindHttpRequest $requeset
- * @return void
- */
- protected function setParams($params, $request) {
- foreach ($params as $key => $value) {
- if ($key === $this->actionKey) {
- $this->setAction($value);
- } elseif ($key === $this->controllerKey) {
- $this->setController($value);
- } elseif ($key === $this->moduleKey) {
- $this->setModule($value);
- }
- $_GET[$key] = $value;
- }
- }
-
- /**
- * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常
- *
- * @param string
- * @param AbstractWindRoute $route
- * @param boolean $default 是否为默认
- * @return void
- * @throws WindException
- */
- public function addRoute($alias, $route, $default = false) {
- $this->addInterceptors(array($alias => $route));
- if ($default) $this->defaultRoute = $alias;
- }
-
- /**
- * 根据rule的规则名称,从路由链中获得该路由的对象
- *
- * @param string $ruleName 路由协议别名
- * @return AbstractWindRoute
- */
- public function getRoute($ruleName) {
- return isset($this->_interceptors[$ruleName]) ? $this->_interceptors[$ruleName] : null;
- }
-
- /**
- * 返回action
- *
- * @return string
- */
- public function getAction() {
- return $this->action;
- }
-
- /**
- * 返回controller
- *
- * @return string
- */
- public function getController() {
- return $this->controller;
- }
-
- /**
- * 设置action
- *
- * @param string $action
- * @return void
- */
- public function setAction($action) {
- $this->action = $action;
- }
-
- /**
- * 设置controller
- *
- * @param string $controller
- * @return void
- */
- public function setController($controller) {
- $this->controller = $controller;
- }
-
- /**
- * @return string
- */
- public function getModule() {
- return $this->module;
- }
-
- /**
- * @param string
- */
- public function setModule($module) {
- $this->module = $module;
- }
-
- /**
- * @return string
- */
- public function getModuleKey() {
- return $this->moduleKey;
- }
-
- /**
- * @return string
- */
- public function getControllerKey() {
- return $this->controllerKey;
- }
-
- /**
- * @return string
- */
- public function getActionKey() {
- return $this->actionKey;
- }
-
- /**
- * @param string $moduleKey
- */
- public function setModuleKey($moduleKey) {
- $this->moduleKey = $moduleKey;
- }
-
- /**
- * @param string $controllerKey
- */
- public function setControllerKey($controllerKey) {
- $this->controllerKey = $controllerKey;
- }
-
- /**
- * @param string $actionKey
- */
- public function setActionKey($actionKey) {
- $this->actionKey = $actionKey;
- }
-
- /**
- * 返回默认的module值
- *
- * @return string
- */
- public function getDefaultModule() {
- return $this->_module;
- }
-
- /**
- * 返回默认的controller值
- *
- * @return string
- */
- public function getDefaultController() {
- return $this->_controller;
- }
-
- /**
- * 返回默认的action值
- *
- * @return string
- */
- public function getDefaultAction() {
- return $this->_action;
- }
-}
\ No newline at end of file
+abstract class AbstractWindRouter extends WindHandlerInterceptorChain
+{
+ protected $moduleKey = 'm';
+ protected $controllerKey = 'c';
+ protected $actionKey = 'a';
+ protected $module;
+ protected $controller;
+ protected $action;
+ protected $_action = 'run';
+ protected $_controller = 'index';
+ protected $_module = 'default';
+ protected $defaultRoute = '';
+
+ /**
+ * 路由解析
+ *
+ * @param WindHttpRequest $request
+ * @return string
+ */
+ abstract public function route($request);
+
+ /**
+ * 创建Url,并返回构建好的Url值
+ *
+ * @param string $action 操作信息
+ * @param array $args 参数信息
+ * @param string $route 路由协议别名
+ * @return string
+ */
+ abstract public function assemble($action, $args = array(), $route = '');
+
+ /* (non-PHPdoc)
+ * @see WindModule::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ if ($this->_config) {
+ $this->_module = $this->getConfig('module', 'default-value', $this->_module);
+ $this->_controller = $this->getConfig('controller', 'default-value', $this->_controller);
+ $this->_action = $this->getConfig('action', 'default-value', $this->_action);
+ $this->moduleKey = $this->getConfig('module', 'url-param', $this->moduleKey);
+ $this->controllerKey = $this->getConfig('controller', 'url-param', $this->controllerKey);
+ $this->actionKey = $this->getConfig('action', 'url-param', $this->actionKey);
+ foreach ($this->getConfig('routes', '', array()) as $routeName => $route) {
+ if (!isset($route['class'])) {
+ continue;
+ }
+ $instance = WindFactory::createInstance(Wind::import($route['class']));
+ $instance->setConfig($route);
+ $this->addRoute($routeName, $instance, (isset($route['default']) && $route['default'] === true));
+ }
+ }
+ }
+
+ /**
+ * 将路由解析到的url参数信息保存早系统变量中
+ *
+ * @param string $params
+ * @param WindHttpRequest $requeset
+ */
+ protected function setParams($params, $request)
+ {
+ foreach ($params as $key => $value) {
+ if ($key === $this->actionKey) {
+ $this->setAction($value);
+ } elseif ($key === $this->controllerKey) {
+ $this->setController($value);
+ } elseif ($key === $this->moduleKey) {
+ $this->setModule($value);
+ } else {
+ $_GET[$key] = $value;
+ }
+ }
+ }
+
+ /**
+ * 添加路由协议对象,如果添加的路由协议已经存在则抛出异常
+ *
+ * @param string
+ * @param AbstractWindRoute $route
+ * @param bool $default 是否为默认
+ */
+ public function addRoute($alias, $route, $default = false)
+ {
+ $this->addInterceptors(array($alias => $route));
+ if ($default) {
+ $this->defaultRoute = $alias;
+ }
+ }
+
+ /**
+ * 根据rule的规则名称,从路由链中获得该路由的对象
+ *
+ * @param string $ruleName 路由协议别名
+ * @return AbstractWindRoute
+ */
+ public function getRoute($ruleName)
+ {
+ return isset($this->_interceptors[$ruleName]) ? $this->_interceptors[$ruleName] : null;
+ }
+
+ /**
+ * 返回action
+ *
+ * @return string
+ */
+ public function getAction()
+ {
+ return $this->action;
+ }
+
+ /**
+ * 返回controller
+ *
+ * @return string
+ */
+ public function getController()
+ {
+ return $this->controller;
+ }
+
+ /**
+ * 设置action
+ *
+ * @param string $action
+ */
+ public function setAction($action)
+ {
+ $this->action = $action;
+ }
+
+ /**
+ * 设置controller
+ *
+ * @param string $controller
+ */
+ public function setController($controller)
+ {
+ $this->controller = $controller;
+ }
+
+ /**
+ * @return string
+ */
+ public function getModule()
+ {
+ return $this->module;
+ }
+
+ /**
+ * @param string
+ */
+ public function setModule($module)
+ {
+ $this->module = $module;
+ }
+
+ /**
+ * @return string
+ */
+ public function getModuleKey()
+ {
+ return $this->moduleKey;
+ }
+
+ /**
+ * @return string
+ */
+ public function getControllerKey()
+ {
+ return $this->controllerKey;
+ }
+
+ /**
+ * @return string
+ */
+ public function getActionKey()
+ {
+ return $this->actionKey;
+ }
+
+ /**
+ * @param string $moduleKey
+ */
+ public function setModuleKey($moduleKey)
+ {
+ $this->moduleKey = $moduleKey;
+ }
+
+ /**
+ * @param string $controllerKey
+ */
+ public function setControllerKey($controllerKey)
+ {
+ $this->controllerKey = $controllerKey;
+ }
+
+ /**
+ * @param string $actionKey
+ */
+ public function setActionKey($actionKey)
+ {
+ $this->actionKey = $actionKey;
+ }
+
+ /**
+ * 返回默认的module值
+ *
+ * @return string
+ */
+ public function getDefaultModule()
+ {
+ return $this->_module;
+ }
+
+ /**
+ * 设置默认module
+ *
+ * @param string $module
+ */
+ public function setDefaultModule($module)
+ {
+ $this->_module = $module;
+ }
+
+ /**
+ * 返回默认的controller值
+ *
+ * @return string
+ */
+ public function getDefaultController()
+ {
+ return $this->_controller;
+ }
+
+ /**
+ * 设置默认的controller
+ *
+ * @param string $controller
+ */
+ public function setDefaultController($controller)
+ {
+ $this->_controller = $controller;
+ }
+
+ /**
+ * 返回默认的action值
+ *
+ * @return string
+ */
+ public function getDefaultAction()
+ {
+ return $this->_action;
+ }
+
+ /**
+ * 设置默认的action值
+ *
+ * @param string $action
+ */
+ public function setDefaultAction($action)
+ {
+ $this->_action = $action;
+ }
+}
diff --git a/wind/router/WindCommandRouter.php b/wind/router/WindCommandRouter.php
new file mode 100644
index 00000000..64b7194d
--- /dev/null
+++ b/wind/router/WindCommandRouter.php
@@ -0,0 +1,107 @@
+
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindCommandRouter.php 3859 2012-12-18 09:25:51Z yishuo $
+ * @package command
+ */
+class WindCommandRouter extends AbstractWindRouter
+{
+ protected $moduleKey = '-m,module,--module';
+ protected $controllerKey = '-c,controller,--controller';
+ protected $actionKey = '-a,action,--action';
+ protected $helpKey = '-h,help,--help';
+ protected $paramKey = '-p,param,--param';
+ protected $help = false;
+ protected $cmd = '';
+ /**
+ * @var WindCommandRequest
+ */
+ private $request = null;
+
+ /* (non-PHPdoc)
+ * @see AbstractWindRouter::route()
+ */
+ public function route($request)
+ {
+ $this->request = $request;
+ $this->_action = $this->action;
+ $this->_controller = $this->controller;
+ $this->_module = $this->module;
+ if (!empty($this->_config['routes'])) {
+ $params = $this->getHandler()->handle($request);
+ $this->setParams($params, $request);
+ } else {
+ $args = $request->getRequest('argv', array());
+ $this->cmd = $args[0];
+ $_count = count($args);
+ for ($i = 1; $i < $_count; $i++) {
+ if (in_array($args[$i], explode(',', $this->helpKey))) {
+ $this->help = true;
+ } elseif (in_array($args[$i], explode(',', $this->moduleKey))) {
+ $this->module = $args[++$i];
+ } elseif (in_array($args[$i], explode(',', $this->controllerKey))) {
+ $this->controller = $args[++$i];
+ } elseif (in_array($args[$i], explode(',', $this->actionKey))) {
+ $this->action = $args[++$i];
+ } elseif (in_array($args[$i], explode(',', $this->paramKey))) {
+ $_SERVER['argv'] = array_slice($args, $i + 1);
+ break;
+ }
+ }
+ }
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindRouter::assemble()
+ */
+ public function assemble($action, $args = array(), $route = '')
+ {
+ return '';
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindRouter::setParams()
+ */
+ protected function setParams($params, $request)
+ {
+ /* @var $request WindCommandRequest */
+ $_SERVER['argv'] = isset($params[$this->paramKey]) ? $params[$this->paramKey] : array();
+ isset($params[$this->moduleKey]) && $this->setModule($params[$this->moduleKey]);
+ isset($params[$this->controllerKey]) && $this->setController($params[$this->controllerKey]);
+ isset($params[$this->actionKey]) && $this->setAction($params[$this->actionKey]);
+ }
+
+ /**
+ * 是否是请求帮助
+ *
+ * @return bool
+ */
+ public function isHelp()
+ {
+ return $this->help;
+ }
+
+ /**
+ * 返回当前命令
+ *
+ * @return string
+ */
+ public function getCmd()
+ {
+ return $this->cmd;
+ }
+
+ /**
+ * @return string
+ */
+ public function getParamKey()
+ {
+ return $this->paramKey;
+ }
+}
diff --git a/wind/router/WindMultiAppRouter.php b/wind/router/WindMultiAppRouter.php
new file mode 100644
index 00000000..0ece47c6
--- /dev/null
+++ b/wind/router/WindMultiAppRouter.php
@@ -0,0 +1,124 @@
+ 2012-1-12
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindMultiAppRouter.php 3772 2012-10-19 08:58:57Z yishuo $
+ * @package router
+ */
+class WindMultiAppRouter extends WindRouter
+{
+ protected $appKey = 'p';
+ protected $app = 'default';
+
+ protected $_app;
+
+ /* (non-PHPdoc)
+ * @see WindRouter::route()
+ */
+ public function route($request)
+ {
+ $this->_app = $this->app;
+ parent::route($request);
+ }
+
+ /* (non-PHPdoc)
+ * @see WindRouter::assemble()
+ */
+ public function assemble($action, $args = array(), $route = null)
+ {
+ $route || $route = $this->defaultRoute;
+ if ($route && (null !== $route = $this->getRoute($route))) {
+ $_url = $route->build($this, $action, $args);
+ } else {
+ list($_a, $_c, $_m, $_p, $args) = WindUrlHelper::resolveAction($action, $args);
+ $_p || $_p = $this->getApp();
+ if ($_p && $_p !== $this->_app) {
+ $args[$this->appKey] = $_p;
+ }
+ if ($_m && $_m !== $this->_module) {
+ $args[$this->moduleKey] = $_m;
+ }
+ if ($_c && $_c !== $this->_controller) {
+ $args[$this->controllerKey] = $_c;
+ }
+ if ($_a && $_a !== $this->_action) {
+ $args[$this->actionKey] = $_a;
+ }
+ $_url = $this->request->getScript().'?'.WindUrlHelper::argsToUrl($args);
+ }
+
+ return $_url;
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindRouter::setConfig()
+ */
+ public function setConfig($config)
+ {
+ parent::setConfig($config);
+ if ($this->_config) {
+ $this->app = $this->getConfig('app', 'default-value', $this->app);
+ $this->appKey = $this->getConfig('app', 'url-param', $this->appKey);
+ }
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindRouter::setParams()
+ */
+ protected function setParams($params, $request)
+ {
+ parent::setParams($params, $request);
+ $app = isset($params[$this->appKey]) ? $params[$this->appKey] : $request->getRequest(
+ $this->appKey);
+ $app && $this->setApp($app);
+ }
+
+ /**
+ * @return string
+ */
+ public function getApp()
+ {
+ return $this->app;
+ }
+
+ /**
+ * 设置当前要访问的appname
+ *
+ * @param string $appName
+ */
+ public function setApp($appName)
+ {
+ $this->app = $appName;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAppKey()
+ {
+ return $this->appKey;
+ }
+
+ /**
+ * @param string $appKey
+ */
+ public function setAppKey($appKey)
+ {
+ $this->appKey = $appKey;
+ }
+
+ /**
+ * 返回默认的app值
+ *
+ * @return string
+ */
+ public function getDefaultApp()
+ {
+ return $this->_app;
+ }
+}
diff --git a/wind/router/WindMutilAppRouter.php b/wind/router/WindMutilAppRouter.php
deleted file mode 100644
index 5b598655..00000000
--- a/wind/router/WindMutilAppRouter.php
+++ /dev/null
@@ -1,106 +0,0 @@
- 2012-1-12
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package router
- */
-class WindMutilAppRouter extends WindRouter {
- protected $appKey = 'p';
- protected $app = 'default';
-
- protected $_app;
-
- /* (non-PHPdoc)
- * @see WindRouter::route()
- */
- public function route($request) {
- $this->_app = $this->app;
- parent::route($request);
- }
-
- /* (non-PHPdoc)
- * @see WindRouter::assemble()
- */
- public function assemble($action, $args = array(), $route = null) {
- $route || $route = $this->defaultRoute;
- if ($route && (null !== $route = $this->getRoute($route))) {
- $_url = $route->build($this, $action, $args);
- } else {
- list($_a, $_c, $_m, $_p, $args) = WindUrlHelper::resolveAction($action, $args);
- $_p || $_p = $this->getApp();
- if ($_p && $_p !== $this->_app) $args[$this->appKey] = $_p;
- if ($_m && $_m !== $this->_module) $args[$this->moduleKey] = $_m;
- if ($_c && $_c !== $this->_controller) $args[$this->controllerKey] = $_c;
- if ($_a && $_a !== $this->_action) $args[$this->actionKey] = $_a;
- $_url = $this->request->getScript() . '?' . WindUrlHelper::argsToUrl($args);
- }
- return $_url;
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindRouter::setConfig()
- */
- public function setConfig($config) {
- parent::setConfig($config);
- if ($this->_config) {
- $this->app = $this->getConfig('app', 'default-value', $this->app);
- $this->appKey = $this->getConfig('app', 'url-param', $this->appKey);
- }
- }
-
- /* (non-PHPdoc)
- * @see AbstractWindRouter::setParams()
- */
- protected function setParams($params, $request) {
- parent::setParams($params, $request);
- $app = isset($params[$this->appKey]) ? $params[$this->appKey] : $request->getRequest(
- $this->appKey);
- $app && $this->setApp($app);
- }
-
- /**
- * @return string
- */
- public function getApp() {
- return $this->app;
- }
-
- /**
- * 设置当前要访问的appname
- *
- * @param string $appName
- */
- public function setApp($appName) {
- $this->app = $appName;
- }
-
- /**
- * @return string
- */
- public function getAppKey() {
- return $this->appKey;
- }
-
- /**
- * @param string $appKey
- */
- public function setAppKey($appKey) {
- $this->appKey = $appKey;
- }
-
- /**
- * 返回默认的app值
- *
- * @return string
- */
- public function getDefaultApp() {
- return $this->_app;
- }
-}
-
-?>
\ No newline at end of file
diff --git a/wind/router/WindRouter.php b/wind/router/WindRouter.php
index 4bda7704..cd81340d 100644
--- a/wind/router/WindRouter.php
+++ b/wind/router/WindRouter.php
@@ -1,8 +1,9 @@
@@ -27,52 +28,70 @@
* 'params' => array(), //参数mapping
* 'reverse' => '')), //反向解析
*
- *
+ *
* @author Qiong Wu /^(\w+)(\/\w+)(\/\w+)(.*)$/i
+ * 例如:请求http://blog.p9.com/myModule/myController/myAction/id/1/name/2,
+ * 则解析为module => myModule, controller => myController, action => myAction,
+ * GET参数id => 1, name => 2
+ *
+ *
+ * @author Shi Long
- * 当token有效时则返回true,同时删除token.
- * 当coken无效时则返回false.
- *
- * @param string $token
- * @param string $tokenName token名称,默认名称为_tokenAppName
- */
- public function validateToken($token, $tokenName = '');
+ /**
+ * 保存token
+ *
+ * @param string $tokenName token名称,默认名称为_tokenAppName
+ * @return string 返回token值
+ */
+ public function saveToken($tokenName = '');
+ /**
+ * 验证token的有效性
+ *
+ * 验证token的有效性.
+ * 当token有效时则返回true,同时删除token.
+ * 当coken无效时则返回false.
+ *
+ * @param string $token
+ * @param string $tokenName token名称,默认名称为_tokenAppName
+ */
+ public function validateToken($token, $tokenName = '');
}
-
-?>
\ No newline at end of file
diff --git a/wind/token/WindSecurityToken.php b/wind/token/WindSecurityToken.php
index 5d289fb1..4b947b38 100644
--- a/wind/token/WindSecurityToken.php
+++ b/wind/token/WindSecurityToken.php
@@ -1,8 +1,9 @@
tokenContainer可以是WindCookie或者WindSeesion类型:
* 'windToken' => array(
@@ -10,7 +11,7 @@
* 'scope' => 'singleton',
* 'properties' => array(
* 'tokenContainer' => array('ref' => 'windCookie'))),
- *
+ *
* 'windCookie' => array(
* 'path' => 'WIND:http.cookie.WindNormalCookie',
* 'scope' => 'singleton',
@@ -19,84 +20,93 @@
* @author Qiong Wu 2011-10-19
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindSecurityToken.php 3533 2012-05-08 08:24:20Z yishuo $
* @package utility
*/
-class WindSecurityToken extends WindModule implements IWindSecurityToken {
- /**
- * url token
- *
- * @var string
- */
- protected $token = null;
- /**
- * 令牌容器
- *
- * 可以通过组件配置方式配置不同的容器类型
- * @var IWindHttpContainer
- */
- protected $tokenContainer = null;
+class WindSecurityToken extends WindModule implements IWindSecurityToken
+{
+ /**
+ * url token
+ *
+ * @var string
+ */
+ protected $token = null;
+ /**
+ * 令牌容器
+ *
+ * 可以通过组件配置方式配置不同的容器类型
+ * @var IWindHttpContainer
+ */
+ protected $tokenContainer = null;
- /* (non-PHPdoc)
- * @see IWindSecurityToken::saveToken($tokenName)
- */
- public function saveToken($tokenName = '') {
- if ($this->token === null) {
- /* @var $tokenContainer IWindHttpContainer */
- $tokenContainer = $this->_getTokenContainer();
- $tokenName = $this->getTokenName($tokenName);
- if ($tokenContainer->isRegistered($tokenName)) {
- $_token = $tokenContainer->get($tokenName);
- } else {
- $_token = WindSecurity::generateGUID();
- $tokenContainer->set($tokenName, $_token);
- }
- $this->token = $_token;
- }
- return $this->token;
- }
+ /* (non-PHPdoc)
+ * @see IWindSecurityToken::saveToken($tokenName)
+ */
+ public function saveToken($tokenName = '')
+ {
+ if ($this->token === null) {
+ /* @var $tokenContainer IWindHttpContainer */
+ $tokenContainer = $this->_getTokenContainer();
+ $tokenName = $this->getTokenName($tokenName);
+ if ($tokenContainer->isRegistered($tokenName)) {
+ $_token = $tokenContainer->get($tokenName);
+ } else {
+ $_token = WindSecurity::generateGUID();
+ $tokenContainer->set($tokenName, $_token);
+ }
+ $this->token = $_token;
+ }
- /* (non-PHPdoc)
- * @see IWindSecurityToken::validateToken()
- */
- public function validateToken($token, $tokenName = '') {
- /* @var $tokenContainer IWindHttpContainer */
- $tokenContainer = $this->_getTokenContainer();
- $tokenName = $this->getTokenName($tokenName);
- $_token = $tokenContainer->get($tokenName);
- return $_token && $_token === $token;
- }
+ return $this->token;
+ }
- /* (non-PHPdoc)
- * @see IWindSecurityToken::deleteToken()
- */
- public function deleteToken($tokenName) {
- /* @var $tokenContainer IWindHttpContainer */
- $tokenContainer = $this->_getTokenContainer();
- $tokenName = $this->getTokenName($tokenName);
- return $tokenContainer->delete($tokenName);
- }
+ /* (non-PHPdoc)
+ * @see IWindSecurityToken::validateToken()
+ */
+ public function validateToken($token, $tokenName = '')
+ {
+ /* @var $tokenContainer IWindHttpContainer */
+ $tokenContainer = $this->_getTokenContainer();
+ $tokenName = $this->getTokenName($tokenName);
+ $_token = $tokenContainer->get($tokenName);
- /* (non-PHPdoc)
- * @see IWindSecurityToken::getToken()
- */
- public function getToken($tokenName) {
- /* @var $tokenContainer IWindHttpContainer */
- $tokenContainer = $this->_getTokenContainer();
- $tokenName = $this->getTokenName($tokenName);
- return $tokenContainer->get($tokenName);
- }
+ return $_token && $_token === $token;
+ }
- /**
- * token名称处理
- *
- * @param string $tokenName
- * @return string
- */
- protected function getTokenName($tokenName) {
- $tokenName || $tokenName = Wind::getAppName();
- return substr(md5('_token' . $tokenName . '_csrf'), -16);
- }
-}
+ /* (non-PHPdoc)
+ * @see IWindSecurityToken::deleteToken()
+ */
+ public function deleteToken($tokenName)
+ {
+ /* @var $tokenContainer IWindHttpContainer */
+ $tokenContainer = $this->_getTokenContainer();
+ $tokenName = $this->getTokenName($tokenName);
+
+ return $tokenContainer->delete($tokenName);
+ }
-?>
\ No newline at end of file
+ /* (non-PHPdoc)
+ * @see IWindSecurityToken::getToken()
+ */
+ public function getToken($tokenName)
+ {
+ /* @var $tokenContainer IWindHttpContainer */
+ $tokenContainer = $this->_getTokenContainer();
+ $tokenName = $this->getTokenName($tokenName);
+
+ return $tokenContainer->get($tokenName);
+ }
+
+ /**
+ * token名称处理
+ *
+ * @param string $tokenName
+ * @return string
+ */
+ protected function getTokenName($tokenName)
+ {
+ $tokenName || $tokenName = Wind::getAppName();
+
+ return substr(md5('_token'.$tokenName.'_csrf'), -16);
+ }
+}
diff --git a/wind/upload/AbstractWindUpload.php b/wind/upload/AbstractWindUpload.php
index a8a80097..6041d1ef 100644
--- a/wind/upload/AbstractWindUpload.php
+++ b/wind/upload/AbstractWindUpload.php
@@ -1,273 +1,305 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: AbstractWindUpload.php 3172 2011-11-24 07:57:52Z yishuo $
* @package upload
*/
-abstract class AbstractWindUpload {
-
- /**
- * 是否有错误产生
- *
- * @var boolean
- */
- protected $hasError = false;
-
- /**
- * 错误信息
- *
- * @var array
- */
- protected $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array());
-
- /**
- * 允许的类型
- *
- * @var array
- */
- protected $allowType = array();//允许上传的类型及对应的大小,array(ext=>size);
-
- /**
- * 上传文件
- *
- * @param string $saveDir 文件保存的目录
- * @param string $preFileName 文件保存的前缀
- * @param array $allowType 允许的格式array(ext=>size) size单位为b
- *
- * array(
- * 'jpg' => 1024,
- * 'gif => 1000,
- *
- * @return array 返回上传成功的文件
- */
- public function upload($saveDir, $preFileName = '', $allowType = array()) {
- $this->setAllowType($allowType);
- $uploaddb = array();
- foreach ($_FILES as $key => $value) {
- if (is_array($value['name'])) {
- $temp = $this->multiUpload($key, $saveDir, $preFileName);
- $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array)$uploaddb[$key], $temp) : $temp;
- } else {
- $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName);
- }
- }
- return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb;
- }
-
- /**
- * 多文件上传
- *
- * 多个控件
- * 一个表单中拥有多个上传文件的控件
- *
- * @param string $key 文件的key
- * @param string $saveDir 文件保存的目录
- * @param string $preFileName 保存文件的前缀默认为空字串
- * @return array 返回上传成功之后的文件信息
- */
- private function simpleUpload($key, $saveDir, $preFileName = '') {
- return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName);
- }
-
- /**
- * 多文件上传
- *
- * 多个控件
- * 一个表单中拥有多个上传文件的控件
- *
- * @param string $key 文件的key
- * @param string $saveDir 文件保存的目录
- * @param string $preFileName 保存文件的前缀默认为空字串
- * @return array 返回上传成功之后的文件信息
- */
- private function multiUpload($key, $saveDir, $preFileName = '') {
- $uploaddb = array();
- $files = $_FILES[$key];
- $num = count($files['name']);
- for($i = 0; $i < $num; $i ++) {
- $one = array();
- $one['name'] = $files['name'][$i];
- $one['tmp_name'] = $files['tmp_name'][$i];
- $one['error'] = $files['error'][$i];
- $one['size'] = $files['size'][$i];
- $one['type'] = $files['type'][$i];
- if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) continue;
- $uploaddb[] = $upload;
- }
- return $uploaddb;
- }
-
- /**
- * 执行上传操作
- *
- * @param string $tmp_name 临时文件
- * @param string $filename 目的文件名
- * @return bool
- */
- abstract protected function postUpload($tmp_name, $filename);
-
- /**
- * 返回是否含有错误
- *
- * @return boolean
- */
- public function hasError() {
- return $this->hasError;
- }
-
- /**
- * 返回错误信息
- *
- * @param string $errorType 错误类型,可选参数为:
- *
- * - 'type': 类型出错而不能上传的文件信息,
- * - 'size': 超过指定大小而上传失败的文件信息
-
- *
- 'upload': 文件不能上传过程出现错误的文件信息
- *
默认为空,则返回所有上述类型的错误信息
- * @return array
- */
- public function getErrorInfo($errorType = '') {
- return isset($this->errorInfo[$errorType]) ? $this->errorInfo[$errorType] : $this->errorInfo;
- }
-
- /**
- * 设置允许上传的类型
- *
- * @param array $allowType 允许上传的格式配置
- * @return void
- */
- public function setAllowType($allowType) {
- $allowType && $this->allowType = $allowType;
- }
-
- /**
- * 检查文件是否允许上传
- *
- * @param string $ext 文件的后缀
- * @return bool 如果在允许的范围则返回true,否则返回false
- */
- protected function checkAllowType($ext) {
- $allowType = array_keys((array)$this->allowType);
- return $allowType ? in_array($ext, $allowType) : true;
- }
-
- /**
- * 检查上传文件的大小
- *
- * @param string $type 文件的类型
- * @param string $uploadSize 上传文件的大小
- * @return bool 如果上传文件超过指定允许上传的大小则返回false,否则返回true
- */
- protected function checkAllowSize($type, $uploadSize) {
- if ($uploadSize < 0) return false;
- if (!$this->allowType || !$this->allowType[$type]) return true;
- return $uploadSize < $this->allowType[$type];
- }
-
-
- /**
- * 获得文件名字
- *
- * @param array $attInfo 上传文件的信息
- * @param string $preFileName 文件的前缀
- * @return string 上传文件的名字
- */
- protected function getFileName($attInfo, $preFileName = '') {
- $fileName = mt_rand(1, 10) . time() . substr(md5(time() . $attInfo['attname'] . mt_rand(1, 10)), 10, 15) . '.' . $attInfo['ext'];
- return $preFileName ? $preFileName . $fileName : $fileName;
- }
-
- /**
- * 获得保存路径
- *
- * @param string $fileName 保存的文件名字
- * @param string $saveDir 保存文件的路径
- * @return string 上传后的保存文件的完整路径
- */
- protected function getSavePath($fileName, $saveDir) {
- return $saveDir ? rtrim($saveDir, '\\/') . '/' . $fileName : $fileName;
- }
-
- /**
- * 判断是否有上传文件
- *
- * @param string $tmp_name 临时上传文件
- * @return boolean 如果该文件可以被上传则返回true,否则返回false
- */
- protected function isUploadFile($tmp_name) {
- if (!$tmp_name || $tmp_name == 'none') {
- return false;
- } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) {
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * 初始化上传的文件信息
- *
- * @param string $key 上传文件的key
- * @param string $value 上传文件的信息
- * @param string $preFileName 上传文件的前缀
- * @param string $saveDir 上传文件保存路径
- * @return array 返回文件上传的信息
- */
- protected function initUploadInfo($key, $value, $preFileName, $saveDir) {
- $arr = array('attname' => $key, 'name' => $value['name'], 'size' => $value['size'], 'type' => $value['type'], 'ifthumb' => 0, 'fileuploadurl' => '');
- $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1));
- $arr['filename'] = $this->getFileName($arr, $preFileName);
- $arr['fileuploadurl'] = $this->getSavePath($arr['filename'], $saveDir);
- return $arr;
- }
-
-
- /**
- * 判断是否使图片,如果使图片则返回
- *
- * @param string $ext 文件后缀
- * @return boolean 如果该文件允许被上传则返回true,否则返回false
- */
- protected function isImage($ext) {
- return in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'swf'));
- }
-
- /**
- * 执行上传操作
- *
- * @param string $key 上传文件的Key值
- * @param array $value 文件的上传信息
- * @param string $saveDir 上传文件的保存路径
- * @param string $preFileName 上传文件的前缀
- * @return array 上传成功后的文件信息
- */
- protected function doUp($key, $value, $saveDir, $preFileName) {
- if (!$this->isUploadFile($value['tmp_name'])) return array();
- $upload = $this->initUploadInfo($key, $value, $preFileName, $saveDir);
-
- if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'])) {
- $this->errorInfo['type'][$key][] = $upload;
- $this->hasError = true;
- return array();
- }
- if (!$this->checkAllowSize($upload['ext'], $upload['size'])) {
- $upload['maxSize'] = $this->allowType[$upload['ext']];
- $this->errorInfo['size'][$key][] = $upload;
- $this->hasError = true;
- return array();
- }
- if (!($uploadSize = $this->postUpload($value['tmp_name'], $upload['fileuploadurl']))) {
- $this->errorInfo['upload'][$key][] = $upload;
- $this->hasError = true;
- return array();
- }
- $upload['size'] = intval($uploadSize);
- return $upload;
- }
-}
\ No newline at end of file
+abstract class AbstractWindUpload
+{
+ /**
+ * 是否有错误产生
+ *
+ * @var bool
+ */
+ protected $hasError = false;
+
+ /**
+ * 错误信息
+ *
+ * @var array
+ */
+ protected $errorInfo = array('type' => array(), 'size' => array(), 'upload' => array());
+
+ /**
+ * 允许的类型
+ *
+ * @var array
+ */
+ protected $allowType = array(); //允许上传的类型及对应的大小,array(ext=>size);
+
+ /**
+ * 上传文件
+ *
+ * @param string $saveDir 文件保存的目录
+ * @param string $preFileName 文件保存的前缀
+ * @param array $allowType 允许的格式array(ext=>size) size单位为b
+ *
+ * array(
+ * 'jpg' => 1024,
+ * 'gif => 1000,
+ *
+ * @return array 返回上传成功的文件
+ */
+ public function upload($saveDir, $preFileName = '', $allowType = array())
+ {
+ $this->setAllowType($allowType);
+ $uploaddb = array();
+ foreach ($_FILES as $key => $value) {
+ if (is_array($value['name'])) {
+ $temp = $this->multiUpload($key, $saveDir, $preFileName);
+ $uploaddb[$key] = isset($uploaddb[$key]) ? array_merge((array) $uploaddb[$key], $temp) : $temp;
+ } else {
+ $uploaddb[$key][] = $this->simpleUpload($key, $saveDir, $preFileName);
+ }
+ }
+
+ return 1 == count($uploaddb) ? array_shift($uploaddb) : $uploaddb;
+ }
+
+ /**
+ * 多文件上传
+ *
+ * 多个控件
+ * 一个表单中拥有多个上传文件的控件
+ *
+ * @param string $key 文件的key
+ * @param string $saveDir 文件保存的目录
+ * @param string $preFileName 保存文件的前缀默认为空字串
+ * @return array 返回上传成功之后的文件信息
+ */
+ private function simpleUpload($key, $saveDir, $preFileName = '')
+ {
+ return $this->doUp($key, $_FILES[$key], $saveDir, $preFileName);
+ }
+
+ /**
+ * 多文件上传
+ *
+ * 多个控件
+ * 一个表单中拥有多个上传文件的控件
+ *
+ * @param string $key 文件的key
+ * @param string $saveDir 文件保存的目录
+ * @param string $preFileName 保存文件的前缀默认为空字串
+ * @return array 返回上传成功之后的文件信息
+ */
+ private function multiUpload($key, $saveDir, $preFileName = '')
+ {
+ $uploaddb = array();
+ $files = $_FILES[$key];
+ $num = count($files['name']);
+ for ($i = 0; $i < $num; $i ++) {
+ $one = array();
+ $one['name'] = $files['name'][$i];
+ $one['tmp_name'] = $files['tmp_name'][$i];
+ $one['error'] = $files['error'][$i];
+ $one['size'] = $files['size'][$i];
+ $one['type'] = $files['type'][$i];
+ if (!($upload = $this->doUp($key, $one, $saveDir, $preFileName))) {
+ continue;
+ }
+ $uploaddb[] = $upload;
+ }
+
+ return $uploaddb;
+ }
+
+ /**
+ * 执行上传操作
+ *
+ * @param string $tmp_name 临时文件
+ * @param string $filename 目的文件名
+ * @return bool
+ */
+ abstract protected function postUpload($tmp_name, $filename);
+
+ /**
+ * 返回是否含有错误
+ *
+ * @return bool
+ */
+ public function hasError()
+ {
+ return $this->hasError;
+ }
+
+ /**
+ * 返回错误信息
+ *
+ * @param string $errorType 错误类型,可选参数为:
+ *
+ * - 'type': 类型出错而不能上传的文件信息,
+ * - 'size': 超过指定大小而上传失败的文件信息
-
+ *
- 'upload': 文件不能上传过程出现错误的文件信息
+ *
默认为空,则返回所有上述类型的错误信息
+ * @return array
+ */
+ public function getErrorInfo($errorType = '')
+ {
+ return isset($this->errorInfo[$errorType]) ? $this->errorInfo[$errorType] : $this->errorInfo;
+ }
+
+ /**
+ * 设置允许上传的类型
+ *
+ * @param array $allowType 允许上传的格式配置
+ */
+ public function setAllowType($allowType)
+ {
+ $allowType && $this->allowType = $allowType;
+ }
+
+ /**
+ * 检查文件是否允许上传
+ *
+ * @param string $ext 文件的后缀
+ * @return bool 如果在允许的范围则返回true,否则返回false
+ */
+ protected function checkAllowType($ext)
+ {
+ $allowType = array_keys((array) $this->allowType);
+
+ return $allowType ? in_array($ext, $allowType) : true;
+ }
+
+ /**
+ * 检查上传文件的大小
+ *
+ * @param string $type 文件的类型
+ * @param string $uploadSize 上传文件的大小
+ * @return bool 如果上传文件超过指定允许上传的大小则返回false,否则返回true
+ */
+ protected function checkAllowSize($type, $uploadSize)
+ {
+ if ($uploadSize < 0) {
+ return false;
+ }
+ if (!$this->allowType || !$this->allowType[$type]) {
+ return true;
+ }
+
+ return $uploadSize < $this->allowType[$type];
+ }
+
+
+ /**
+ * 获得文件名字
+ *
+ * @param array $attInfo 上传文件的信息
+ * @param string $preFileName 文件的前缀
+ * @return string 上传文件的名字
+ */
+ protected function getFileName($attInfo, $preFileName = '')
+ {
+ $fileName = mt_rand(1, 10).time().substr(md5(time().$attInfo['attname'].mt_rand(1, 10)), 10, 15).'.'.$attInfo['ext'];
+
+ return $preFileName ? $preFileName.$fileName : $fileName;
+ }
+
+ /**
+ * 获得保存路径
+ *
+ * @param string $fileName 保存的文件名字
+ * @param string $saveDir 保存文件的路径
+ * @return string 上传后的保存文件的完整路径
+ */
+ protected function getSavePath($fileName, $saveDir)
+ {
+ return $saveDir ? rtrim($saveDir, '\\/').'/'.$fileName : $fileName;
+ }
+
+ /**
+ * 判断是否有上传文件
+ *
+ * @param string $tmp_name 临时上传文件
+ * @return bool 如果该文件可以被上传则返回true,否则返回false
+ */
+ protected function isUploadFile($tmp_name)
+ {
+ if (!$tmp_name || $tmp_name == 'none') {
+ return false;
+ } elseif (function_exists('is_uploaded_file') && !is_uploaded_file($tmp_name) && !is_uploaded_file(str_replace('\\\\', '\\', $tmp_name))) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * 初始化上传的文件信息
+ *
+ * @param string $key 上传文件的key
+ * @param string $value 上传文件的信息
+ * @param string $preFileName 上传文件的前缀
+ * @param string $saveDir 上传文件保存路径
+ * @return array 返回文件上传的信息
+ */
+ protected function initUploadInfo($key, $value, $preFileName, $saveDir)
+ {
+ $arr = array('attname' => $key, 'name' => $value['name'], 'size' => $value['size'], 'type' => $value['type'], 'ifthumb' => 0, 'fileuploadurl' => '');
+ $arr['ext'] = strtolower(substr(strrchr($arr['name'], '.'), 1));
+ $arr['filename'] = $this->getFileName($arr, $preFileName);
+ $arr['fileuploadurl'] = $this->getSavePath($arr['filename'], $saveDir);
+
+ return $arr;
+ }
+
+
+ /**
+ * 判断是否使图片,如果使图片则返回
+ *
+ * @param string $ext 文件后缀
+ * @return bool 如果该文件允许被上传则返回true,否则返回false
+ */
+ protected function isImage($ext)
+ {
+ return in_array($ext, array('gif', 'jpg', 'jpeg', 'png', 'bmp', 'swf'));
+ }
+
+ /**
+ * 执行上传操作
+ *
+ * @param string $key 上传文件的Key值
+ * @param array $value 文件的上传信息
+ * @param string $saveDir 上传文件的保存路径
+ * @param string $preFileName 上传文件的前缀
+ * @return array 上传成功后的文件信息
+ */
+ protected function doUp($key, $value, $saveDir, $preFileName)
+ {
+ if (!$this->isUploadFile($value['tmp_name'])) {
+ return array();
+ }
+ $upload = $this->initUploadInfo($key, $value, $preFileName, $saveDir);
+
+ if (empty($upload['ext']) || !$this->checkAllowType($upload['ext'])) {
+ $this->errorInfo['type'][$key][] = $upload;
+ $this->hasError = true;
+
+ return array();
+ }
+ if (!$this->checkAllowSize($upload['ext'], $upload['size'])) {
+ $upload['maxSize'] = $this->allowType[$upload['ext']];
+ $this->errorInfo['size'][$key][] = $upload;
+ $this->hasError = true;
+
+ return array();
+ }
+ if (!($uploadSize = $this->postUpload($value['tmp_name'], $upload['fileuploadurl']))) {
+ $this->errorInfo['upload'][$key][] = $upload;
+ $this->hasError = true;
+
+ return array();
+ }
+ $upload['size'] = intval($uploadSize);
+
+ return $upload;
+ }
+}
diff --git a/wind/upload/WindFormUpload.php b/wind/upload/WindFormUpload.php
index 37159193..3618d739 100644
--- a/wind/upload/WindFormUpload.php
+++ b/wind/upload/WindFormUpload.php
@@ -1,52 +1,58 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindFormUpload.php 3228 2011-12-02 06:49:38Z yishuo $
* @package upload
*/
-class WindFormUpload extends AbstractWindUpload {
+class WindFormUpload extends AbstractWindUpload
+{
+ /**
+ * 初始化允许用户上传的类型
+ *
+ * @param array $allowType
+ */
+ public function __construct($allowType = array())
+ {
+ $this->setAllowType($allowType);
+ }
+
+ /*
+ * (non-PHPdoc)
+ * @see AbstractWindUpload::postUpload()
+ */
+ protected function postUpload($tmp_name, $filename)
+ {
+ if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match('/\.php$/',
+ $filename)) {
+ exit('illegal file type!');
+ }
+ WindFolder::mkRecur(dirname($filename));
+ if (function_exists('move_uploaded_file') && @move_uploaded_file($tmp_name, $filename)) {
+ @unlink($tmp_name);
+ @chmod($filename, 0777);
+
+ return filesize($filename);
+ } elseif (@copy($tmp_name, $filename)) {
+ @unlink($tmp_name);
+ @chmod($filename, 0777);
+
+ return filesize($filename);
+ } elseif (is_readable($tmp_name)) {
+ WindFile::write($filename, WindFile::read($tmp_name));
+ @unlink($tmp_name);
+ if (file_exists($filename)) {
+ @chmod($filename, 0777);
- /**
- * 初始化允许用户上传的类型
- *
- * @param array $allowType
- */
- public function __construct($allowType = array()) {
- $this->setAllowType($allowType);
- }
+ return filesize($filename);
+ }
+ }
- /*
- * (non-PHPdoc)
- * @see AbstractWindUpload::postUpload()
- */
- protected function postUpload($tmp_name, $filename) {
- if (strpos($filename, '..') !== false || strpos($filename, '.php.') !== false || preg_match('/\.php$/',
- $filename)) {
- exit('illegal file type!');
- }
- WindFolder::mkRecur(dirname($filename));
- if (function_exists("move_uploaded_file") && @move_uploaded_file($tmp_name, $filename)) {
- @unlink($tmp_name);
- @chmod($filename, 0777);
- return filesize($filename);
- } elseif (@copy($tmp_name, $filename)) {
- @unlink($tmp_name);
- @chmod($filename, 0777);
- return filesize($filename);
- } elseif (is_readable($tmp_name)) {
- Wind::import('WIND:utility.WindFile');
- WindFile::write($filename, WindFile::read($tmp_name));
- @unlink($tmp_name);
- if (file_exists($filename)) {
- @chmod($filename, 0777);
- return filesize($filename);
- }
- }
- return false;
- }
-}
\ No newline at end of file
+ return false;
+ }
+}
diff --git a/wind/upload/WindFtpUpload.php b/wind/upload/WindFtpUpload.php
index f5e0f17b..e0358465 100644
--- a/wind/upload/WindFtpUpload.php
+++ b/wind/upload/WindFtpUpload.php
@@ -1,65 +1,79 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindFtpUpload.php 2973 2011-10-15 19:22:48Z yishuo $
* @package upload
*/
-class WindFtpUpload extends AbstractWindUpload {
+class WindFtpUpload extends AbstractWindUpload
+{
+ private $config = array();
+
+ private $ftp = null;
+
+ /**
+ * 构造函数设置远程ftp链接信息
+ *
+ * @param array $config
+ */
+ public function __construct($config)
+ {
+ $this->setConfig($config);
+ }
+
+ /* (non-PHPdoc)
+ * @see AbstractWindUpload::postUpload()
+ */
+ protected function postUpload($tmp_name, $filename)
+ {
+ $ftp = $this->getFtpConnection();
+ if (!($size = $ftp->upload($tmp_name, $filename))) {
+ return false;
+ }
+ @unlink($tmp_name);
+
+ return $size;
+ }
- private $config = array();
+ /**
+ * 设置ftp链接配置文件
+ *
+ * @param array $config ftp链接信息
+ * @return bool
+ */
+ public function setConfig($config)
+ {
+ if (!is_array($config)) {
+ return false;
+ }
+ $this->config = $config;
- private $ftp = null;
+ return true;
+ }
- /**
- * 构造函数设置远程ftp链接信息
- *
- * @param array $config
- */
- public function __construct($config) {
- $this->setConfig($config);
- }
+ /**
+ * 获得ftp链接对象
+ *
+ * @return AbstractWindFtp
+ */
+ private function getFtpConnection()
+ {
+ if (is_object($this->ftp)) {
+ return $this->ftp;
+ }
+ if (function_exists('ftp_connect')) {
+ $this->ftp = new WindFtp($this->config);
- /* (non-PHPdoc)
- * @see AbstractWindUpload::postUpload()
- */
- protected function postUpload($tmp_name, $filename) {
- $ftp = $this->getFtpConnection();
- if (!($size = $ftp->upload($tmp_name, $filename))) return false;
- @unlink($tmp_name);
- return $size;
- }
+ return $this->ftp;
+ }
- /**
- * 设置ftp链接配置文件
- *
- * @param array $config ftp链接信息
- * @return bool
- */
- public function setConfig($config) {
- if (!is_array($config)) return false;
- $this->config = $config;
- return true;
- }
+ $this->ftp = new WindSocketFtp($this->config);
- /**
- * 获得ftp链接对象
- *
- * @return AbstractWindFtp
- */
- private function getFtpConnection() {
- if (is_object($this->ftp)) return $this->ftp;
- if (function_exists('ftp_connect')) {
- Wind::import("WIND:ftp.WindFtp");
- $this->ftp = new WindFtp($this->config);
- return $this->ftp;
- }
- Wind::import("WIND:ftp.WindSocketFtp");
- $this->ftp = new WindSocketFtp($this->config);
- return $this->ftp;
- }
-}
\ No newline at end of file
+ return $this->ftp;
+ }
+}
diff --git a/wind/utility/WindArray.php b/wind/utility/WindArray.php
index cd386424..f3a5a697 100644
--- a/wind/utility/WindArray.php
+++ b/wind/utility/WindArray.php
@@ -1,81 +1,87 @@
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package utility
+/**
+ * 数组工具类
+ *
+ * @author Qiong Wu
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindArray.php 2973 2011-10-15 19:22:48Z yishuo $
+ * @package utility
*/
-class WindArray {
+class WindArray
+{
+ /**
+ * 按指定key合并两个数组
+ *
+ * @param string key 合并数组的参照值
+ * @param array $array1 要合并数组
+ * @param array $array2 要合并数组
+ * @return array 返回合并的数组
+ */
+ public static function mergeArrayWithKey($key, array $array1, array $array2)
+ {
+ if (!$key || !$array1 || !$array2) {
+ return array();
+ }
+ $array1 = self::rebuildArrayWithKey($key, $array1);
+ $array2 = self::rebuildArrayWithKey($key, $array2);
+ $tmp = array();
+ foreach ($array1 as $key => $array) {
+ if (isset($array2[$key])) {
+ $tmp[$key] = array_merge($array, $array2[$key]);
+ unset($array2[$key]);
+ } else {
+ $tmp[$key] = $array;
+ }
+ }
- /**
- * 按指定key合并两个数组
- *
- * @param string key 合并数组的参照值
- * @param array $array1 要合并数组
- * @param array $array2 要合并数组
- * @return array 返回合并的数组
- */
- public static function mergeArrayWithKey($key, array $array1, array $array2) {
- if (!$key || !$array1 || !$array2) {
- return array();
- }
- $array1 = self::rebuildArrayWithKey($key, $array1);
- $array2 = self::rebuildArrayWithKey($key, $array2);
- $tmp = array();
- foreach ($array1 as $key => $array) {
- if (isset($array2[$key])) {
- $tmp[$key] = array_merge($array, $array2[$key]);
- unset($array2[$key]);
- } else {
- $tmp[$key] = $array;
- }
- }
- return array_merge($tmp, (array) $array2);
- }
+ return array_merge($tmp, (array) $array2);
+ }
- /**
- * 按指定key合并两个数组
- *
- * @param string key 合并数组的参照值
- * @param array $array1 要合并数组
- * @param array $array2 要合并数组
- * @return array 返回合并的数组
- */
- public static function filterArrayWithKey($key, array $array1, array $array2) {
- if (!$key || !$array1 || !$array2) {
- return array();
- }
- $array1 = self::rebuildArrayWithKey($key, $array1);
- $array2 = self::rebuildArrayWithKey($key, $array2);
- $tmp = array();
- foreach ($array1 as $key => $array) {
- if (isset($array2[$key])) {
- $tmp[$key] = array_merge($array, $array2[$key]);
- }
- }
- return $tmp;
- }
+ /**
+ * 按指定key合并两个数组
+ *
+ * @param string key 合并数组的参照值
+ * @param array $array1 要合并数组
+ * @param array $array2 要合并数组
+ * @return array 返回合并的数组
+ */
+ public static function filterArrayWithKey($key, array $array1, array $array2)
+ {
+ if (!$key || !$array1 || !$array2) {
+ return array();
+ }
+ $array1 = self::rebuildArrayWithKey($key, $array1);
+ $array2 = self::rebuildArrayWithKey($key, $array2);
+ $tmp = array();
+ foreach ($array1 as $key => $array) {
+ if (isset($array2[$key])) {
+ $tmp[$key] = array_merge($array, $array2[$key]);
+ }
+ }
- /**
- * 按指定KEY重新生成数组
- *
- * @param string key 重新生成数组的参照值
- * @param array $array 要重新生成的数组
- * @return array 返回重新生成后的数组
- */
- public static function rebuildArrayWithKey($key, array $array) {
- if (!$key || !$array) {
- return array();
- }
- $tmp = array();
- foreach ($array as $_array) {
- if (isset($_array[$key])) {
- $tmp[$_array[$key]] = $_array;
- }
- }
- return $tmp;
- }
-}
\ No newline at end of file
+ return $tmp;
+ }
+
+ /**
+ * 按指定KEY重新生成数组
+ *
+ * @param string key 重新生成数组的参照值
+ * @param array $array 要重新生成的数组
+ * @return array 返回重新生成后的数组
+ */
+ public static function rebuildArrayWithKey($key, array $array)
+ {
+ if (!$key || !$array) {
+ return array();
+ }
+ $tmp = array();
+ foreach ($array as $_array) {
+ if (isset($_array[$key])) {
+ $tmp[$_array[$key]] = $_array;
+ }
+ }
+
+ return $tmp;
+ }
+}
diff --git a/wind/utility/WindConvert.php b/wind/utility/WindConvert.php
index b56f6a65..6d8a122f 100644
--- a/wind/utility/WindConvert.php
+++ b/wind/utility/WindConvert.php
@@ -1,9 +1,9 @@
- * 1. utf16be转化为utf8
+ * 1.
+ * utf16be转化为utf8
* 2. utf8转化为utf16be
* 3. utf8转化为unicode
* 4. unicode转化为utf8
@@ -12,189 +12,209 @@
* @author Qiong Wu 2011-10-19
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindConvert.php 3829 2012-11-19 11:13:22Z yishuo $
* @package utility
*/
-class WindConvert {
- /**
- * 编码转换
- *
- * @param string $str 内容字符串
- * @param string $toEncoding 转为新编码
- * @param string $fromEncoding 原编码
- * @param bool $ifMb 是否使用mb函数
- * @return string
- */
- public static function convert($str, $toEncoding, $fromEncoding, $ifMb = true) {
- if (!strcasecmp($toEncoding, $fromEncoding)) return $str;
- switch (gettype($str)) {
- case 'string':
- if ($ifMb && function_exists('mb_convert_encoding'))
- $str = mb_convert_encoding($str, $toEncoding, $fromEncoding);
- else {
- !$toEncoding && $toEncoding = 'GBK';
- !$fromEncoding && $fromEncoding = 'GBK';
- Wind::getApp()->getWindFactory()->addClassDefinitions('windConverter',
- array('path' => 'WIND:convert.WindGeneralConverter', 'scope' => 'singleton'));
- /* @var $converter WindGeneralConverter */
- $converter = Wind::getApp()->getComponent('windConverter');
- $str = $converter->convert($str, $fromEncoding, $toEncoding);
- }
- break;
- case 'array':
- foreach ($str as $key => $value) {
- is_object($value) && $value = get_object_vars($value);
- $str[$key] = self::convert($value, $toEncoding, $fromEncoding, $ifMb);
- }
- break;
- default:
- break;
- }
- return $str;
- }
+class WindConvert
+{
+ /**
+ * 编码转换
+ *
+ * @param string $str
+ * 内容字符串
+ * @param string $toEncoding
+ * 转为新编码
+ * @param string $fromEncoding
+ * 原编码
+ * @param bool $ifMb
+ * 是否使用mb函数
+ * @return string
+ */
+ public static function convert($str, $toEncoding, $fromEncoding, $ifMb = true)
+ {
+ if (!strcasecmp($toEncoding, $fromEncoding)) {
+ return $str;
+ }
+ switch (gettype($str)) {
+ case 'string':
+ if ($ifMb && function_exists('mb_convert_encoding')) {
+ $str = mb_convert_encoding($str, $toEncoding, $fromEncoding);
+ } else {
+ !$toEncoding && $toEncoding = 'GBK';
+ !$fromEncoding && $fromEncoding = 'GBK';
+ Wind::registeComponent(array('path' => 'WIND:convert.WindGeneralConverter', 'scope' => 'singleton'),
+ 'windConverter');
- /**
- * gbk转为utf8编码
- *
- * @param mixed $srcText
- */
- public static function gbkToUtf8($srcText) {
- return iconv('GBK', 'UTF-8', $srcText);
- $this->getTableIndex();
- $tarText = '';
- for ($i = 0; $i < strlen($srcText); $i += 2) {
- $h = ord($srcText[$i]);
- if ($h > 127 && isset($this->TableIndex[$this->EncodeLang][$h])) {
- $l = ord($srcText[$i + 1]);
- if (!isset($this->TableEncode[$this->EncodeLang][$h][$l])) {
- fseek($this->TableHandle, $l * 2 + $this->TableIndex[$this->EncodeLang][$h]);
- $this->TableEncode[$this->EncodeLang][$h][$l] = $this->UNICODEtoUTF8(
- hexdec(bin2hex(fread($this->TableHandle, 2))));
- }
- $tarText .= $this->TableEncode[$this->EncodeLang][$h][$l];
- } elseif ($h < 128) {
- $tarText .= $srcText[$i];
- $i--;
- }
- }
- return $tarText;
- }
+ /* @var $converter WindGeneralConverter */
+ $converter = Wind::getComponent('windConverter');
+ $str = $converter->convert($str, $fromEncoding, $toEncoding);
+ }
+ break;
+ case 'array':
+ foreach ($str as $key => $value) {
+ is_object($value) && $value = get_object_vars($value);
+ $str[$key] = self::convert($value, $toEncoding, $fromEncoding, $ifMb);
+ }
+ break;
+ default:
+ break;
+ }
- /**
- * utf16be编码转化为utf8编码
- *
- * @param string $str
- * @return string
- */
- public static function utf16beToUTF8(&$str) {
- return self::unicodeToUTF8(unpack('n*', $str));
- }
+ return $str;
+ }
- /**
- * utf8编码转为utf16BE
- *
- * @param string $string
- * @param boolean $bom 是否Big-Endian
- */
- public static function utf8ToUTF16BE(&$string, $bom = false) {
- $out = $bom ? "\xFE\xFF" : '';
- if (function_exists('mb_convert_encoding')) {
- return $out . mb_convert_encoding($string, 'UTF-16BE', 'UTF-8');
- }
- $uni = self::utf8ToUnicode($string);
- foreach ($uni as $cp) {
- $out .= pack('n', $cp);
- }
- return $out;
- }
+ /**
+ * gbk转为utf8编码
+ *
+ * @param mixed $srcText
+ */
+ public static function gbkToUtf8($srcText)
+ {
+ return iconv('GBK', 'UTF-8', $srcText);
+ $this->getTableIndex();
+ $tarText = '';
+ for ($i = 0; $i < strlen($srcText); $i += 2) {
+ $h = ord($srcText[$i]);
+ if ($h > 127 && isset($this->TableIndex[$this->EncodeLang][$h])) {
+ $l = ord($srcText[$i + 1]);
+ if (!isset($this->TableEncode[$this->EncodeLang][$h][$l])) {
+ fseek($this->TableHandle, $l * 2 + $this->TableIndex[$this->EncodeLang][$h]);
+ $this->TableEncode[$this->EncodeLang][$h][$l] = $this->UNICODEtoUTF8(
+ hexdec(bin2hex(fread($this->TableHandle, 2))));
+ }
+ $tarText .= $this->TableEncode[$this->EncodeLang][$h][$l];
+ } elseif ($h < 128) {
+ $tarText .= $srcText[$i];
+ $i--;
+ }
+ }
- /**
- * unicode编码转化为utf8编码
- *
- * @param string $str
- * @return string
- */
- public static function unicodeToUTF8(&$str) {
- $utf8 = '';
- foreach ($str as $unicode) {
- if ($unicode < 128) {
- $utf8 .= chr($unicode);
- } elseif ($unicode < 2048) {
- $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64));
- $utf8 .= chr(128 + ($unicode % 64));
- } else {
- $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096));
- $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64));
- $utf8 .= chr(128 + ($unicode % 64));
- }
- }
- return $utf8;
- }
+ return $tarText;
+ }
- /**
- * utf8编码转化为unicode
- *
- * @param string $string
- * @return Ambigous
- */
- public static function utf8ToUnicode(&$string) {
- $unicode = $values = array();
- $lookingFor = 1;
- for ($i = 0, $length = strlen($string); $i < $length; $i++) {
- $thisValue = ord($string[$i]);
- if ($thisValue < 128) {
- $unicode[] = $thisValue;
- } else {
- if (count($values) == 0) {
- $lookingFor = ($thisValue < 224) ? 2 : 3;
- }
- $values[] = $thisValue;
- if (count($values) == $lookingFor) {
- $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64;
- $values = array();
- $lookingFor = 1;
- }
- }
- }
- return $unicode;
- }
+ /**
+ * utf16be编码转化为utf8编码
+ *
+ * @param string $str
+ * @return string
+ */
+ public static function utf16beToUTF8($str)
+ {
+ return self::unicodeToUTF8(unpack('n*', $str));
+ }
- /**
- * 获取输入编码
- *
- * @param string $lang
- * @return string
- */
- private static function _getCharset($lang) {
- switch (strtoupper(substr($lang, 0, 2))) {
- case 'GB':
- $lang = 'GBK';
- break;
- case 'UT':
- $lang = 'UTF8';
- break;
- case 'UN':
- $lang = 'UNICODE';
- break;
- case 'BI':
- $lang = 'BIG5';
- break;
- default:
- $lang = '';
- }
- return $lang;
- }
+ /**
+ * utf8编码转为utf16BE
+ *
+ * @param string $string
+ * @param bool $bom
+ * 是否Big-Endian
+ */
+ public static function utf8ToUTF16BE($string, $bom = false)
+ {
+ $out = $bom ? "\xFE\xFF" : '';
+ if (function_exists('mb_convert_encoding')) {
+ return $out.mb_convert_encoding($string, 'UTF-16BE', 'UTF-8');
+ }
+ $uni = self::utf8ToUnicode($string);
+ foreach ($uni as $cp) {
+ $out .= pack('n', $cp);
+ }
- /**
- * iconv 是否开启
- *
- * @param 目标编码 $targeLang
- * @return boolean
- */
- private static function _isIconv($targeLang) {
- return function_exists('iconv') && $targeLang != 'BIG5';
- }
+ return $out;
+ }
-}
+ /**
+ * unicode编码转化为utf8编码
+ *
+ * @param string $str
+ * @return string
+ */
+ public static function unicodeToUTF8($str)
+ {
+ $utf8 = '';
+ foreach ($str as $unicode) {
+ if ($unicode < 128) {
+ $utf8 .= chr($unicode);
+ } elseif ($unicode < 2048) {
+ $utf8 .= chr(192 + (($unicode - ($unicode % 64)) / 64));
+ $utf8 .= chr(128 + ($unicode % 64));
+ } else {
+ $utf8 .= chr(224 + (($unicode - ($unicode % 4096)) / 4096));
+ $utf8 .= chr(128 + ((($unicode % 4096) - ($unicode % 64)) / 64));
+ $utf8 .= chr(128 + ($unicode % 64));
+ }
+ }
+
+ return $utf8;
+ }
+
+ /**
+ * utf8编码转化为unicode
+ *
+ * @param string $string
+ * @return Ambigous
+ */
+ public static function utf8ToUnicode($string)
+ {
+ $unicode = $values = array();
+ $lookingFor = 1;
+ for ($i = 0, $length = strlen($string); $i < $length; $i++) {
+ $thisValue = ord($string[$i]);
+ if ($thisValue < 128) {
+ $unicode[] = $thisValue;
+ } else {
+ if (count($values) == 0) {
+ $lookingFor = ($thisValue < 224) ? 2 : 3;
+ }
+ $values[] = $thisValue;
+ if (count($values) == $lookingFor) {
+ $unicode[] = ($lookingFor == 3) ? ($values[0] % 16) * 4096 + ($values[1] % 64) * 64 + $values[2] % 64 : ($values[0] % 32) * 64 + $values[1] % 64;
+ $values = array();
+ $lookingFor = 1;
+ }
+ }
+ }
+
+ return $unicode;
+ }
-?>
\ No newline at end of file
+ /**
+ * 获取输入编码
+ *
+ * @param string $lang
+ * @return string
+ */
+ private static function _getCharset($lang)
+ {
+ switch (strtoupper(substr($lang, 0, 2))) {
+ case 'GB':
+ $lang = 'GBK';
+ break;
+ case 'UT':
+ $lang = 'UTF8';
+ break;
+ case 'UN':
+ $lang = 'UNICODE';
+ break;
+ case 'BI':
+ $lang = 'BIG5';
+ break;
+ default:
+ $lang = '';
+ }
+
+ return $lang;
+ }
+
+ /**
+ * iconv 是否开启
+ *
+ * @param 目标编码 $targeLang
+ * @return bool
+ */
+ private static function _isIconv($targeLang)
+ {
+ return function_exists('iconv') && $targeLang != 'BIG5';
+ }
+}
diff --git a/wind/utility/WindCookie.php b/wind/utility/WindCookie.php
index 33e3194c..9d9e3c60 100644
--- a/wind/utility/WindCookie.php
+++ b/wind/utility/WindCookie.php
@@ -1,90 +1,102 @@
-
- * Wind::import('WIND:http.cookie.WindCookie');
+ *
* WindCookie::set('name', 'test');
*
- *
+ *
* @author Qian Su
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindCookie.php 3760 2012-10-11 08:02:25Z yishuo $
* @package http
* @subpackage cookie
- */
-class WindCookie {
-
- /**
- * 设置cookie
- *
- * @param string $name cookie名称
- * @param string $value cookie值,默认为null
- * @param boolean $encode 是否使用 MIME base64 对数据进行编码,默认是false即不进行编码
- * @param string|int $expires 过期时间,默认为null即会话cookie,随着会话结束将会销毁
- * @param string $path cookie保存的路径,默认为null即采用默认
- * @param string $domain cookie所属域,默认为null即不设置
- * @param boolean $secure 是否安全连接,默认为false即不采用安全链接
- * @param boolean $httponly 是否可通过客户端脚本访问,默认为false即客户端脚本可以访问cookie
- * @return boolean 设置成功返回true,失败返回false
- */
- public static function set($name, $value = null, $encode = false, $expires = null, $path = null, $domain = null, $secure = false, $httponly = false) {
- if (empty($name)) return false;
- $encode && $value && $value = base64_encode(serialize($value));
- $path = $path ? $path : '/';
- setcookie($name, $value, $expires, $path, $domain, $secure, $httponly);
- return true;
- }
-
- /**
- * 根据cookie的名字删除cookie
- *
- * @param string $name cookie名称
- * @return boolean 删除成功返回true
- */
- public static function delete($name) {
- if (self::exist($name)) {
- self::set($name, '');
- unset($_COOKIE[$name]);
- }
- return true;
- }
-
- /**
- * 取得指定名称的cookie值
- *
- * @param string $name cookie名称
- * @param boolean $dencode 是否对cookie值进行过解码,默认为false即不用解码
- * @return mixed 获取成功将返回保存的cookie值,获取失败将返回false
- */
- public static function get($name, $dencode = false) {
- if (self::exist($name)) {
- $value = $_COOKIE[$name];
- $value && $dencode && $value = unserialize(base64_decode($value));
- return $value ? $value : $value;
- }
- return false;
- }
-
- /**
- * 移除全部cookie
- *
- * @return boolean 移除成功将返回true
- */
- public static function deleteAll() {
- $_COOKIE = array();
- return true;
- }
-
- /**
- * 判断cookie是否存在
- *
- * @param string $name cookie名称
- * @return boolean 如果不存在则返回false,否则返回true
- */
- public static function exist($name) {
- return isset($_COOKIE[$name]);
- }
-}
\ No newline at end of file
+ */
+class WindCookie
+{
+ /**
+ * 设置cookie
+ *
+ * @param string $name cookie名称
+ * @param string $value cookie值,默认为null
+ * @param bool $encode 是否使用 MIME base64 对数据进行编码,默认是false即不进行编码
+ * @param string|int $expires 过期时间,默认为null即会话cookie,随着会话结束将会销毁
+ * @param string $path cookie保存的路径,默认为null即采用默认
+ * @param string $domain cookie所属域,默认为null即不设置
+ * @param bool $secure 是否安全连接,默认为false即不采用安全链接
+ * @param bool $httponly 是否可通过客户端脚本访问,默认为false即客户端脚本可以访问cookie
+ * @return bool 设置成功返回true,失败返回false
+ */
+ public static function set($name, $value = null, $encode = false, $expires = null, $path = null, $domain = null, $secure = false, $httponly = false)
+ {
+ if (empty($name)) {
+ return false;
+ }
+ $encode && $value && $value = base64_encode($value);
+ $path = $path ? $path : '/';
+ setcookie($name, $value, $expires, $path, $domain, $secure, $httponly);
+
+ return true;
+ }
+
+ /**
+ * 根据cookie的名字删除cookie
+ *
+ * @param string $name cookie名称
+ * @return bool 删除成功返回true
+ */
+ public static function delete($name)
+ {
+ if (self::exist($name)) {
+ self::set($name, '');
+ unset($_COOKIE[$name]);
+ }
+
+ return true;
+ }
+
+ /**
+ * 取得指定名称的cookie值
+ *
+ * @param string $name cookie名称
+ * @param bool $dencode 是否对cookie值进行过解码,默认为false即不用解码
+ * @return mixed 获取成功将返回保存的cookie值,获取失败将返回false
+ */
+ public static function get($name, $dencode = false)
+ {
+ if (self::exist($name)) {
+ $value = $_COOKIE[$name];
+ $value && $dencode && $value = base64_decode($value);
+
+ return $value ? $value : $value;
+ }
+
+ return false;
+ }
+
+ /**
+ * 移除全部cookie
+ *
+ * @return bool 移除成功将返回true
+ */
+ public static function deleteAll()
+ {
+ $_COOKIE = array();
+
+ return true;
+ }
+
+ /**
+ * 判断cookie是否存在
+ *
+ * @param string $name cookie名称
+ * @return bool 如果不存在则返回false,否则返回true
+ */
+ public static function exist($name)
+ {
+ return isset($_COOKIE[$name]);
+ }
+}
diff --git a/wind/utility/WindDate.php b/wind/utility/WindDate.php
index eed51bd9..dafacc61 100644
--- a/wind/utility/WindDate.php
+++ b/wind/utility/WindDate.php
@@ -1,332 +1,362 @@
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package utility
+/**
+ * 日期的换算与计算
+ *
+ * @author Qian Su
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindDate.php 2973 2011-10-15 19:22:48Z yishuo $
+ * @package utility
*/
-class WindDate {
+class WindDate
+{
+ /**
+ * 获取时区
+ *
+ * @return string
+ */
+ public static function getTimeZone()
+ {
+ return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e');
+ }
- /**
- * 获取时区
- *
- * @return string
- */
- public static function getTimeZone() {
- return function_exists('date_default_timezone_get') ? date_default_timezone_get() : date('e');
- }
+ /**
+ * 设置时区
+ *
+ * @param string $timezone 时区
+ */
+ public static function setTimezone($timezone)
+ {
+ function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}");
+ }
- /**
- * 设置时区
- *
- * @param string $timezone 时区
- */
- public static function setTimezone($timezone) {
- function_exists('date_default_timezone_set') ? date_default_timezone_set($timezone) : putenv("TZ={$timezone}");
- }
+ /**
+ * 格式化输出
+ *
+ * @param string $format 目标格式,默认为null则以Y-m-d H:i:s格式输出
+ * @param int $dateTime unix时间戳,默认为null则用当前时间
+ * @return string
+ */
+ public static function format($format = null, $dateTime = null)
+ {
+ return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime));
+ }
- /**
- * 格式化输出
- *
- * @param string $format 目标格式,默认为null则以Y-m-d H:i:s格式输出
- * @param int $dateTime unix时间戳,默认为null则用当前时间
- * @return string
- */
- public static function format($format = null, $dateTime = null) {
- return date($format ? $format : 'Y-m-d H:i:s', self::getTimeStamp($dateTime));
- }
+ /**
+ * 获取日期的某部分
+ *
+ * @param string $interval 字符串表达式 ,时间间隔类型
+ * @param mixed $dateTime 表示日期的文字,默认为null则用当前时间
+ * @return string 返回日期的某部分
+ */
+ public static function datePart($interval, $dateTime = null)
+ {
+ return date($interval, self::getTimeStamp($dateTime));
+ }
- /**
- * 获取日期的某部分
- *
- * @param string $interval 字符串表达式 ,时间间隔类型
- * @param mixed $dateTime 表示日期的文字,默认为null则用当前时间
- * @return string 返回日期的某部分
- */
- public static function datePart($interval, $dateTime = null) {
- return date($interval, self::getTimeStamp($dateTime));
- }
+ /**
+ * 获取两个日期的差
+ *
+ * @param string $interval 返回两个日期差的间隔类型
+ * @param mixed $startDateTime 开始日期
+ * @param mixed $endDateTime 结束日期
+ * @return string
+ */
+ public static function dateDiff($interval, $startDateTime, $endDateTime)
+ {
+ $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime);
+ $retval = 0;
+ switch ($interval) {
+ case 'y':
+ $retval = bcdiv($diff, (60 * 60 * 24 * 365));
+ break;
+ case 'm':
+ $retval = bcdiv($diff, (60 * 60 * 24 * 30));
+ break;
+ case 'w':
+ $retval = bcdiv($diff, (60 * 60 * 24 * 7));
+ break;
+ case 'd':
+ $retval = bcdiv($diff, (60 * 60 * 24));
+ break;
+ case 'h':
+ $retval = bcdiv($diff, (60 * 60));
+ break;
+ case 'n':
+ $retval = bcdiv($diff, 60);
+ break;
+ case 's':
+ default:
+ $retval = $diff;
+ break;
+ }
- /**
- * 获取两个日期的差
- *
- * @param string $interval 返回两个日期差的间隔类型
- * @param mixed $startDateTime 开始日期
- * @param mixed $endDateTime 结束日期
- * @return string
- */
- public static function dateDiff($interval, $startDateTime, $endDateTime) {
- $diff = self::getTimeStamp($endDateTime) - self::getTimeStamp($startDateTime);
- $retval = 0;
- switch ($interval) {
- case "y":
- $retval = bcdiv($diff, (60 * 60 * 24 * 365));
- break;
- case "m":
- $retval = bcdiv($diff, (60 * 60 * 24 * 30));
- break;
- case "w":
- $retval = bcdiv($diff, (60 * 60 * 24 * 7));
- break;
- case "d":
- $retval = bcdiv($diff, (60 * 60 * 24));
- break;
- case "h":
- $retval = bcdiv($diff, (60 * 60));
- break;
- case "n":
- $retval = bcdiv($diff, 60);
- break;
- case "s":
- default:
- $retval = $diff;
- break;
- }
- return $retval;
- }
+ return $retval;
+ }
- /**
- * 返回向指定日期追加指定间隔类型的一段时间间隔后的日期
- *
- * @param string $interval 字符串表达式,是所要加上去的时间间隔类型。
- * @param int $value 数值表达式,是要加上的时间间隔的数目。其数值可以为正数(得到未来的日期),也可以为负数(得到过去的日期)。
- * @param string $dateTime 表示日期的文字,这一日期还加上了时间间隔。
- * @param mixed $format 格式化输出
- * @return string 返回追加后的时间
- */
- public static function dateAdd($interval, $value, $dateTime, $format = null) {
- $date = getdate(self::getTimeStamp($dateTime));
- switch ($interval) {
- case "y":
- $date["year"] += $value;
- break;
- case "q":
- $date["mon"] += ($value * 3);
- break;
- case "m":
- $date["mon"] += $value;
- break;
- case "w":
- $date["mday"] += ($value * 7);
- break;
- case "d":
- $date["mday"] += $value;
- break;
- case "h":
- $date["hours"] += $value;
- break;
- case "n":
- $date["minutes"] += $value;
- break;
- case "s":
- default:
- $date["seconds"] += $value;
- break;
- }
- return self::format($format, mktime($date["hours"], $date["minutes"], $date["seconds"], $date["mon"], $date["mday"], $date["year"]));
- }
+ /**
+ * 返回向指定日期追加指定间隔类型的一段时间间隔后的日期
+ *
+ * @param string $interval 字符串表达式,是所要加上去的时间间隔类型。
+ * @param int $value 数值表达式,是要加上的时间间隔的数目。其数值可以为正数(得到未来的日期),也可以为负数(得到过去的日期)。
+ * @param string $dateTime 表示日期的文字,这一日期还加上了时间间隔。
+ * @param mixed $format 格式化输出
+ * @return string 返回追加后的时间
+ */
+ public static function dateAdd($interval, $value, $dateTime, $format = null)
+ {
+ $date = getdate(self::getTimeStamp($dateTime));
+ switch ($interval) {
+ case 'y':
+ $date['year'] += $value;
+ break;
+ case 'q':
+ $date['mon'] += ($value * 3);
+ break;
+ case 'm':
+ $date['mon'] += $value;
+ break;
+ case 'w':
+ $date['mday'] += ($value * 7);
+ break;
+ case 'd':
+ $date['mday'] += $value;
+ break;
+ case 'h':
+ $date['hours'] += $value;
+ break;
+ case 'n':
+ $date['minutes'] += $value;
+ break;
+ case 's':
+ default:
+ $date['seconds'] += $value;
+ break;
+ }
- /**
- * 得到一年中每个月真实的天数
- *
- * @param string $year 需要获得的月份天数的年份
- * @return array 每月的天数组成的数组
- */
- public static function getRealDaysInMonthsOfYear($year) {
- $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
- if (self::isLeapYear($year)) {
- $months[1] = 29;
- }
- return $months;
- }
+ return self::format($format, mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']));
+ }
- /**
- * 获取该月的天数
- *
- * @param int $month 月份
- * @param int $year 年份
- * @return int
- */
- public static function getDaysInMonth($month, $year) {
- if (1 > $month || 12 < $month) {
- return 0;
- }
- if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) {
- return 0;
- }
- return $daysInmonths[$month - 1];
- }
+ /**
+ * 得到一年中每个月真实的天数
+ *
+ * @param string $year 需要获得的月份天数的年份
+ * @return array 每月的天数组成的数组
+ */
+ public static function getRealDaysInMonthsOfYear($year)
+ {
+ $months = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+ if (self::isLeapYear($year)) {
+ $months[1] = 29;
+ }
- /**
- * 获取该年的天数
- *
- * @return int
- */
- public static function getDaysInYear($year) {
- return self::isLeapYear($year) ? 366 : 365;
- }
+ return $months;
+ }
- /**
- * 取得RFC格式的日期与时间
- *
- * @param string $data 需要获取的时间,默认为null则获取当前时间
- * @return string
- */
- public static function getRFCDate($date = null) {
- $time = $date ? is_int($date) ? $date : strtotime($date) : time();
- $tz = date('Z', $time);
- $tzs = ($tz < 0) ? '-' : '+';
- $tz = abs($tz);
- $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60;
- return sprintf("%s %s%04d", date('D, j M Y H:i:s', $time), $tzs, $tz);
- }
+ /**
+ * 获取该月的天数
+ *
+ * @param int $month 月份
+ * @param int $year 年份
+ * @return int
+ */
+ public static function getDaysInMonth($month, $year)
+ {
+ if (1 > $month || 12 < $month) {
+ return 0;
+ }
+ if (!($daysInmonths = self::getRealDaysInMonthsOfYear($year))) {
+ return 0;
+ }
- /**
- * 取得中国日期时间
- *
- * @param int $time 需要使用的时间戳,默认为null则获取当前时间戳
- * @return string
- */
- public static function getChinaDate($time = null) {
- list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i', $time ? $time : time()));
- return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i);
- }
+ return $daysInmonths[$month - 1];
+ }
- /**
- * 取得中国的星期
- *
- * @param int $week 处国人的星期,是一个数值,默认为null则使用当前时间
- * @return string
- */
- public static function getChinaWeek($week = null) {
- $week = $week ? $week : (int) date('w', time());
- $weekMap = array("星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
- return $weekMap[$week];
- }
+ /**
+ * 获取该年的天数
+ *
+ * @return int
+ */
+ public static function getDaysInYear($year)
+ {
+ return self::isLeapYear($year) ? 366 : 365;
+ }
- /**
- * 取得一天中的时段
- *
- * @param int $hour 小时,默认为null则获取当前时间
- * @return string
- */
- public static function getPeriodOfTime($hour = null) {
- $hour = $hour ? $hour : (int) date('G', time());
- $period = '';
- if (0 <= $hour && 6 > $hour) {
- $period = '凌晨';
- } elseif (6 <= $hour && 8 > $hour) {
- $period = '早上';
- } elseif (8 <= $hour && 11 > $hour) {
- $period = '上午';
- } elseif (11 <= $hour && 13 > $hour) {
- $period = '中午';
- } elseif (13 <= $hour && 15 > $hour) {
- $period = '响午';
- } elseif (15 <= $hour && 18 > $hour) {
- $period = '下午';
- } elseif (18 <= $hour && 20 > $hour) {
- $period = '傍晚';
- } elseif (20 <= $hour && 22 > $hour) {
- $period = '晚上';
- } elseif (22 <= $hour && 23 >= $hour) {
- $period = '深夜';
- }
- return $period;
- }
+ /**
+ * 取得RFC格式的日期与时间
+ *
+ * @param string $data 需要获取的时间,默认为null则获取当前时间
+ * @return string
+ */
+ public static function getRFCDate($date = null)
+ {
+ $time = $date ? is_int($date) ? $date : strtotime($date) : time();
+ $tz = date('Z', $time);
+ $tzs = ($tz < 0) ? '-' : '+';
+ $tz = abs($tz);
+ $tz = (int) ($tz / 3600) * 100 + ($tz % 3600) / 60;
- /**
- * 获取UTC日期格式
- *
- * @param mixed $dateTime 时间,默认为null则获取当前时间
- * @return string
- */
- public static function getUTCDate($dateTime = null) {
- $oldTimezone = self::getTimezone();
- if ('UTC' !== strtoupper($oldTimezone)) {
- self::setTimezone('UTC');
- }
- $date = date('D, d M y H:i:s e', self::getTimeStamp($dateTime));
- if ('UTC' !== strtoupper($oldTimezone)) {
- self::setTimezone($oldTimezone);
- }
- return $date;
- }
+ return sprintf('%s %s%04d', date('D, j M Y H:i:s', $time), $tzs, $tz);
+ }
- /**
- * 获取微秒数
- *
- * @param string $mircrotime 微妙时间,默认为null则获取当前时间
- * @param string $get_as_float 获取微妙时间是否以浮点数返回,默认为false即不以浮点数方式返回
- * @return int
- */
- public static function getMicroTime($mircrotime = null, $get_as_float = false) {
- return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float)));
- }
+ /**
+ * 取得中国日期时间
+ *
+ * @param int $time 需要使用的时间戳,默认为null则获取当前时间戳
+ * @return string
+ */
+ public static function getChinaDate($time = null)
+ {
+ list($y, $m, $d, $w, $h, $_h, $i) = explode(' ', date('Y n j w G g i', $time ? $time : time()));
- /**
- * 判断是否是闰年
- *
- * @param int $year 需要判断的年份
- * @return boolean 如果是润年则返回true
- */
- public static function isLeapYear($year) {
- return (0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400);
- }
+ return sprintf('%s年%s月%s日(%s) %s%s:%s', $y, $m, $d, self::getChinaWeek($w), self::getPeriodOfTime($h), $_h, $i);
+ }
- /**
- * 获得时间戳
- *
- * @param int $dateTime 时间戳,默认为null则以当前时间戳返回
- * @return int
- */
- public static function getTimeStamp($dateTime = null) {
- return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time();
- }
+ /**
+ * 取得中国的星期
+ *
+ * @param int $week 处国人的星期,是一个数值,默认为null则使用当前时间
+ * @return string
+ */
+ public static function getChinaWeek($week = null)
+ {
+ $week = $week ? $week : (int) date('w', time());
+ $weekMap = array('星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六');
- /**
- * 比较两个时间返回离现在最近的一个时间
- *
- * @param int $time 当前时间戳
- * @param int $timestamp 比较的时间戳,默认为null则获取当前时间戳
- * @param string $format 格式化当前时间戳,默认为null则转化为格式Y-m-d H:i:s
- * @param array $type 要返回的时间类型,默认为 1则只返回Y-m-d否则返回Y-m-d m-d H:i
- * @return array
- */
- public static function getLastDate($time, $timestamp = null, $format = null, $type = 1) {
- $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' => '前天');
- $timestamp = $timestamp ? $timestamp : time();
- $compareTime = strtotime(self::format('Y-m-d', $timestamp));
- $currentTime = strtotime(self::format('Y-m-d', $time));
- $decrease = $timestamp - $time;
- $result = self::format($format, $time);
- if (0 >= $decrease) {
- return 1 == $type ? array(self::format('Y-m-d', $time), $result) : array(
- self::format('Y-m-d m-d H:i', $time), $result);
- }
- if ($currentTime == $compareTime) {
- if (1 == $type) {
- if (60 >= $decrease) {
- return array($decrease . $timelang['second'], $result);
- }
- return 3600 >= $decrease ? array(ceil($decrease / 60) . $timelang['minute'], $result) : array(
- ceil($decrease / 3600) . $timelang['hour'], $result);
- }
- return array(self::format('H:i', $time), $result);
- } elseif ($currentTime == $compareTime - 86400) {
- return 1 == $type ? array($timelang['yesterday'] . " " . self::format('H:i', $time), $result) : array(
- self::format('m-d H:i', $time), $result);
- } elseif ($currentTime == $compareTime - 172800) {
- return 1 == $type ? array($timelang['qiantian'] . " " . self::format('H:i', $time), $result) : array(
- self::format('m-d H:i', $time), $result);
- } elseif (strtotime(self::format('Y', $time)) == strtotime(self::format('Y', $timestamp))) {
- return 1 == $type ? array(self::format('m-d', $time), $result) : array(self::format('m-d H:i', $time),
- $result);
- }
- return 1 == $type ? array(self::format('Y-m-d', $time), $result) : array(self::format('Y-m-d m-d H:i', $time),
- $result);
- }
-}
\ No newline at end of file
+ return $weekMap[$week];
+ }
+
+ /**
+ * 取得一天中的时段
+ *
+ * @param int $hour 小时,默认为null则获取当前时间
+ * @return string
+ */
+ public static function getPeriodOfTime($hour = null)
+ {
+ $hour = $hour ? $hour : (int) date('G', time());
+ $period = '';
+ if (0 <= $hour && 6 > $hour) {
+ $period = '凌晨';
+ } elseif (6 <= $hour && 8 > $hour) {
+ $period = '早上';
+ } elseif (8 <= $hour && 11 > $hour) {
+ $period = '上午';
+ } elseif (11 <= $hour && 13 > $hour) {
+ $period = '中午';
+ } elseif (13 <= $hour && 15 > $hour) {
+ $period = '响午';
+ } elseif (15 <= $hour && 18 > $hour) {
+ $period = '下午';
+ } elseif (18 <= $hour && 20 > $hour) {
+ $period = '傍晚';
+ } elseif (20 <= $hour && 22 > $hour) {
+ $period = '晚上';
+ } elseif (22 <= $hour && 23 >= $hour) {
+ $period = '深夜';
+ }
+
+ return $period;
+ }
+
+ /**
+ * 获取UTC日期格式
+ *
+ * @param mixed $dateTime 时间,默认为null则获取当前时间
+ * @return string
+ */
+ public static function getUTCDate($dateTime = null)
+ {
+ $oldTimezone = self::getTimezone();
+ if ('UTC' !== strtoupper($oldTimezone)) {
+ self::setTimezone('UTC');
+ }
+ $date = date('D, d M y H:i:s e', self::getTimeStamp($dateTime));
+ if ('UTC' !== strtoupper($oldTimezone)) {
+ self::setTimezone($oldTimezone);
+ }
+
+ return $date;
+ }
+
+ /**
+ * 获取微秒数
+ *
+ * @param string $mircrotime 微妙时间,默认为null则获取当前时间
+ * @param string $get_as_float 获取微妙时间是否以浮点数返回,默认为false即不以浮点数方式返回
+ * @return int
+ */
+ public static function getMicroTime($mircrotime = null, $get_as_float = false)
+ {
+ return array_sum(explode(' ', $mircrotime ? $mircrotime : microtime($get_as_float)));
+ }
+
+ /**
+ * 判断是否是闰年
+ *
+ * @param int $year 需要判断的年份
+ * @return bool 如果是润年则返回true
+ */
+ public static function isLeapYear($year)
+ {
+ return 0 == $year % 4 && 0 != $year % 100 || 0 == $year % 400;
+ }
+
+ /**
+ * 获得时间戳
+ *
+ * @param int $dateTime 时间戳,默认为null则以当前时间戳返回
+ * @return int
+ */
+ public static function getTimeStamp($dateTime = null)
+ {
+ return $dateTime ? is_int($dateTime) ? $dateTime : strtotime($dateTime) : time();
+ }
+
+ /**
+ * 比较两个时间返回离现在最近的一个时间
+ *
+ * @param int $time 当前时间戳
+ * @param int $timestamp 比较的时间戳,默认为null则获取当前时间戳
+ * @param string $format 格式化当前时间戳,默认为null则转化为格式Y-m-d H:i:s
+ * @param array $type 要返回的时间类型,默认为 1则只返回Y-m-d否则返回Y-m-d m-d H:i
+ * @return array
+ */
+ public static function getLastDate($time, $timestamp = null, $format = null, $type = 1)
+ {
+ $timelang = array('second' => '秒前', 'yesterday' => '昨天', 'hour' => '小时前', 'minute' => '分钟前', 'qiantian' => '前天');
+ $timestamp = $timestamp ? $timestamp : time();
+ $compareTime = strtotime(self::format('Y-m-d', $timestamp));
+ $currentTime = strtotime(self::format('Y-m-d', $time));
+ $decrease = $timestamp - $time;
+ $result = self::format($format, $time);
+ if (0 >= $decrease) {
+ return 1 == $type ? array(self::format('Y-m-d', $time), $result) : array(
+ self::format('Y-m-d m-d H:i', $time), $result, );
+ }
+ if ($currentTime == $compareTime) {
+ if (1 == $type) {
+ if (60 >= $decrease) {
+ return array($decrease.$timelang['second'], $result);
+ }
+
+ return 3600 >= $decrease ? array(ceil($decrease / 60).$timelang['minute'], $result) : array(
+ ceil($decrease / 3600).$timelang['hour'], $result, );
+ }
+
+ return array(self::format('H:i', $time), $result);
+ } elseif ($currentTime == $compareTime - 86400) {
+ return 1 == $type ? array($timelang['yesterday'].' '.self::format('H:i', $time), $result) : array(
+ self::format('m-d H:i', $time), $result, );
+ } elseif ($currentTime == $compareTime - 172800) {
+ return 1 == $type ? array($timelang['qiantian'].' '.self::format('H:i', $time), $result) : array(
+ self::format('m-d H:i', $time), $result, );
+ } elseif (strtotime(self::format('Y', $time)) == strtotime(self::format('Y', $timestamp))) {
+ return 1 == $type ? array(self::format('m-d', $time), $result) : array(self::format('m-d H:i', $time),
+ $result, );
+ }
+
+ return 1 == $type ? array(self::format('Y-m-d', $time), $result) : array(self::format('Y-m-d m-d H:i', $time),
+ $result, );
+ }
+}
diff --git a/wind/utility/WindFile.php b/wind/utility/WindFile.php
index d04d1e85..66f0e317 100644
--- a/wind/utility/WindFile.php
+++ b/wind/utility/WindFile.php
@@ -1,150 +1,172 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindFile.php 3298 2012-01-06 12:48:26Z yishuo $
* @package utility
*/
-class WindFile {
- /**
- * 以读的方式打开文件,具有较强的平台移植性
- *
- * @var string
- */
- const READ = 'rb';
- /**
- * 以读写的方式打开文件,具有较强的平台移植性
- *
- * @var string
- */
- const READWRITE = 'rb+';
- /**
- * 以写的方式打开文件,具有较强的平台移植性
- *
- * @var string
- */
- const WRITE = 'wb';
- /**
- * 以读写的方式打开文件,具有较强的平台移植性
- *
- * @var string
- */
- const WRITEREAD = 'wb+';
- /**
- * 以追加写入方式打开文件,具有较强的平台移植性
- *
- * @var string
- */
- const APPEND_WRITE = 'ab';
- /**
- * 以追加读写入方式打开文件,具有较强的平台移植性
- *
- * @var string
- */
- const APPEND_WRITEREAD = 'ab+';
-
- /**
- * 删除文件
- *
- * @param string $filename 文件名称
- * @return boolean
- */
- public static function del($filename) {
- return @unlink($filename);
- }
+class WindFile
+{
+ /**
+ * 以读的方式打开文件,具有较强的平台移植性
+ *
+ * @var string
+ */
+ const READ = 'rb';
+ /**
+ * 以读写的方式打开文件,具有较强的平台移植性
+ *
+ * @var string
+ */
+ const READWRITE = 'rb+';
+ /**
+ * 以写的方式打开文件,具有较强的平台移植性
+ *
+ * @var string
+ */
+ const WRITE = 'wb';
+ /**
+ * 以读写的方式打开文件,具有较强的平台移植性
+ *
+ * @var string
+ */
+ const WRITEREAD = 'wb+';
+ /**
+ * 以追加写入方式打开文件,具有较强的平台移植性
+ *
+ * @var string
+ */
+ const APPEND_WRITE = 'ab';
+ /**
+ * 以追加读写入方式打开文件,具有较强的平台移植性
+ *
+ * @var string
+ */
+ const APPEND_WRITEREAD = 'ab+';
+
+ /**
+ * 删除文件
+ *
+ * @param string $filename 文件名称
+ * @return bool
+ */
+ public static function del($filename)
+ {
+ return @unlink($filename);
+ }
+
+ /**
+ * 保存文件
+ *
+ * @param string $fileName 保存的文件名
+ * @param mixed $data 保存的数据
+ * @param bool $isBuildReturn 是否组装保存的数据是return $params的格式,如果没有则以变量声明的方式保存,默认为true则以return的方式保存
+ * @param string $method 打开文件方式,默认为rb+的形式
+ * @param bool $ifLock 是否对文件加锁,默认为true即加锁
+ */
+ public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = self::READWRITE, $ifLock = true)
+ {
+ $temp = " $value) {
+ if (!preg_match('/^\w+$/', $key)) {
+ continue;
+ }
+ $temp .= '$'.$key.' = '.WindString::varToString($value).";\r\n";
+ }
+ $temp .= "\r\n?>";
+ } else {
+ ($isBuildReturn) && $temp .= ' return ';
+ $temp .= WindString::varToString($data).";\r\n?>";
+ }
+
+ return self::write($fileName, $temp, $method, $ifLock);
+ }
+
+ /**
+ * 写文件
+ *
+ * @param string $fileName 文件绝对路径
+ * @param string $data 数据
+ * @param string $method 读写模式,默认模式为rb+
+ * @param bool $ifLock 是否锁文件,默认为true即加锁
+ * @param bool $ifCheckPath 是否检查文件名中的“..”,默认为true即检查
+ * @param bool $ifChmod 是否将文件属性改为可读写,默认为true
+ * @return int 返回写入的字节数
+ */
+ public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true)
+ {
+ touch($fileName);
+ if (!$handle = fopen($fileName, $method)) {
+ return false;
+ }
+ $ifLock && flock($handle, LOCK_EX);
+ $writeCheck = fwrite($handle, $data);
+ $method == self::READWRITE && ftruncate($handle, strlen($data));
+ fclose($handle);
+ $ifChmod && chmod($fileName, 0777);
+
+ return $writeCheck;
+ }
- /**
- * 保存文件
- *
- * @param string $fileName 保存的文件名
- * @param mixed $data 保存的数据
- * @param boolean $isBuildReturn 是否组装保存的数据是return $params的格式,如果没有则以变量声明的方式保存,默认为true则以return的方式保存
- * @param string $method 打开文件方式,默认为rb+的形式
- * @param boolean $ifLock 是否对文件加锁,默认为true即加锁
- */
- public static function savePhpData($fileName, $data, $isBuildReturn = true, $method = self::READWRITE, $ifLock = true) {
- $temp = " $value) {
- if (!preg_match('/^\w+$/', $key)) continue;
- $temp .= "\$" . $key . " = " . WindString::varToString($value) . ";\r\n";
- }
- $temp .= "\r\n?>";
- } else {
- ($isBuildReturn) && $temp .= " return ";
- $temp .= WindString::varToString($data) . ";\r\n?>";
- }
- return self::write($fileName, $temp, $method, $ifLock);
- }
+ /**
+ * 读取文件
+ *
+ * @param string $fileName 文件绝对路径
+ * @param string $method 读取模式默认模式为rb
+ * @return string 从文件中读取的数据
+ */
+ public static function read($fileName, $method = self::READ)
+ {
+ $data = '';
+ if (!$handle = fopen($fileName, $method)) {
+ return false;
+ }
+ while (!feof($handle)) {
+ $data .= fgets($handle, 4096);
+ }
+ fclose($handle);
- /**
- * 写文件
- *
- * @param string $fileName 文件绝对路径
- * @param string $data 数据
- * @param string $method 读写模式,默认模式为rb+
- * @param bool $ifLock 是否锁文件,默认为true即加锁
- * @param bool $ifCheckPath 是否检查文件名中的“..”,默认为true即检查
- * @param bool $ifChmod 是否将文件属性改为可读写,默认为true
- * @return int 返回写入的字节数
- */
- public static function write($fileName, $data, $method = self::READWRITE, $ifLock = true, $ifCheckPath = true, $ifChmod = true) {
- touch($fileName);
- if (!$handle = fopen($fileName, $method)) return false;
- $ifLock && flock($handle, LOCK_EX);
- $writeCheck = fwrite($handle, $data);
- $method == self::READWRITE && ftruncate($handle, strlen($data));
- fclose($handle);
- $ifChmod && chmod($fileName, 0777);
- return $writeCheck;
- }
+ return $data;
+ }
- /**
- * 读取文件
- *
- * @param string $fileName 文件绝对路径
- * @param string $method 读取模式默认模式为rb
- * @return string 从文件中读取的数据
- */
- public static function read($fileName, $method = self::READ) {
- $data = '';
- if (!$handle = fopen($fileName, $method)) return false;
- while (!feof($handle))
- $data .= fgets($handle, 4096);
- fclose($handle);
- return $data;
- }
+ /**
+ * @param string $fileName
+ * @return bool
+ */
+ public static function isFile($fileName)
+ {
+ return $fileName ? is_file($fileName) : false;
+ }
- /**
- * @param string $fileName
- * @return boolean
- */
- public static function isFile($fileName) {
- return $fileName ? is_file($fileName) : false;
- }
+ /**
+ * 取得文件信息
+ *
+ * @param string $fileName 文件名字
+ * @return array 文件信息
+ */
+ public static function getInfo($fileName)
+ {
+ return self::isFile($fileName) ? stat($fileName) : array();
+ }
- /**
- * 取得文件信息
- *
- * @param string $fileName 文件名字
- * @return array 文件信息
- */
- public static function getInfo($fileName) {
- return self::isFile($fileName) ? stat($fileName) : array();
- }
+ /**
+ * 取得文件后缀
+ *
+ * @param string $filename 文件名称
+ * @return string
+ */
+ public static function getSuffix($filename)
+ {
+ if (false === ($rpos = strrpos($filename, '.'))) {
+ return '';
+ }
- /**
- * 取得文件后缀
- *
- * @param string $filename 文件名称
- * @return string
- */
- public static function getSuffix($filename) {
- if (false === ($rpos = strrpos($filename, '.'))) return '';
- return substr($filename, $rpos + 1);
- }
-}
\ No newline at end of file
+ return substr($filename, $rpos + 1);
+ }
+}
diff --git a/wind/utility/WindFolder.php b/wind/utility/WindFolder.php
index 9e6d6113..9f1643b7 100644
--- a/wind/utility/WindFolder.php
+++ b/wind/utility/WindFolder.php
@@ -1,139 +1,179 @@
2011-12-2
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindFolder.php 3772 2012-10-19 08:58:57Z yishuo $
* @package utility
*/
-class WindFolder {
- const READ_ALL = '0';
- const READ_FILE = '1';
- const READ_DIR = '2';
+class WindFolder
+{
+ const READ_ALL = '0';
+ const READ_FILE = '1';
+ const READ_DIR = '2';
- /**
- * 获取文件列表
- *
- * @param string $dir
- * @param boolean $mode 只读取文件列表,不包含文件夹
- * @return array
- */
- public static function read($dir, $mode = self::READ_ALL) {
- if (!$handle = @opendir($dir)) return array();
- $files = array();
- while (false !== ($file = @readdir($handle))) {
- if ('.' === $file || '..' === $file) continue;
- if ($mode === self::READ_DIR) {
- if (self::isDir($dir . '/' . $file)) $files[] = $file;
- } elseif ($mode === self::READ_FILE) {
- if (WindFile::isFile($dir . '/' . $file)) $files[] = $file;
- } else
- $files[] = $file;
- }
- @closedir($handle);
- return $files;
- }
+ /**
+ * 获取文件列表
+ *
+ * @param string $dir
+ * @param bool $mode 只读取文件列表,不包含文件夹
+ * @return array
+ */
+ public static function read($dir, $mode = self::READ_ALL)
+ {
+ if (!$handle = @opendir($dir)) {
+ return array();
+ }
+ $files = array();
+ while (false !== ($file = @readdir($handle))) {
+ if ('.' === $file || '..' === $file) {
+ continue;
+ }
+ if ($mode === self::READ_DIR) {
+ if (self::isDir($dir.'/'.$file)) {
+ $files[] = $file;
+ }
+ } elseif ($mode === self::READ_FILE) {
+ if (WindFile::isFile($dir.'/'.$file)) {
+ $files[] = $file;
+ }
+ } else {
+ $files[] = $file;
+ }
+ }
+ @closedir($handle);
- /**
- * 删除目录
- *
- * @param string $dir
- * @param boolean $f 是否强制删除
- * @return boolean
- */
- public static function rm($dir, $f = false) {
- return $f ? self::clearRecur($dir, true) : @rmdir($dir);
- }
+ return $files;
+ }
- /**
- * 删除指定目录下的文件
- *
- * @param string $dir 目录
- * @param boolean $delFolder 是否删除目录
- * @return boolean
- */
- public static function clear($dir, $delFolder = false) {
- if (!self::isDir($dir)) return false;
- if (!$handle = @opendir($dir)) return false;
- while (false !== ($file = readdir($handle))) {
- if ('.' === $file[0] || '..' === $file[0]) continue;
- $filename = $dir . '/' . $file;
- if (WindFile::isFile($filename)) WindFile::del($filename);
- }
- $delFolder && @rmdir($dir);
- @closedir($handle);
- return true;
- }
+ /**
+ * 删除目录
+ *
+ * @param string $dir
+ * @param bool $f 是否强制删除
+ * @return bool
+ */
+ public static function rm($dir, $f = false)
+ {
+ return $f ? self::clearRecur($dir, true) : @rmdir($dir);
+ }
- /**
- * 递归的删除目录
- *
- * @param string $dir 目录
- * @param Boolean $delFolder 是否删除目录
- */
- public static function clearRecur($dir, $delFolder = false) {
- if (!self::isDir($dir)) return false;
- if (!$handle = @opendir($dir)) return false;
- while (false !== ($file = readdir($handle))) {
- if ('.' === $file || '..' === $file) continue;
- $_path = $dir . '/' . $file;
- if (self::isDir($_path)) {
- self::clearRecur($_path, $delFolder);
- } elseif (WindFile::isFile($_path))
- WindFile::del($_path);
- }
- $delFolder && @rmdir($dir);
- @closedir($handle);
- return true;
- }
+ /**
+ * 删除指定目录下的文件
+ *
+ * @param string $dir 目录
+ * @param bool $delFolder 是否删除目录
+ * @return bool
+ */
+ public static function clear($dir, $delFolder = false)
+ {
+ if (!self::isDir($dir)) {
+ return false;
+ }
+ if (!$handle = @opendir($dir)) {
+ return false;
+ }
+ while (false !== ($file = readdir($handle))) {
+ if ('.' === $file[0] || '..' === $file[0]) {
+ continue;
+ }
+ $filename = $dir.'/'.$file;
+ if (WindFile::isFile($filename)) {
+ WindFile::del($filename);
+ }
+ }
+ @closedir($handle);
+ $delFolder && @rmdir($dir);
- /**
- * 判断输入是否为目录
- *
- * @param string $dir
- * @return boolean
- */
- public static function isDir($dir) {
- return $dir ? is_dir($dir) : false;
- }
+ return true;
+ }
- /**
- * 取得目录信息
- *
- * @param string $dir 目录路径
- * @return array
- */
- public static function getInfo($dir) {
- return self::isDir($dir) ? stat($dir) : array();
- }
+ /**
+ * 递归的删除目录
+ *
+ * @param string $dir 目录
+ * @param Boolean $delFolder 是否删除目录
+ */
+ public static function clearRecur($dir, $delFolder = false)
+ {
+ if (!self::isDir($dir)) {
+ return false;
+ }
+ if (!$handle = @opendir($dir)) {
+ return false;
+ }
+ while (false !== ($file = readdir($handle))) {
+ if ('.' === $file || '..' === $file) {
+ continue;
+ }
+ $_path = $dir.'/'.$file;
+ if (self::isDir($_path)) {
+ self::clearRecur($_path, $delFolder);
+ } elseif (WindFile::isFile($_path)) {
+ WindFile::del($_path);
+ }
+ }
+ @closedir($handle);
+ $delFolder && @rmdir($dir);
- /**
- * 创建目录
- *
- * @param string $path 目录路径
- * @param int $permissions 权限
- * @return boolean
- */
- public static function mk($path, $permissions = 0777) {
- return @mkdir($path, $permissions);
- }
+ return true;
+ }
- /**
- * 递归的创建目录
- *
- * @param string $path 目录路径
- * @param int $permissions 权限
- * @return boolean
- */
- public static function mkRecur($path, $permissions = 0777) {
- if (is_dir($path)) return true;
- $_path = dirname($path);
- if ($_path !== $path) self::mkRecur($_path, $permissions);
- return self::mk($path, $permissions);
- }
-}
+ /**
+ * 判断输入是否为目录
+ *
+ * @param string $dir
+ * @return bool
+ */
+ public static function isDir($dir)
+ {
+ return $dir ? is_dir($dir) : false;
+ }
+
+ /**
+ * 取得目录信息
+ *
+ * @param string $dir 目录路径
+ * @return array
+ */
+ public static function getInfo($dir)
+ {
+ return self::isDir($dir) ? stat($dir) : array();
+ }
-?>
\ No newline at end of file
+ /**
+ * 创建目录
+ *
+ * @param string $path 目录路径
+ * @param int $permissions 权限
+ * @return bool
+ */
+ public static function mk($path, $permissions = 0777)
+ {
+ return @mkdir($path, $permissions);
+ }
+
+ /**
+ * 递归的创建目录
+ *
+ * @param string $path 目录路径
+ * @param int $permissions 权限
+ * @return bool
+ */
+ public static function mkRecur($path, $permissions = 0777)
+ {
+ if (is_dir($path)) {
+ return true;
+ }
+ $_path = dirname($path);
+ if ($_path !== $path) {
+ self::mkRecur($_path, $permissions);
+ }
+
+ return self::mk($path, $permissions);
+ }
+}
diff --git a/wind/utility/WindGeneralDate.php b/wind/utility/WindGeneralDate.php
index 2dc80f3a..77a50d97 100644
--- a/wind/utility/WindGeneralDate.php
+++ b/wind/utility/WindGeneralDate.php
@@ -1,302 +1,325 @@
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package utility
+/**
+ * 是将日期转化为一个对象去操作
+ *
+ * @author Qian Su
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindGeneralDate.php 2973 2011-10-15 19:22:48Z yishuo $
+ * @package utility
*/
-class WindGeneralDate {
+class WindGeneralDate
+{
+ /**
+ * 填充展示
+ *
+ * @var int
+ */
+ const FILL = 0;
- /**
- * 填充展示
- *
- * @var int
- */
- const FILL = 0;
+ /**
+ * 数字展示
+ *
+ * @var int
+ */
+ const DIGIT = 1;
- /**
- * 数字展示
- *
- * @var int
- */
- const DIGIT = 1;
+ /**
+ * 文本展示
+ *
+ * @var int
+ */
+ const TEXT = 2;
- /**
- * 文本展示
- *
- * @var int
- */
- const TEXT = 2;
+ /**
+ * 默认格式化
+ *
+ * @var string
+ */
+ const DEFAULT_FORMAT = 'Y-m-d H:i:s';
- /**
- * 默认格式化
- *
- * @var string
- */
- const DEFAULT_FORMAT = 'Y-m-d H:i:s';
+ /**
+ * unix时间戳
+ *
+ * @var int
+ */
+ private $time = 0;
- /**
- * unix时间戳
- *
- * @var int
- */
- private $time = 0;
+ /**
+ * 根据输入的日期格式转化为时间戳进行属性time初始化
+ *
+ * mktime函数,在只有输入一个年份的时候,就会默认转化为上一年的最后一天,输入一个月份并且缺省输入day的时候,
+ * 会转化为上个月的最后一天。所以这种情况需要注意。
+ * 如果该构造函数没有参数传入的时候,得到的日期不是期望的当前日期,而是上两年的11月的30日
+ *
+ * 如果月份为空:如果年份为空,则取当前月份;否则取1
+ * 如果日期为空:如果年份为空,则取当前日期,否则取1
+ * 如果小时为空:如果年份为空,则取当前小时
+ * 如果分为空:如果年份为空,则取当前分
+ * 如果秒为空:如果年份为空,则取当前秒
+ * 如果年份为空:取当前年份
+ *
+ * @param int $year 年,默认为null,获取当前年
+ * @param int $month 月,默认为null获取当前月
+ * @param int $day 日,默认为null获取当前日期
+ * @param int $hours 小时,默认为null获取当前小时
+ * @param int $minutes 分,默认为null获取当前分钟
+ * @param int $second 秒,默认为null获取当前秒
+ */
+ public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null)
+ {
+ $time = time();
+ !$month && ((!$year) ? $month = date('m', $time) : $month = 1);
+ !$day && ((!$year) ? $day = date('d', $time) : $day = 1);
+ !$hours && !$year && $hours = date('H', $time);
+ !$minutes && !$year && $minutes = date('i', $time);
+ !$second && !$year && $second = date('s', $time);
+ !$year && $year = date('Y', $time);
+ $this->time = mktime($hours, $minutes, $second, $month, $day, $year);
+ }
- /**
- * 根据输入的日期格式转化为时间戳进行属性time初始化
- *
- * mktime函数,在只有输入一个年份的时候,就会默认转化为上一年的最后一天,输入一个月份并且缺省输入day的时候,
- * 会转化为上个月的最后一天。所以这种情况需要注意。
- * 如果该构造函数没有参数传入的时候,得到的日期不是期望的当前日期,而是上两年的11月的30日
- *
- * 如果月份为空:如果年份为空,则取当前月份;否则取1
- * 如果日期为空:如果年份为空,则取当前日期,否则取1
- * 如果小时为空:如果年份为空,则取当前小时
- * 如果分为空:如果年份为空,则取当前分
- * 如果秒为空:如果年份为空,则取当前秒
- * 如果年份为空:取当前年份
- *
- * @param int $year 年,默认为null,获取当前年
- * @param int $month 月,默认为null获取当前月
- * @param int $day 日,默认为null获取当前日期
- * @param int $hours 小时,默认为null获取当前小时
- * @param int $minutes 分,默认为null获取当前分钟
- * @param int $second 秒,默认为null获取当前秒
- * @return void
- */
- public function __construct($year = null, $month = null, $day = null, $hours = null, $minutes = null, $second = null) {
- $time = time();
- !$month && ((!$year) ? $month = date('m', $time) : $month = 1);
- !$day && ((!$year) ? $day = date('d', $time) : $day = 1);
- !$hours && !$year && $hours = date('H', $time);
- !$minutes && !$year && $minutes = date('i', $time);
- !$second && !$year && $second = date('s', $time);
- !$year && $year = date('Y', $time);
- $this->time = mktime($hours, $minutes, $second, $month, $day, $year);
- }
+ /**
+ * 获取当前时间所在月的天数
+ *
+ * @return string
+ */
+ public function getDaysInMonth()
+ {
+ return date('t', $this->time);
+ }
- /**
- * 获取当前时间所在月的天数
- *
- * @return string
- */
- public function getDaysInMonth() {
- return date('t', $this->time);
- }
+ /**
+ * 获取当前时间所在年的天数
+ *
+ * @return int 如果是闰年返回366否则返回365
+ */
+ public function getDaysInYear()
+ {
+ return $this->isLeapYear() ? 366 : 365;
+ }
- /**
- * 获取当前时间所在年的天数
- *
- * @return int 如果是闰年返回366否则返回365
- */
- public function getDaysInYear() {
- return $this->isLeapYear() ? 366 : 365;
- }
+ /**
+ * 所表示当前日期是该年中的第几天。
+ *
+ * @return int 返回时该年中的第几天
+ */
+ public function getDayOfYear()
+ {
+ return date('z', $this->time) + 1;
+ }
- /**
- * 所表示当前日期是该年中的第几天。
- *
- * @return int 返回时该年中的第几天
- */
- public function getDayOfYear() {
- return date('z', $this->time) + 1;
- }
+ /**
+ * 表示当前日期为该月中的第几天。
+ *
+ * @return int
+ */
+ public function getDayOfMonth()
+ {
+ return date('j', $this->time);
+ }
- /**
- * 表示当前日期为该月中的第几天。
- *
- * @return int
- */
- public function getDayOfMonth() {
- return date('j', $this->time);
- }
+ /**
+ * 表示当前日期是该星期中的第几天。
+ *
+ * @return int
+ */
+ public function getDayOfWeek()
+ {
+ return date('w', $this->time) + 1;
+ }
- /**
- * 表示当前日期是该星期中的第几天。
- *
- * @return int
- */
- public function getDayOfWeek() {
- return date('w', $this->time) + 1;
- }
+ /**
+ * 判断当前日期所在年的第几周
+ *
+ * @return int
+ */
+ public function getWeekOfYear()
+ {
+ return date('W', $this->time);
+ }
- /**
- * 判断当前日期所在年的第几周
- *
- * @return int
- */
- public function getWeekOfYear() {
- return date('W', $this->time);
- }
+ /**
+ * 获取当前日期的年份
+ *
+ * @param bool $format 是否返回四位格式的年份或是两位格式的年份,默认为true则以Y返回四位数
+ * @return string
+ */
+ public function getYear($format = true)
+ {
+ return date($format ? 'Y' : 'y', $this->time);
+ }
- /**
- * 获取当前日期的年份
- *
- * @param boolean $format 是否返回四位格式的年份或是两位格式的年份,默认为true则以Y返回四位数
- * @return string
- */
- public function getYear($format = true) {
- return date($format ? 'Y' : 'y', $this->time);
- }
+ /**
+ * 获当前日期的取月份
+ *
+ * @param int $display 显示类型,默认为0,则显示两位的月份
+ * @return string
+ */
+ public function getMonth($display = self::FILL)
+ {
+ if (self::FILL == $display) {
+ return date('m', $this->time);
+ } elseif (self::DIGIT == $display) {
+ return date('n', $this->time);
+ } elseif (self::TEXT == $display) {
+ return date('M', $this->time);
+ }
- /**
- * 获当前日期的取月份
- *
- * @param int $display 显示类型,默认为0,则显示两位的月份
- * @return string
- */
- public function getMonth($display = self::FILL) {
- if (self::FILL == $display) {
- return date('m', $this->time);
- } elseif (self::DIGIT == $display) {
- return date('n', $this->time);
- } elseif (self::TEXT == $display) {
- return date('M', $this->time);
- }
- return date('n', $this->time);
- }
+ return date('n', $this->time);
+ }
- /**
- * 获取当前日期的天数
- *
- * @param string $display 显示类型,默认为0,显示两位的日期
- * @return string
- */
- public function getDay($display = self::FILL) {
- if (self::FILL == $display) {
- return date('d', $this->time);
- } elseif (self::DIGIT == $display) {
- return date('j', $this->time);
- } elseif (self::TEXT == $display) {
- return date('jS', $this->time);
- }
- return date('j', $this->time);
- }
+ /**
+ * 获取当前日期的天数
+ *
+ * @param string $display 显示类型,默认为0,显示两位的日期
+ * @return string
+ */
+ public function getDay($display = self::FILL)
+ {
+ if (self::FILL == $display) {
+ return date('d', $this->time);
+ } elseif (self::DIGIT == $display) {
+ return date('j', $this->time);
+ } elseif (self::TEXT == $display) {
+ return date('jS', $this->time);
+ }
- /**
- * 获取当前日期的星期
- *
- * @param string $display 显示类型,默认为0,返回数字表示的星期中的第几天
- * @return string
- */
- public function getWeek($display = self::FILL) {
- if (self::FILL == $display || self::DIGIT == $display) {
- return date('w', $this->time);
- } elseif (self::TEXT == $display) {
- return date('D', $this->time);
- }
- return date('N', $this->time);
- }
+ return date('j', $this->time);
+ }
- /**
- * 获取当前日期的12小时制时间
- *
- * @param string $display 显示类型,默认为0,显示两位的小时
- * @return string
- */
- public function get12Hours($display = self::FILL) {
- if (self::FILL == $display) {
- return date('h', $this->time);
- } elseif (self::DIGIT == $display) {
- return date('g', $this->time);
- ;
- }
- return date('h', $this->time);
- }
+ /**
+ * 获取当前日期的星期
+ *
+ * @param string $display 显示类型,默认为0,返回数字表示的星期中的第几天
+ * @return string
+ */
+ public function getWeek($display = self::FILL)
+ {
+ if (self::FILL == $display || self::DIGIT == $display) {
+ return date('w', $this->time);
+ } elseif (self::TEXT == $display) {
+ return date('D', $this->time);
+ }
- /**
- * 获取当前日期的24小时制时间
- *
- * @param string $display 显示类型,默认为0,显示两位的小时
- * @return string
- */
- public function get24Hours($display = self::FILL) {
- if (self::FILL == $display) {
- return date('H', $this->time);
- } elseif (self::DIGIT == $display) {
- return date('G', $this->time);
- ;
- }
- return date('H', $this->time);
- }
+ return date('N', $this->time);
+ }
- /**
- * 获取当前日期的分钟
- *
- * @return string
- */
- public function getMinutes() {
- return date('i', $this->time);
- }
+ /**
+ * 获取当前日期的12小时制时间
+ *
+ * @param string $display 显示类型,默认为0,显示两位的小时
+ * @return string
+ */
+ public function get12Hours($display = self::FILL)
+ {
+ if (self::FILL == $display) {
+ return date('h', $this->time);
+ } elseif (self::DIGIT == $display) {
+ return date('g', $this->time);
+ }
- /**
- * 获取当前日期的秒数
- *
- * @return string
- */
- public function getSeconds() {
- return date('s', $this->time);
- }
+ return date('h', $this->time);
+ }
- /**
- * 获取当前日期的本地时区
- *
- * @return string
- */
- public function getLocalTimeZone() {
- return date('T', $this->time);
- }
+ /**
+ * 获取当前日期的24小时制时间
+ *
+ * @param string $display 显示类型,默认为0,显示两位的小时
+ * @return string
+ */
+ public function get24Hours($display = self::FILL)
+ {
+ if (self::FILL == $display) {
+ return date('H', $this->time);
+ } elseif (self::DIGIT == $display) {
+ return date('G', $this->time);
+ }
- /**
- * 重新设置当前日期与时间
- *
- * @param string $time 时间戳
- * @return void
- */
- public function setTime($time) {
- if (is_int($time) || (is_string($time) && ($time = strtotime($time)))) {
- $this->time = $time;
- }
- }
+ return date('H', $this->time);
+ }
- /**
- * 取得当前日期时间对象
- *
- * @return WindGeneralDate
- */
- public function getNow() {
- $date = getdate($this->time);
- return new self($date["year"], $date["mon"], $date["mday"], $date["hours"], $date["minutes"], $date["seconds"]);
- }
+ /**
+ * 获取当前日期的分钟
+ *
+ * @return string
+ */
+ public function getMinutes()
+ {
+ return date('i', $this->time);
+ }
- /**
- * 对象转化为字符串,魔术方法
- *
- * @return string
- */
- public function __toString() {
- return $this->toString();
- }
+ /**
+ * 获取当前日期的秒数
+ *
+ * @return string
+ */
+ public function getSeconds()
+ {
+ return date('s', $this->time);
+ }
- /**
- * 格式化时间输出
- *
- * @param string $format 需要输出的格式,默认为null,则采用格式Y-m-d H:i:s
- * @return string
- */
- public function toString($format = null) {
- return date($format ? $format : self::DEFAULT_FORMAT, $this->time);
- }
+ /**
+ * 获取当前日期的本地时区
+ *
+ * @return string
+ */
+ public function getLocalTimeZone()
+ {
+ return date('T', $this->time);
+ }
- /**
- * 判断是否是闰年
- *
- * @return int 返回1或是0
- */
- public function isLeapYear() {
- return date('L', $this->time);
- }
-}
\ No newline at end of file
+ /**
+ * 重新设置当前日期与时间
+ *
+ * @param string $time 时间戳
+ */
+ public function setTime($time)
+ {
+ if (is_int($time) || (is_string($time) && ($time = strtotime($time)))) {
+ $this->time = $time;
+ }
+ }
+
+ /**
+ * 取得当前日期时间对象
+ *
+ * @return WindGeneralDate
+ */
+ public function getNow()
+ {
+ $date = getdate($this->time);
+
+ return new self($date['year'], $date['mon'], $date['mday'], $date['hours'], $date['minutes'], $date['seconds']);
+ }
+
+ /**
+ * 对象转化为字符串,魔术方法
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->toString();
+ }
+
+ /**
+ * 格式化时间输出
+ *
+ * @param string $format 需要输出的格式,默认为null,则采用格式Y-m-d H:i:s
+ * @return string
+ */
+ public function toString($format = null)
+ {
+ return date($format ? $format : self::DEFAULT_FORMAT, $this->time);
+ }
+
+ /**
+ * 判断是否是闰年
+ *
+ * @return int 返回1或是0
+ */
+ public function isLeapYear()
+ {
+ return date('L', $this->time);
+ }
+}
diff --git a/wind/utility/WindImage.php b/wind/utility/WindImage.php
index 696545b9..0f32ec5e 100644
--- a/wind/utility/WindImage.php
+++ b/wind/utility/WindImage.php
@@ -1,318 +1,372 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindImage.php 2973 2011-10-15 19:22:48Z yishuo $
* @package utility
*/
-class WindImage {
-
- /**
- * 生成略缩图
- *
- * @param string $srcFile 源图片
- * @param string $dstFile 略缩图保存位置
- * @param int $dstW 略缩图宽度
- * @param string $dstH 略缩图高度
- * @param string $isProportion 略缩图是否等比略缩,默认为false
- * @return array|boolean
- */
- public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = FALSE) {
- if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) return false;
- list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']);
- if (!$imagecreate) return false;
- $imgwidth = $minitemp['width'];
- $imgheight = $minitemp['height'];
-
- $srcX = $srcY = $dstX = $dstY =0;
- if (!$isProportion) {
- $dsDivision = $imgheight / $imgwidth;
- $fixDivision = $dstH / $dstW;
- if ($dsDivision > $fixDivision) {
- $tmp = $imgwidth * $fixDivision;
- $srcY = round(($imgheight - $tmp) / 2);
- $imgheight = $tmp;
- } else {
- $tmp = $imgheight / $fixDivision;
- $srcX = round(($imgwidth - $tmp) / 2);
- $imgwidth = $tmp;
- }
- }
- $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']);
-
- if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) {
- $black = imagecolorallocate($thumb, 0, 0, 0);
- imagecolortransparent($thumb, $black);
- }
- $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight);
- self::makeImg($minitemp['type'], $thumb, $dstFile);
- imagedestroy($thumb);
- return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']);
- }
+class WindImage
+{
+ /**
+ * 生成略缩图
+ *
+ * @param string $srcFile 源图片
+ * @param string $dstFile 略缩图保存位置
+ * @param int $dstW 略缩图宽度
+ * @param string $dstH 略缩图高度
+ * @param string $isProportion 略缩图是否等比略缩,默认为false
+ * @return array|bool
+ */
+ public static function makeThumb($srcFile, $dstFile, $dstW, $dstH, $isProportion = false)
+ {
+ if (false === ($minitemp = self::getThumbInfo($srcFile, $dstW, $dstH, $isProportion))) {
+ return false;
+ }
+ list($imagecreate, $imagecopyre) = self::getImgcreate($minitemp['type']);
+ if (!$imagecreate) {
+ return false;
+ }
+ $imgwidth = $minitemp['width'];
+ $imgheight = $minitemp['height'];
+
+ $srcX = $srcY = $dstX = $dstY = 0;
+ if (!$isProportion) {
+ $dsDivision = $imgheight / $imgwidth;
+ $fixDivision = $dstH / $dstW;
+ if ($dsDivision > $fixDivision) {
+ $tmp = $imgwidth * $fixDivision;
+ $srcY = round(($imgheight - $tmp) / 2);
+ $imgheight = $tmp;
+ } else {
+ $tmp = $imgheight / $fixDivision;
+ $srcX = round(($imgwidth - $tmp) / 2);
+ $imgwidth = $tmp;
+ }
+ }
+ $thumb = $imagecreate($minitemp['dstW'], $minitemp['dstH']);
+
+ if (function_exists('imagecolorallocate') && function_exists('imagecolortransparent')) {
+ $black = imagecolorallocate($thumb, 0, 0, 0);
+ imagecolortransparent($thumb, $black);
+ }
+ $imagecopyre($thumb, $minitemp['source'], $dstX, $dstY, $srcX, $srcY, $minitemp['dstW'], $minitemp['dstH'], $imgwidth, $imgheight);
+ self::makeImg($minitemp['type'], $thumb, $dstFile);
+ imagedestroy($thumb);
+
+ return array('width' => $minitemp['dstW'], 'height' => $minitemp['dstH'], 'type' => $minitemp['type']);
+ }
+
+ /**
+ * 给图片制作水印
+ *
+ * 水印的位置可以为:
+ *
+ * array(0 => '随机位置', 1 => '顶部居左', 2 => '顶部居中', 3 => '顶部居右', 4 => '底部居左', 5 => '底部居中', 6 => '底部居右', 7 => '中心位置')
+ *
+ *
+ * @param string $source 图片的源文件
+ * @param int|array $waterPos 水印的位置,可以选择从0-7或是制定开始位置x,y,默认为0,随机位置
+ * @param string $waterImg 作为水印的图片,默认为空
+ * @param string $waterText 作为水印的文字,默认为空
+ * @param array $attribute 文字水印的属性,只对文字水印有效
+ *
+ * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小')
+ *
+ * @param string $waterPct 水印透明度,从0到100,0完全透明,100完全不透明,默认为50
+ * @param string $waterQuality 图片质量--jpeg,默认为75
+ * @param string $dstsrc 目标文件位置,默认为null即不保存
+ * @return bool
+ */
+ public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null)
+ {
+ $sourcedb = $waterdb = array();
+ if (false === ($sourcedb = self::getImgInfo($source))) {
+ return false;
+ }
+ if (!$waterImg && !$waterText) {
+ return false;
+ }
+ imagealphablending($sourcedb['source'], true);
+ if ($waterImg) {
+ $waterdb = self::getImgInfo($waterImg);
+ list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1);
+ if ($waterdb['type'] == 'png') {
+ $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']);
+ imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']);
+ imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']);
+ $sourcedb['source'] = $tmp;
+ } else {
+ imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct);
+ }
+ } elseif ($waterText) {
+ list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute);
+ empty($waterFont) && $waterFont = 12;
+ $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); //取得使用 TrueType 字体的文本的范围
+ $waterdb['width'] = $temp[2] - $temp[6];
+ $waterdb['height'] = $temp[3] - $temp[7];
+ unset($temp);
+ list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2);
+ if (strlen($color) != 7) {
+ return false;
+ }
+ $R = hexdec(substr($color, 1, 2));
+ $G = hexdec(substr($color, 3, 2));
+ $B = hexdec(substr($color, 5));
+ self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset);
+ imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText);
+ }
+ $dstsrc && $source = $dstsrc;
+ self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality);
+ isset($waterdb['source']) && imagedestroy($waterdb['source']);
+ imagedestroy($sourcedb['source']);
+
+ return true;
+ }
+
+ /**
+ * 文字水印的属性设置过滤
+ *
+ * 返回为:
+ *
+ * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小')
+ *
+ * @param array $attribute 设置的属性
+ * @return array
+ */
+ private static function checkAttribute($attribute)
+ {
+ $attribute = is_string($attribute) ? array($attribute) : $attribute;
+ if (!isset($attribute[1]) || !$attribute[1]) {
+ $attribute[1] = 'UTF-8';
+ }
+ if (!isset($attribute[2]) || !$attribute[2]) {
+ $attribute[2] = '#FF0000';
+ }
+ if (!isset($attribute[3]) || !$attribute[3]) {
+ $attribute[3] = 12;
+ }
+
+ return $attribute;
+ }
+
+ /**
+ * 判断是否需要转编码
+ *
+ * 判断依据为,编码格式为utf-8
+ *
+ * @param string $charset 编码方式
+ * @return bool
+ */
+ private static function changeCharset($charset)
+ {
+ $charset = strtolower($charset);
+
+ return !in_array($charset, array('utf8', 'utf-8'));
+ }
+
+ /**
+ * 获得打水印的位置
+ *
+ * 如果传入的是数组,则两个元素分别为水印的宽度x和高度y
+ *
+ * @param int|array $pos 获得水印的位置
+ * @param array $sourcedb 原图片的信息
+ * @param array $waterdb 水印图片的信息
+ * @param int $markType 水印类型,1为图片水印,2为文字水印
+ * @return array
+ */
+ private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType)
+ {
+ if (is_array($waterPos)) {
+ return $waterPos;
+ }
+ $wX = $wY = 0;
+ switch (intval($waterPos)) {
+ case 0:
+ $wX = rand(0, ($sourcedb['width'] - $waterdb['width']));
+ $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']);
+ break;
+ case 1:
+ $wX = 5;
+ $wY = $markType == 1 ? 5 : $waterdb['height'];
+ break;
+ case 2:
+ $wX = ($sourcedb['width'] - $waterdb['width']) / 2;
+ $wY = $markType == 1 ? 5 : $waterdb['height'];
+ break;
+ case 3:
+ $wX = $sourcedb['width'] - $waterdb['width'] - 5;
+ $wY = $markType == 1 ? 5 : $waterdb['height'];
+ break;
+ case 4:
+ $wX = 5;
+ $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5;
+ break;
+ case 5:
+ $wX = ($sourcedb['width'] - $waterdb['width']) / 2;
+ $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5;
+ break;
+ case 6:
+ $wX = $sourcedb['width'] - $waterdb['width'] - 5;
+ $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5;
+ break;
+ default:
+ $wX = ($sourcedb['width'] - $waterdb['width']) / 2;
+ $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2;
+ break;
+ }
+
+ return array($wX, $wY);
+ }
+
+ /**
+ * 获得略缩图的信息
+ *
+ * @param string $srcFile 源文件
+ * @param int $dstW 目标文件的宽度
+ * @param int $dstH 目标文件的高度
+ * @param bool $isProportion 是否定比略缩
+ * @return array|bool
+ */
+ private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion = false)
+ {
+ if (false === ($imgdata = self::getImgInfo($srcFile))) {
+ return false;
+ }
+ if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) {
+ return false;
+ }
+
+ $imgdata['dstW'] = $dstW;
+ $imgdata['dstH'] = $dstH;
+ if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) {
+ $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']);
+ } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) {
+ $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']);
+ } elseif ($dstW > 0 && $dstH > 0) {
+ if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) {
+ $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']);
+ }
+ if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) {
+ $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']);
+ }
+ } else {
+ $imgdata = false;
+ }
+
+ return $imgdata;
+ }
+
+ /**
+ * 获得图片的信息,返回图片的源及图片的高度和宽度
+ *
+ * @param string $srcFile 图像地址
+ * @return array|bool
+ */
+ public static function getImgInfo($srcFile)
+ {
+ if (false === ($imgdata = self::getImgSize($srcFile))) {
+ return false;
+ }
+ $imgdata['type'] = self::getTypes($imgdata['type']);
+ if (empty($imgdata) || !function_exists('imagecreatefrom'.$imgdata['type'])) {
+ return false;
+ }
+ $imagecreatefromtype = 'imagecreatefrom'.$imgdata['type'];
+ $imgdata['source'] = $imagecreatefromtype($srcFile);
+ !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']);
+ !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']);
+
+ return $imgdata;
+ }
+
+ /**
+ * 获得图片的类型及宽高
+ *
+ *
+ * 图片type:
+ * 1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,
+ * 11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
+ *
、
+ *
+ * @param string $srcFile 图像地址
+ * @param string $srcExt 图像后缀,默认为null则将会从图片地址中分析获取
+ * @return array|bool 返回图像的类型及高度和宽度
+ */
+ private static function getImgSize($srcFile, $srcExt = null)
+ {
+ empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1));
+ $srcdata = array();
+ $exts = array('jpg', 'jpeg', 'jpe', 'jfif');
+ in_array($srcExt, $exts) && $srcdata['type'] = 2;
+ if (false === ($info = getimagesize($srcFile))) {
+ return false;
+ }
+ list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info;
+ if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) {
+ return false;
+ }
+
+ return $srcdata;
+ }
+
+ /**
+ * 获得创建图像的方法
+ *
+ * @param string $imagetype 图片类型
+ * @return array
+ */
+ private static function getImgcreate($imagetype)
+ {
+ if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) {
+ return array('imagecreatetruecolor', 'imagecopyresampled');
+ }
+ if (function_exists('imagecreate') && function_exists('imagecopyresized')) {
+ return array('imagecreate', 'imagecopyresized');
+ }
+
+ return array('', '');
+ }
+
+ /**
+ * 创建图像
+ *
+ * @param string $type 图像类型
+ * @param resource $image 图像源
+ * @param string $filename 图像保存名字
+ * @param int $quality 创建jpeg的时候用到,默认为75
+ * @return bool
+ */
+ private static function makeImg($type, $image, $filename, $quality = '75')
+ {
+ $makeimage = 'image'.$type;
+ if (!function_exists($makeimage)) {
+ return false;
+ }
+ if ($type == 'jpeg') {
+ $makeimage($image, $filename, $quality);
+ } else {
+ $makeimage($image, $filename);
+ }
+
+ return true;
+ }
+
+ /**
+ * 图片的对应类型
+ *
+ * @param int $id 图片类型ID
+ * @return string
+ */
+ private static function getTypes($id)
+ {
+ $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp');
- /**
- * 给图片制作水印
- *
- * 水印的位置可以为:
- *
- * array(0 => '随机位置', 1 => '顶部居左', 2 => '顶部居中', 3 => '顶部居右', 4 => '底部居左', 5 => '底部居中', 6 => '底部居右', 7 => '中心位置')
- *
- *
- * @param string $source 图片的源文件
- * @param int|array $waterPos 水印的位置,可以选择从0-7或是制定开始位置x,y,默认为0,随机位置
- * @param string $waterImg 作为水印的图片,默认为空
- * @param string $waterText 作为水印的文字,默认为空
- * @param array $attribute 文字水印的属性,只对文字水印有效
- *
- * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小')
- *
- * @param string $waterPct 水印透明度,从0到100,0完全透明,100完全不透明,默认为50
- * @param string $waterQuality 图片质量--jpeg,默认为75
- * @param string $dstsrc 目标文件位置,默认为null即不保存
- * @return boolean
- */
- public static function makeWatermark($source, $waterPos = 0, $waterImg = '', $waterText = '', $attribute = '', $waterPct = 50, $waterQuality = 75, $dstsrc = null) {
- $sourcedb = $waterdb = array();
- if (false === ($sourcedb = self::getImgInfo($source))) return false;
- if (!$waterImg && !$waterText) return false;
- imagealphablending($sourcedb['source'], true);
- if ($waterImg) {
- $waterdb = self::getImgInfo($waterImg);
- list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 1);
- if ($waterdb['type'] == 'png') {
- $tmp = imagecreatetruecolor($sourcedb['width'], $sourcedb['height']);
- imagecopy($tmp, $sourcedb['source'], 0, 0, 0, 0, $sourcedb['width'], $sourcedb['height']);
- imagecopy($tmp, $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height']);
- $sourcedb['source'] = $tmp;
- } else {
- imagecopymerge($sourcedb['source'], $waterdb['source'], $wX, $wY, 0, 0, $waterdb['width'], $waterdb['height'], $waterPct);
- }
- } elseif ($waterText) {
- list($fontFile, $charset, $color, $waterFont) = self::checkAttribute($attribute);
- empty($waterFont) && $waterFont = 12;
- $temp = imagettfbbox($waterFont, 0, $fontFile, $waterText); //取得使用 TrueType 字体的文本的范围
- $waterdb['width'] = $temp[2] - $temp[6];
- $waterdb['height'] = $temp[3] - $temp[7];
- unset($temp);
- list($wX, $wY) = self::getWaterPos($waterPos, $sourcedb, $waterdb, 2);
- if (strlen($color) != 7) return false;
- $R = hexdec(substr($color, 1, 2));
- $G = hexdec(substr($color, 3, 2));
- $B = hexdec(substr($color, 5));
- self::changeCharset($charset) && $waterText = mb_convert_encoding($waterText, 'UTF-8', $charset);
- imagettftext($sourcedb['source'], $waterFont, 0, $wX, $wY, imagecolorallocate($sourcedb['source'], $R, $G, $B), $fontFile, $waterText);
- }
- $dstsrc && $source = $dstsrc;
- self::makeImg($sourcedb['type'], $sourcedb['source'], $source, $waterQuality);
- isset($waterdb['source']) && imagedestroy($waterdb['source']);
- imagedestroy($sourcedb['source']);
- return true;
- }
-
- /**
- * 文字水印的属性设置过滤
- *
- * 返回为:
- *
- * array(0 => '字体文件',1 => '系统编码', 2 => '字体颜色', 3 => '字体大小')
- *
- * @param array $attribute 设置的属性
- * @return array
- */
- private static function checkAttribute($attribute) {
- $attribute = is_string($attribute) ? array($attribute) : $attribute;
- if (!isset($attribute[1]) || !$attribute[1]) $attribute[1] = 'UTF-8';
- if (!isset($attribute[2]) || !$attribute[2]) $attribute[2] = '#FF0000';
- if (!isset($attribute[3]) || !$attribute[3]) $attribute[3] = 12;
- return $attribute;
- }
-
- /**
- * 判断是否需要转编码
- *
- * 判断依据为,编码格式为utf-8
- *
- * @param string $charset 编码方式
- * @return boolean
- */
- private static function changeCharset($charset) {
- $charset = strtolower($charset);
- return !in_array($charset, array('utf8', 'utf-8'));
- }
-
- /**
- * 获得打水印的位置
- *
- * 如果传入的是数组,则两个元素分别为水印的宽度x和高度y
- *
- * @param int|array $pos 获得水印的位置
- * @param array $sourcedb 原图片的信息
- * @param array $waterdb 水印图片的信息
- * @param int $markType 水印类型,1为图片水印,2为文字水印
- * @return array
- */
- private static function getWaterPos($waterPos, $sourcedb, $waterdb, $markType) {
- if (is_array($waterPos)) return $waterPos;
- $wX = $wY = 0;
- switch (intval($waterPos)) {
- case 0 :
- $wX = rand(0, ($sourcedb['width'] - $waterdb['width']));
- $wY = $markType == 1 ? rand(0, ($sourcedb['height'] - $waterdb['height'])) : rand($waterdb['height'], $sourcedb['height']);
- break;
- case 1 :
- $wX = 5;
- $wY = $markType == 1 ? 5 : $waterdb['height'];
- break;
- case 2:
- $wX = ($sourcedb['width'] - $waterdb['width']) / 2;
- $wY = $markType == 1 ? 5 : $waterdb['height'];
- break;
- case 3:
- $wX = $sourcedb['width'] - $waterdb['width'] - 5;
- $wY = $markType == 1 ? 5 : $waterdb['height'];
- break;
- case 4:
- $wX = 5;
- $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5;
- break;
- case 5:
- $wX = ($sourcedb['width'] - $waterdb['width']) / 2;
- $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5;
- break;
- case 6:
- $wX = $sourcedb['width'] - $waterdb['width'] - 5;
- $wY = $markType == 1 ? $sourcedb['height'] - $waterdb['height'] - 5 : $sourcedb['height'] - 5;
- break;
- default:
- $wX = ($sourcedb['width'] - $waterdb['width']) / 2;
- $wY = $markType == 1 ? ($sourcedb['height'] - $waterdb['height']) / 2 : ($sourcedb['height'] + $waterdb['height']) / 2;
- break;
- }
- return array($wX, $wY);
- }
-
- /**
- * 获得略缩图的信息
- *
- * @param string $srcFile 源文件
- * @param int $dstW 目标文件的宽度
- * @param int $dstH 目标文件的高度
- * @param boolean $isProportion 是否定比略缩
- * @return array|boolean
- */
- private static function getThumbInfo($srcFile, $dstW, $dstH, $isProportion= FALSE) {
- if (false === ($imgdata = self::getImgInfo($srcFile))) return false;
- if ($imgdata['width'] <= $dstW && $imgdata['height'] <= $dstH) return false;
-
- $imgdata['dstW'] = $dstW;
- $imgdata['dstH'] = $dstH;
- if (empty($dstW) && $dstH > 0 && $imgdata['height'] > $dstH) {
- $imgdata['dstW'] = !$isProportion ? $dstH : round($dstH / $imgdata['height'] * $imgdata['width']);
- } elseif (empty($dstH) && $dstW > 0 && $imgdata['width'] > $dstW) {
- $imgdata['dstH'] = !$isProportion ? $dstW : round($dstW / $imgdata['width'] * $imgdata['height']);
- } elseif ($dstW > 0 && $dstH > 0) {
- if (($imgdata['width'] / $dstW) < ($imgdata['height'] / $dstH)) {
- $imgdata['dstW'] = !$isProportion ? $dstW : round($dstH / $imgdata['height'] * $imgdata['width']);
- }
- if (($imgdata['width'] / $dstW) > ($imgdata['height'] / $dstH)) {
- $imgdata['dstH'] = !$isProportion ? $dstH : round($dstW / $imgdata['width'] * $imgdata['height']);
- }
- } else {
- $imgdata = false;
- }
- return $imgdata;
- }
-
- /**
- * 获得图片的信息,返回图片的源及图片的高度和宽度
- *
- * @param string $srcFile 图像地址
- * @return array|boolean
- */
- public static function getImgInfo($srcFile) {
- if (false === ($imgdata = self::getImgSize($srcFile))) return false;
- $imgdata['type'] = self::getTypes($imgdata['type']);
- if (empty($imgdata) || !function_exists('imagecreatefrom' . $imgdata['type'])) return false;
- $imagecreatefromtype = 'imagecreatefrom' . $imgdata['type'];
- $imgdata['source'] = $imagecreatefromtype($srcFile);
- !$imgdata['width'] && $imgdata['width'] = imagesx($imgdata['source']);
- !$imgdata['height'] && $imgdata['height'] = imagesy($imgdata['source']);
- return $imgdata;
- }
-
- /**
- * 获得图片的类型及宽高
- *
- *
- * 图片type:
- * 1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,
- * 11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
- *
、
- *
- * @param string $srcFile 图像地址
- * @param string $srcExt 图像后缀,默认为null则将会从图片地址中分析获取
- * @return array|boolean 返回图像的类型及高度和宽度
- */
- private static function getImgSize($srcFile, $srcExt = null) {
- empty($srcExt) && $srcExt = strtolower(substr(strrchr($srcFile, '.'), 1));
- $srcdata = array();
- $exts = array('jpg', 'jpeg', 'jpe', 'jfif');
- in_array($srcExt, $exts) && $srcdata['type'] = 2;
- if (false === ($info = getimagesize($srcFile))) return false;
- list($srcdata['width'], $srcdata['height'], $srcdata['type']) = $info;
- if (!$srcdata['type'] || ($srcdata['type'] == 1 && in_array($srcExt, $exts))) return false;
- return $srcdata;
- }
-
- /**
- * 获得创建图像的方法
- *
- * @param string $imagetype 图片类型
- * @return array
- */
- private static function getImgcreate($imagetype) {
- if ($imagetype != 'gif' && function_exists('imagecreatetruecolor') && function_exists('imagecopyresampled')) {
- return array('imagecreatetruecolor', 'imagecopyresampled');
- }
- if (function_exists('imagecreate') && function_exists('imagecopyresized')) {
- return array('imagecreate', 'imagecopyresized');
- }
- return array('', '');
- }
-
- /**
- * 创建图像
- *
- * @param string $type 图像类型
- * @param resource $image 图像源
- * @param string $filename 图像保存名字
- * @param int $quality 创建jpeg的时候用到,默认为75
- * @return boolean
- */
- private static function makeImg($type, $image, $filename, $quality = '75') {
- $makeimage = 'image' . $type;
- if (!function_exists($makeimage)) return false;
- if ($type == 'jpeg') {
- $makeimage($image, $filename, $quality);
- } else {
- $makeimage($image, $filename);
- }
- return true;
- }
-
- /**
- * 图片的对应类型
- *
- * @param int $id 图片类型ID
- * @return string
- */
- private static function getTypes($id) {
- $imageTypes = array(1 => 'gif', 2 => 'jpeg', '3' => 'png', 6 => 'bmp');
- return isset($imageTypes[$id]) ? $imageTypes[$id] : '';
- }
-}
\ No newline at end of file
+ return isset($imageTypes[$id]) ? $imageTypes[$id] : '';
+ }
+}
diff --git a/wind/utility/WindJson.php b/wind/utility/WindJson.php
index 48a9c3e6..81d7e105 100644
--- a/wind/utility/WindJson.php
+++ b/wind/utility/WindJson.php
@@ -1,317 +1,348 @@
2011-10-19
- * @copyright ©2003-2103 phpwind.com
- * @license http://www.windframework.com
- * @version $Id$
- * @package utility
+ *
+ * 支持json转php类型,以及php类型转json.
+ * @author Long.shi 2011-10-19
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindJson.php 3859 2012-12-18 09:25:51Z yishuo $
+ * @package utility
*/
-class WindJson {
- const JSON_SLICE = 1;
- const JSON_IN_STR = 2;
- const JSON_IN_ARR = 4;
- const JSON_IN_OBJ = 8;
- const JSON_IN_CMT = 16;
+class WindJson
+{
+ const JSON_SLICE = 1;
+ const JSON_IN_STR = 2;
+ const JSON_IN_ARR = 4;
+ const JSON_IN_OBJ = 8;
+ const JSON_IN_CMT = 16;
- /**
- * 将数据用json加密
- *
- * @param mixed $value 要加密的值
- * @param string $charset
- * @return string
- */
- public static function encode($source, $charset = 'utf8') {
- switch (gettype($source)) {
- case 'boolean':
- $source = $source ? 'true' : 'false';
- break;
- case 'NULL':
- $source = 'null';
- break;
- case 'integer':
- $source = (int) $source;
- break;
- case 'double':
- case 'float':
- $source = (float) $source;
- break;
- case 'string':
- $source = WindConvert::convert($source, 'utf8', $charset);
- $source = self::stringToJson($source);
- break;
- case 'array':
- $source = WindConvert::convert($source, 'utf8', $charset);
- $source = self::arrayToJson($source);
- break;
- case 'object':
- $source = WindConvert::convert($source, 'utf8', $charset);
- $source = self::objectToJson($source);
- break;
- default:
- break;
- }
- return $source;
- }
+ /**
+ * 将数据用json加密
+ *
+ * @param mixed $value 要加密的值
+ * @param string $charset
+ * @return string
+ */
+ public static function encode($source, $charset = 'utf-8')
+ {
+ switch (gettype($source)) {
+ case 'boolean':
+ $source = $source ? 'true' : 'false';
+ break;
+ case 'NULL':
+ $source = 'null';
+ break;
+ case 'integer':
+ $source = (int) $source;
+ break;
+ case 'double':
+ case 'float':
+ $source = (float) $source;
+ break;
+ case 'string':
+ $source = self::stringToJson($source, $charset);
+ break;
+ case 'array':
+ $source = self::arrayToJson($source, $charset);
+ break;
+ case 'object':
+ $source = self::objectToJson($source, $charset);
+ break;
+ default:
+ break;
+ }
- /**
- * 将json格式数据解密
- *
- * @param string $str
- * @param boolean $toArray
- * @param string $charset
- * @return mixed
- */
- public static function decode($str, $toArray = true, $charset = 'utf8') {
- $str = self::_reduceString($str);
- $_str = strtolower($str);
- if ('true' == $_str) {
- return true;
- } elseif ('false' == $_str) {
- return false;
- } elseif ('null' == $_str) {
- return null;
- } elseif (is_numeric($str)) {
- return (float) $str == (integer) $str ? (integer) $str : (float) $str;
- } elseif (preg_match('/^("|\').+(\1)$/s', $_str, $matche) && $matche[1] == $matche[2]) {
- $str = self::jsonToString($str);
- } elseif (preg_match('/^\[.*\]$/s', $_str) || preg_match('/^\{.*\}$/s', $_str)) {
- $str = self::complexConvert($str, $toArray);
- }
- WindConvert::convert($str, $charset, 'utf8');
- return $str;
- }
+ return $source;
+ }
- /**
- * 将json格式转成php string类型
- *
- * @param string $string json字符串
- * @return Ambigous
- */
- protected static function jsonToString($string) {
- $delim = substr($string, 0, 1);
- $chrs = substr($string, 1, -1);
- $decodeStr = '';
- for ($c = 0, $length = strlen($chrs); $c < $length; ++$c) {
- $compare = substr($chrs, $c, 2);
- $ordCode = ord($chrs{$c});
- if ('\b' == $compare) {
- $decodeStr .= chr(0x08);
- ++$c;
- } elseif ('\t' == $compare) {
- $decodeStr .= chr(0x09);
- ++$c;
- } elseif ('\n' == $compare) {
- $decodeStr .= chr(0x0A);
- ++$c;
- } elseif ('\f' == $compare) {
- $decodeStr .= chr(0x0C);
- ++$c;
- } elseif ('\r' == $compare) {
- $decodeStr .= chr(0x0D);
- ++$c;
- } elseif (in_array($compare, array('\\"', '\\\'', '\\\\', '\\/'))) {
- if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) {
- $decodeStr .= $chrs{++$c};
- }
- } elseif (preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))) {
- $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) . chr(hexdec(substr($chrs, ($c + 4), 2)));
- $decodeStr .= WindConvert::utf16beToUTF8($utf16); //self::utf16beToUTF8($utf16);
- $c += 5;
- } elseif (0x20 <= $ordCode && 0x7F >= $ordCode) {
- $decodeStr .= $chrs{$c};
- } elseif (0xC0 == ($ordCode & 0xE0)) {
- $decodeStr .= substr($chrs, $c, 2);
- ++$c;
- } elseif (0xE0 == ($ordCode & 0xF0)) {
- $decodeStr .= substr($chrs, $c, 3);
- $c += 2;
- } elseif (0xF0 == ($ordCode & 0xF8)) {
- $decodeStr .= substr($chrs, $c, 4);
- $c += 3;
- } elseif (0xF8 == ($ordCode & 0xFC)) {
- $decodeStr .= substr($chrs, $c, 5);
- $c += 4;
- } elseif (0xFC == ($ordCode & 0xFE)) {
- $decodeStr .= substr($chrs, $c, 6);
- $c += 5;
- }
- }
- return $decodeStr;
- }
+ /**
+ * 将json格式数据解密
+ *
+ * @param string $str
+ * @param bool $toArray
+ * @param string $charset
+ * @return mixed
+ */
+ public static function decode($str, $toArray = true, $charset = 'utf8')
+ {
+ $str = self::_reduceString($str);
+ $_str = strtolower($str);
+ if ('true' == $_str) {
+ return true;
+ } elseif ('false' == $_str) {
+ return false;
+ } elseif ('null' == $_str) {
+ return null;
+ } elseif (is_numeric($str)) {
+ return $str;
+ } elseif (preg_match('/^("|\').*(\1)$/s', $_str, $matche) && $matche[1] == $matche[2]) {
+ $str = self::jsonToString($str);
+ } elseif (preg_match('/^\[.*\]$/s', $_str) || preg_match('/^\{.*\}$/s', $_str)) {
+ $str = self::complexConvert($str, $toArray);
+ }
- /**
- * 复杂的json格式转换,支持object array格式
- *
- * @param string $str
- * @param boolean $toArray
- * @return Ambigous |multitype:|Ambigous |boolean
- */
- protected static function complexConvert($str, $toArray = true) {
- if ('[' == $str{0}) {
- $stk = array(self::JSON_IN_ARR);
- $arr = array();
- } else {
- $obj = $toArray ? array() : new stdClass();
- $stk = array(self::JSON_IN_OBJ);
- }
- array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false));
- $chrs = substr($str, 1, -1);
- $chrs = self::_reduceString($chrs);
- if ('' == $chrs) {
- return self::JSON_IN_ARR == reset($stk) ? $arr : $obj;
- }
- for ($c = 0, $length = strlen($chrs); $c <= $length; ++$c) {
- $top = end($stk);
- $substr_chrs_c_2 = substr($chrs, $c, 2);
- if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) {
- $slice = substr($chrs, $top['where'], ($c - $top['where']));
- array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
- if (reset($stk) == self::JSON_IN_ARR) {
- array_push($arr, self::decode($slice, $toArray));
- } elseif (reset($stk) == self::JSON_IN_OBJ) {
- if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
- $key = self::decode($parts[1], $toArray);
- $toArray ? $obj[$key] = self::decode($parts[2], $toArray) : $obj->$key = self::decode($parts[2],
- $toArray);
- } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
- $toArray ? $obj[$parts[1]] = self::decode($parts[2], $toArray) : $obj->$parts[1] = self::decode(
- $parts[2], $toArray);
- }
- }
-
- } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) {
- array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
- } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != "\\") || ($chrs{$c - 1} == "\\" && $chrs{$c - 2} == "\\"))) {
- array_pop($stk);
- } elseif (($chrs{$c} == '[') && in_array($top['what'],
- array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
- array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false));
- } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) {
- array_pop($stk);
- } elseif (($chrs{$c} == '{') && in_array($top['what'],
- array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
- array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false));
- } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) {
- array_pop($stk);
- } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'],
- array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
- array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false));
- } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) {
- array_pop($stk);
- for ($i = $top['where']; $i <= ++$c; ++$i) {
- $chrs = substr_replace($chrs, ' ', $i, 1);
- }
- }
-
- }
- if (self::JSON_IN_ARR == reset($stk)) {
- return $arr;
- } elseif (self::JSON_IN_OBJ == reset($stk)) {
- return $obj;
- }
- return false;
- }
+ return WindConvert::convert($str, $charset, 'utf8');
+ }
- /**
- * 将字符串转化成json格式对象
- *
- * @param string $string
- * @return string
- */
- protected static function stringToJson($string) {
- $ascii = '';
- $strlen = strlen($string);
- for ($c = 0; $c < $strlen; ++$c) {
- $b = $string{$c};
- $ordVar = ord($string{$c});
- if (0x08 == $ordVar) {
- $ascii .= '\b';
- } elseif (0x09 == $ordVar) {
- $ascii .= '\t';
- } elseif (0x0A == $ordVar) {
- $ascii .= '\n';
- } elseif (0x0C == $ordVar) {
- $ascii .= '\f';
- } elseif (0x0D == $ordVar) {
- $ascii .= '\r';
- } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) {
- $ascii .= '\\' . $string{$c};
- } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) {
- $ascii .= $string{$c}; //ASCII
- } elseif (0xC0 == ($ordVar & 0xE0)) {
- $char = pack('C*', $ordVar, ord($string{++$c}));
- $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
- } elseif (0xE0 == ($ordVar & 0xF0)) {
- $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}));
- $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
- } elseif (0xF0 == ($ordVar & 0xF8)) {
- $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}));
- $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
- } elseif (0xF8 == ($ordVar & 0xFC)) {
- $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}),
- ord($string{++$c}));
- $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
- } elseif (0xFC == ($ordVar & 0xFE)) {
- $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}),
- ord($string{++$c}), ord($string{++$c}));
- $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
- }
- }
- return '"' . $ascii . '"';
- }
+ /**
+ * 将json格式转成php string类型
+ *
+ * @param string $string json字符串
+ * @return Ambigous
+ */
+ protected static function jsonToString($string)
+ {
+ $delim = substr($string, 0, 1);
+ $chrs = substr($string, 1, -1);
+ $decodeStr = '';
+ for ($c = 0, $length = strlen($chrs); $c < $length; ++$c) {
+ $compare = substr($chrs, $c, 2);
+ $ordCode = ord($chrs{$c});
+ if ('\b' == $compare) {
+ $decodeStr .= chr(0x08);
+ ++$c;
+ } elseif ('\t' == $compare) {
+ $decodeStr .= chr(0x09);
+ ++$c;
+ } elseif ('\n' == $compare) {
+ $decodeStr .= chr(0x0A);
+ ++$c;
+ } elseif ('\f' == $compare) {
+ $decodeStr .= chr(0x0C);
+ ++$c;
+ } elseif ('\r' == $compare) {
+ $decodeStr .= chr(0x0D);
+ ++$c;
+ } elseif (in_array($compare, array('\\"', '\\\'', '\\\\', '\\/'))) {
+ if (('"' == $delim && '\\\'' != $compare) || ("'" == $delim && '\\"' != $compare)) {
+ $decodeStr .= $chrs{++$c};
+ }
+ } elseif (preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6))) {
+ $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))).chr(hexdec(substr($chrs, ($c + 4), 2)));
+ $decodeStr .= WindConvert::utf16beToUTF8($utf16); //self::utf16beToUTF8($utf16);
+ $c += 5;
+ } elseif (0x20 <= $ordCode && 0x7F >= $ordCode) {
+ $decodeStr .= $chrs{$c};
+ } elseif (0xC0 == ($ordCode & 0xE0)) {
+ $decodeStr .= substr($chrs, $c, 2);
+ ++$c;
+ } elseif (0xE0 == ($ordCode & 0xF0)) {
+ $decodeStr .= substr($chrs, $c, 3);
+ $c += 2;
+ } elseif (0xF0 == ($ordCode & 0xF8)) {
+ $decodeStr .= substr($chrs, $c, 4);
+ $c += 3;
+ } elseif (0xF8 == ($ordCode & 0xFC)) {
+ $decodeStr .= substr($chrs, $c, 5);
+ $c += 4;
+ } elseif (0xFC == ($ordCode & 0xFE)) {
+ $decodeStr .= substr($chrs, $c, 6);
+ $c += 5;
+ }
+ }
- /**
- * 将数组转化成json格式对象
- *
- * @param array $array
- * @return string
- */
- protected static function arrayToJson(array $array) {
- if (is_array($array) && count($array) && (array_keys($array) !== range(0, sizeof($array) - 1))) {
- return '{' . join(',', array_map(array('WindJson', '_nameValue'), array_keys($array), array_values($array))) . '}';
- }
- return '[' . join(',', array_map(array('WindJson', 'encode'), $array)) . ']';
- }
+ return $decodeStr;
+ }
- /**
- * 将对象转化成json格式对象
- *
- * @param string $object
- * @return string
- */
- protected static function objectToJson($object) {
- if ($object instanceof Traversable) {
- $vars = array();
- foreach ($object as $k => $v) {
- $vars[$k] = $v;
- }
- } else {
- $vars = get_object_vars($object);
- }
- return '{' . join(',', array_map(array('WindJson', '_nameValue'), array_keys($vars), array_values($vars))) . '}';
- }
+ /**
+ * 复杂的json格式转换,支持object array格式
+ *
+ * @param string $str
+ * @param bool $toArray
+ * @return Ambigous |multitype:|Ambigous |boolean
+ */
+ protected static function complexConvert($str, $toArray = true)
+ {
+ if ('[' == $str{0}) {
+ $stk = array(self::JSON_IN_ARR);
+ $arr = array();
+ } else {
+ $obj = $toArray ? array() : new stdClass();
+ $stk = array(self::JSON_IN_OBJ);
+ }
+ array_push($stk, array('what' => self::JSON_SLICE, 'where' => 0, 'delim' => false));
+ $chrs = substr($str, 1, -1);
+ $chrs = self::_reduceString($chrs);
+ if ('' == $chrs) {
+ return self::JSON_IN_ARR == reset($stk) ? $arr : $obj;
+ }
+ for ($c = 0, $length = strlen($chrs); $c <= $length; ++$c) {
+ $top = end($stk);
+ $substr_chrs_c_2 = substr($chrs, $c, 2);
+ if (($c == $length) || (($chrs{$c} == ',') && ($top['what'] == self::JSON_SLICE))) {
+ $slice = substr($chrs, $top['where'], ($c - $top['where']));
+ array_push($stk, array('what' => self::JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
+ if (reset($stk) == self::JSON_IN_ARR) {
+ array_push($arr, self::decode($slice, $toArray));
+ } elseif (reset($stk) == self::JSON_IN_OBJ) {
+ if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ $key = self::decode($parts[1], $toArray);
+ $toArray ? $obj[$key] = self::decode($parts[2], $toArray) : $obj->$key = self::decode($parts[2],
+ $toArray);
+ } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) {
+ $toArray ? $obj[$parts[1]] = self::decode($parts[2], $toArray) : $obj->$parts[1] = self::decode(
+ $parts[2], $toArray);
+ }
+ }
+ } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != self::JSON_IN_STR)) {
+ array_push($stk, array('what' => self::JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c}));
+ } elseif (($chrs{$c} == $top['delim']) && ($top['what'] == self::JSON_IN_STR) && (($chrs{$c - 1} != '\\') || ($chrs{$c - 1} == '\\' && $chrs{$c - 2} == '\\'))) {
+ array_pop($stk);
+ } elseif (($chrs{$c} == '[') && in_array($top['what'],
+ array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
+ array_push($stk, array('what' => self::JSON_IN_ARR, 'where' => $c, 'delim' => false));
+ } elseif (($chrs{$c} == ']') && ($top['what'] == self::JSON_IN_ARR)) {
+ array_pop($stk);
+ } elseif (($chrs{$c} == '{') && in_array($top['what'],
+ array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
+ array_push($stk, array('what' => self::JSON_IN_OBJ, 'where' => $c, 'delim' => false));
+ } elseif (($chrs{$c} == '}') && ($top['what'] == self::JSON_IN_OBJ)) {
+ array_pop($stk);
+ } elseif (($substr_chrs_c_2 == '/*') && in_array($top['what'],
+ array(self::JSON_SLICE, self::JSON_IN_ARR, self::JSON_IN_OBJ))) {
+ array_push($stk, array('what' => self::JSON_IN_CMT, 'where' => ++$c, 'delim' => false));
+ } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == self::JSON_IN_CMT)) {
+ array_pop($stk);
+ for ($i = $top['where']; $i <= ++$c; ++$i) {
+ $chrs = substr_replace($chrs, ' ', $i, 1);
+ }
+ }
+ }
+ if (self::JSON_IN_ARR == reset($stk)) {
+ return $arr;
+ } elseif (self::JSON_IN_OBJ == reset($stk)) {
+ return $obj;
+ }
- /**
- * @param string $str
- * @return string
- */
- private static function _reduceString($str) {
- return trim(preg_replace(array('#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str));
- }
+ return false;
+ }
- /**
- * callback函数,用于数组或对象加密
- *
- * @param mixed $name
- * @param mixed $value
- */
- private static function _nameValue($name, $value) {
- return self::encode(strval($name)) . ':' . self::encode($value);
- }
-}
+ /**
+ * 将字符串转化成json格式对象
+ *
+ * @param string $string
+ * @param string $charset
+ * @return string
+ */
+ protected static function stringToJson($string, $charset = 'utf-8')
+ {
+ $string = WindConvert::convert($string, 'utf-8', $charset);
+ $ascii = '';
+ $strlen = strlen($string);
+ for ($c = 0; $c < $strlen; ++$c) {
+ $b = $string{$c};
+ $ordVar = ord($string{$c});
+ if (0x08 == $ordVar) {
+ $ascii .= '\b';
+ } elseif (0x09 == $ordVar) {
+ $ascii .= '\t';
+ } elseif (0x0A == $ordVar) {
+ $ascii .= '\n';
+ } elseif (0x0C == $ordVar) {
+ $ascii .= '\f';
+ } elseif (0x0D == $ordVar) {
+ $ascii .= '\r';
+ } elseif (in_array($ordVar, array(0x22, 0x2F, 0x5C))) {
+ $ascii .= '\\'.$string{$c};
+ } elseif (0x20 <= $ordVar && 0x7F >= $ordVar) {
+ $ascii .= $string{$c}; //ASCII
+ } elseif (0xC0 == ($ordVar & 0xE0)) {
+ $char = pack('C*', $ordVar, ord($string{++$c}));
+ $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
+ } elseif (0xE0 == ($ordVar & 0xF0)) {
+ $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}));
+ $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
+ } elseif (0xF0 == ($ordVar & 0xF8)) {
+ $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}));
+ $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
+ } elseif (0xF8 == ($ordVar & 0xFC)) {
+ $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}),
+ ord($string{++$c}));
+ $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
+ } elseif (0xFC == ($ordVar & 0xFE)) {
+ $char = pack('C*', $ordVar, ord($string{++$c}), ord($string{++$c}), ord($string{++$c}),
+ ord($string{++$c}), ord($string{++$c}));
+ $ascii .= sprintf('\u%04s', bin2hex(WindConvert::utf8ToUTF16BE($char)));
+ }
+ }
+
+ return '"'.$ascii.'"';
+ }
+
+ /**
+ * 将数组转化成json格式对象
+ *
+ * @param array $array
+ * @param string $charset
+ * @return string
+ */
+ protected static function arrayToJson(array $array, $charset = 'utf-8')
+ {
+ if (is_array($array) && count($array) && (array_keys($array) !== range(0, count($array) - 1))) {
+ array_walk($array, array('WindJson', '_nameValue'), $charset);
+
+ return '{'.implode(',', $array).'}';
+ }
+ array_walk($array, array('WindJson', '_value'), $charset);
-?>
\ No newline at end of file
+ return '['.implode(',', $array).']';
+ }
+
+ /**
+ * 将对象转化成json格式对象
+ *
+ * @param string $object
+ * @param string $charset
+ * @return string
+ */
+ protected static function objectToJson($object, $charset = 'utf-8')
+ {
+ if ($object instanceof Traversable) {
+ $vars = array();
+ foreach ($object as $k => $v) {
+ $vars[$k] = $v;
+ }
+ } else {
+ $vars = get_object_vars($object);
+ }
+ array_walk($vars, array('WindJson', '_nameValue'), $charset);
+
+ return '{'.implode(',', $vars).'}';
+ }
+
+ /**
+ * @param string $str
+ * @return string
+ */
+ private static function _reduceString($str)
+ {
+ return trim(preg_replace(array('#^\s*//(.+)$#m', '#^\s*/\*(.+)\*/#Us', '#/\*(.+)\*/\s*$#Us'), '', $str));
+ }
+
+ /**
+ * callback函数,用于数组或对象加密
+ *
+ * @param mixed $name
+ * @param mixed $value
+ * @param string $charset
+ */
+ private static function _nameValue(&$value, $name, $charset)
+ {
+ $value = self::encode(strval($name), $charset).':'.self::encode($value, $charset);
+ }
+
+ /**
+ * callback函数,用于数组加密(无key)
+ *
+ * @param mixed $value
+ * @param mixed $name
+ * @param string $charset
+ */
+ private static function _value(&$value, $name, $charset)
+ {
+ $value = self::encode($value, $charset);
+ }
+}
diff --git a/wind/utility/WindPack.php b/wind/utility/WindPack.php
index 7b6f1517..0a2c901e 100644
--- a/wind/utility/WindPack.php
+++ b/wind/utility/WindPack.php
@@ -1,294 +1,328 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindPack.php 3647 2012-06-08 04:14:06Z yishuo $
* @package utility
*/
-class WindPack {
-
- /**
- * 使用正则打包
- *
- * @var string
- */
- const STRIP_SELF = 'stripWhiteSpaceBySelf';
-
- /**
- * 利用php自身的函数打包
- *
- * @var string
- */
- const STRIP_PHP = 'stripWhiteSpaceByPhp';
-
- /**
- * 通过token方式打包
- *
- * @var string
- */
- const STRIP_TOKEN = 'stripWhiteSpaceByToken';
- private $packList = array();
- private $contentInjectionPosition;
- private $contentInjectionCallBack = '';
+class WindPack
+{
+ /**
+ * 使用正则打包
+ *
+ * @var string
+ */
+ const STRIP_SELF = 'stripWhiteSpaceBySelf';
+
+ /**
+ * 利用php自身的函数打包
+ *
+ * @var string
+ */
+ const STRIP_PHP = 'stripWhiteSpaceByPhp';
+
+ /**
+ * 通过token方式打包
+ *
+ * @var string
+ */
+ const STRIP_TOKEN = 'stripWhiteSpaceByToken';
+ private $packList = array();
+ private $contentInjectionPosition;
+ private $contentInjectionCallBack = '';
+
+ /**
+ * 将给出的文件列表进行打包
+ *
+ * @param mixed $fileList 文件列表
+ * @param string $dst 打包文件的存放位置
+ * @param method $packMethod 打包的方式,默认为stripWhiteSpaceByPhp
+ * @param bool $compress 打包是否采用压缩的方式,默认为true
+ * @return bool
+ */
+ public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true)
+ {
+ if (empty($dst) || empty($fileList)) {
+ return false;
+ }
+ $content = array();
+ $this->readContentFromFileList($fileList, $packMethod, $content);
+ $replace = $compress ? ' ' : "\n";
+ $content = implode($replace, $content);
+ $content = $this->callBack($content, $replace);
+ $content = $this->stripNR($content, $replace);
+ $content = $this->stripPhpIdentify($content, '');
+
+ return WindFile::write($dst, '');
+ }
+
+ /**
+ * 通过php自身方式去除指定文件的注释及空白
+ *
+ * @param string $filename 文件名
+ * @return string
+ */
+ public function stripWhiteSpaceByPhp($filename)
+ {
+ return php_strip_whitespace($filename);
+ }
+
+ /**
+ * 通过正则方式去除指定文件的注释及空白
+ *
+ * @param string $filename 文件名字
+ * @param bool $compress 是否采用压缩,默认为true
+ * @return string
+ */
+ public function stripWhiteSpaceBySelf($filename, $compress = true)
+ {
+ $content = $this->getContentFromFile($filename);
+ $content = $this->stripComment($content, '');
+
+ return $this->stripSpace($content, ' ');
+ }
+
+ /**
+ * 通过token方式去除指定文件的注释及空白
+ *
+ * @param string $filename 文件名称
+ * @return string
+ */
+ public function stripWhiteSpaceByToken($filename)
+ {
+ $content = $this->getContentFromFile($filename);
+ $compressContent = '';
+ $lastToken = 0;
+ foreach (token_get_all($content) as $key => $token) {
+ if (is_array($token)) {
+ if (in_array($token[0], array(T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) {
+ continue;
+ }
+ $compressContent .= ' '.$token[1];
+ } else {
+ $compressContent .= $token;
+ }
+ $lastToken = $token[0];
+ }
+
+ return $compressContent;
+ }
+
+ /**
+ * 从文件列表中取得对应的每个文件的内容
+ *
+ * @param mixed $fileList 文件列表
+ * @param method $packMethod 打包方式,默认为stripWhiteSpaceByPhp
+ * @param array $content 保存文件内容,默认为空数组
+ * @return array:
+ */
+ public function readContentFromFileList(array $fileList, $packMethod = WindPack::STRIP_PHP, &$content = array())
+ {
+ if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) {
+ return array();
+ }
+
+ foreach ($fileList as $key => $value) {
+ $parents = class_parents($key);
+ $_fileList = $this->buildFileList($parents, $fileList);
+ $this->readContentFromFileList($_fileList, $packMethod, $content);
+ $implements = class_implements($key);
+ $_fileList = $this->buildFileList($implements, $fileList);
+ $this->readContentFromFileList($_fileList, $packMethod, $content);
+ if (in_array($key, $this->packList)) {
+ continue;
+ }
+ if (is_file($value)) {
+ $content[] = $this->$packMethod($value);
+ $this->packList[] = $key;
+ }
+ }
+ }
- /**
- * 将给出的文件列表进行打包
- *
- * @param mixed $fileList 文件列表
- * @param string $dst 打包文件的存放位置
- * @param method $packMethod 打包的方式,默认为stripWhiteSpaceByPhp
- * @param boolean $compress 打包是否采用压缩的方式,默认为true
- * @return boolean
- */
- public function packFromFileList($fileList, $dst, $packMethod = WindPack::STRIP_PHP, $compress = true) {
- if (empty($dst) || empty($fileList)) return false;
- $content = array();
- $this->readContentFromFileList($fileList, $packMethod, $content);
- $replace = $compress ? ' ' : "\n";
- $content = implode($replace, $content);
- $content = $this->callBack($content, $replace);
- $content = $this->stripNR($content, $replace);
- $content = $this->stripPhpIdentify($content, '');
- return WindFile::write($dst, '');
- }
+ /**
+ * 去除注释
+ *
+ * @param string $content 要去除的内容
+ * @param mixed $replace 要替换的文本
+ * @return string
+ */
+ public function stripComment($content, $replace = '')
+ {
+ return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content);
+ }
- /**
- * 通过php自身方式去除指定文件的注释及空白
- *
- * @param string $filename 文件名
- * @return string
- */
- public function stripWhiteSpaceByPhp($filename) {
- return php_strip_whitespace($filename);
- }
+ /**
+ * 去除换行
+ *
+ * @param string $content 要去除的内容
+ * @param mixed $replace 要替换的文本
+ * @return string
+ */
+ public function stripNR($content, $replace = array('\n', '\r\n', '\r'))
+ {
+ return preg_replace('/[\n\r]+/', $replace, $content);
+ }
- /**
- * 通过正则方式去除指定文件的注释及空白
- *
- * @param string $filename 文件名字
- * @param boolean $compress 是否采用压缩,默认为true
- * @return string
- */
- public function stripWhiteSpaceBySelf($filename, $compress = true) {
- $content = $this->getContentFromFile($filename);
- $content = $this->stripComment($content, '');
- return $this->stripSpace($content, ' ');
- }
+ /**
+ * 去除空格符
+ *
+ * @param string $content 要去除的内容
+ * @param mixed $replace 要替换的文本,默认为空
+ * @return string
+ */
+ public function stripSpace($content, $replace = ' ')
+ {
+ return preg_replace('/[ ]+/', $replace, $content);
+ }
- /**
- * 通过token方式去除指定文件的注释及空白
- *
- * @param string $filename 文件名称
- * @return string
- */
- public function stripWhiteSpaceByToken($filename) {
- $content = $this->getContentFromFile($filename);
- $compressContent = '';
- $lastToken = 0;
- foreach (token_get_all($content) as $key => $token) {
- if (is_array($token)) {
- if (in_array($token[0], array(T_COMMENT, T_WHITESPACE, T_DOC_COMMENT))) {
- continue;
- }
- $compressContent .= ' ' . $token[1];
- } else {
- $compressContent .= $token;
- }
- $lastToken = $token[0];
- }
- return $compressContent;
- }
+ /**
+ * 去除php标识
+ *
+ * @param string $content 需要处理的内容
+ * @param mixed $replace 将php标识替换为该值,默认为空
+ * @return string
+ */
+ public function stripPhpIdentify($content, $replace = '')
+ {
+ return preg_replace('/(?:<\?(?:php)*)|(\?>)/i', $replace, $content);
+ }
- /**
- * 从文件列表中取得对应的每个文件的内容
- *
- * @param mixed $fileList 文件列表
- * @param method $packMethod 打包方式,默认为stripWhiteSpaceByPhp
- * @param array $content 保存文件内容,默认为空数组
- * @return array:
- */
- public function readContentFromFileList(array $fileList, $packMethod = WindPack::STRIP_PHP, &$content = array()) {
- if (empty($fileList) || false === $this->isValidatePackMethod($packMethod)) return array();
-
- foreach ($fileList as $key => $value) {
- $parents = class_parents($key);
- $_fileList = $this->buildFileList($parents, $fileList);
- $this->readContentFromFileList($_fileList, $packMethod, $content);
- $implements = class_implements($key);
- $_fileList = $this->buildFileList($implements, $fileList);
- $this->readContentFromFileList($_fileList, $packMethod, $content);
- if (in_array($key, $this->packList)) continue;
- if (is_file($value)) {
- $content[] = $this->$packMethod($value);
- $this->packList[] = $key;
- }
- }
- }
+ /**
+ * 根据指定规则替换指定内容中相应的内容
+ *
+ * @param string $content 需要处理的内容
+ * @param string $rule 需要匹配的正则
+ * @param $mixed $replace 用来替换将匹配出来的结果,默认为空
+ * @return string
+ */
+ public function stripStrByRule($content, $rule, $replace = '')
+ {
+ return preg_replace("/$rule/", $replace, $content);
+ }
- /**
- * 去除注释
- *
- * @param string $content 要去除的内容
- * @param mixed $replace 要替换的文本
- * @return string
- */
- public function stripComment($content, $replace = '') {
- return preg_replace('/(?:\/\*.*\*\/)*|(?:\/\/[^\r\n]*[\r\n])*/Us', $replace, $content);
- }
+ /**
+ * 去除多余的文件导入信息
+ *
+ * @param string $content 需要处理的内容
+ * @param mixed $replace 用来替换将匹配出来的结果,默认为空
+ * @return string
+ */
+ public function stripImport($content, $replace = '')
+ {
+ $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content,
+ $matchs);
+ if ($matchs[1]) {
+ foreach ($matchs[1] as $key => $value) {
+ $name = substr($value, strrpos($value, '.') + 1);
+ if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) {
+ $strip = str_replace(array('(', ')'), array('\(', '\)'), addslashes($matchs[0][$key])).'[\t ]*;';
+ $content = $this->stripStrByRule($content, $strip, $replace);
+ }
+ }
+ }
- /**
- * 去除换行
- *
- * @param string $content 要去除的内容
- * @param mixed $replace 要替换的文本
- * @return string
- */
- public function stripNR($content, $replace = array('\n','\r\n','\r')) {
- return preg_replace('/[\n\r]+/', $replace, $content);
- }
+ return $content;
+ }
- /**
- * 去除空格符
- *
- * @param string $content 要去除的内容
- * @param mixed $replace 要替换的文本,默认为空
- * @return string
- */
- public function stripSpace($content, $replace = ' ') {
- return preg_replace('/[ ]+/', $replace, $content);
- }
+ /**
+ * 从文件读取内容
+ *
+ * @param string $filename 文件名
+ * @return string 如果给出的文件不是一个有效文件则返回false
+ */
+ public function getContentFromFile($filename)
+ {
+ if (is_file($filename)) {
+ $content = '';
+ $fp = fopen($filename, 'r');
+ while (!feof($fp)) {
+ $line = fgets($fp);
+ if (in_array(strlen($line), array(2, 3)) && in_array(ord($line), array(9, 10, 13))) {
+ continue;
+ }
+ $content .= $line;
+ }
+ fclose($fp);
- /**
- * 去除php标识
- *
- * @param string $content 需要处理的内容
- * @param mixed $replace 将php标识替换为该值,默认为空
- * @return string
- */
- public function stripPhpIdentify($content, $replace = '') {
- return preg_replace('/(?:<\?(?:php)*)|(\?>)/i', $replace, $content);
- }
+ return $content;
+ }
- /**
- * 根据指定规则替换指定内容中相应的内容
- *
- * @param string $content 需要处理的内容
- * @param string $rule 需要匹配的正则
- * @param $mixed $replace 用来替换将匹配出来的结果,默认为空
- * @return string
- */
- public function stripStrByRule($content, $rule, $replace = '') {
- return preg_replace("/$rule/", $replace, $content);
- }
+ return false;
+ }
- /**
- * 去除多余的文件导入信息
- *
- * @param string $content 需要处理的内容
- * @param mixed $replace 用来替换将匹配出来的结果,默认为空
- * @return string
- */
- public function stripImport($content, $replace = '') {
- $str = preg_match_all('/L[\t ]*::[\t ]*import[\t ]*\([\t ]*[\'\"]([^$][\w\.:]+)[\"\'][\t ]*\)[\t ]*/', $content,
- $matchs);
- if ($matchs[1]) {
- foreach ($matchs[1] as $key => $value) {
- $name = substr($value, strrpos($value, '.') + 1);
- if (preg_match("/(abstract[\t ]*|class|interface)[\t ]+$name/i", $content)) {
- $strip = str_replace(array('(', ')'), array('\(', '\)'), addslashes($matchs[0][$key])) . '[\t ]*;';
- $content = $this->stripStrByRule($content, $strip, $replace);
- }
- }
- }
- return $content;
- }
+ /**
+ * 构造文件列表
+ *
+ * @param array $list 需要处理的文件列表
+ * @param array $fileList 文件列表
+ * @return array 保存$list中存在于$fileList中的文件列表
+ */
+ private function buildFileList(array $list, $fileList)
+ {
+ $_temp = array();
+ foreach ($list as $fileName) {
+ foreach ($fileList as $key => $value) {
+ if ($key == $fileName) {
+ $_temp[$key] = $value;
+ break;
+ }
+ }
+ }
- /**
- * 从文件读取内容
- *
- * @param string $filename 文件名
- * @return string 如果给出的文件不是一个有效文件则返回false
- */
- public function getContentFromFile($filename) {
- if (is_file($filename)) {
- $content = '';
- $fp = fopen($filename, "r");
- while (!feof($fp)) {
- $line = fgets($fp);
- if (in_array(strlen($line), array(2, 3)) && in_array(ord($line), array(9, 10, 13))) continue;
- $content .= $line;
- }
- fclose($fp);
- return $content;
- }
- return false;
- }
+ return $_temp;
+ }
- /**
- * 构造文件列表
- *
- * @param array $list 需要处理的文件列表
- * @param array $fileList 文件列表
- * @return array 保存$list中存在于$fileList中的文件列表
- */
- private function buildFileList(array $list, $fileList) {
- $_temp = array();
- foreach ($list as $fileName) {
- foreach ($fileList as $key => $value) {
- if ($key == $fileName) {
- $_temp[$key] = $value;
- break;
- }
- }
- }
- return $_temp;
- }
+ /**
+ * 设置回调
+ *
+ * @author Qiong Wu
+ * @param array $contentInjectionCallBack 回调函数
+ * @param string $position 调用位置(before|after)默认为before
+ */
+ public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before')
+ {
+ if (!in_array($position, array('before', 'after'))) {
+ $position = 'before';
+ }
+ $this->contentInjectionPosition = $position;
+ $this->contentInjectionCallBack = $contentInjectionCallBack;
+ }
- /**
- * 设置回调
- *
- * @author Qiong Wu
- * @param array $contentInjectionCallBack 回调函数
- * @param string $position 调用位置(before|after)默认为before
- * @return void
- */
- public function setContentInjectionCallBack($contentInjectionCallBack, $position = 'before') {
- if (!in_array($position, array('before', 'after'))) $position = 'before';
- $this->contentInjectionPosition = $position;
- $this->contentInjectionCallBack = $contentInjectionCallBack;
- }
+ /**
+ * 回调函数调用
+ *
+ * @param string $content 被回调的内容
+ * @param string $replace 替换内容,默认为空
+ * @return string
+ */
+ public function callBack($content, $replace = '')
+ {
+ if ($this->contentInjectionCallBack !== '') {
+ $_content = call_user_func_array($this->contentInjectionCallBack, array($this->packList));
+ if ($this->contentInjectionPosition == 'before') {
+ $content = $replace.$_content.$content;
+ } elseif ($this->contentInjectionPosition == 'after') {
+ $content .= $replace.$_content.$replace;
+ }
+ }
- /**
- * 回调函数调用
- *
- * @param string $content 被回调的内容
- * @param string $replace 替换内容,默认为空
- * @return string
- */
- public function callBack($content, $replace = '') {
- if ($this->contentInjectionCallBack !== '') {
- $_content = call_user_func_array($this->contentInjectionCallBack, array($this->packList));
- if ($this->contentInjectionPosition == 'before') {
- $content = $replace . $_content . $content;
- } elseif ($this->contentInjectionPosition == 'after') {
- $content .= $replace . $_content . $replace;
- }
- }
- return $content;
- }
+ return $content;
+ }
- /**
- * 检查打包方法的有效性
- *
- * @param string $packMethod 被检查的方法
- * @return boolean
- */
- private function isValidatePackMethod($packMethod) {
- return method_exists($this, $packMethod) && in_array($packMethod,
- array(WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN));
- }
-}
\ No newline at end of file
+ /**
+ * 检查打包方法的有效性
+ *
+ * @param string $packMethod 被检查的方法
+ * @return bool
+ */
+ private function isValidatePackMethod($packMethod)
+ {
+ return method_exists($this, $packMethod) && in_array($packMethod,
+ array(WindPack::STRIP_PHP, WindPack::STRIP_SELF, WindPack::STRIP_TOKEN));
+ }
+}
diff --git a/wind/utility/WindSecurity.php b/wind/utility/WindSecurity.php
index 0cfde2e4..976620cc 100644
--- a/wind/utility/WindSecurity.php
+++ b/wind/utility/WindSecurity.php
@@ -1,124 +1,166 @@
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindSecurity.php 3939 2013-05-29 06:22:57Z xiaoxia.xuxx $
* @package utility
*/
-class WindSecurity {
-
- /**
- * 转义输出字符串
- *
- * @param string $str 被转义的字符串
- * @return string
- */
- public static function escapeHTML($str) {
- if (!is_string($str)) return $str;
- return htmlspecialchars($str, ENT_QUOTES);
- }
-
- /**
- * 转义字符串
- *
- * @param array $array 被转移的数组
- * @return array
- */
- public static function escapeArrayHTML($array) {
- if (!is_array($array) || count($array) > 100) return $array;
- $_tmp = array();
- foreach ($array as $key => $value) {
- is_string($key) && $key = self::escapeHTML($key);
- $_tmp[$key] = self::escapeHTML($value);
- }
- return $_tmp;
- }
-
- /**
- * 字符串加密
- *
- * @param string $str 需要加密的字符串
- * @param string $key 密钥
- * @return string 加密后的结果
- */
- public static function encrypt($str, $key, $iv = '') {
- if (!$key || !is_string($key)) throw new WindException(
- '[utility.WindSecurity.encrypt] security key is required. ', WindException::ERROR_PARAMETER_TYPE_ERROR);
- if (!$str || !is_string($str)) throw new WindException(
- '[utility.WindSecurity.encrypt] security string is required.', WindException::ERROR_PARAMETER_TYPE_ERROR);
-
- $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
- $iv = substr(md5($iv ? $iv : $key), -$size);
- $pad = $size - (strlen($str) % $size);
- $str .= str_repeat(chr($pad), $pad);
- @$data = mcrypt_cbc(MCRYPT_DES, $key, $str, MCRYPT_ENCRYPT, $iv);
- return base64_encode($data);
- }
-
- /**
- * 解密字符串
- *
- * @param string $str 解密的字符串
- * @param string $key 密钥
- * @return string 解密后的结果
- */
- public static function decrypt($str, $key, $iv = '') {
- if (!$str || !is_string($str)) throw new WindException(
- '[utility.WindSecurity.dncrypt] security string is required.', WindException::ERROR_PARAMETER_TYPE_ERROR);
- if (!$key || !is_string($key)) throw new WindException('[utility.WindSecurity.decrypt] security key is required.',
- WindException::ERROR_PARAMETER_TYPE_ERROR);
-
- $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
- $iv = substr(md5($iv ? $iv : $key), -$size);
- $str = base64_decode($str);
- @$str = mcrypt_cbc(MCRYPT_DES, $key, $str, MCRYPT_DECRYPT, $iv);
- $pad = ord($str{strlen($str) - 1});
- if ($pad > strlen($str)) return false;
- if (strspn($str, chr($pad), strlen($str) - $pad) != $pad) return false;
- return substr($str, 0, -1 * $pad);
- }
-
- /**
- * 创建token令牌串
- *
- * 创建token令牌串,用于避免表单重复提交等.
- * 使用当前的sessionID以及当前时间戳,生成唯一一串令牌串,并返回.
- * @deprecated
- * @return string
- */
- public static function createToken() {
- return self::generateGUID();
- }
-
- /**
- * 获取唯一标识符串,标识符串的长度为16个字节,128位.
- *
- * 根据当前时间与sessionID,混合生成一个唯一的串.
- * @return string GUID串,16个字节
- */
- public static function generateGUID() {
- return substr(md5(WindUtility::generateRandStr(8) . microtime()), -16);
- }
-
- /**
- * 路径检查转义
- *
- * @param string $fileName 被检查的路径
- * @param boolean $ifCheck 是否需要检查文件名,默认为false
- * @return string
- */
- public static function escapePath($filePath, $ifCheck = false) {
- $_tmp = array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '');
- $_tmp['://'] = $_tmp["\0"] = '';
- $ifCheck && $_tmp['..'] = '';
- if (strtr($filePath, $_tmp) == $filePath) return preg_replace('/[\/\\\]{1,}/i', '/', $filePath);
- if (WIND_DEBUG & 2) {
- Wind::getApp()->getComponent('windLogger')->info(
- "[utility.WindSecurity.escapePath] file path is illegal.\r\n\tFilePath:" . $filePath);
- }
- throw new WindException('[utility.WindSecurity.escapePath] file path is illegal');
- }
-}
\ No newline at end of file
+class WindSecurity
+{
+ /**
+ * 输出json到页面
+ * 添加转义
+ *
+ * @param mixed $source
+ * @param string $charset
+ * @return string
+ */
+ public static function escapeEncodeJson($source, $charset = 'utf-8')
+ {
+ return WindJson::encode(is_string($source) ? self::escapeHTML($source) : self::escapeArrayHTML($source), $charset);
+ }
+
+ /**
+ * 转义输出字符串
+ *
+ * @param string $str 被转义的字符串
+ * @return string
+ */
+ public static function escapeHTML($str, $charset = 'ISO-8859-1')
+ {
+ if (!is_string($str)) {
+ return $str;
+ }
+
+ return htmlspecialchars($str, ENT_QUOTES, $charset);
+ }
+
+ /**
+ * 转义字符串
+ *
+ * @param array $array 被转移的数组
+ * @return array
+ */
+ public static function escapeArrayHTML($array)
+ {
+ if (!is_array($array)) {
+ return self::escapeHTML($array);
+ }
+ $_tmp = array();
+ foreach ($array as $key => $value) {
+ is_string($key) && $key = self::escapeHTML($key);
+ $_tmp[$key] = is_array($value) ? self::escapeArrayHTML($value) : self::escapeHTML($value);
+ }
+
+ return $_tmp;
+ }
+
+ /**
+ * 字符串加密
+ *
+ * @param string $str 需要加密的字符串
+ * @param string $key 密钥
+ * @return string 加密后的结果
+ */
+ public static function encrypt($str, $key, $iv = '')
+ {
+ if (!$key || !is_string($key)) {
+ throw new WindException(
+ '[utility.WindSecurity.encrypt] security key is required. ', WindException::ERROR_PARAMETER_TYPE_ERROR);
+ }
+ if (!$str || !is_string($str)) {
+ throw new WindException(
+ '[utility.WindSecurity.encrypt] security string is required.', WindException::ERROR_PARAMETER_TYPE_ERROR);
+ }
+
+ $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
+ $iv = substr(md5($iv ? $iv : $key), -$size);
+ $pad = $size - (strlen($str) % $size);
+ $str .= str_repeat(chr($pad), $pad);
+ @$data = mcrypt_cbc(MCRYPT_DES, $key, $str, MCRYPT_ENCRYPT, $iv);
+
+ return base64_encode($data);
+ }
+
+ /**
+ * 解密字符串
+ *
+ * @param string $str 解密的字符串
+ * @param string $key 密钥
+ * @return string 解密后的结果
+ */
+ public static function decrypt($str, $key, $iv = '')
+ {
+ if (!$str || !is_string($str)) {
+ throw new WindException(
+ '[utility.WindSecurity.decrypt] security string is required.', WindException::ERROR_PARAMETER_TYPE_ERROR);
+ }
+ if (!$key || !is_string($key)) {
+ throw new WindException(
+ '[utility.WindSecurity.decrypt] security key is required.', WindException::ERROR_PARAMETER_TYPE_ERROR);
+ }
+
+ $size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC);
+ $iv = substr(md5($iv ? $iv : $key), -$size);
+ $str = base64_decode($str);
+ @$str = mcrypt_cbc(MCRYPT_DES, $key, $str, MCRYPT_DECRYPT, $iv);
+ $pad = ord($str{strlen($str) - 1});
+ if ($pad > strlen($str)) {
+ return false;
+ }
+ if (strspn($str, chr($pad), strlen($str) - $pad) != $pad) {
+ return false;
+ }
+
+ return substr($str, 0, -1 * $pad);
+ }
+
+ /**
+ * 创建token令牌串
+ * 创建token令牌串,用于避免表单重复提交等.
+ * 使用当前的sessionID以及当前时间戳,生成唯一一串令牌串,并返回.
+ *
+ * @deprecated
+ *
+ * @return string
+ */
+ public static function createToken()
+ {
+ return self::generateGUID();
+ }
+
+ /**
+ * 获取唯一标识符串,标识符串的长度为16个字节,128位.
+ * 根据当前时间与sessionID,混合生成一个唯一的串.
+ *
+ * @return string GUID串,16个字节
+ */
+ public static function generateGUID()
+ {
+ return substr(md5(WindUtility::generateRandStr(8).microtime()), -16);
+ }
+
+ /**
+ * 路径检查转义
+ *
+ * @param string $fileName 被检查的路径
+ * @param bool $ifCheck 是否需要检查文件名,默认为false
+ * @return string
+ */
+ public static function escapePath($filePath, $ifCheck = false)
+ {
+ $_tmp = array("'" => '', '#' => '', '=' => '', '`' => '', '$' => '', '%' => '', '&' => '', ';' => '');
+ $_tmp['://'] = $_tmp["\0"] = '';
+ $ifCheck && $_tmp['..'] = '';
+ if (strtr($filePath, $_tmp) == $filePath) {
+ return preg_replace('/[\/\\\]{1,}/i', '/', $filePath);
+ }
+ throw new WindException('[utility.WindSecurity.escapePath] file path is illegal');
+ }
+}
diff --git a/wind/utility/WindString.php b/wind/utility/WindString.php
index dfebef0d..25a78d2a 100644
--- a/wind/utility/WindString.php
+++ b/wind/utility/WindString.php
@@ -5,237 +5,276 @@
* @author Qian Su
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindString.php 3760 2012-10-11 08:02:25Z yishuo $
* @package utility
*/
-class WindString {
-
- const UTF8 = 'utf-8';
-
- const GBK = 'gbk';
-
- /**
- * 截取字符串,支持字符编码,默认为utf-8
- *
- * @param string $string 要截取的字符串编码
- * @param int $start 开始截取
- * @param int $length 截取的长度
- * @param string $charset 原妈编码,默认为UTF8
- * @param boolean $dot 是否显示省略号,默认为false
- * @return string 截取后的字串
- */
- public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false) {
- switch (strtolower($charset)) {
- case self::GBK:
- $string = self::substrForGbk($string, $start, $length, $dot);
- break;
- default:
- $string = self::substrForUtf8($string, $start, $length, $dot);
- break;
- }
- return $string;
- }
-
- /**
- * 求取字符串长度
- *
- * @param string $string 要计算的字符串编码
- * @param string $charset 原始编码,默认为UTF8
- * @return int
- */
- public static function strlen($string, $charset = self::UTF8) {
- $len = strlen($string);
- $i = $count = 0;
- $charset = strtolower(substr($charset, 0, 3));
- while ($i < $len) {
- if (ord($string[$i]) <= 129)
- $i++;
- else
- switch ($charset) {
- case 'utf':
- $i += 3;
- break;
- default:
- $i += 2;
- break;
- }
- $count++;
- }
- return $count;
- }
-
- /**
- * 将变量的值转换为字符串
- *
- * @param mixed $input 变量
- * @param string $indent 缩进,默认为''
- * @return string
- */
- public static function varToString($input, $indent = '') {
- switch (gettype($input)) {
- case 'string':
- return "'" . str_replace(array("\\", "'"), array("\\\\", "\\'"), $input) . "'";
- case 'array':
- $output = "array(\r\n";
- foreach ($input as $key => $value) {
- $output .= $indent . "\t" . self::varToString($key, $indent . "\t") . ' => ' . self::varToString(
- $value, $indent . "\t");
- $output .= ",\r\n";
- }
- $output .= $indent . ')';
- return $output;
- case 'boolean':
- return $input ? 'true' : 'false';
- case 'NULL':
- return 'NULL';
- case 'integer':
- case 'double':
- case 'float':
- return "'" . (string) $input . "'";
- }
- return 'NULL';
- }
-
- /**
- * 将数据用json加密
- *
- * @param mixed $value 需要加密的数据
- * @param string $charset 字符编码
- * @return string 加密后的数据
- */
- public static function jsonEncode($value, $charset = self::UTF8) {
- Wind::import('Wind:utility.WindJson');
- return WindJson::encode($value, $charset);
- }
-
- /**
- * 将json格式数据解密
- *
- * @param string $value 待解密的数据
- * @param string $charset 解密后字符串编码
- * @return mixed 解密后的数据
- */
- public static function jsonDecode($value, $charset = self::UTF8) {
- Wind::import('Wind:utility.WindJson');
- return WindJson::decode($value, true, $charset);
- }
-
- /**
- * 以utf8格式截取的字符串编码
- *
- * @param string $string 要截取的字符串编码
- * @param int $start 开始截取
- * @param int $length 截取的长度,默认为null,取字符串的全长
- * @param boolean $dot 是否显示省略号,默认为false
- * @return string
- */
- public static function substrForUtf8($string, $start, $length = null, $dot = false) {
- if (empty($string)) return '';
- $strlen = strlen($string);
- $length = $length ? (int) $length : $strlen;
- $substr = '';
- $chinese = $word = 0;
- for ($i = 0, $j = 0; $i < (int) $start; $i++) {
- if (0xa0 < ord(substr($string, $j, 1))) {
- $chinese++;
- $j += 2;
- } else {
- $word++;
- }
- $j++;
- }
- $start = $word + 3 * $chinese;
- for ($i = $start, $j = $start; $i < $start + $length; $i++) {
- if (0xa0 < ord(substr($string, $j, 1))) {
- $substr .= substr($string, $j, 3);
- $j += 2;
- } else {
- $substr .= substr($string, $j, 1);
- }
- $j++;
- }
- (strlen($substr) < $strlen) && $dot && $substr .= "...";
- return $substr;
- }
-
- /**
- * 以gbk格式截取的字符串编码
- *
- * @param string $string 要截取的字符串编码
- * @param int $start 开始截取
- * @param int $length 截取的长度,默认为null,取字符串的全长
- * @param boolean $dot 是否显示省略号,默认为false
- * @return string
- */
- public static function substrForGbk($string, $start, $length = null, $dot = false) {
- if (empty($string) || !is_int($start) || ($length && !is_int($length))) {
- return '';
- }
- $strlen = strlen($string);
- $length = $length ? $length : $strlen;
- $substr = '';
- $chinese = $word = 0;
- for ($i = 0, $j = 0; $i < $start; $i++) {
- if (0xa0 < ord(substr($string, $j, 1))) {
- $chinese++;
- $j++;
- } else {
- $word++;
- }
- $j++;
- }
- $start = $word + 2 * $chinese;
- for ($i = $start, $j = $start; $i < $start + $length; $i++) {
- if (0xa0 < ord(substr($string, $j, 1))) {
- $substr .= substr($string, $j, 2);
- $j++;
- } else {
- $substr .= substr($string, $j, 1);
- }
- $j++;
- }
- (strlen($substr) < $strlen) && $dot && $substr .= "...";
- return $substr;
- }
-
- /**
- * 以utf8求取字符串长度
- *
- * @param string $str 要计算的字符串编码
- * @return int
- */
- public static function strlenForUtf8($str) {
- $i = $count = 0;
- $len = strlen($str);
- while ($i < $len) {
- $chr = ord($str[$i]);
- $count++;
- $i++;
- if ($i >= $len) break;
- if ($chr & 0x80) {
- $chr <<= 1;
- while ($chr & 0x80) {
- $i++;
- $chr <<= 1;
- }
- }
- }
- return $count;
- }
-
- /**
- * 以gbk求取字符串长度
- *
- * @param string $str 要计算的字符串编码
- * @return int
- */
- public static function strlenForGbk($string) {
- $len = strlen($string);
- $i = $count = 0;
- while ($i < $len) {
- ord($string[$i]) > 129 ? $i += 2 : $i++;
- $count++;
- }
- return $count;
- }
-}
\ No newline at end of file
+class WindString
+{
+ const UTF8 = 'utf-8';
+ const GBK = 'gbk';
+
+ /**
+ * 截取字符串,支持字符编码,默认为utf-8
+ *
+ * @param string $string 要截取的字符串编码
+ * @param int $start 开始截取
+ * @param int $length 截取的长度
+ * @param string $charset 原妈编码,默认为UTF8
+ * @param bool $dot 是否显示省略号,默认为false
+ * @return string 截取后的字串
+ */
+ public static function substr($string, $start, $length, $charset = self::UTF8, $dot = false)
+ {
+ switch (strtolower($charset)) {
+ case self::GBK:
+ $string = self::substrForGbk($string, $start, $length, $dot);
+ break;
+ case self::UTF8:
+ $string = self::substrForUtf8($string, $start, $length, $dot);
+ break;
+ default:
+ $string = substr($string, $start, $length);
+ }
+
+ return $string;
+ }
+
+ /**
+ * 求取字符串长度
+ *
+ * @param string $string 要计算的字符串编码
+ * @param string $charset 原始编码,默认为UTF8
+ * @return int
+ */
+ public static function strlen($string, $charset = self::UTF8)
+ {
+ switch (strtolower($charset)) {
+ case self::GBK:
+ $count = self::strlenForGbk($string);
+ break;
+ case self::UTF8:
+ $count = self::strlenForUtf8($string);
+ break;
+ default:
+ $count = strlen($string);
+ }
+
+ return $count;
+ }
+
+ /**
+ * 将变量的值转换为字符串
+ *
+ * @param mixed $input 变量
+ * @param string $indent 缩进,默认为''
+ * @return string
+ */
+ public static function varToString($input, $indent = '')
+ {
+ switch (gettype($input)) {
+ case 'string':
+ return "'".str_replace(array('\\', "'"), array('\\\\', "\\'"), $input)."'";
+ case 'array':
+ $output = "array(\r\n";
+ foreach ($input as $key => $value) {
+ $output .= $indent."\t".self::varToString($key, $indent."\t").' => '.self::varToString(
+ $value, $indent."\t");
+ $output .= ",\r\n";
+ }
+ $output .= $indent.')';
+
+ return $output;
+ case 'boolean':
+ return $input ? 'true' : 'false';
+ case 'NULL':
+ return 'NULL';
+ case 'integer':
+ case 'double':
+ case 'float':
+ return "'".(string) $input."'";
+ }
+
+ return 'NULL';
+ }
+
+ /**
+ * 将数据用json加密
+ *
+ * @param mixed $value 需要加密的数据
+ * @param string $charset 字符编码
+ * @return string 加密后的数据
+ */
+ public static function jsonEncode($value, $charset = self::UTF8)
+ {
+ return WindJson::encode($value, $charset);
+ }
+
+ /**
+ * 将json格式数据解密
+ *
+ * @param string $value 待解密的数据
+ * @param string $charset 解密后字符串编码
+ * @return mixed 解密后的数据
+ */
+ public static function jsonDecode($value, $charset = self::UTF8)
+ {
+ return WindJson::decode($value, true, $charset);
+ }
+
+ /**
+ * 以utf8格式截取的字符串编码
+ *
+ * @param string $string 要截取的字符串编码
+ * @param int $start 开始截取
+ * @param int $length 截取的长度,默认为null,取字符串的全长
+ * @param bool $dot 是否显示省略号,默认为false
+ * @return string
+ */
+ public static function substrForUtf8($string, $start, $length = null, $dot = false)
+ {
+ $l = strlen($string);
+ $p = $s = 0;
+ if (0 !== $start) {
+ while ($start-- && $p < $l) {
+ $c = $string[$p];
+ if ($c < "\xC0") {
+ $p++;
+ } elseif ($c < "\xE0") {
+ $p += 2;
+ } elseif ($c < "\xF0") {
+ $p += 3;
+ } elseif ($c < "\xF8") {
+ $p += 4;
+ } elseif ($c < "\xFC") {
+ $p += 5;
+ } else {
+ $p += 6;
+ }
+ }
+ $s = $p;
+ }
+
+ if (empty($length)) {
+ $t = substr($string, $s);
+ } else {
+ $i = $length;
+ while ($i-- && $p < $l) {
+ $c = $string[$p];
+ if ($c < "\xC0") {
+ $p++;
+ } elseif ($c < "\xE0") {
+ $p += 2;
+ } elseif ($c < "\xF0") {
+ $p += 3;
+ } elseif ($c < "\xF8") {
+ $p += 4;
+ } elseif ($c < "\xFC") {
+ $p += 5;
+ } else {
+ $p += 6;
+ }
+ }
+ $t = substr($string, $s, $p - $s);
+ }
+
+ $dot && ($p < $l) && $t .= '...';
+
+ return $t;
+ }
+
+ /**
+ * 以gbk格式截取的字符串编码
+ *
+ * @param string $string 要截取的字符串编码
+ * @param int $start 开始截取
+ * @param int $length 截取的长度,默认为null,取字符串的全长
+ * @param bool $dot 是否显示省略号,默认为false
+ * @return string
+ */
+ public static function substrForGbk($string, $start, $length = null, $dot = false)
+ {
+ $l = strlen($string);
+ $p = $s = 0;
+ if (0 !== $start) {
+ while ($start-- && $p < $l) {
+ if ($string[$p] > "\x80") {
+ $p += 2;
+ } else {
+ $p++;
+ }
+ }
+ $s = $p;
+ }
+
+ if (empty($length)) {
+ $t = substr($string, $s);
+ } else {
+ $i = $length;
+ while ($i-- && $p < $l) {
+ if ($string[$p] > "\x80") {
+ $p += 2;
+ } else {
+ $p++;
+ }
+ }
+ $t = substr($string, $s, $p - $s);
+ }
+
+ $dot && ($p < $l) && $t .= '...';
+
+ return $t;
+ }
+
+ /**
+ * 以utf8求取字符串长度
+ *
+ * @param string $string 要计算的字符串编码
+ * @return int
+ */
+ public static function strlenForUtf8($string)
+ {
+ $l = strlen($string);
+ $p = $c = 0;
+ while ($p < $l) {
+ $a = $string[$p];
+ if ($a < "\xC0") {
+ $p++;
+ } elseif ($a < "\xE0") {
+ $p += 2;
+ } elseif ($a < "\xF0") {
+ $p += 3;
+ } elseif ($a < "\xF8") {
+ $p += 4;
+ } elseif ($a < "\xFC") {
+ $p += 5;
+ } else {
+ $p += 6;
+ }
+ $c++;
+ }
+
+ return $c;
+ }
+
+ /**
+ * 以gbk求取字符串长度
+ *
+ * @param string $string 要计算的字符串编码
+ * @return int
+ */
+ public static function strlenForGbk($string)
+ {
+ $l = strlen($string);
+ $p = $c = 0;
+ while ($p < $l) {
+ if ($string[$p] > "\x80") {
+ $p += 2;
+ } else {
+ $p++;
+ }
+ $c++;
+ }
+
+ return $c;
+ }
+}
diff --git a/wind/utility/WindUrlHelper.php b/wind/utility/WindUrlHelper.php
new file mode 100644
index 00000000..7a54bdbd
--- /dev/null
+++ b/wind/utility/WindUrlHelper.php
@@ -0,0 +1,154 @@
+
+ * @copyright ©2003-2103 phpwind.com
+ * @license http://www.windframework.com
+ * @version $Id: WindUrlHelper.php 3928 2013-01-29 10:21:53Z yishuo $
+ * @package web
+ */
+class WindUrlHelper
+{
+ /**
+ * url检查
+ *
+ * 当$absolute === true且url不包含协议部分时,默认加上当前应用的协议部分.
+ * @param string $url 需要检查合法性的url
+ * @param bool $absolute 是否为绝对路径
+ * @return string
+ */
+ public static function checkUrl($url, $absolute = true)
+ {
+ if ($absolute) {
+ $_baseUrl = $absolute === true ? Wind::getComponent('request')->getBaseUrl(true) : $absolute;
+ if (strpos($url, '://') === false) {
+ $url = trim($_baseUrl, '/').'/'.trim($url, '/');
+ }
+ }
+
+ return $url;
+ }
+
+ /**
+ * url字符串转化为数组格式
+ *
+ * 效果同'argsToUrl'相反
+ * @param string $url
+ * @param bool $decode 是否需要进行url反编码处理
+ * @param string $separator url的分隔符
+ * @return array
+ */
+ public static function urlToArgs($url, $decode = true, $separator = '&=')
+ {
+ if (strlen($separator) !== 2) {
+ return array();
+ }
+ if (false !== $pos = strpos($url, '?')) {
+ $url = substr($url, $pos + 1);
+ }
+ $url = explode($separator[0], trim($url, $separator[0]));
+ $args = array();
+ if ($separator[0] === $separator[1]) {
+ $_count = count($url);
+ for ($i = 0; $i < $_count; $i += 2) {
+ if (!isset($url[$i + 1])) {
+ $args[] = $decode ? rawurldecode($url[$i]) : $url[$i];
+ continue;
+ }
+ $_k = $decode ? rawurldecode($url[$i]) : $url[$i];
+ $_v = $decode ? rawurldecode($url[$i + 1]) : $url[$i + 1];
+ $args[$_k] = $_v;
+ }
+ } else {
+ foreach ($url as $value) {
+ if (strpos($value, $separator[1]) === false) {
+ $args[] = $decode ? rawurldecode($value) : $value;
+ continue;
+ }
+ list($__k, $__v) = explode($separator[1], $value);
+ $args[$__k] = $decode && $__v ? rawurldecode($__v) : $__v;
+ }
+ }
+
+ return $args;
+ }
+
+ /**
+ * 将数组格式的参数列表转换为Url格式,并将url进行编码处理
+ *
+ * 参数:array('b'=>'b','c'=>'index','d'=>'d')
+ * 分割符: '&='
+ * 转化结果:&b=b&c=index&d=d
+ * 如果分割符为: '/' 则转化结果为: /b/b/c/index/d/d/
+ * @param array $args
+ * @param bool $encode 是否进行url编码 默认值为true
+ * @param string $separator url分隔符 支持双字符,前一个字符用于分割参数对,后一个字符用于分割键值对
+ * @return string
+ */
+ public static function argsToUrl($args, $encode = true, $separator = '&=', $key = null)
+ {
+ if (strlen($separator) !== 2) {
+ return;
+ }
+ $_tmp = '';
+ foreach ((array) $args as $_k => $_v) {
+ if ($key !== null) {
+ $_k = $key.'['.$_k.']';
+ }
+ if (is_array($_v)) {
+ $_tmp .= self::argsToUrl($_v, $encode, $separator, $_k).$separator[0];
+ continue;
+ }
+ $_v = $encode ? rawurlencode($_v) : $_v;
+ if (is_int($_k)) {
+ $_v && $_tmp .= $_v.$separator[0];
+ continue;
+ }
+ $_k = ($encode ? rawurlencode($_k) : $_k);
+ $_tmp .= $_k.$separator[1].$_v.$separator[0];
+ }
+
+ return trim($_tmp, $separator[0]);
+ }
+
+ /**
+ * 解析ControllerPath,并返回解析后的结果集
+ *
+ * 返回值:array(action,controller,module,args)
+ * action格式:'/module/controller/action/?a=a&b=b&c=c&',前边用斜线分割mca信息,后边用问号分割参数列表.
+ * @param string $controllerPath
+ * @param array $args 默认值为空数组
+ * @return array
+ */
+ public static function resolveAction($action, $args = array())
+ {
+ list($action, $_args) = explode('?', $action.'?');
+ $args = array_merge($args, ($_args ? self::urlToArgs($_args, false) : array()));
+ $action = explode('/', trim($action, '/').'/');
+ end($action);
+
+ return array(prev($action), prev($action), prev($action), $args);
+ }
+
+ /**
+ * 构造并返回Url地址
+ *
+ * 将根据是否开启url重写来分别构造相对应的url
+ * @param string $action 执行的操作
+ * @param array $args 附带的参数
+ * @param string $anchor url锚点
+ * @param AbstractWindRoute $route
+ * @param bool $absolute 是否返回绝对地址
+ * @return string 返回url地址
+ */
+ public static function createUrl($action, $args = array(), $anchor = '', $route = null, $absolute = true)
+ {
+ /* @var $router AbstractWindRouter */
+ $router = Wind::getComponent('router');
+ $url = $router->assemble($action, $args, $route);
+ $url .= $anchor ? '#'.$anchor : '';
+
+ return self::checkUrl($url, $absolute);
+ }
+}
diff --git a/wind/utility/WindUtility.php b/wind/utility/WindUtility.php
index 54f311ef..1f8d0f09 100644
--- a/wind/utility/WindUtility.php
+++ b/wind/utility/WindUtility.php
@@ -1,245 +1,209 @@
-
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindUtility.php 3859 2012-12-18 09:25:51Z yishuo $
* @package utility
- */
-class WindUtility {
-
- /**
- * 解析表达式
- *
- * 表达式格式: namespace:arg1.arg2.arg3.arg4.arg5==value
- * 返回: array($namespace, $param1, $operator, $param1)
- *
- * @param string $expression 待解析的表达式
- * @return array 返回解析后的表达式,由表达式的各项组成的数组:
- *
- * - 第一个元素: 命名空间
- * - 第二个元素: 表达式的左边操作数
- * - 第三个元素: 表达式的操作符
- * - 第四个元素: 表达式的右边操作数
- *
- */
- public static function resolveExpression($expression) {
- $operators = array('==', '!=', '<', '>', '<=', '>=');
- $operatorsReplace = array('#==#', '#!=#', '#<#', '#>#', '#<=#', '#>=#');
- list($p, $o, $v2) = explode('#', str_replace($operators, $operatorsReplace, $expression));
- if (strpos($p, ":") !== false)
- list($_namespace, $p) = explode(':', trim($p, ':'));
- else
- $_namespace = '';
- return array($_namespace, $p, $o, $v2);
- }
-
- /**
- * 执行简单的条件表达式
- *
- * 只能执行==、!=、<、>、<=、>=简单的比较
- *
- * @param string $v1 左边的操作数
- * @param string $v2 右边的操作数
- * @param string $operator 操作符号
- * @return boolean
- */
- public static function evalExpression($v1, $v2, $operator) {
- switch ($operator) {
- case '==':
- return $v1 == $v2;
- case '!=':
- return $v1 != $v2;
- case '<':
- return $v1 < $v2;
- case '>':
- return $v1 > $v2;
- case '<=':
- return $v1 <= $v2;
- case '>=':
- return $v1 >= $v2;
- default:
- return false;
- }
- return false;
- }
-
- /**
- * 递归合并两个数组
- *
- * @param array $array1 数组1
- * @param array $array2 数组2
- * @return array 合并后的数组
- */
- public static function mergeArray($array1, $array2) {
- foreach ($array2 as $key => $value) {
- if (empty($value)) {
- $array1[$key] = $value;
- } else if (!isset($array1[$key])) {
- $array1[$key] = $value;
- } elseif (is_array($array1[$key]) && is_array($value)) {
- $array1[$key] = self::mergeArray($array1[$key], $array2[$key]);
- } elseif (is_numeric($key) && $array1[$key] !== $array2[$key]) {
- $array1[] = $value;
- } else
- $array1[$key] = $value;
- }
- return $array1;
- }
-
- /**
- * 将字符串首字母小写
- *
- * @param string $str 待处理的字符串
- * @return string 返回处理后的字符串
- */
- public static function lcfirst($str) {
- $str[0] = strtolower($str[0]);
- return $str;
- }
-
- /**
- * 获得随机数字符串
- *
- * @param int $length 随机数的长度
- * @return string 随机获得的字串
- */
- public static function generateRandStr($length) {
- $randstr = "";
- for ($i = 0; $i < (int) $length; $i++) {
- $randnum = mt_rand(0, 61);
- if ($randnum < 10) {
- $randstr .= chr($randnum + 48);
- } else if ($randnum < 36) {
- $randstr .= chr($randnum + 55);
- } else {
- $randstr .= chr($randnum + 61);
- }
- }
- return $randstr;
- }
-
- /**
- * 通用组装测试验证规则
- *
- * @param string $field 验证字段名称
- * @param string $validator 验证方法
- * @param array $args 验证方法中传递的其他参数,需在待验证字段值的后面,默认为空数组
- * @param string $default 验证失败是设置的默认值,默认为null
- * @param string $message 验证失败是返回的错误信息,默认为空字串
- * @return array 返回验证规则
- *
- * - field: 验证字段名称
- * - validator: 验证方法
- * - args: 验证方法中传递的其他参数,需在待验证字段值的后面,缺省为空数组
- * - default: 验证失败是设置的默认值,缺省为null
- * - message: 验证失败是返回的错误信息,默认为'提示:XX验证失败'
- *
- */
- public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '') {
- return array(
- 'field' => $field,
- 'validator' => $validator,
- 'args' => (array) $args,
- 'default' => $default,
- 'message' => ($message ? $message : '提示:\'' . $field . '\'验证失败'));
- }
-
- /**
- * 对字符串中的参数进行替换
- *
- * 该函优化了php strtr()实现, 在进行数组方式的字符替换时支持了两种模式的字符替换:
- * @example
- * 1. echo WindUtility::strtr("I Love {you}",array('{you}' => 'lili'));
- * 结果: I Love lili
- * 2. echo WindUtility::strtr("I Love #0,#1",array('lili','qiong'));
- * 结果: I Love lili,qiong
- *
- * @see WindLangResource::getMessage()
- * @param string $str
- * @param string $from
- * @param string $to 可选参数,默认值为''
- * @return string
- */
- public static function strtr($str, $from, $to = '') {
- if (is_string($from)) return strtr($str, $from, $to);
- if (isset($from[0])) {
- foreach ($from as $key => $value) {
- $from['#' . $key] = $value;
- unset($from[$key]);
- }
- }
- return !empty($from) ? strtr($str, $from) : $str;
- }
-
- /**
- * 错误信息处理方法
- *
- * @param string $file
- * @param string $line
- * @param array $trace
- */
- public static function crash($file, $line, $trace) {
- $msg = '';
- $count = count($trace);
- $padLen = strlen($count);
- foreach ($trace as $key => $call) {
- if (!isset($call['file']) || $call['file'] == '') {
- $call['file'] = '~Internal Location~';
- $call['line'] = 'N/A';
- }
- $traceLine = '#' . str_pad(($count - $key), $padLen, "0", STR_PAD_LEFT) . ' ' . self::getCallLine(
- $call);
- $trace[$key] = $traceLine;
- }
- $fileLines = array();
- if (is_file($file)) {
- $currentLine = $line - 1;
- $fileLines = explode("\n", file_get_contents($file, null, null, 0, 10000000));
- $topLine = $currentLine - 5;
- $fileLines = array_slice($fileLines, $topLine > 0 ? $topLine : 0, 10, true);
- if (($count = count($fileLines)) > 0) {
- $padLen = strlen($count);
- foreach ($fileLines as $line => &$fileLine)
- $fileLine = " " . htmlspecialchars(
- str_pad($line + 1, $padLen, "0", STR_PAD_LEFT) . ": " . str_replace("\t",
- " ", rtrim($fileLine)), null, "UTF-8");
- }
- }
- return array($fileLines, $trace);
- }
-
- /**
- * @param array $call
- * @return string
- */
- private static function getCallLine($call) {
- $call_signature = "";
- if (isset($call['file'])) $call_signature .= $call['file'] . " ";
- if (isset($call['line'])) $call_signature .= "(" . $call['line'] . ") ";
- if (isset($call['function'])) {
- $call_signature .= $call['function'] . "(";
- if (isset($call['args'])) {
- foreach ($call['args'] as $arg) {
- if (is_string($arg))
- $arg = '"' . (strlen($arg) <= 64 ? $arg : substr($arg, 0, 64) . "…") . '"';
- else if (is_object($arg))
- $arg = "[Instance of '" . get_class($arg) . "']";
- else if ($arg === true)
- $arg = "true";
- else if ($arg === false)
- $arg = "false";
- else if ($arg === null)
- $arg = "null";
- else
- $arg = strval($arg);
- $call_signature .= $arg . ',';
- }
- }
- $call_signature = trim($call_signature, ',') . ")";
- }
- return $call_signature;
- }
-}
\ No newline at end of file
+ */
+class WindUtility
+{
+ /**
+ * 解析表达式
+ *
+ * 表达式格式: namespace:arg1.arg2.arg3.arg4.arg5==value
+ * 返回: array($namespace, $param1, $operator, $param1)
+ *
+ * @param string $expression
+ * 待解析的表达式
+ * @return array 返回解析后的表达式,由表达式的各项组成的数组:
+ *
+ * - 第一个元素: 命名空间
+ * - 第二个元素: 表达式的左边操作数
+ * - 第三个元素: 表达式的操作符
+ * - 第四个元素: 表达式的右边操作数
+ *
+ */
+ public static function resolveExpression($expression)
+ {
+ $operators = array('==', '!=', '<', '>', '<=', '>=');
+ $operatorsReplace = array('#==#', '#!=#', '#<#', '#>#', '#<=#', '#>=#');
+ list($p, $o, $v2) = explode('#', str_replace($operators, $operatorsReplace, $expression));
+ if (strpos($p, ':') !== false) {
+ list($_namespace, $p) = explode(':', trim($p, ':'));
+ } else {
+ $_namespace = '';
+ }
+
+ return array($_namespace, $p, $o, $v2);
+ }
+
+ /**
+ * 执行简单的条件表达式
+ *
+ * 只能执行==、!=、<、>、<=、>=简单的比较
+ *
+ * @param string $v1
+ * 左边的操作数
+ * @param string $v2
+ * 右边的操作数
+ * @param string $operator
+ * 操作符号
+ * @return bool
+ */
+ public static function evalExpression($v1, $v2, $operator)
+ {
+ switch ($operator) {
+ case '==':
+ return $v1 == $v2;
+ case '!=':
+ return $v1 != $v2;
+ case '<':
+ return $v1 < $v2;
+ case '>':
+ return $v1 > $v2;
+ case '<=':
+ return $v1 <= $v2;
+ case '>=':
+ return $v1 >= $v2;
+ default:
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * 递归合并两个数组
+ *
+ * @param array $array1
+ * 数组1
+ * @param array $array2
+ * 数组2
+ * @return array 合并后的数组
+ */
+ public static function mergeArray($array1, $array2)
+ {
+ foreach ($array2 as $key => $value) {
+ if (!isset($array1[$key])) {
+ $array1[$key] = $value;
+ } elseif (is_array($array1[$key]) && is_array($value)) {
+ $array1[$key] = self::mergeArray($array1[$key], $array2[$key]);
+ } elseif (is_numeric($key) && $array1[$key] !== $array2[$key]) {
+ $array1[] = $value;
+ } else {
+ $array1[$key] = $value;
+ }
+ }
+
+ return $array1;
+ }
+
+ /**
+ * 将字符串首字母小写
+ *
+ * @param string $str
+ * 待处理的字符串
+ * @return string 返回处理后的字符串
+ */
+ public static function lcfirst($str)
+ {
+ $str[0] = strtolower($str[0]);
+
+ return $str;
+ }
+
+ /**
+ * 获得随机数字符串
+ *
+ * @param int $length
+ * 随机数的长度
+ * @return string 随机获得的字串
+ */
+ public static function generateRandStr($length)
+ {
+ $mt_string = 'AzBy0CxDwEv1FuGtHs2IrJqK3pLoM4nNmOlP5kQjRi6ShTgU7fVeW8dXcY9bZa';
+ $randstr = '';
+ for ($i = 0; $i < $length; $i++) {
+ $randstr .= $mt_string[mt_rand(0, 61)];
+ }
+
+ return $randstr;
+ }
+
+ /**
+ * 通用组装测试验证规则
+ *
+ * @param string $field
+ * 验证字段名称
+ * @param string $validator
+ * 验证方法
+ * @param array $args
+ * 验证方法中传递的其他参数,需在待验证字段值的后面,默认为空数组
+ * @param string $default
+ * 验证失败是设置的默认值,默认为null
+ * @param string $message
+ * 验证失败是返回的错误信息,默认为空字串
+ * @return array 返回验证规则
+ *
+ * - field: 验证字段名称
+ * - validator: 验证方法
+ * - args: 验证方法中传递的其他参数,需在待验证字段值的后面,缺省为空数组
+ * - default: 验证失败是设置的默认值,缺省为null
+ * - message: 验证失败是返回的错误信息,默认为'提示:XX验证失败'
+ *
+ */
+ public static function buildValidateRule($field, $validator, $args = array(), $default = null, $message = '')
+ {
+ return array(
+ 'field' => $field,
+ 'validator' => $validator,
+ 'args' => (array) $args,
+ 'default' => $default,
+ 'message' => ($message ? $message : '提示:\''.$field.'\'验证失败'), );
+ }
+
+ /**
+ * 对字符串中的参数进行替换
+ *
+ * 该函优化了php strtr()实现, 在进行数组方式的字符替换时支持了两种模式的字符替换:
+ *
+ * @example
+ * 1. echo WindUtility::strtr("I Love {you}",array('{you}' =>
+ * 'lili'));
+ * 结果: I Love lili
+ * 2. echo WindUtility::strtr("I Love
+ * #0,#1",array('lili','qiong'));
+ * 结果: I Love lili,qiong
+ *
+ * @see WindLangResource::getMessage()
+ * @param string $str
+ * @param string $from
+ * @param string $to
+ * 可选参数,默认值为''
+ * @return string
+ */
+ public static function strtr($str, $from, $to = '')
+ {
+ if (is_string($from)) {
+ return strtr($str, $from, $to);
+ }
+ if (isset($from[0])) {
+ foreach ($from as $key => $value) {
+ $from['#'.$key] = $value;
+ unset($from[$key]);
+ }
+ }
+
+ return !empty($from) ? strtr($str, $from) : $str;
+ }
+
+ public static function dump(/* $a, $b, ... */)
+ {
+ foreach (func_get_args() as $var) {
+ error_log(var_export($var, true));
+ }
+ }
+}
diff --git a/wind/utility/WindValidator.php b/wind/utility/WindValidator.php
index f478be60..936890ca 100644
--- a/wind/utility/WindValidator.php
+++ b/wind/utility/WindValidator.php
@@ -5,204 +5,221 @@
* @author Qian Su
* @copyright ©2003-2103 phpwind.com
* @license http://www.windframework.com
- * @version $Id$
+ * @version $Id: WindValidator.php 2973 2011-10-15 19:22:48Z yishuo $
* @package utility
*/
-class WindValidator {
+class WindValidator
+{
+ /**
+ * 验证是否是电话号码
+ *
+ * 国际区号-地区号-电话号码的格式(在国际区号前可以有前导0和前导+号),
+ * 国际区号支持0-4位
+ * 地区号支持0-6位
+ * 电话号码支持4到12位
+ *
+ * @param string $phone 被验证的电话号码
+ * @return bool 如果验证通过则返回true,否则返回false
+ */
+ public static function isTelPhone($phone)
+ {
+ return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone);
+ }
- /**
- * 验证是否是电话号码
- *
- * 国际区号-地区号-电话号码的格式(在国际区号前可以有前导0和前导+号),
- * 国际区号支持0-4位
- * 地区号支持0-6位
- * 电话号码支持4到12位
- *
- * @param string $phone 被验证的电话号码
- * @return boolean 如果验证通过则返回true,否则返回false
- */
- public static function isTelPhone($phone) {
- return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{0,6}[\-\s]?\d{4,12}$/', $phone);
- }
+ /**
+ * 验证是否是手机号码
+ *
+ * 国际区号-手机号码
+ *
+ * @param string $number 待验证的号码
+ * @return bool 如果验证失败返回false,验证成功返回true
+ */
+ public static function isTelNumber($number)
+ {
+ return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number);
+ }
- /**
- * 验证是否是手机号码
- *
- * 国际区号-手机号码
- *
- * @param string $number 待验证的号码
- * @return boolean 如果验证失败返回false,验证成功返回true
- */
- public static function isTelNumber($number) {
- return 0 < preg_match('/^\+?[0\s]*[\d]{0,4}[\-\s]?\d{4,12}$/', $number);
- }
+ /**
+ * 验证是否是QQ号码
+ *
+ * QQ号码必须是以1-9的数字开头,并且长度5-15为的数字串
+ *
+ * @param string $qq 待验证的qq号码
+ * @return bool 如果验证成功返回true,否则返回false
+ */
+ public static function isQQ($qq)
+ {
+ return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq);
+ }
- /**
- * 验证是否是QQ号码
- *
- * QQ号码必须是以1-9的数字开头,并且长度5-15为的数字串
- *
- * @param string $qq 待验证的qq号码
- * @return boolean 如果验证成功返回true,否则返回false
- */
- public static function isQQ($qq) {
- return 0 < preg_match('/^[1-9]\d{4,14}$/', $qq);
- }
+ /**
+ * 验证是否是邮政编码
+ *
+ * 邮政编码是4-8个长度的数字串
+ *
+ * @param string $zipcode 待验证的邮编
+ * @return bool 如果验证成功返回true,否则返回false
+ */
+ public static function isZipcode($zipcode)
+ {
+ return 0 < preg_match('/^\d{4,8}$/', $zipcode);
+ }
- /**
- * 验证是否是邮政编码
- *
- * 邮政编码是4-8个长度的数字串
- *
- * @param string $zipcode 待验证的邮编
- * @return boolean 如果验证成功返回true,否则返回false
- */
- public static function isZipcode($zipcode) {
- return 0 < preg_match('/^\d{4,8}$/', $zipcode);
- }
+ /**
+ * 验证是否是有合法的email
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasEmail($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string);
+ }
- /**
- * 验证是否是有合法的email
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasEmail($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp("/\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/", $string);
- }
+ /**
+ * 验证是否是合法的email
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是email则返回true,否则返回false
+ */
+ public static function isEmail($string)
+ {
+ return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string);
+ }
- /**
- * 验证是否是合法的email
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是email则返回true,否则返回false
- */
- public static function isEmail($string) {
- return 0 < preg_match("/^\w+(?:[-+.']\w+)*@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*$/", $string);
- }
+ /**
+ * 验证是否有合法的身份证号
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasIdCard($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll);
+ }
- /**
- * 验证是否有合法的身份证号
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasIdCard($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp("/\d{17}[\d|X]|\d{15}/", $string, $matches, $ifAll);
- }
+ /**
+ * 验证是否是合法的身份证号
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是合法的身份证号则返回true,否则返回false
+ */
+ public static function isIdCard($string)
+ {
+ return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string);
+ }
- /**
- * 验证是否是合法的身份证号
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是合法的身份证号则返回true,否则返回false
- */
- public static function isIdCard($string) {
- return 0 < preg_match("/^(?:\d{17}[\d|X]|\d{15})$/", $string);
- }
+ /**
+ * 验证是否有合法的URL
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasUrl($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll);
+ }
- /**
- * 验证是否有合法的URL
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasUrl($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp('/http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/', $string, $matches, $ifAll);
- }
+ /**
+ * 验证是否是合法的url
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是合法的url则返回true,否则返回false
+ */
+ public static function isUrl($string)
+ {
+ return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string);
+ }
- /**
- * 验证是否是合法的url
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是合法的url则返回true,否则返回false
- */
- public static function isUrl($string) {
- return 0 < preg_match('/^(?:http(?:s)?:\/\/(?:[\w-]+\.)+[\w-]+(?:\:\d+)*+(?:\/[\w- .\/?%&=]*)?)$/', $string);
- }
+ /**
+ * 验证是否有中文
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasChinese($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll);
+ }
- /**
- * 验证是否有中文
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasChinese($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp('/[\x{4e00}-\x{9fa5}]+/u', $string, $matches, $ifAll);
- }
+ /**
+ * 验证是否是中文
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是中文则返回true,否则返回false
+ */
+ public static function isChinese($string)
+ {
+ return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string);
+ }
- /**
- * 验证是否是中文
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是中文则返回true,否则返回false
- */
- public static function isChinese($string) {
- return 0 < preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $string);
- }
+ /**
+ * 验证是否有html标记
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasHtml($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll);
+ }
- /**
- * 验证是否有html标记
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasHtml($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp('/<(.*)>.*|<(.*)\/>/', $string, $matches, $ifAll);
- }
+ /**
+ * 验证是否是合法的html标记
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是合法的html标记则返回true,否则返回false
+ */
+ public static function isHtml($string)
+ {
+ return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string);
+ }
- /**
- * 验证是否是合法的html标记
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是合法的html标记则返回true,否则返回false
- */
- public static function isHtml($string) {
- return 0 < preg_match('/^<(.*)>.*|<(.*)\/>$/', $string);
- }
+ /**
+ * 验证是否有合法的ipv4地址
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasIpv4($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll);
+ }
- /**
- * 验证是否有合法的ipv4地址
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasIpv4($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp('/((25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string, $matches, $ifAll);
- }
+ /**
+ * 验证是否是合法的IP
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是合法的IP则返回true,否则返回false
+ */
+ public static function isIpv4($string)
+ {
+ return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string);
+ }
- /**
- * 验证是否是合法的IP
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是合法的IP则返回true,否则返回false
- */
- public static function isIpv4($string) {
- return 0 < preg_match('/(?:(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|0?[1-9]\d|0?0?\d)/', $string);
- }
-
- /**
- * 验证是否有合法的ipV6
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasIpv6($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}|
+ /**
+ * 验证是否有合法的ipV6
+ *
+ * @param string $string 被搜索的 字符串
+ * @param array $matches 会被搜索的结果,默认为array()
+ * @param bool $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
+ * @return bool 如果匹配成功返回true,否则返回false
+ */
+ public static function hasIpv6($string, &$matches = array(), $ifAll = false)
+ {
+ return 0 < self::validateByRegExp('/\A((([a-f0-9]{1,4}:){6}|
::([a-f0-9]{1,4}:){5}|
([a-f0-9]{1,4})?::([a-f0-9]{1,4}:){4}|
(([a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::([a-f0-9]{1,4}:){3}|
@@ -216,16 +233,17 @@ public static function hasIpv6($string, &$matches = array(), $ifAll = false) {
(([a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?::
)
)\Z/ix', $string, $matches, $ifAll);
- }
+ }
- /**
- * 验证是否是合法的ipV6
- *
- * @param string $string 待验证的字串
- * @return boolean 如果是合法的ipV6则返回true,否则返回false
- */
- public static function isIpv6($string) {
- return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}|
+ /**
+ * 验证是否是合法的ipV6
+ *
+ * @param string $string 待验证的字串
+ * @return bool 如果是合法的ipV6则返回true,否则返回false
+ */
+ public static function isIpv6($string)
+ {
+ return 0 < preg_match('/\A(?:(?:(?:[a-f0-9]{1,4}:){6}|
::(?:[a-f0-9]{1,4}:){5}|
(?:[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){4}|
(?:(?:[a-f0-9]{1,4}:){0,1}[a-f0-9]{1,4})?::(?:[a-f0-9]{1,4}:){3}|
@@ -239,93 +257,100 @@ public static function isIpv6($string) {
(?:(?:[a-f0-9]{1,4}:){0,6}[a-f0-9]{1,4})?::
)
)\Z/ix', $string);
- }
+ }
- /**
- * 验证是否有客户端脚本
- *
- * @param string $string 被搜索的 字符串
- * @param array $matches 会被搜索的结果,默认为array()
- * @param boolean $ifAll 是否进行全局正则表达式匹配,默认为false即仅进行一次匹配
- * @return boolean 如果匹配成功返回true,否则返回false
- */
- public static function hasScript($string, &$matches = array(), $ifAll = false) {
- return 0 < self::validateByRegExp('/