예제 #1
0
파일: Json.php 프로젝트: zonquan/cmlphp
 /**
  * 输出数据
  *
  */
 public function display()
 {
     header('Content-Type: application/json;charset=' . Config::get('default_charset'));
     if ($GLOBALS['debug']) {
         $sqls = Debug::getSqls();
         if (isset($sqls[0])) {
             $this->args['sql'] = implode($sqls, ', ');
         }
     }
     Plugin::hook('cml.before_cml_stop');
     exit(json_encode($this->args, PHP_VERSION >= '5.4.0' ? JSON_UNESCAPED_UNICODE : 0));
 }
예제 #2
0
파일: Pdo.php 프로젝트: linhecheng/cmlphp
 /**
  * 执行预处理语句
  *
  * @param object $stmt PDOStatement
  * @param bool $clearBindParams
  *
  * @return bool
  */
 public function execute($stmt, $clearBindParams = true)
 {
     //empty($param) && $param = $this->bindParams;
     $this->conf['log_slow_sql'] && ($startQueryTimeStamp = microtime(true));
     if (!$stmt->execute()) {
         $error = $stmt->errorInfo();
         throw new \InvalidArgumentException('Pdo execute Sql error!,【Sql : ' . $this->buildDebugSql() . '】,【Error:' . $error[2] . '】');
     }
     $slow = 0;
     if ($this->conf['log_slow_sql']) {
         $queryTime = microtime(true) - $startQueryTimeStamp;
         if ($queryTime > $this->conf['log_slow_sql']) {
             if (Plugin::hook('cml.mysql_query_slow', ['sql' => $this->buildDebugSql(), 'query_time' => $queryTime]) !== false) {
                 Log::notice('slow_sql', ['sql' => $this->buildDebugSql(), 'query_time' => $queryTime]);
             }
             $slow = $queryTime;
         }
     }
     if (Cml::$debug) {
         $this->debugLogSql($slow > 0 ? Debug::SQL_TYPE_SLOW : Debug::SQL_TYPE_NORMAL, $slow);
     }
     $this->currentSql = '';
     $clearBindParams && $this->clearBindParams();
     return true;
 }
예제 #3
0
파일: Redis.php 프로젝트: linhecheng/cmlphp
 /**
  * 根据key获取redis实例
  * 这边还是用取模的方式,一致性hash用php实现性能开销过大。取模的方式对只有几台机器的情况足够用了
  * 如果有集群需要,直接使用redis3.0+自带的集群功能就好了。不管是可用性还是性能都比用php自己实现好
  *
  * @param $key
  *
  * @return \Redis
  */
 private function hash($key)
 {
     $serverNum = count($this->conf['server']);
     $success = sprintf('%u', crc32($key)) % $serverNum;
     if (!isset($this->redis[$success]) || !is_object($this->redis[$success])) {
         $instance = new \Redis();
         $connectToRedisFunction = function ($host, $port, $isPersistentConnect) use($instance) {
             if ($isPersistentConnect) {
                 return $instance->pconnect($host, $port, 1.5);
             } else {
                 return $instance->connect($host, $port, 1.5);
             }
         };
         $isPersistentConnect = !(isset($this->conf['server'][$success]['pconnect']) && $this->conf['server'][$success]['pconnect'] === false);
         $connectResult = $connectToRedisFunction($this->conf['server'][$success]['host'], $this->conf['server'][$success]['port'], $isPersistentConnect);
         $failOver = null;
         if (!$connectResult && !empty($this->conf['back'])) {
             $failOver = $this->conf['back'];
             $isPersistentConnect = !(isset($failOver['pconnect']) && $failOver['pconnect'] === false);
             $connectResult = $connectToRedisFunction($failOver['host'], $failOver['port'], $isPersistentConnect);
         }
         if (!$connectResult && $serverNum > 1) {
             $failOver = $success + 1;
             $failOver >= $serverNum && ($failOver = $success - 1);
             $failOver = $this->conf['server'][$failOver];
             $isPersistentConnect = !(isset($failOver['pconnect']) && $failOver['pconnect'] === false);
             $connectResult = $connectToRedisFunction($failOver['host'], $failOver['port'], $isPersistentConnect);
         }
         if (!$connectResult) {
             Plugin::hook('cml.cache_server_down', [$this->conf['server'][$success]]);
             throw new CacheConnectFailException(Lang::get('_CACHE_CONNECT_FAIL_', 'Redis', $this->conf['server'][$success]['host'] . ':' . $this->conf['server'][$success]['port']));
         }
         $password = false;
         if (is_null($failOver)) {
             if (isset($this->conf['server'][$success]['password']) && !empty($this->conf['server'][$success]['password'])) {
                 $password = $this->conf['server'][$success]['password'];
             }
             isset($this->conf['server'][$success]['db']) && $instance->select($this->conf['server'][$success]['db']);
         } else {
             if (isset($failOver['password']) && !empty($failOver['password'])) {
                 $password = $failOver['password'];
             }
             isset($failOver['db']) && $instance->select($failOver['db']);
             Log::emergency('redis server down', ['downServer' => $this->conf['server'][$success], 'failOverTo' => $failOver]);
             Plugin::hook('cml.redis_server_down_fail_over', ['downServer' => $this->conf['server'][$success], 'failOverTo' => $failOver]);
         }
         if ($password && !$instance->auth($password)) {
             throw new \RuntimeException('redis password error!');
         }
         $instance->setOption(\Redis::OPT_PREFIX, $this->conf['prefix']);
         $this->redis[$success] = $instance;
     }
     return $this->redis[$success];
 }
