Exemple #1
0
Fichier : Db.php Projet : tourze/db
 /**
  * 单例模式,获取一个指定的实例
  *
  *     // 加载默认实例
  *     $db = Database::instance();
  *
  *     // 指定实例名称和配置
  *     $db = Database::instance('custom', $config);
  *
  * @param  string $name   实例名
  * @param  array  $config 配置参数
  * @return Connection
  */
 public static function instance($name = null, array $config = null)
 {
     if (null === $name) {
         $name = Db::$default;
     }
     if (!isset(Db::$instances[$name])) {
         // 读取配置
         if (null === $config) {
             $config = (array) Config::load(self::$configFile)->get($name);
             Base::getLog()->debug(__METHOD__ . ' get default config', ['name' => $name]);
         }
         // 合并默认配置
         if (isset(self::$defaultConfig[Arr::get($config, 'driver')])) {
             $config = Arr::merge(self::$defaultConfig[Arr::get($config, 'driver')], $config);
             Base::getLog()->debug(__METHOD__ . ' merge config', ['name' => $name]);
         }
         $conn = DriverManager::getConnection($config);
         Base::getLog()->debug(__METHOD__ . ' create dbal connection', ['name' => $name]);
         // 额外注册字段类型
         if (isset(self::$mappingType[Arr::get($config, 'driver')])) {
             $platform = $conn->getDatabasePlatform();
             foreach (self::$mappingType[Arr::get($config, 'driver')] as $dbType => $doctrineType) {
                 if (!$platform->hasDoctrineTypeMappingFor($dbType)) {
                     Base::getLog()->debug(__METHOD__ . ' add dbal mapping type', ['raw' => $dbType, 'dbal' => $doctrineType]);
                     $platform->registerDoctrineTypeMapping($dbType, $doctrineType);
                 }
             }
         }
         Db::$instances[$name] = $conn;
         Base::getLog()->debug(__METHOD__ . ' save db instance', ['name' => $name]);
     }
     return Db::$instances[$name];
 }
Exemple #2
0
 /**
  * 读取消息文本
  *
  *     // 读取message/text.php中的username
  *     $username = Message::load('text', 'username');
  *
  * @param   string $file    文件名
  * @param   string $path    键名
  * @param   mixed  $default 键名不存在时返回默认值
  * @return  string|array  内容,如果$path为空的话,就返回完整数组内容
  */
 public static function load($file, $path = null, $default = null)
 {
     static $messages;
     if (!isset($messages[$file])) {
         $messages[$file] = [];
         $files = [];
         foreach (self::$_messagePaths as $includePath) {
             if (is_file($includePath . $file . self::$ext)) {
                 $files[] = $includePath . $file . self::$ext;
             }
         }
         if (!empty($files)) {
             foreach ($files as $f) {
                 $messages[$file] = Arr::merge($messages[$file], Base::load($f));
             }
         }
     }
     if (null === $path) {
         // 返回完整的数组
         return $messages[$file];
     } else {
         // 返回指定的键名
         return Arr::path($messages[$file], $path, $default);
     }
 }
Exemple #3
0
 /**
  * @param string $text     明文
  * @param string $hashType 加密方式
  * @param array  $extra    附加参数
  * @return string
  */
 public static function hash($text, $hashType = self::MD5_HASH, array $extra = null)
 {
     $params = Arr::merge(['text' => $text], (array) $extra);
     switch ($hashType) {
         case self::MD5_HASH:
             $object = new MD5($params);
             break;
         case self::SHA1_HASH:
             $object = new SHA1($params);
             break;
         case self::MD5_TWICE_HASH:
             $object = new MD5Twice($params);
             break;
         case self::PASS_SALT_MD5_HASH:
             $object = new Joomla($params);
             break;
         case self::SALT_PASS_MD5_HASH:
             $object = new osCommerce($params);
             break;
         default:
             $object = new Plain($params);
     }
     /** @var HashInterface $object */
     return (string) $object->hash();
 }
