public function onRequest($request, $response) { $filename = ZPHP::getRootPath() . DS . 'webroot' . $request->server['path_info']; if (is_file($filename)) { //解析静态文件 $response->header("Content-Type", $this->getMime($filename) . '; charset=utf-8'); $response->end(file_get_contents($filename)); return; } $param = []; if (!empty($request->get)) { $param = $request->get; } if (!empty($request->post)) { $param += $request->post; } $_SERVER['HTTP_USER_AGENT'] = $request->header['user-agent']; Request::parse($param); Request::setViewMode('Php'); Request::setHttpServer(1); Response::setResponse($response); try { $result = ZRoute::route(); } catch (\Exception $e) { $model = Formater::exception($e); $model['_view_mode'] = 'Json'; $result = Response::display($model); } $response->end($result); Request::setViewMode(ZConfig::getField('project', 'view_mode', 'Json')); Request::setHttpServer(0); }
public function display() { $tplPath = ZPHP\Core\Config::getField('project', 'tpl_path', 'template' . DS . 'template'); $fileName = ZPHP\ZPHP::getRootPath() . DS . $tplPath . DS . $this->tplFile; if (!\is_file($fileName)) { throw new \Exception("no file {$fileName}"); } if (!empty($this->model)) { \extract($this->model); } include "{$fileName}"; }
public function onSend($fd, $data) { $pathInfo = $_SERVER['PATH_INFO']; $filePath = \ZPHP\ZPHP::getRootPath() . DS . ZConfig::getField('project', 'webroot', 'webroot') . $pathInfo; $mime = 'text/html'; if (is_file($filePath)) { $result = file_get_contents($filePath); $mime = $this->getMime($filePath); } else { $result = $this->route($data, $fd); } $this->sendTo($fd, $result, $mime); }
public static function info($type, $params = array()) { $t = \date("Ymd"); $logPath = Config::get('log_path', ''); if (empty($logPath)) { $dir = ZPHP::getRootPath() . DS . 'log' . DS . $t; } else { $dir = $logPath . DS . $t; } Dir::make($dir); $str = \date('Y-m-d H:i:s', Config::get('now_time', time())) . self::SEPARATOR . \implode(self::SEPARATOR, array_map('json_encode', $params)); $logFile = $dir . \DS . $type . '.log'; \error_log($str . "\n", 3, $logFile); }
public static function info($type, $params = array()) { $t = \date("Ymd"); $logPath = Config::getField('project', 'log_path', ''); if (empty($logPath)) { $dir = ZPHP::getRootPath() . DS . 'log' . DS . $t; } else { $dir = $logPath . DS . $t; } Dir::make($dir); $str = \date('Y-m-d H:i:s', Config::get('now_time', time())) . self::SEPARATOR . \implode(self::SEPARATOR, array_map('ZPHP\\Common\\Log::myJson', $params)); $logFile = $dir . \DS . $type . '.log'; \file_put_contents($logFile, $str . "\n", FILE_APPEND | LOCK_EX); }
public function display() { $tplPath = ZPHP\Core\Config::getField('project', 'tpl_path', ZPHP\ZPHP::getRootPath() . DS . 'template' . DS . 'default' . DS); $fileName = $tplPath . $this->tplFile; if (!\is_file($fileName)) { throw new \Exception("no file {$fileName}"); } if (!empty($this->model)) { \extract($this->model); } if (ZPHP\Protocol\Request::isLongServer()) { \ob_start(); include "{$fileName}"; $content = ob_get_contents(); \ob_end_clean(); return $content; } include "{$fileName}"; return null; }
public function display() { $tplPath = ZPHP\Core\Config::getField('project', 'tpl_path', ZPHP\ZPHP::getRootPath() . DS . 'template' . DS . 'default' . DS); $fileName = $tplPath . $this->tplFile; if (!\is_file($fileName)) { throw new \Exception("no file {$fileName}"); } if (!empty($this->model)) { \extract($this->model); } if (Config::get('server_mode') == 'Http') { include "{$fileName}"; } else { \ob_start(); include "{$fileName}"; $content = ob_get_contents(); \ob_end_clean(); return $content; } }
public function to_string() { $params = array_merge($this->_params, array()); $params['width'] = $this->get_width(); $params['height'] = $this->get_height(); $params['type'] = 'application/x-java-applet'; $attrs_html = self::_get_attr_html($params); $html = "<{$this->_tagname}{$attrs_html}>"; $html .= '<param name="code" value=' . HTMLHelper::quote($this->get_code_class()) . ' />'; // $jar_url = String::put_sufix($this->get_jar_url(), '.jar', false).'?i='; $jar_url = $this->get_jar_url() . '?i='; if (!ZPHP::get_is_production()) { $jar_url .= uniqid(); } else { $jar_url .= ZPHP::get_app_version(); } $html .= '<param name="archive" value=' . HTMLHelper::quote($jar_url) . ' />'; foreach ($this->_args->to_array() as $key => $value) { $html .= '<param name=' . HTMLHelper::quote($key) . ' value=' . HTMLHelper::quote($value) . ' />'; } $html .= $this->get_error_string(); $html .= "</{$this->_tagname}>"; return $html; }
<?php use ZPHP\ZPHP; if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); } $rootPath = dirname(__DIR__); require dirname($rootPath) . '/ZPHP/ZPHP.php'; ZPHP::setRootPath($rootPath); //:~ $cmds = array('reload', 'shutdown', 'test'); $server = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : ''; $cmd = isset($_SERVER['argv'][2]) ? $_SERVER['argv'][2] : ''; if (empty($server)) { exit("wrong server.\n"); } if (!in_array($cmd, $cmds)) { exit("cmd must in [ " . implode("|", $cmds) . "]\n"); } require_once "../config/{$server}/config.php"; $servInfo = array(); $servInfo['host'] = $config['socket']['host']; $servInfo['port'] = $config['socket']['port']; if (empty($servInfo['host']) || empty($servInfo['port'])) { exit("wrong server host or port.\n"); } //:~ //发送给server的数据 $reqData = array('a' => "server\\{$cmd}"); //$reqData = array( // 'a' => "user\\login"
private function getPath() { return isset($this->config['save_path']) ? $this->config['save_path'] : ZPHP::getRootPath() . DS . 'session_tmp'; }
<?php use ZPHP\ZPHP; $config = array('server_mode' => 'Server\\WebSocket', 'project_name' => 'zwebsocket', 'app_path' => 'apps', 'ctrl_path' => 'ctrl', 'lib_path' => ZPHP::getRootPath() . DS . '..' . DS . 'lib', 'project' => array('default_ctrl_name' => 'main', 'log_path' => 'socket', 'static_url' => 'http://hs.static.45117.com/', 'app_host' => $_SERVER['HTTP_HOST']), 'socket' => array('host' => '0.0.0.0', 'port' => 8993, 'adapter' => 'Swoole', 'adapter' => 'Swoole', 'socket_type' => '\\ZPHP', 'work_mode' => 3, 'worker_num' => 1, 'client_class' => 'socket\\WebSocket', 'parse_class' => 'WebSocketChatParse', 'protocol' => 'Rpc', 'call_mode' => 'ZPHP', 'max_request' => 10000, 'dispatch_mode' => 2, 'heartbeat_idle_time' => 600, 'heartbeat_check_interval' => 610)); $publicConfig = array('connection.php', 'cache.php'); foreach ($publicConfig as $file) { $file = ZPHP::getRootPath() . DS . 'config' . DS . 'public' . DS . $file; $config += (include "{$file}"); } return $config;
public function request(array $url, $stdin = false) { $params = array('GATEWAY_INTERFACE' => 'CGI/1.1', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'REQUEST_METHOD' => 'GET', 'SCRIPT_FILENAME' => isset($url['SCRIPT_NAME']) ? $url['SCRIPT_NAME'] : ZPHP::getRootPath() . DS . 'webroot' . DS . 'main.php', 'SCRIPT_NAME' => isset($url['SCRIPT_NAME']) ? $url['SCRIPT_NAME'] : DS . 'main.php', 'DOCUMENT_URI' => isset($url['DOCUMENT_URI']) ? $url['DOCUMENT_URI'] : DS . 'main.php', 'HTTP_HOST' => isset($url['HTTP_HOST']) ? $url['HTTP_HOSTI'] : 'default', 'QUERY_STRING' => $url['query'], 'REQUEST_URI' => DS . $url['query'], 'SERVER_SOFTWARE' => 'zphp', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => '9985', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_PORT' => '80', 'SERVER_NAME' => php_uname('n'), 'CONTENT_TYPE' => '', 'CONTENT_LENGTH' => 0, 'REQUEST_TIME' => time()); $response = ''; $this->connect(); $request = $this->buildPacket(self::BEGIN_REQUEST, chr(0) . chr(self::RESPONDER) . chr((int) $this->_keepAlive) . str_repeat(chr(0), 5)); $paramsRequest = ''; foreach ($params as $key => $value) { $paramsRequest .= $this->buildNvpair($key, $value); } if ($paramsRequest) { $request .= $this->buildPacket(self::PARAMS, $paramsRequest); } $request .= $this->buildPacket(self::PARAMS, ''); if ($stdin) { $request .= $this->buildPacket(self::STDIN, $stdin); } $request .= $this->buildPacket(self::STDIN, ''); fwrite($this->_sock, $request); do { $resp = $this->readPacket(); if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) { $response .= $resp['content']; } } while ($resp && $resp['type'] != self::END_REQUEST); if (!is_array($resp)) { throw new \Exception('Bad request'); } switch (ord($resp['content'][4])) { case self::CANT_MPX_CONN: throw new \Exception('This app can\'t multiplex [CANT_MPX_CONN]'); break; case self::OVERLOADED: throw new \Exception('New request rejected; too busy [OVERLOADED]'); break; case self::UNKNOWN_ROLE: throw new \Exception('Role value not known [UNKNOWN_ROLE]'); break; case self::REQUEST_COMPLETE: list($header, $content) = explode("\r\n\r\n", $response, 2); return array('header' => $header, 'content' => $content); } }
protected static function _get_exception_html(Exception $ex) { $message = $ex->getMessage(); $id_type = 0; $type_name = array_key_exists($id_type, self::$_error_types_names) ? self::$_error_types_names[$id_type] : null; $trace = self::_get_trace_array($ex->getTraceAsString()); $file_lines = file($ex->getFile()); $error_line = $ex->getLine(); foreach ($file_lines as $index => $line) { $file_lines[$index] = rtrim($line); } $file_lines_count = count($file_lines); if ($file_lines_count > self::FILE_OUT_PADDING * 2 + 1) { $start_line = $ex->getLine() - self::FILE_OUT_PADDING; $end_line = $ex->getLine() + self::FILE_OUT_PADDING; if ($start_line < 0) { $start_line = 0; } else { if ($end_line >= $file_lines_count) { $start_line = $file_lines_count - $end_line; } } if ($start_line < 1) { $start_line = 1; } $new_file_lines = array(); for ($i = 0; $i <= self::FILE_OUT_PADDING * 2 + 1; $i++) { $new_file_lines[$i + $start_line] = $file_lines[$start_line + $i - 1]; } $file_lines = $new_file_lines; } $trace_odd_item_background = '#DDD'; $trace_even_item_background = '#EEE'; $trace_item_style = "list-style-type: none; font-size: 10pt; padding: 7px 10px;"; $trace_item_file_style = "font-weight: bold; "; $trace_item_function_style = ""; $line_number_style = "display: inline-block; width: 50px; color: #888;"; $selected_line_number_style = "color: #EEE;"; $line_style = "font-family: mono;font-size: 10pt; font-weight: bold;"; $stack_trace_file_style = "font-weight: bold;"; $stack_trace_line_style = ""; $stack_trace_line_number_style = "font-weight: bold; color: #555; padding-right: 10px; padding-left: 5px;"; $stack_trace_line_index_style = "display: inline-block; width: 30px; color: #555; "; $current_line_style = "background: #FF7070 !important; font-weight: bold; color: #FFF !important;"; $header_row_style = "padding: 3px 0;"; $link_style = "color: #FFF; text-decoration: underline; "; $box_style = "box-shadow: 2px 2px 1px 1px rgba(0,0,0,0.5); border: solid 1px #111; border-radius: 5px; margin-bottom: 40px !important; "; $red_box_style = "box-shadow: 2px 2px 1px 1px rgba(0,0,0,0.5); border: solid 1px #EEE; border-radius: 5px; margin-bottom: 40px !important; "; $list_style = "border-radius: 5px;"; $first_list_item_style = "border-radius: 5px 5px 0 0;"; $last_list_item_style = "border-radius: 0 0 5px 5px;"; $list_item_style = "border-radius: 0;"; $html = '<div style="padding: 20px; background: #F2F2F2;"> <div style="background: #F00; padding: 10px 15px; border: solid 1px #A88; font-size: 12pt; ' . $red_box_style . '"> <div style="text-transform: uppercase; font-weight: bold; padding-right: 5px; color: #FFF; text-decoration: underline; padding-bottom: 8px;"> Error </div> <div style="' . $header_row_style . '"> <span style="color: #FFF; font-weight: bold; padding-right: 5px;"> Site: </span> <span style="color: #FFF"> ' . env('APP_NAME', '') . ' <span style="padding-left: 10px;">[ <a target="_blank" style="' . $link_style . '" href="' . \ZPHP\ZPHP::get_app_url() . '">' . \ZPHP\ZPHP::get_app_url() . '</a> ]</span> </span> </div> <div style="' . $header_row_style . '"> <span style="color: #FFF; font-weight: bold; padding-right: 5px;"> Request URL: </span> <span style="color: #FFF"> ' . $_SERVER['REQUEST_URI'] . ' </span> </div> <div style="' . $header_row_style . '"> <span style="color: #FFF; font-weight: bold; "> Message: </span> <span style="color: #FFF"> ' . $message . ' </span> </div></div>'; if ($type_name) { $html .= '<div style="' . $header_row_style . '"> <span style="color: #FFF; font-weight: bold; "> Error Type: </span> <span style="color: #FFF"> ' . $type_name . ' </span> </div>'; } if (!empty($trace)) { $html .= '<div style="margin: 20px 0 0;' . $box_style . ';max-height:300px;overflow-y:auto;"> <ul style="list-style-type: none; width: 100%; list-style-position: inside;margin:0;padding:0;' . $list_style . '"> <li style="margin-left: 0; padding: 10px 10px; background: ' . $trace_odd_item_background . ';background: #F00;"> <span style="color: #DDD; ' . $trace_item_file_style . '"> Stack Trace </span> </li> '; foreach ($trace as $index => $line) { $html .= '<li style="margin-left: 0;background: ' . ($index % 2 == 0 ? $trace_even_item_background : $trace_odd_item_background) . ' !important;' . $trace_item_style . ($index == count($trace) - 1 ? $last_list_item_style : $list_item_style) . '"> <span style="' . $stack_trace_line_index_style . '"> #' . ($index + 1) . ' </span> <span style="' . $stack_trace_file_style . '">' . $line['file'] . ' </span><span style="' . $stack_trace_line_number_style . '">[' . $line['line'] . '] </span> <span style="' . $stack_trace_line_style . '"> ' . $line['code'] . ' </span> </li>'; } $html .= '</ul></div>'; } $html .= ' <div style="margin: 20px 0 0;' . $box_style . '"> <ul style="list-style-type: none; width: 100%; list-style-position: inside;margin:0;padding:0;border: solid 1px #555;' . $list_style . '"> <li style="margin-left: 0; padding: 10px 10px; background: ' . $trace_odd_item_background . ';background: #F00;"> <span style="color: #DDD; ' . $trace_item_file_style . '"> ' . $ex->getFile() . ' </span> <span style="color: #FFF; padding-left: 5px; font-weight: bold;"> [' . $ex->getLine() . '] </span> </li> '; $index = 0; foreach ((array) $file_lines as $line_number => $lines) { if ($line_number == 0) { continue; } $lines = HTMLHelper::escape($lines); $html .= '<li style="margin-left: 0;' . ($index == 0 ? ' padding-top: 10px !important; ' : '') . 'background: ' . ($index % 2 == 0 ? $trace_even_item_background : $trace_odd_item_background) . ' !important;' . $trace_item_style . ($line_number == $error_line ? $current_line_style : '') . ($index == count($file_lines) - 1 ? $last_list_item_style : $list_item_style) . '"> <span style="' . $line_number_style . ($line_number == $error_line ? $selected_line_number_style : '') . '"> # ' . $line_number . ' </span> <span style="' . $line_style . '"> <!--<pre style="display: inline; border: 0; background: transparent;">' . $lines . '</pre>--> ' . str_replace("\t", ' ', $lines) . ' </span> </li>'; $index++; } $html .= '</ul></div>'; foreach (self::$_debug_vars as $debug_var) { $var = isset($GLOBALS[$debug_var]) ? $GLOBALS[$debug_var] : array(); $html .= '<div style="' . $box_style . '"> <div style="margin: 0px; border: solid 1px #333; background: #777; font-weight: bold; padding: 10px; color: #FFF;"> ' . $debug_var . ' </div> ' . VariableHelper::var_export_html($var, true) . ' </div>'; } return $html; }
<?php use ZPHP\ZPHP; use ZPHP\Socket\Adapter\Swoole; define('TPL_PATH', ZPHP::getRootPath() . DS . 'template' . DS . 'zchat' . DS); define('STATIC_URL', '/static/'); return array('server_mode' => 'Server\\WebSocket', 'project_name' => 'zwebsocket', 'app_path' => 'apps', 'ctrl_path' => 'ctrl', 'lib_path' => ZPHP::getRootPath() . DS . '..' . DS . 'lib', 'project' => array('default_ctrl_name' => 'main', 'log_path' => 'socket', 'static_url' => STATIC_URL, 'tpl_path' => TPL_PATH), 'socket' => array('host' => '0.0.0.0', 'port' => 8992, 'adapter' => 'Swoole', 'server_type' => Swoole::TYPE_WEBSOCKET, 'protocol' => 'Json', 'daemonize' => 1, 'client_class' => 'socket\\WebSocket', 'work_mode' => 3, 'worker_num' => 4, 'task_worker_num' => 2, 'max_request' => 0, 'debug_mode' => 0), 'pdo' => ['dsn' => 'mysql:host=localhost;port=3306', 'name' => 'cd', 'user' => 'laya_log', 'pass' => 'NXdfHu3aWfXmGMjE', 'dbname' => 'laya_log', 'charset' => 'UTF8', 'pconnect' => true, 'ping' => 1], 'route' => ['static' => ['/' => ['main', 'main']], 'dynamic' => ['/^\\/(.+)\\/(.+)$/iU' => ['{1}', '{2}', [], '/{a}/{m}']]]);
private static function getTrace() { $traces = debug_backtrace(); // only display 2 to 6 backtrace for ($i = 2, $n = count($traces); $i < $n && $i < 7; $i++) { //for ($i = 3, $n = count($traces); $i < $n; $i++){ $trace = $traces[$i]; if (isset($trace['type'])) { $callInfo = $trace['class'] . $trace['type'] . $trace['function'] . '()'; } else { $callInfo = 'internal:' . $trace['function'] . '()'; } if (isset($trace['file'])) { $fileInfo = str_replace(ZPHP::getRootPath() . '/', '', $trace['file']) . ':' . $trace['line']; } else { $fileInfo = ''; } //$traces_data[] = $fileInfo . " " . $callInfo; $traces_data[] = $callInfo . " " . $fileInfo; } return $traces_data; }
public static function get_site_url() { return \ZPHP\ZPHP::get_app_url(); }
public function onWorkerStart() { //这里require zphp框架目录地址 opcache_reset(); require dirname(__DIR__) . DIRECTORY_SEPARATOR . 'ZPHP' . DIRECTORY_SEPARATOR . 'ZPHP.php'; ///home/wwwroot/www.zphp.com, 是应用的地址 $this->zphp = ZPHP::run($this->webPath, false, $this->configPath); $params = func_get_args(); // echo "worker {$params[1]} start".PHP_EOL; $this->mimes = (require 'mimes.php'); }
<?php use ZPHP\ZPHP; define('START_SERV_TIME', time()); $config = array('server_mode' => 'Socket', 'project_name' => 'gambleapp', 'app_path' => 'app', 'ctrl_path' => 'control', 'project' => array('language' => 'zh-cn', 'debug_mode' => 1, 'log_path' => 'log'), 'socket' => array('host' => '0.0.0.0', 'port' => 8991, 'adapter' => 'Swoole', 'daemonize' => 0, 'times' => array('rungame' => 1000, 'online' => 10000), 'work_mode' => 3, 'worker_num' => 4, 'task_worker_num' => 2, 'client_class' => 'socket\\Swoole', 'protocol' => 'Json', 'max_request' => 10000, 'heartbeat_idle_time' => 21600, 'heartbeat_check_interval' => 30, 'log_file' => dirname(dirname(__DIR__)) . '/log/swoole.log', 'dispatch_mode' => 2, 'data_eof' => "~~code~~")); $publicConfig = array('pdo.php', 'connection.php', 'cache.php'); foreach ($publicConfig as $file) { $file = ZPHP::getRootPath() . DS . 'config' . DS . 'public' . DS . $file; $config += (include "{$file}"); } //load exception language if (isset($config['project']['language'])) { $langFile = ZPHP::getRootPath() . DS . "{$config['app_path']}" . DS . "language" . DS . "{$config['project']['language']}" . DS . "ui.php"; $config += (include "{$langFile}"); } //load game config $gameConfig = array('init.php', 'item.php', 'map.php', 'reward.php', 'itemrate.php'); foreach ($gameConfig as $file) { $file = ZPHP::getRootPath() . DS . 'config' . DS . 'game' . DS . $file; $config += (include "{$file}"); } return $config;
<?php /** * Created by PhpStorm. * User: ���� * Date: 2015/8/27 * Time: 20:08 * Desc: ����ļ� */ use ZPHP\ZPHP; $rootPath = dirname(__DIR__); require 'zphp' . DIRECTORY_SEPARATOR . 'ZPHP' . DIRECTORY_SEPARATOR . 'ZPHP.php'; ZPHP::run($rootPath);
<?php /** * Created by PhpStorm. * User: 王晶 * Date: 2015/8/27 * Time: 20:09 */ use ZPHP\ZPHP; use ZPHP\Socket\Adapter\Swoole; //定义当前请求时间 define('NOW_TIME', isset($_SERVER['REQUEST_TIME']) ? $_SERVER['REQUEST_TIME'] : time()); //定义项目根目录 if (!defined('ROOT_PATH')) { define('ROOT_PATH', ZPHP::getRootPath()); } //定义项目名称 define('PROJECT_NAME', 'zmail'); //定义模版目录 define('TPL_PATH', ROOT_PATH . DS . 'template' . DS . PROJECT_NAME . DS); //定义静态地址目录 define('STATIC_URL', '/static/'); //定义上传目录 define('UPLOAD_PATH', ROOT_PATH . DS . 'webroot' . DS . 'upload' . DS); //项目配置 $config = ['server_mode' => 'Socket', 'project_name' => PROJECT_NAME, 'app_path' => 'apps', 'ctrl_path' => 'ctrl', 'lib_path' => ROOT_PATH . DS . '..' . DS . 'lib', 'project' => ['default_ctrl_name' => 'mail', 'default_method_name' => 'send', 'log_path' => ROOT_PATH . DS . 'log' . DS . PROJECT_NAME, 'static_url' => STATIC_URL, 'tpl_path' => TPL_PATH, 'view_mode' => 'Json', 'app_host' => empty($_SERVER['HTTP_HOST']) ? '' : $_SERVER['HTTP_HOST'], 'exception_handler' => 'common\\MyException::exceptionHandler', 'fatal_handler' => 'common\\MyException::fatalHandler', 'debug_mode' => 0, 'ctrl_name' => '_act', 'method_name' => '_mod'], 'socket' => array('host' => '0.0.0.0', 'port' => 8996, 'adapter' => 'Swoole', 'server_type' => Swoole::TYPE_TCP, 'protocol' => 'Json', 'daemonize' => 1, 'client_class' => 'socket\\Tcp', 'work_mode' => 3, 'worker_num' => 4, 'task_worker_num' => 16, 'max_request' => 0, 'debug_mode' => 0, 'open_length_check' => true, 'package_length_type' => 'N', 'package_length_offset' => 0, 'package_body_offset' => 4, 'package_max_length' => 2000000), 'mail' => ['smtp_host' => 'smtp.163.com', 'smtp_port' => 25, 'username' => '*****@*****.**', 'password' => '123456', 'sendname' => 'zmail.server'], 'route' => ['static' => ['/' => ['main', 'main']], 'dynamic' => ['/^\\/(.+)\\/(.+)$/iU' => ['{1}', '{2}', [], '/{a}/{m}']]]]; return $config;