예제 #4
0
파일: Cml.php 프로젝트: linhecheng/cmlphp
 /**
  * 未找到控制器的时候设置勾子
  *
  */
 public static function montFor404Page()
 {
     Plugin::mount('cml.before_show_404_page', [function () {
         $cmdLists = Config::get('cmlframework_system_command');
         $cmd = strtolower(trim(Cml::getContainer()->make('cml_route')->getAppName(), '/'));
         if (isset($cmdLists[$cmd])) {
             call_user_func($cmdLists[$cmd]);
         }
     }]);
     Plugin::hook('cml.before_show_404_page');
 }
예제 #5
0
 /**
  * 使用的缓存配置 默认为使用default_cache配置的参数
  *
  * @param bool|array $conf
  *
  * @throws CacheConnectFailException | PhpExtendNotInstall
  */
 public function __construct($conf = false)
 {
     $this->conf = $conf ? $conf : Config::get('default_cache');
     if (extension_loaded('Memcached')) {
         $this->memcache = new \Memcached('cml_memcache_pool');
         $this->type = 1;
     } elseif (extension_loaded('Memcache')) {
         $this->memcache = new \Memcache();
         $this->type = 2;
     } else {
         throw new PhpExtendNotInstall(Lang::get('_CACHE_EXTEND_NOT_INSTALL_', 'Memcached/Memcache'));
     }
     if (!$this->memcache) {
         throw new PhpExtendNotInstall(Lang::get('_CACHE_NEW_INSTANCE_ERROR_', 'Memcache'));
     }
     $singleNodeDownFunction = function ($host, $port) {
         //这边挂掉调用此回调在几s内只会调用一次。其它情况使用memcache方法均返回flase不报错
         Plugin::hook('cml.cache_server_down', ['host' => $host, 'port' => $port]);
         Log::emergency('memcache server down', ['downServer' => ['host' => $host, 'port' => $port]]);
     };
     $allNodeDownFunction = function ($serverList) {
         Plugin::hook('cml.cache_server_down', $this->conf['server'], $serverList);
         //全挂
         throw new CacheConnectFailException(Lang::get('_CACHE_CONNECT_FAIL_', 'Memcache', json_encode($serverList)));
     };
     $downServer = 0;
     if ($this->type == 2) {
         //memcache
         foreach ($this->conf['server'] as $val) {
             if (!$this->memcache->addServer($val['host'], $val['port'])) {
                 Log::emergency('memcache server down', ['downServer' => $val]);
             }
         }
         $this->memcache->setFailureCallback($singleNodeDownFunction);
         $serverList = $this->memcache->getextendedstats();
         foreach ($serverList as $server => $status) {
             $status || $downServer++;
         }
         if (count($serverList) <= $downServer) {
             $allNodeDownFunction($serverList);
         }
         return;
     }
     if (md5(json_encode($this->conf['server'])) !== md5(json_encode($this->memcache->getServerList()))) {
         $this->memcache->quit();
         $this->memcache->resetServerList();
         $this->memcache->addServers(array_values($this->conf['server']));
         $this->memcache->setOptions([\Memcached::OPT_PREFIX_KEY => $this->conf['prefix'], \Memcached::OPT_DISTRIBUTION => \Memcached::DISTRIBUTION_CONSISTENT, \Memcached::OPT_LIBKETAMA_COMPATIBLE => true, \Memcached::OPT_SERVER_FAILURE_LIMIT => 1, \Memcached::OPT_RETRY_TIMEOUT => 30, \Memcached::OPT_AUTO_EJECT_HOSTS => true, \Memcached::OPT_REMOVE_FAILED_SERVERS => true]);
         \Memcached::HAVE_JSON && $this->memcache->setOption(\Memcached::OPT_SERIALIZER, \Memcached::SERIALIZER_JSON_ARRAY);
     }
     $serverStatus = $this->memcache->getStats();
     foreach ($serverStatus as $server => $status) {
         if ($status['pid'] < 1) {
             $downServer++;
             $server = explode(':', $server);
             $singleNodeDownFunction($server[0], $server[1]);
         }
     }
     if (count($serverStatus) <= $downServer) {
         $allNodeDownFunction($serverStatus);
     }
 }