Exemple #4
0
 /**
  * 初始化数据构造器
  *
  * @param  int $type 要执行的SQL类型
  * @return $this
  */
 protected function _build($type)
 {
     switch ($type) {
         case Db::SELECT:
             $this->_dbBuilder = $this->_db->createQueryBuilder()->select();
             break;
         case Db::UPDATE:
             $this->_dbBuilder = $this->_db->createQueryBuilder()->update($this->_tableName, $this->_objectName);
             break;
         case Db::DELETE:
             $this->_dbBuilder = $this->_db->createQueryBuilder()->delete($this->_tableName);
     }
     $selectList = [];
     foreach ($this->_dbPending as $method) {
         $name = $method['name'];
         $args = $method['args'];
         // 如果是select,那么暂时先不执行
         if ($name == 'select') {
             $selectList = Arr::merge($selectList, $args);
             continue;
         }
         $this->_dbApplied[$name] = $name;
         call_user_func_array([$this->_dbBuilder, $name], $args);
     }
     $this->_dbBuilder->select($selectList);
     return $this;
 }
Exemple #5
0
 /**
  * 执行检测
  *
  *     if ($validation->check())
  *     {
  *          // 校验通过
  *     }
  *
  * @return bool
  */
 public function check()
 {
     // 清空数据和错误
     $data = $this->_errors = [];
     // 保存原来的数据
     $original = $this->_data;
     // 读取字段信息
     $fields = Arr::merge(array_keys($original), array_keys($this->_labels));
     // 现在的规则
     $rules = $this->_rules;
     // 逐个字段格式化下规则
     foreach ($fields as $field) {
         $data[$field] = Arr::get($this->_data, $field);
         // 如果key为true,那么规则就是所有字段都生效
         if (isset($rules[true])) {
             if (!isset($rules[$field])) {
                 $rules[$field] = [];
             }
             $rules[$field] = array_merge($rules[$field], $rules[true]);
         }
     }
     // 保存格式化后的规则
     $this->_data = $data;
     // 清空全局规则
     unset($rules[true]);
     // 绑定一些必要的变量
     $this->bind(':validation', $this);
     $this->bind(':data', $this->_data);
     foreach ($rules as $field => $set) {
         $value = Arr::get($this->_data, $field);
         // 绑定当前处理的字段和值
         $this->bind([':field' => $field, ':value' => $value]);
         foreach ($set as $array) {
             // 格式:[$rule, $params]
             $rule = array_shift($array);
             $params = array_shift($array);
             foreach ($params as $key => $param) {
                 // 替换绑定的变量
                 if (is_string($param) && array_key_exists($param, $this->_bound)) {
                     $params[$key] = $this->_bound[$param];
                 }
             }
             // 默认错误名跟规则名一致,因为一般规则都是字符串表示的
             $errorName = $rule;
             // 规则是数组,说明传入的是一个callback
             if (is_array($rule)) {
                 // 允许rule('field', [':model', 'some_rule']);
                 if (is_string($rule[0]) && array_key_exists($rule[0], $this->_bound)) {
                     $rule[0] = $this->_bound[$rule[0]];
                 }
                 // 把索引为1的值作为错误标记
                 $errorName = $rule[1];
                 $passed = call_user_func_array($rule, $params);
             } elseif (!is_string($rule)) {
                 // 匿名函数不做错误处理,留待内容做处理
                 $errorName = false;
                 $passed = call_user_func_array($rule, $params);
             } elseif (method_exists(self::$validHelperClass, $rule)) {
                 // 调用校验助手类来完成操作
                 $method = new ReflectionMethod(self::$validHelperClass, $rule);
                 $passed = $method->invokeArgs(null, $params);
             } elseif (false === strpos($rule, '::')) {
                 // 不符合静态方法调用的规则,那么直接按照函数调用
                 $function = new ReflectionFunction($rule);
                 $passed = $function->invokeArgs($params);
             } else {
                 // 当做一次静态函数调用
                 $temp = explode('::', $rule, 2);
                 $class = array_shift($temp);
                 $method = array_shift($temp);
                 $method = new ReflectionMethod($class, $method);
                 $passed = $method->invokeArgs(null, $params);
             }
             if (!in_array($rule, $this->_emptyRules) && !Valid::notEmpty($value)) {
                 continue;
             }
             if (false === $passed && false !== $errorName) {
                 $this->error($field, $errorName, $params);
                 break;
             } elseif (isset($this->_errors[$field])) {
                 // 匿名函数自己处理错误信息,这里就不处理了
                 break;
             }
         }
     }
     // 还原原来的值
     $this->_data = $original;
     return empty($this->_errors);
 }
