public function write($str) { $dirName = dirname($this->path); BaseModelCommon::recursiveMkdir($dirName); defined('DAGGER_DEBUG') && BaseModelCommon::debug($this->path, 'file_write'); return file_put_contents($this->path, $str); }
/** * 输出读取MC数据的代码信息 * @author */ protected static function debugMCInfo() { if (defined("DAGGER_DEBUG")) { $trace = debug_backtrace(false); $trace = $trace[2]; BaseModelCommon::debug($trace['file'] . '_' . $trace['line'], 'mc_' . $trace['class'] . '_' . $trace['function']); } }
/** * 连接redis服务器 * @param string $link redis服务器标识 */ private static function connect($link) { if (!self::$instances[$link] instanceof Redis || self::$instances[$link]->ping() !== '+PONG') { self::$instances[$link] = new Redis(); list($host, $port) = explode(':', $link); defined('DAGGER_DEBUG') && BaseModelCommon::debug("{$host}:{$port}", 'connect to redis'); self::$instances[$link]->connect($host, $port); if (!self::$instances[$link]) { throw new BaseModelException("Redis连接失败", 90600, 'redis_trace'); } } }
/** * 文件引用器 * @param string $prefixPath 文件所在文件夹绝对路径 * @param string $filename 文件名 * @param strint $postfix 文件后缀 */ public static function includeFile($prefixPath, $filename, $postfix = '.php') { $_file = $prefixPath . $filename . $postfix; if (is_file($_file)) { include $_file; } else { if (!(include $_file)) { defined('DAGGER_DEBUG') && BaseModelCommon::debug($filename . '类include文件:' . $_file . '不存在,您现在指向的app为:app/' . Configure::$app . '/', 'error'); $trace = debug_backtrace(); defined('DAGGER_DEBUG') && BaseModelCommon::debug($trace, __METHOD__); $filename = htmlspecialchars($filename); if ($filename == 'Controller') { defined('DAGGER_DEBUG') && BaseModelCommon::debug(RouterConfig::$config, 'router_config'); BaseModelMessage::showError('请配置RouteConfig.php中' . htmlspecialchars(Configure::$app, ENT_QUOTES, 'UTF-8') . '的DAGGER_APP路由信息'); } else { BaseModelMessage::showError('class:' . $filename . ' not found in app:' . htmlspecialchars(Configure::$app, ENT_QUOTES, 'UTF-8')); } } } }
/** * 连接数据库,返回连接上的PDO对象 * @param int $DBName 数据库名称 * @param string $master_or_slave master;主库|slave:从库 * @return master db handle; */ public static function connectDB($DBName, $master_or_slave = 'slave', $DBConfig = array(), $reConnect = false) { $master_or_slave === 'master' || ($master_or_slave = 'slave'); if ($master_or_slave === 'master' && !empty($_SERVER['HTTP_HOST']) && isset($_SERVER['REQUEST_METHOD']) && strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST' && BaseModelSwitch::check(BaseModelSwitch::SWITCH_MASTERDB_POST_ONLY) === true) { throw new BaseModelDBException('请求方法不允许,主库操作必须为post', 90300); } $DBType = DAGGER_ENV; in_array($DBType, array('dev', 'test', 'product'), true) || ($DBType = 'product'); empty($DBName) && ($DBName = DAGGER_DB_DEFAULT); if (empty(DBConfig::$config['mysql'][$DBName][$DBType]['master']['host'])) { $DBType = 'product'; } $username = empty($DBConfig[$master_or_slave]['user']) ? DBConfig::$config['mysql'][$DBName][$DBType][$master_or_slave]['user'] : $DBConfig[$master_or_slave]['user']; $password = empty($DBConfig[$master_or_slave]['pass']) ? DBConfig::$config['mysql'][$DBName][$DBType][$master_or_slave]['pass'] : $DBConfig[$master_or_slave]['pass']; $hostspec = empty($DBConfig[$master_or_slave]['host']) ? DBConfig::$config['mysql'][$DBName][$DBType][$master_or_slave]['host'] : $DBConfig[$master_or_slave]['host']; $port = !isset($DBConfig[$master_or_slave]['port']) || !is_numeric($DBConfig[$master_or_slave]['port']) ? DBConfig::$config['mysql'][$DBName][$DBType][$master_or_slave]['port'] : $DBConfig[$master_or_slave]['port']; $database = empty($DBConfig[$master_or_slave]['database']) ? DBConfig::$config['mysql'][$DBName][$DBType][$master_or_slave]['database'] : $DBConfig[$master_or_slave]['database']; $charset = empty($DBConfig['charset']) ? DBConfig::$config['mysql'][$DBName][$DBType][$master_or_slave]['charset'] : strtolower($DBConfig['charset']); $db_key = md5(implode('-', array($hostspec, $port, $username, $database, $charset))); self::$linkConfig = array('host' => $hostspec, 'port' => $port, 'db' => $database, 'charset' => $charset); if (isset(self::$links[$db_key]) && !$reConnect) { return self::$links[$db_key]; } // self::$links[$db_key] = new PDO($dsn, $username, $password); $dsn = "mysql:dbname={$database};port={$port};host={$hostspec}"; $connectType = $reConnect ? 'db_reconnect' : 'db_connect'; defined('DAGGER_DEBUG') && BaseModelCommon::debug($dsn . "|username:{$username}|pw:***", $connectType); $mysqli = mysqli_init(); $mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 4); if ($mysqli->real_connect($hostspec, $username, $password, $database, $port)) { $mysqli->set_charset($charset); defined('DAGGER_DEBUG') && BaseModelCommon::debug($charset, "db_set_charset"); self::$links[$db_key] = $mysqli; return self::$links[$db_key]; } else { return false; } }
function daggerExceptionHandler($exception) { $errormsg = $exception->getMessage(); $errno = $exception->getCode(); $sendmsg = (empty($_SERVER['REQUEST_URI']) ? empty($_SERVER['SCRIPT_FILENAME']) ? '' : '(' . $_SERVER['SCRIPT_FILENAME'] . ')' : '(' . $_SERVER['REQUEST_URI'] . ')') . $errormsg; //记录到监控中心 switch (get_class($exception)) { case 'BaseModelDBException': BaseModelLog::sendLog($errno, $sendmsg, '', BaseModelLog::ERROR_MODEL_ID_DB); break; case 'BaseModelMCException': BaseModelLog::sendLog($errno, $sendmsg, '', BaseModelLog::ERROR_MODEL_ID_MC); break; case 'BaseModelHTTPException': BaseModelLog::sendLog($errno, $sendmsg, '', BaseModelLog::ERROR_MODEL_ID_HTTP); break; case 'BaseModelS3Exception': BaseModelLog::sendLog($errno, $sendmsg, '', BaseModelLog::ERROR_MODEL_ID_S3); break; default: BaseModelLog::sendLog($errno, $sendmsg, '', BaseModelLog::ERROR_MODEL_ID_DEFAULT); break; } defined('DAGGER_DEBUG') && BaseModelCommon::debug('[errro code] ' . $errno . ' [errro msg] ' . $errormsg . ' [详细说明]:https://github.com/wxkingstar/dagger/wiki/' . $errno, 'dagger_error'); if (!defined('DAGGER_DEBUG') || defined('DAGGER_ENV') && DAGGER_ENV === 'product') { BaseModelMessage::showError('抱歉让您看到这个页面'); } else { if (defined('QUEUE') || isset($_SERVER['HTTP_X_REQUESTED_WITH'])) { BaseModelMessage::showError($errormsg, BaseModelException::$data, $errno); } else { $trace = $exception->getTrace(); $tracemsg = array(); $pos = 0; foreach ($trace as $k => $error) { if (strpos($error['function'], "smarty_function_") === 0) { $errormsg = 'smarty插件:' . substr($error['function'], 16) . $errormsg; $pos = false; defined('DAGGER_DEBUG') && BaseModelCommon::debug($errormsg, 'dagger_error'); } if (!isset($error['line']) && $pos === 0) { $pos = $k; } if (!empty($error['function'])) { $fun = ''; if (!empty($error['class'])) { $fun .= $error['class'] . $error['type']; } $fun .= $error['function'] . '('; if (!empty($error['args'])) { $mark = ''; foreach ($error['args'] as $arg) { //由于smarty和call_user方法会出现超大对象或数组传入,导致报错页面崩溃,所以直接跳过参数解析输出 if (stripos($error['function'], 'smarty') === 0 || stripos($error['function'], 'call_user') === 0) { continue; } $fun .= $mark; if (is_array($arg)) { $fun .= var_export($arg, true); } else { if (is_bool($arg)) { $fun .= $arg ? 'true' : 'false'; } else { if (is_int($arg) || is_float($arg)) { $fun .= $arg; } else { if (is_null($arg)) { $fun .= 'NULL'; } else { $fun .= '\'' . BaseModelException::daggerHtmlspecialchars(BaseModelException::daggerClear($arg)) . '\''; } } } } $mark = ', '; } } $fun .= ')'; $error['function'] = $fun; } $tracemsg[] = array('file' => isset($error['file']) ? str_replace(array(DAGGER_PATH_ROOT, '\\'), array('', '/'), $error['file']) : '', 'line' => isset($error['line']) ? $error['line'] : '', 'function' => $error['function']); } $throwPhpCode = file($exception->getFile()); $tracemsg = array_merge(array(array('file' => str_replace(array(DAGGER_PATH_ROOT, '\\'), array('', '/'), $exception->getFile()), 'line' => $exception->getLine(), 'function' => $throwPhpCode[$exception->getLine() - 1])), $tracemsg); defined('DAGGER_DEBUG') && BaseModelCommon::debug(array_merge(array(array('File', 'Line', 'Function')), $tracemsg), 'dagger_error_trace'); if ($pos > 0) { $errorFileCode = array_slice(file($tracemsg[$pos]['file']), $tracemsg[$pos]['line'] > 6 ? $tracemsg[$pos]['line'] - 7 : 0, 13); $tracemsg[$pos]['function'] = '<pre class="brush: php; toolbar : false; highlight: ' . $tracemsg[$pos]['line'] . '; first-line: ' . ($tracemsg[$pos]['line'] > 6 ? $tracemsg[$pos]['line'] - 6 : 1) . '">' . implode('', $errorFileCode) . '</pre>'; } $traceTable = ''; if (is_array($tracemsg) && !empty($tracemsg)) { $traceTable .= '<table cellpadding="5" cellspacing="1" width="100%" class="table">'; $traceTable .= '<tr class="bg2"><th width="249px">File</th><th width="44px">Line</th><th width="629px">Function</th></tr>'; foreach ($tracemsg as $k => $msg) { $traceTable .= '<tr class="' . ($pos > 0 && $k == $pos ? 'bg3' : 'bg1') . '">'; $traceTable .= '<td>' . $msg['file'] . '</td>'; $traceTable .= '<td>' . $msg['line'] . '</td>'; $traceTable .= '<td>' . $msg['function'] . '</td>'; $traceTable .= '</tr>'; } $traceTable .= '</table>'; } BaseModelDebug::showTrace($errno, $errormsg, $traceTable); } } }
public static function sysMail($addresses = '', $subject = "", $content = '', $options = array()) { // 环境变量设置 $_SERVER['SINASRV_DPMAIL_TIMEOUT'] = 3; $_SERVER['SINASRV_DPMAIL_HOST'] = '10.44.6.21'; $_SERVER['SINASRV_DPMAIL_URL'] = 'http://10.44.6.21/mailservice/api.php'; $_SERVER['SERVER_NAME'] = 'topic.t.sina.com.cn'; if (!class_exists('Mail', false)) { include 'DPUtils/Mail.php'; } $mail = new Mail(); $from = array('*****@*****.**', 'web_monitor'); /* $subject = 'test'; $content = 'test'; $addresses = array( array('*****@*****.**') ); $options = array('cc' => array(array('*****@*****.**', 'xu yan'),),); */ if (is_array($addresses)) { foreach ($addresses as $k => $address) { $recipients[$k] = (array) $address; } } else { $recipients = array((array) $addresses); } $result = $mail->send($from, $recipients, $subject, $content, $options); if ($result === false) { $errno = $mail->errno(); BaseModelCommon::debug($errno, 'mail_error'); return $errno; } else { return true; } }
/** * 检测memcache是否正常运行 */ private function checkConnection() { $timeout = defined('DAGGER_MCCONNECT_TIMEOUT') ? DAGGER_MCCONNECT_TIMEOUT : 0.5; $startTime = microtime(true); $rs = $this->mc->getVersion(); $checkTime = microtime(true) - $startTime; if ($checkTime > $timeout) { $errno = 90501; $error = "MC连接超{$timeout}秒" . "request_uri[{$_SERVER['REQUEST_URI']}]," . "c/s[{$_SERVER['REMOTE_ADDR']}/{$_SERVER['SERVER_ADDR']}]," . "mc[" . $this->servers . "]" . "runtime[{$runTime}s/{$timeout}s]"; defined('DAGGER_DEBUG') && BaseModelCommon::debug('[errro code] ' . $errno . ' [errro msg] ' . $errormsg . ' [详细说明]:https://github.com/wxkingstar/dagger/wiki/' . $errno, 'mc_error'); BaseModelLog::sendLog($errno, $error, '', BaseModelLog::ERROR_MODEL_ID_MC); } if ($rs !== false) { return true; } BaseModelLog::sendLog(90500, "memcache服务器: {$this->servers} 无法响应", '', BaseModelLog::ERROR_MODEL_ID_MC); return false; }
/** * 增加慢查询提示 */ public function debugResult($result, $type = '') { parent::debugResult($result, $type); if (defined('DAGGER_DEBUG')) { $runTime = floatval($this->runTime) * 1000; if ($runTime > 100) { BaseModelCommon::debug('slow sql', 'warn'); } } }
/** * 调试结果 * @param string $sql * @param array $data * @return void */ protected function debugResult($result, $type = '') { $this->runTime = BaseModelCommon::addStatInfo('db', $this->runTime); if (defined('DAGGER_DEBUG')) { $arr = empty($type) ? array(array('运行时间', '查询结果'), array($this->runTime, $result)) : array(array('运行时间', '影响条目'), array($this->runTime, $result['affected_num'])); BaseModelCommon::debug($arr, 'db_sql_result'); } }
private static function _curl_check($ch) { $curl_errno = curl_errno($ch); if ($curl_errno) { $curl_error = curl_error($ch); $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); defined('DAGGER_DEBUG') && BaseModelCommon::debug("[errno] {$curl_errno} [error] {$curl_error}", 'request_curl_error'); self::_error(90404, "curl内部错误信息[{$curl_errno}][{$curl_error}][{$url}]"); return false; } return true; }
public static function route() { if (isset($_GET[DAGGER_APP]) && preg_match('/^\\w*$/i', $_GET[DAGGER_APP])) { Configure::$app = $_GET[DAGGER_APP]; } else { Configure::getDefaultApp(); } if (DAGGER_ROUTER == 1 && !empty(RouterConfig::$config[Configure::$app])) { $uri = str_replace('/index.php', '', $_SERVER['REQUEST_URI']); //对于中文,已经变为urlencode,参数化的时候需要先decode出来 $uri = urldecode($uri); defined('DAGGER_DEBUG') && BaseModelCommon::debug($uri, 'router_request_uri'); //从uri中过滤掉key value查询串 $uri = explode('?', $uri); $uri = array_shift($uri); $uriArr = explode('/', trim($uri, '/')); $uriArrWithoutApp = array(); //判断是否选择了app foreach ($uriArr as $uripart) { if (strpos($uripart, DAGGER_APP_PREFIX) === 0) { Configure::$app = substr($uripart, strlen(DAGGER_APP_PREFIX)); self::$get[DAGGER_APP] = Configure::$app; } else { if (strlen($uripart) > 0) { $uriArrWithoutApp[] = $uripart; } } } $uri = '/' . implode('/', $uriArrWithoutApp); //从URI中去除baseurl中的多级目录 $baseUrlArr = explode('/', RouterConfig::$baseUrl[Configure::$app], 2); if (!empty($baseUrlArr[1])) { $baseUrl = '/' . trim($baseUrlArr[1], '/'); if (strpos($uri, $baseUrl) === 0) { defined('DAGGER_DEBUG') && BaseModelCommon::debug('url规则匹配上BaseUrl:' . $baseUrl, 'router_base_url'); //匹配RouterConfig中设置的对应BaseUrl $uri = substr($uri, strlen($baseUrl)); $uri === false && ($uri = ""); } } //将uri变为参数数组 $paramsArr = explode('/', trim($uri, '/')); self::$get = array_merge(self::$get, $_GET); $configArr = RouterConfig::$config[Configure::$app]; if (isset($configArr[$paramsArr[0]])) { /** * 从URI的第一个参数开始,搜索RouterConfig中的配置项。 * 不能匹配的URI参数尝试匹配下一个RouterConfig配置项 */ $_GET[DAGGER_CONTROLLER] = $paramsArr[0]; self::$get[DAGGER_CONTROLLER] = $_GET[DAGGER_CONTROLLER]; array_shift($paramsArr); $configArr = $configArr[$_GET[DAGGER_CONTROLLER]]; if (!isset($_GET[DAGGER_ACTION])) { if (isset($paramsArr[0]) && isset($configArr[$paramsArr[0]])) { $_GET[DAGGER_ACTION] = $paramsArr[0]; self::$get[DAGGER_ACTION] = $_GET[DAGGER_ACTION]; array_shift($paramsArr); } elseif (isset(RouterConfig::$defaultRouter) && isset(RouterConfig::$defaultRouter[Configure::$app]['default_action'][$_GET[DAGGER_CONTROLLER]])) { $_GET[DAGGER_ACTION] = RouterConfig::$defaultRouter[Configure::$app]['default_action'][$_GET[DAGGER_CONTROLLER]]; } else { throw new BaseModelException("APP:" . Configure::$app . ",controller:" . $_GET[DAGGER_CONTROLLER] . "没有设置默认action", 90206, 'router_trace'); } } $configArr = explode('/', $configArr[$_GET[DAGGER_ACTION]]); } else { //检测是否有controller参数,没有使用默认设置 if (!isset($_GET[DAGGER_CONTROLLER])) { if (isset(RouterConfig::$defaultRouter) && isset(RouterConfig::$defaultRouter[Configure::$app]['default_controller'])) { $_GET[DAGGER_CONTROLLER] = RouterConfig::$defaultRouter[Configure::$app]['default_controller']; } else { throw new BaseModelException("APP:" . Configure::$app . "没有设置默认Controller", 90205, 'router_trace'); } if (isset($_GET[DAGGER_ACTION])) { throw new BaseModelException("指定action参数时必须指定controller参数", 90207, 'router_trace'); } } if (!isset($_GET[DAGGER_ACTION])) { //使用默认action设置 if (isset(RouterConfig::$defaultRouter) && isset(RouterConfig::$defaultRouter[Configure::$app]['default_action'][$_GET[DAGGER_CONTROLLER]])) { $_GET[DAGGER_ACTION] = RouterConfig::$defaultRouter[Configure::$app]['default_action'][$_GET[DAGGER_CONTROLLER]]; } else { throw new BaseModelException("APP:" . Configure::$app . ",controller:" . $_GET[DAGGER_CONTROLLER] . "没有设置默认action", 90206, 'router_trace'); } } } while (!empty($paramsArr[0])) { if (empty($configArr)) { self::init(Configure::$app); defined('DAGGER_DEBUG') && BaseModelCommon::debug(RouterConfig::$config, "router_RouterConfig"); throw new BaseModelException("[app]:" . Configure::$app . " [controller]:{$_GET[DAGGER_CONTROLLER]} [action]:{$_GET[DAGGER_ACTION]} ,不识别“/" . implode("/", $paramsArr) . "”,请配置路由规则", 90200, 'router_trace'); } if (self::match($configArr[0], $paramsArr[0])) { array_shift($paramsArr); } array_shift($configArr); } defined('DAGGER_DEBUG') && BaseModelCommon::debug($_GET, 'router_$_GET'); } $_GET[DAGGER_APP] = Configure::$app; self::init(Configure::$app); }
private function _checkStats($function, $times = 0, $native = false) { $runTime = 0; if (!empty($times)) { $runTime = BaseModelCommon::addStatInfo('mc', $this->startRunTime, $times); } $native = $this->native || $native; $code = $native ? $this->mcd->getResultCode() : $this->lastResultCode; if (in_array($code, array(Memcached::RES_SUCCESS, Memcached::RES_NOTFOUND), true)) { return $runTime; } else { if (in_array($function, array('add', 'addByKey', '_getLock'), true) && in_array($code, array(Memcached::RES_DATA_EXISTS, Memcached::RES_NOTSTORED), true)) { return $runTime; } } $errno = 90502; $error = $native ? $this->mcd->getResultMessage() : $this->lastResultMessage; defined('DAGGER_DEBUG') && BaseModelCommon::debug("[errro code] {$errno} [errro msg] {$error} [详细说明]:http://wiki.intra.sina.com.cn/display/dagger/{$errno}", 'request_error'); BaseModelLog::sendLog($errno, "[code]{$code}[msg]{$error}[method]{$function}[server]{$this->servers}", BaseModelException::getCodeName($errno), BaseModelLog::ERROR_MODEL_ID_MC); return $runTime; }
/** * 增加慢查询提示 */ public function debugResult($result, $type = '') { parent::debugResult($result, $type); if (defined('DAGGER_DEBUG')) { $runTime = floatval($this->runTime); //本来就是毫秒..不用成1000.. if ($runTime > 100) { //超过100ms 就为慢查询... BaseModelCommon::debug('slow sql', 'warn'); } } }