예제 #6
0
파일: Excel.php 프로젝트: zonquan/cmlphp
 /**
  * 生成Excel文件
  *
  * @param string $filename
  *
  * @return void
  */
 public function display($filename = '')
 {
     $filename == '' && ($filename = 'excel');
     $this->config('utf-8', false, 'default', $filename);
     header("Content-Type: application/vnd.ms-excel; charset=" . $this->coding);
     header("Content-Disposition: inline; filename=\"" . $this->filename . ".xls\"");
     /*打印*/
     echo stripslashes(sprintf($this->header, $this->coding));
     echo "\n<Worksheet ss:Name=\"" . $this->tWorksheetTitle . "\">\n<Table>\n";
     foreach ($this->args as $val) {
         $rows = $this->addRow($val);
         echo "<Row>\n" . $rows . "</Row>\n";
     }
     echo "</Table>\n</Worksheet>\n";
     echo "</Workbook>";
     Plugin::hook('cml.before_cml_stop');
     exit;
 }
예제 #7
0
파일: Cml.php 프로젝트: dlpc/cmlphp
 /**
  * 程序中并输出调试信息
  *
  */
 public static function cmlStop()
 {
     Plugin::hook('cml.before_cml_stop');
     //输出Debug模式的信息
     if ($GLOBALS['debug']) {
         header('Content-Type:text/html; charset=' . Config::get('default_charset'));
         Debug::stop();
     } else {
         $deBugLogData = dump('', 1);
         if (!empty($deBugLogData)) {
             require CML_PATH . DIRECTORY_SEPARATOR . 'Cml' . DIRECTORY_SEPARATOR . 'ConsoleLog.php';
         }
         CML_OB_START && ob_end_flush();
         exit;
     }
 }
예제 #8
0
파일: Xml.php 프로젝트: zonquan/cmlphp
 /**
  * 输出数据
  *
  */
 public function display()
 {
     header('Content-Type: application/xml;charset=' . Config::get('default_charset'));
     Plugin::hook('cml.before_cml_stop');
     exit($this->array2xml($this->args));
 }
예제 #9
0
 /**
  * 挂载插件钩子
  *
  */
 public function __destruct()
 {
     Plugin::hook('cml.run_controller_end');
 }
예제 #10
0
파일: Cml.php 프로젝트: hongweipeng/cmlphp
 /**
  * 未找到控制器的时候设置勾子
  *
  */
 public static function montFor404Page()
 {
     Plugin::mount('cml.before_show_404_page', array(function () {
         $cmdLists = Config::get('cmlframework_system_command');
         $cmd = strtolower(trim(Route::$urlParams['path'], DIRECTORY_SEPARATOR));
         if (isset($cmdLists[$cmd])) {
             call_user_func($cmdLists[$cmd]);
         }
     }));
     Plugin::hook('cml.before_show_404_page');
 }