/qeephp/library/q.php
PHP | 979 lines | 711 code | 24 blank | 244 comment | 25 complexity | c98c55761b5722d9405024c688dd6710 MD5 | raw file
Possible License(s): BSD-3-Clause
- <?php
- // $Id: q.php 2361 2009-04-01 15:36:05Z dualface $
- /**
- * ?? QeePHP ??????????????
- *
- * @link http://qeephp.com/
- * @copyright Copyright (c) 2006-2009 Qeeyuan Inc. {@link http://www.qeeyuan.com}
- * @license New BSD License {@link http://qeephp.com/license/}
- * @version $Id: q.php 2361 2009-04-01 15:36:05Z dualface $
- * @package core
- */
- /**
- * QeePHP ?????????
- */
- define('Q_DIR', dirname(__FILE__));
- /**
- * DIRECTORY_SEPARATOR ???
- */
- define('DS', DIRECTORY_SEPARATOR);
- /**
- * CURRENT_TIMESTAMP ?????????????? time() ???
- */
- define('CURRENT_TIMESTAMP', time());
- global $G_CLASS_FILES;
- if (empty($G_CLASS_FILES))
- {
- require Q_DIR . '/_config/qeephp_class_files.php';
- }
- /**
- * ? Q ? QeePHP ?????????????????????
- *
- * ? Q ?? QeePHP ???????????
- *
- * - ?????????
- * - ????????????
- * - ????????????????????
- * - ???????
- * - ???????
- *
- * @author YuLei Liao <liaoyulei@qeeyuan.com>
- * @version $Id: q.php 2361 2009-04-01 15:36:05Z dualface $
- * @package core
- */
- class Q
- {
- /**
- * ??????????
- */
- // ??????
- const RUN_MODE_DEVEL = 'devel';
- // ??????
- const RUN_MODE_DEPLOY = 'deploy';
- // ????
- const RUN_MODE_TEST = 'test';
- /**
- * ?????
- *
- * @var array
- */
- private static $_objects = array();
- /**
- * ?????
- *
- * @var array
- */
- private static $_class_path = array();
- /**
- * ????????
- *
- * @var array
- */
- private static $_class_path_options = array();
- /**
- * ??????
- *
- * @var array
- */
- private static $_ini = array();
- /**
- * ?? QeePHP ???
- *
- * @return string QeePHP ???
- */
- static function version()
- {
- return '2.1';
- }
- /**
- * ?????????
- *
- * $option ????????????
- * ?????????????????? $default ???????
- *
- * @code php
- * $option_value = Q::ini('my_option');
- * @endcode
- *
- * ???????????????? $option ???/??????
- *
- * ??????? option_group ???????????????
- * ???????? my_option ???????
- *
- * @code php
- * // +--- option_group
- * // +-- my_option = this is my_option
- * // +-- my_option2 = this is my_option2
- * // \-- my_option3 = this is my_option3
- *
- * // ?? option_group ?????? my_option ?
- * // ???? this is my_option
- * echo Q::ini('option_group/my_option');
- * @endcode
- *
- * ???????????????????/??????????????????
- *
- * ??????????????? $option ????? '/' ???
- *
- * @code php
- * // ??????????
- * $all = Q::ini('/');
- * @endcode
- *
- * @param string $option ?????????
- * @param mixed $default ????????????????
- *
- * @return mixed ???????
- */
- static function ini($option, $default = null)
- {
- if ($option == '/') return self::$_ini;
- if (strpos($option, '/') === false)
- {
- return array_key_exists($option, self::$_ini)
- ? self::$_ini[$option]
- : $default;
- }
- $parts = explode('/', $option);
- $pos =& self::$_ini;
- foreach ($parts as $part)
- {
- if (!isset($pos[$part])) return $default;
- $pos =& $pos[$part];
- }
- return $pos;
- }
- /**
- * ?????????
- *
- * ? $option ????????$option ???????????
- * $data ???????????????
- *
- * @code php
- * // ???????
- * Q::changeIni('option_group/my_option2', 'new value');
- * @endcode
- *
- * ?? $option ??????????????????
- * ?? $option ???????????????????????????????
- *
- * @code php
- * // ????????
- * // +--- option_1 = old value
- * // +--- option_group
- * // +-- option1 = old value
- * // +-- option2 = old value
- * // \-- option3 = old value
- *
- * // ???????
- * $arr = array(
- * 'option_1' => 'value 1',
- * 'option_2' => 'value 2',
- * 'option_group/option2' => 'new value',
- * );
- * Q::changeIni($arr);
- *
- * // ???
- * // +--- option_1 = value 1
- * // +--- option_2 = value 2
- * // +--- option_group
- * // +-- option1 = old value
- * // +-- option2 = new value
- * // \-- option3 = old value
- * @endcode
- *
- * ??????? Q::changeIni() ????????????????????
- *
- * ???????????????????????? Q::replaceIni() ???
- *
- * @param string|array $option ??????????????????????
- * @param mixed $data ????????
- */
- static function changeIni($option, $data = null)
- {
- if (is_array($option))
- {
- foreach ($option as $key => $value)
- {
- self::changeIni($key, $value);
- }
- return;
- }
- if (!is_array($data))
- {
- if (strpos($option, '/') === false)
- {
- self::$_ini[$option] = $data;
- return;
- }
- $parts = explode('/', $option);
- $max = count($parts) - 1;
- $pos =& self::$_ini;
- for ($i = 0; $i <= $max; $i ++)
- {
- $part = $parts[$i];
- if ($i < $max)
- {
- if (!isset($pos[$part]))
- {
- $pos[$part] = array();
- }
- $pos =& $pos[$part];
- }
- else
- {
- $pos[$part] = $data;
- }
- }
- }
- else
- {
- foreach ($data as $key => $value)
- {
- self::changeIni($option . '/' . $key, $value);
- }
- }
- }
- /**
- * ????????
- *
- * Q::replaceIni() ????? Q::changeIni() ???
- * ?? Q::replaceIni() ??????????????
- * ???????????????????
- *
- * @code php
- * // ????????
- * // +--- option_1 = old value
- * // +--- option_group
- * // +-- option1 = old value
- * // +-- option2 = old value
- * // \-- option3 = old value
- *
- * // ???????
- * $arr = array(
- * 'option_1' => 'value 1',
- * 'option_2' => 'value 2',
- * 'option_group/option2' => 'new value',
- * );
- * Q::replaceIni($arr);
- *
- * // ???
- * // +--- option_1 = value 1
- * // +--- option_2 = value 2
- * // +--- option_group
- * // +-- option2 = new value
- * @endcode
- *
- * ?????????????? Q::replaceIni() ? Q::changeIni() ??????
- *
- * ???? Q::replaceIni() ??? Q::changeIni() ????
- * ???????? Q::replaceIni() ??? Q::changeIni()?
- *
- * @param string|array $option ??????????????????????
- * @param mixed $data ????????
- */
- static function replaceIni($option, $data = null)
- {
- if (is_array($option))
- {
- self::$_ini = array_merge(self::$_ini, $option);
- }
- else
- {
- self::$_ini[$option] = $data;
- }
- }
- /**
- * ???????
- *
- * Q::cleanIni() ?????????????????
- *
- * @param mixed $option ?????????
- */
- static function cleanIni($option)
- {
- if (strpos($option, '/') === false)
- {
- unset(self::$_ini[$option]);
- }
- else
- {
- $parts = explode('/', $option);
- $max = count($parts) - 1;
- $pos =& self::$_ini;
- for ($i = 0; $i <= $max; $i ++)
- {
- $part = $parts[$i];
- if ($i < $max)
- {
- if (!isset($pos[$part]))
- {
- $pos[$part] = array();
- }
- $pos =& $pos[$part];
- }
- else
- {
- unset($pos[$part]);
- }
- }
- }
- }
- /**
- * ?????????????????????
- *
- * @code php
- * Q::loadClass('Table_Posts');
- * @endcode
- *
- * $dirs ???????? PATH_SEPARATOR ?????????
- * ?????????????????
- *
- * @code php
- * Q::loadClass('Table_Posts', array('/www/mysite/app', '/www/mysite/lib'));
- * @endcode
- *
- * @param string $class_name ?????
- * @param string|array $dirs ??????????
- *
- * @return string|boolean ??????????? false
- */
- static function loadClass($class_name, $dirs = null, $throw = true)
- {
- if (class_exists($class_name, false) || interface_exists($class_name, false))
- {
- return $class_name;
- }
- global $G_CLASS_FILES;
- $class_name_l = strtolower($class_name);
- if (isset($G_CLASS_FILES[$class_name_l]))
- {
- require Q_DIR . DS . $G_CLASS_FILES[$class_name_l];
- return $class_name_l;
- }
- $filename = str_replace('_', DS, $class_name);
- if ($filename != $class_name)
- {
- $dirname = dirname($filename);
- if (!empty($dirs))
- {
- if (!is_array($dirs))
- {
- $dirs = explode(PATH_SEPARATOR, $dirs);
- }
- }
- else
- {
- $dirs = self::$_class_path;
- }
- $filename = basename($filename) . '.php';
- return self::loadClassFile($filename, $dirs, $class_name, $dirname, $throw);
- }
- else
- {
- return self::loadClassFile("{$filename}.php", self::$_class_path, $class_name, '', $throw);
- }
- }
- /**
- * ?????????
- *
- * ????? Q::loadClass() ??? QeePHP ??????? Q::import() ?????????
- *
- * ????Q::import() ?????????????
- *
- * ??????? Vendor_Smarty_Adapter???????????????? vendor/smarty/adapter.php?
- * ???? Q::import() ?? Vendor_Smarty_Adapter ????????
- * ???? vendor/smarty/adapter.php ?????
- *
- * @code php
- * Q::import('/www/app');
- * Q::loadClass('Vendor_Smarty_Adapter');
- * // ???????? /www/app/vendor/smarty/adapter.php
- * @endcode
- *
- * ?? QeePHP ?????????????????????????????????
- * ???? import() ?????????
- *
- * @code php
- * Q::import('/www/app/vendor', true);
- * Q::loadClass('Zend_Mail');
- * // ???????? /www/app/vendor/Zend/Mail.php
- * @endcode
- *
- * @param string $dir ????????
- * @param boolean $case_sensitive ?????????????????????
- */
- static function import($dir, $case_sensitive = false)
- {
- $real_dir = realpath($dir);
- if ($real_dir)
- {
- $dir = rtrim($real_dir, '/\\');
- if (!isset(self::$_class_path[$dir]))
- {
- self::$_class_path[$dir] = $dir;
- self::$_class_path_options[$dir] = $case_sensitive;
- }
- }
- }
- /**
- * ????????????????????
- *
- * ???? $dirs ????????????? $filename ????????
- * ???????????? $class_name ???????
- *
- * ????????????????
- *
- * @code php
- * Q::loadClassFile('Smarty.class.php', $dirs, 'Smarty');
- * @endcode
- *
- * @param string $filename ???????????????
- * @param string|array $dirs ???????
- * @param string $class_name ?????
- * @param string $dirname ??????????????
- * @param string $throw ????????????
- */
- static function loadClassFile($filename, $dirs, $class_name, $dirname = '', $throw = true)
- {
- if (!is_array($dirs))
- {
- $dirs = explode(PATH_SEPARATOR, $dirs);
- }
- if ($dirname)
- {
- $filename = rtrim($dirname, '/\\') . DS . $filename;
- }
- $filename_l = strtolower($filename);
- foreach ($dirs as $dir)
- {
- if (isset(self::$_class_path[$dir]))
- {
- $path = $dir . DS . (self::$_class_path_options[$dir] ? $filename : $filename_l);
- }
- else
- {
- $path = rtrim($dir, '/\\') . DS . $filename;
- }
- if (is_file($path))
- {
- require $path;
- break;
- }
- }
- // ????????????????????
- if (!class_exists($class_name, false) && ! interface_exists($class_name, false))
- {
- if ($throw)
- {
- throw new Q_ClassNotDefinedException($class_name, $path);
- }
- return false;
- }
- return $class_name;
- }
- /**
- * ???????
- *
- * ???? $dirs ????????????? $filename ????????
- * ??????????? $throw ???????????
- *
- * ? PHP ??? require ? include ???Q::loadFile() ????????
- *
- * <ul>
- * <li>???????????????</li>
- * <li>?????????</li>
- * <li>?????????????</li>
- * </ul>
- *
- * @code php
- * Q::loadFile('my_file.php', $dirs);
- * @endcode
- *
- * @param string $filename ???????????????
- * @param array $dirs ???????
- * @param boolean $throw ?????????????
- *
- * @return mixed
- */
- static function loadFile($filename, $dirs = null, $throw = true)
- {
- if (preg_match('/[^a-z0-9\-_.]/i', $filename))
- {
- throw new Q_IllegalFilenameException($filename);
- }
- if (is_null($dirs))
- {
- $dirs = array();
- }
- elseif (is_string($dirs))
- {
- $dirs = explode(PATH_SEPARATOR, $dirs);
- }
- foreach ($dirs as $dir)
- {
- $path = rtrim($dir, '\\/') . DS . $filename;
- if (is_file($path)) return include $path;
- }
- if ($throw) throw new Q_FileNotFoundException($filename);
- return false;
- }
- /**
- * ???????????
- *
- * Q::singleton() ???????
- *
- * <ul>
- * <li>????????????????????????</li>
- * <li>??????????????</li>
- * <li>?????????????????????????</li>
- * <li>?????????????????????????</li>
- * <li>???????????</li>
- * </ul>
- *
- * ?? Q::singleton() ?????????????????????????
- *
- * @code php
- * // ??? A ????? My_Object
- * $obj = Q::singleton('My_Object');
- * ...
- * ...
- * // ??? B ????? My_Object
- * $obj2 = Q::singleton('My_Object');
- * // $obj ? $obj2 ?????????????????????????
- * @endcode
- *
- * @param string $class_name ??????????
- *
- * @return object ??????
- */
- static function singleton($class_name)
- {
- $key = strtolower($class_name);
- if (isset(self::$_objects[$key]))
- {
- return self::$_objects[$key];
- }
- self::loadClass($class_name);
- return self::register(new $class_name(), $class_name);
- }
- /**
- * ??????????????????
- *
- * ????????????????????????????????? Q::registry() ???????
- * ????????????????????????????????
- *
- * @code php
- * // ??????
- * Q::register(new MyObject());
- * .....
- * // ??????
- * $obj = Q::regitry('MyObject');
- * @endcode
- *
- * ? $persistent ??? true ??????????????
- * ?????????????? Q::registry() ????????????????????????
- *
- * ??????????????????????????????????
- * ?????????????????????
- *
- * ???????????????????? object_persistent_provier ???
- * ???????????????????
- *
- * @code php
- * if (!Q::isRegistered('MyObject'))
- * {
- * Q::register(new MyObject(), 'MyObject', true);
- * }
- * $app = Q::registry('MyObject');
- * @endcode
- *
- * @param object $obj ??????
- * @param string $name ???????
- * @param boolean $persistent ?????????????
- *
- * @return object
- */
- static function register($obj, $name = null, $persistent = false)
- {
- if (!is_object($obj))
- {
- // LC_MSG: Type mismatch. $obj expected is object, actual is "%s".
- throw new QException(__('Type mismatch. $obj expected is object, actual is "%s".',
- gettype($obj)));
- }
- // TODO: ??? $persistent ?????
- if (is_null($name))
- {
- $name = get_class($obj);
- }
- $name = strtolower($name);
- self::$_objects[$name] = $obj;
- return $obj;
- }
- /**
- * ?????????????????????????????
- *
- * @code php
- * // ??????
- * Q::register(new MyObject(), 'obj1');
- * .....
- * // ??????
- * $obj = Q::regitry('obj1');
- * @endcode
- *
- * @param string $name ????????
- *
- * @return object ??????
- */
- static function registry($name)
- {
- $name = strtolower($name);
- if (isset(self::$_objects[$name]))
- {
- return self::$_objects[$name];
- }
- // LC_MSG: No object is registered of name "%s".
- throw new QException(__('No object is registered of name "%s".', $name));
- }
- /**
- * ???????????????
- *
- * @param string $name ????????
- *
- * @return boolean ????????
- */
- static function isRegistered($name)
- {
- $name = strtolower($name);
- return isset(self::$_objects[$name]);
- }
- /**
- * ?????????????????????????? false
- *
- * ???????????????? ID??????????????? ID?
- * ???? A ??? ID ? data-a???? B ??? ID ? data-b?
- *
- * ??????????????????????? ID????????????
- *
- * <ul>
- * <li>?????????????????? page?db ??</li>
- * <li>??????????????????????????????? ID?</li>
- * </ul>
- *
- * ????????? ID ????? page.news.1?db.members.userid?
- *
- * Q::cache() ???? $policy ?????????????????
- * ????????????????????????
- *
- * $backend_class ???????????????????? QCache_File?QCache_APC ??
- *
- * @code php
- * $data = Q::cache($cache_id);
- * if ($data === false)
- * {
- * $data = ....
- * Q::writeCache($cache_id, $data);
- * }
- * @endcode
- *
- * @param string $id ??? ID
- * @param array $policy ????
- * @param string $backend_class ????????
- *
- * @return mixed ????????????? false
- */
- static function cache($id, array $policy = null, $backend_class = null)
- {
- static $obj = null;
- if (is_null($backend_class))
- {
- if (is_null($obj))
- {
- $obj = self::singleton(self::ini('runtime_cache_backend'));
- }
- return $obj->get($id, $policy);
- }
- else
- {
- $cache = self::singleton($backend_class);
- return $cache->get($id, $policy);
- }
- }
- /**
- * ????????????????
- *
- * $data ????????????? $data ?????????????????? serialize ??? true?
- * $policy ????????????????????????????????????
- *
- * ????? Q::cache()?
- *
- * @param string $id ??? ID
- * @param mixed $data ??????
- * @param array $policy ????
- * @param string $backend_class ????????
- */
- static function writeCache($id, $data, array $policy = null, $backend_class = null)
- {
- static $obj = null;
- if (is_null($backend_class))
- {
- if (is_null($obj))
- {
- $obj = self::singleton(self::ini('runtime_cache_backend'));
- }
- $obj->set($id, $data, $policy);
- }
- else
- {
- $cache = self::singleton($backend_class);
- $cache->set($id, $data, $policy);
- }
- }
- /**
- * ?????????
- *
- * ?????????????????????????????????????
- * ????????????????????????????????????????????
- *
- * @code php
- * Q::cleanCache($cache_id);
- * @endcode
- *
- * @param string $id ??? ID
- * @param array $policy ????
- * @param string $backend_class ????????
- */
- static function cleanCache($id, array $policy = null, $backend_class = null)
- {
- static $obj = null;
- if (is_null($backend_class))
- {
- if (is_null($obj))
- {
- $obj = self::singleton(self::ini('runtime_cache_backend'));
- }
- $obj->remove($id, $policy);
- }
- else
- {
- $cache = self::singleton($backend_class);
- $cache->remove($id, $policy);
- }
- }
- /**
- * ??????????????????????
- *
- * $input ?????????????,?????????????????
- * ?????????????? trim() ????????????????????????
- *
- * ?????????????item1, item2, item3 ????????????
- *
- * @code php
- * $input = 'item1, item2, item3';
- * $output = Q::normalize($input);
- * // $output ?????????????
- * // $output = array(
- * // 'item1',
- * // 'item2',
- * // 'item3',
- * // );
- *
- * $input = 'item1|item2|item3';
- * // ?????????????
- * $output = Q::normalize($input, '|');
- * @endcode
- *
- * @param array|string $input ???????????
- * @param string $delimiter ??????????
- *
- * @return array ?????
- */
- static function normalize($input, $delimiter = ',')
- {
- if (!is_array($input))
- {
- $input = explode($delimiter, $input);
- }
- $input = array_map('trim', $input);
- return array_filter($input, 'strlen');
- }
- /**
- * ????????????
- *
- * ?? Q::control() ?????????????????????????
- *
- * @param string $type ???????????
- * @param string $id ??ID
- * @param array $attrs ???????????
- *
- * @return QUI_Control_Abstract ???????????
- */
- static function control($type, $id = null, array $attrs = null)
- {
- $id = (empty($id)) ? strtolower($type) : strtolower($id);
- if (!is_array($attrs)) $attrs = array();
- $class_name = 'Control_' . ucfirst(strtolower($type));
- return new $class_name($id, $attrs);
- }
- /**
- * ?? QeePHP ????????????????
- *
- * @param string $class_name
- */
- static function autoload($class_name)
- {
- self::loadClass($class_name, null, false);
- }
- /**
- * ????????????????
- *
- * ????? Zend Framework?
- *
- * @param string $class ??????????
- * @param boolean $enabled ????????
- */
- static function registerAutoload($class = 'Q', $enabled = true)
- {
- if (!function_exists('spl_autoload_register'))
- {
- require_once Q_DIR . '/core/exception.php';
- throw new QException('spl_autoload does not exist in this PHP installation');
- }
- if ($enabled === true)
- {
- spl_autoload_register(array($class, 'autoload'));
- }
- else
- {
- spl_autoload_unregister(array($class, 'autoload'));
- }
- }
- }
- /**
- * QeePHP ????????????
- *
- * ???????? QTranslate ??????????
- *
- * @return $msg
- */
- function __()
- {
- $args = func_get_args();
- $msg = array_shift($args);
- $language = strtolower(Q::ini('error_language'));
- $messages = Q::loadFile('lc_messages.php', Q_DIR . '/_lang/' . $language, false);
- if (isset($messages[$msg]))
- {
- $msg = $messages[$msg];
- }
- array_unshift($args, $msg);
- return call_user_func_array('sprintf', $args);
- }
- /**
- * ?? HTML ???????? htmlspecialchars()
- *
- * @param string $text
- *
- * @return string
- */
- function h($text)
- {
- return htmlspecialchars($text);
- }
- function nl2p($text)
- {
- $ps = split("(\r\n)+|\n+", trim($text));
- $ret = "";
- foreach($ps as $p){
- $ret .= "<p>$p</p>\n";
- }
- return $ret;
- }
- /**
- * QDebug::dump() ???????????????
- *
- * @param mixed $vars ??????
- * @param string $label ??????????
- * @param boolean $return ????????
- *
- * @return string
- */
- function dump($vars, $label = null, $return = false)
- {
- return QDebug::dump($vars, $label, $return);
- }
- /**
- * QContext::url() ???????????? URL ??
- *
- * url() ????????????? QContext::url() ????????
- *
- * @param string $udi UDI ???
- * @param array|string $params ??????
- * @param string $route_name ???
- * @param array $opts ?????? URL ???
- *
- * @return string ??? URL ??
- */
- function url($udi, $params = null, $route_name = null, array $opts = null)
- {
- return QContext::instance()->url($udi, $params, $route_name, $opts);
- }
- /**
- * ?????????
- */
- Q::registerAutoload();