Exemple #6
0
 /**
  * {@inheritdoc}
  */
 public function withAddedHeader($name, $value)
 {
     if (isset($this->_headers[$name])) {
         // 如果是数组,那么合并
         if (is_array($value)) {
             $this->_headers[$name] = Arr::merge($this->_headers[$name], $value);
         } else {
             $this->_headers[$name][] = $value;
         }
     } else {
         $this->withHeader($name, $value);
     }
     return $this;
 }
Exemple #7
0
 /**
  * 设置模板解析选项
  *
  * @param array $options
  */
 public function setOptions(array $options)
 {
     $this->_templateOptions = Arr::merge($this->_templateOptions, $options);
 }
Exemple #8
0
 /**
  * 返回指定变量的字符串格式
  *
  *     // 返回"?sort=title&limit=10"
  *     $query = Url::query(['sort' => 'title', 'limit' => 10]);
  *
  * [!!] 参数中带null的话,这个键会被忽略
  *
  * @param  array $params 参数列表Array of GET parameters
  * @param  bool  $useGet 是否合并当前的$_GET数组
  * @return string
  */
 public static function query(array $params = null, $useGet = false)
 {
     if ($useGet) {
         if (null === $params) {
             $params = $_GET;
         } else {
             $params = Arr::merge($_GET, $params);
         }
     }
     if (empty($params)) {
         return '';
     }
     $query = http_build_query($params, '', '&');
     return $query === '' ? '' : '?' . $query;
 }
Exemple #9
0
 /**
  * 检验[Arr::merge]的功能
  *
  * @dataProvider dataMerge
  * @param mixed $arr1
  * @param mixed $arr2
  * @param mixed $expected
  */
 public function testMerge($arr1, $arr2, $expected)
 {
     $this->assertEquals($expected, Arr::merge($arr1, $arr2));
 }
Exemple #10
0
 /**
  * 编码,增加HTTP头
  * 覆盖原方法,自定义Server段
  *
  * @param string        $content
  * @param TcpConnection $connection
  * @return string
  */
 public static function encode($content, TcpConnection $connection)
 {
     $headers = HttpCache::$header;
     Base::getLog()->debug(__METHOD__ . ' encode header and send', ['headers' => $headers]);
     $sendHeader = [];
     // 没有http-code默认给个,content-type也是
     $hasStatus = false;
     $hasContentType = false;
     foreach ($headers as $header) {
         if (substr($header, 0, strlen('HTTP/')) == 'HTTP/') {
             $hasStatus = true;
             $sendHeader[] = $header;
             Base::getLog()->debug(__METHOD__ . ' custom http code', ['header' => $header]);
         } elseif (strtolower(substr($header, 0, strlen('content-type:'))) == 'content-type:') {
             $hasContentType = true;
         }
     }
     if (!$hasStatus) {
         $sendHeader[] = "HTTP/1.1 200 OK";
         Base::getLog()->debug(__METHOD__ . ' default http code');
     }
     if (!$hasContentType) {
         Base::getLog()->debug(__METHOD__ . ' missing content type, set default value');
         $sendHeader[] = 'Content-Type: text/html;charset=utf-8';
     }
     // 合并
     $sendHeader = Arr::merge($sendHeader, $headers);
     // 一些额外的header信息
     if (Base::$expose) {
         $sendHeader[] = "Server: tourze/" . Base::VERSION;
     }
     $sendHeader[] = "Content-Length: " . strlen($content);
     // 记录要输出的header
     Base::getLog()->debug(__METHOD__ . ' final send header', $sendHeader);
     $sendHeader = implode("\r\n", $sendHeader);
     $sendHeader .= "\r\n\r\n";
     // save session
     self::sessionWriteClose();
     HttpCache::$header = [];
     // the whole http package
     return $sendHeader . $content;
 }