mirror of
https://github.com/zhamao-robot/zhamao-framework.git
synced 2026-07-20 23:25:35 +08:00
update to 2.1.5 version
change route to Symfony routing
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
"description": "High performance QQ robot and web server development framework",
|
||||
"minimum-stability": "stable",
|
||||
"license": "Apache-2.0",
|
||||
"version": "2.1.4",
|
||||
"version": "2.1.5",
|
||||
"extra": {
|
||||
"exclude_annotate": [
|
||||
"src/ZM"
|
||||
|
||||
@@ -12,6 +12,7 @@ use ReflectionMethod;
|
||||
use ZM\Annotation\Http\{HandleAfter, HandleBefore, Controller, HandleException, Middleware, MiddlewareClass, RequestMapping};
|
||||
use ZM\Annotation\Interfaces\Level;
|
||||
use ZM\Annotation\Module\Closed;
|
||||
use ZM\Http\RouteManager;
|
||||
use ZM\Utils\DataProvider;
|
||||
|
||||
class AnnotationParser
|
||||
@@ -113,7 +114,7 @@ class AnnotationParser
|
||||
$method_anno->class = $v;
|
||||
$method_anno->method = $method_name;
|
||||
if ($method_anno instanceof RequestMapping) {
|
||||
$this->registerRequestMapping($method_anno, $method_name, $v, $methods_annotations); //TODO: 用symfony的routing重写
|
||||
RouteManager::importRouteByAnnotation($method_anno, $method_name, $v, $methods_annotations);
|
||||
} elseif ($method_anno instanceof Middleware) {
|
||||
$this->middleware_map[$method_anno->class][$method_anno->method][] = $method_anno->middleware;
|
||||
}
|
||||
@@ -121,11 +122,6 @@ class AnnotationParser
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//预处理4:生成路由树(换成symfony后就不需要了)
|
||||
$tree = $this->genTree($this->req_mapping);
|
||||
$this->req_mapping = $tree[0];
|
||||
|
||||
Console::debug("解析注解完毕!");
|
||||
}
|
||||
|
||||
@@ -175,109 +171,6 @@ class AnnotationParser
|
||||
|
||||
//private function below
|
||||
|
||||
private function registerRequestMapping(RequestMapping $vss, $method, $class, $methods_annotations) {
|
||||
$prefix = '';
|
||||
foreach ($methods_annotations as $annotation) {
|
||||
if ($annotation instanceof Controller) {
|
||||
$prefix = $annotation->prefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$array = $this->req_mapping;
|
||||
$uid = count($array);
|
||||
$prefix_exp = explode("/", $prefix);
|
||||
$route_exp = explode("/", $vss->route);
|
||||
foreach ($prefix_exp as $k => $v) {
|
||||
if ($v == "" || $v == ".." || $v == ".") {
|
||||
unset($prefix_exp[$k]);
|
||||
}
|
||||
}
|
||||
foreach ($route_exp as $k => $v) {
|
||||
if ($v == "" || $v == ".." || $v == ".") {
|
||||
unset($route_exp[$k]);
|
||||
}
|
||||
}
|
||||
if ($prefix_exp == [] && $route_exp == []) {
|
||||
$array[0]['method'] = $method;
|
||||
$array[0]['class'] = $class;
|
||||
$array[0]['request_method'] = $vss->request_method;
|
||||
$array[0]['route'] = $vss->route;
|
||||
$this->req_mapping = $array;
|
||||
return;
|
||||
}
|
||||
$pid = 0;
|
||||
while (($shift = array_shift($prefix_exp)) !== null) {
|
||||
foreach ($array as $k => $v) {
|
||||
if ($v["name"] == $shift && $pid == ($v["pid"] ?? -1)) {
|
||||
$pid = $v["id"];
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
$array[$uid++] = [
|
||||
'id' => $uid - 1,
|
||||
'pid' => $pid,
|
||||
'name' => $shift
|
||||
];
|
||||
$pid = $uid - 1;
|
||||
}
|
||||
while (($shift = array_shift($route_exp)) !== null) {
|
||||
/*if (mb_substr($shift, 0, 1) == "{" && mb_substr($shift, -1, 1) == "}") {
|
||||
$p->removeAllRoute();
|
||||
Console::info("移除本节点其他所有路由中");
|
||||
}*/
|
||||
foreach ($array as $k => $v) {
|
||||
if ($v["name"] == $shift && $pid == ($v["pid"] ?? -1)) {
|
||||
$pid = $v["id"];
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
if (mb_substr($shift, 0, 1) == "{" && mb_substr($shift, -1, 1) == "}") {
|
||||
foreach ($array as $k => $v) {
|
||||
if ($pid == $v["id"]) {
|
||||
$array[$k]["param_route"] = $uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
$array[$uid++] = [
|
||||
'id' => $uid - 1,
|
||||
'pid' => $pid,
|
||||
'name' => $shift
|
||||
];
|
||||
$pid = $uid - 1;
|
||||
}
|
||||
$array[$uid - 1]['method'] = $method;
|
||||
$array[$uid - 1]['class'] = $class;
|
||||
$array[$uid - 1]['request_method'] = $vss->request_method;
|
||||
$array[$uid - 1]['route'] = $vss->route;
|
||||
$this->req_mapping = $array;
|
||||
}
|
||||
|
||||
/** @noinspection PhpIncludeInspection */
|
||||
private function loadAnnotationClasses() {
|
||||
$class = getAllClasses(WORKING_DIR . "/src/ZM/Annotation/", "ZM\\Annotation");
|
||||
foreach ($class as $v) {
|
||||
$s = WORKING_DIR . '/src/' . str_replace("\\", "/", $v) . ".php";
|
||||
//Console::debug("Requiring annotation " . $s);
|
||||
require_once $s;
|
||||
}
|
||||
$class = getAllClasses(DataProvider::getWorkingDir() . "/src/Custom/Annotation/", "Custom\\Annotation");
|
||||
foreach ($class as $v) {
|
||||
$s = DataProvider::getWorkingDir() . '/src/' . str_replace("\\", "/", $v) . ".php";
|
||||
Console::debug("Requiring custom annotation " . $s);
|
||||
require_once $s;
|
||||
}
|
||||
}
|
||||
|
||||
private function genTree($items) {
|
||||
$tree = array();
|
||||
foreach ($items as $item)
|
||||
if (isset($items[$item['pid']]))
|
||||
$items[$item['pid']]['son'][] = &$items[$item['id']];
|
||||
else
|
||||
$tree[] = &$items[$item['id']];
|
||||
return $tree;
|
||||
}
|
||||
|
||||
private function registerMiddleware(MiddlewareClass $vs, ReflectionClass $reflection_class) {
|
||||
$result = [
|
||||
"class" => "\\" . $reflection_class->getName(),
|
||||
|
||||
@@ -301,7 +301,7 @@ class ServerEventHandler
|
||||
* @param $request
|
||||
* @param $response
|
||||
*/
|
||||
public function onRequest($request, $response) {
|
||||
public function onRequest(?Request $request, ?\Swoole\Http\Response $response) {
|
||||
$response = new Response($response);
|
||||
unset(Context::$context[Co::getCid()]);
|
||||
Console::debug("Calling Swoole \"request\" event from fd=" . $request->fd);
|
||||
|
||||
@@ -280,8 +280,8 @@ class Framework
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Console::info("Calculating ".$x);
|
||||
dump($y);
|
||||
//Console::info("Calculating ".$x);
|
||||
//dump($y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
35
src/ZM/Http/RouteManager.php
Normal file
35
src/ZM/Http/RouteManager.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace ZM\Http;
|
||||
|
||||
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use ZM\Annotation\Http\Controller;
|
||||
use ZM\Annotation\Http\RequestMapping;
|
||||
|
||||
class RouteManager
|
||||
{
|
||||
/** @var null|RouteCollection */
|
||||
public static $routes = null;
|
||||
|
||||
public static function importRouteByAnnotation(RequestMapping $vss, $method, $class, $methods_annotations) {
|
||||
if(self::$routes === null) self::$routes = new RouteCollection();
|
||||
|
||||
// 拿到所属方法的类上面有没有控制器的注解
|
||||
$prefix = '';
|
||||
foreach ($methods_annotations as $annotation) {
|
||||
if ($annotation instanceof Controller) {
|
||||
$prefix = $annotation->prefix;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$route_name = $prefix."/".$vss->route;
|
||||
$route = new Route($route_name, ['_class' => $class, '_method' => $method]);
|
||||
$route->setMethods($vss->request_method);
|
||||
|
||||
self::$routes->add(md5($route_name), $route);
|
||||
}
|
||||
}
|
||||
@@ -5,57 +5,47 @@ namespace ZM\Utils;
|
||||
|
||||
|
||||
use Co;
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use ZM\Config\ZMConfig;
|
||||
use ZM\Console\Console;
|
||||
use ZM\Event\EventManager;
|
||||
use ZM\Http\Response;
|
||||
use ZM\Http\RouteManager;
|
||||
|
||||
class HttpUtil
|
||||
{
|
||||
public static function parseUri($request, $response, $uri, &$node, &$params) {
|
||||
$uri = explode("/", $uri);
|
||||
$uri = array_diff($uri, ["..", "", "."]);
|
||||
$node = EventManager::$req_mapping;
|
||||
$params = [];
|
||||
while (true) {
|
||||
$r = array_shift($uri);
|
||||
if ($r === null) break;
|
||||
if (($cnt = count($node["son"] ?? [])) == 1) {
|
||||
if (isset($node["param_route"])) {
|
||||
foreach ($node["son"] as $k => $v) {
|
||||
if ($v["id"] == $node["param_route"]) {
|
||||
$node = $v;
|
||||
$params[mb_substr($v["name"], 1, -1)] = $r;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
} elseif ($node["son"][0]["name"] == $r) {
|
||||
$node = $node["son"][0];
|
||||
continue;
|
||||
}
|
||||
} elseif ($cnt >= 1) {
|
||||
if (isset($node["param_route"])) {
|
||||
foreach ($node["son"] as $k => $v) {
|
||||
if ($v["id"] == $node["param_route"]) {
|
||||
$node = $v;
|
||||
$params[mb_substr($v["name"], 1, -1)] = $r;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ($node["son"] as $k => $v) {
|
||||
if ($v["name"] == $r) {
|
||||
$node = $v;
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
$context = new RequestContext();
|
||||
$context->setMethod($request->server['request_method']);
|
||||
|
||||
try {
|
||||
$matcher = new UrlMatcher(RouteManager::$routes ?? new RouteCollection(), $context);
|
||||
$matched = $matcher->match($uri);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
if (ZMConfig::get("global", "static_file_server")["status"]) {
|
||||
HttpUtil::handleStaticPage($request->server["request_uri"], $response);
|
||||
return null;
|
||||
}
|
||||
$matched = null;
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
$matched = null;
|
||||
}
|
||||
if ($matched !== null) {
|
||||
$node = [
|
||||
"route" => RouteManager::$routes->get($matched["_route"])->getPath(),
|
||||
"class" => $matched["_class"],
|
||||
"method" => $matched["_method"],
|
||||
"request_method" => $request->server['request_method']
|
||||
];
|
||||
unset($matched["_class"], $matched["_method"]);
|
||||
$params = $matched;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return !isset($node["route"]) ? false : true;
|
||||
}
|
||||
|
||||
public static function getHttpCodePage(int $http_code) {
|
||||
@@ -83,9 +73,9 @@ class HttpUtil
|
||||
return true;
|
||||
}
|
||||
if (is_dir($path)) {
|
||||
if(mb_substr($uri, -1, 1) != "/") {
|
||||
if (mb_substr($uri, -1, 1) != "/") {
|
||||
Console::info("[302] " . $uri);
|
||||
$response->redirect($uri."/", 302);
|
||||
$response->redirect($uri . "/", 302);
|
||||
return true;
|
||||
}
|
||||
foreach ($base_index as $vp) {
|
||||
|
||||
@@ -2,13 +2,17 @@
|
||||
|
||||
require __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
use Symfony\Component\Routing\Route;
|
||||
|
||||
$root = new RouteCollection();
|
||||
$route = new Route('/foo', array('controller' => 'MyController'));
|
||||
$routes = new RouteCollection();
|
||||
|
||||
|
||||
$routes->add('route_name', $route);
|
||||
|
||||
|
||||
@@ -35,30 +39,37 @@ $routes->add('date', new Route(
|
||||
array() // methods
|
||||
));
|
||||
|
||||
|
||||
|
||||
$route = new Route('/archive/test');
|
||||
|
||||
$routes->add('qwerty', $route);
|
||||
|
||||
$route = new Route('/');
|
||||
$route = new Route('/{aas}/{test}', ['_class' => stdClass::class, '_method' => 'foo'],[],["class" => stdClass::class]);
|
||||
|
||||
$routes->add('root', $route);
|
||||
|
||||
$context = new RequestContext();
|
||||
|
||||
$matcher = new UrlMatcher($routes, $context);
|
||||
//$root->addCollection($routes);
|
||||
$matcher = new UrlMatcher($root, $context);
|
||||
$root->addCollection($routes);
|
||||
|
||||
dump($root->all());
|
||||
//$parameters = $matcher->match('/test/foo');var_dump($parameters);
|
||||
|
||||
$parameters = $matcher->match('/archive/2012-01');
|
||||
var_dump($parameters);
|
||||
// array(
|
||||
// 'controller' => 'showArchive',
|
||||
// 'month' => '2012-01',
|
||||
// 'subdomain' => 'www',
|
||||
// '_route' => ...
|
||||
// )
|
||||
try {
|
||||
$parameters = $matcher->match('/fooss/%20');
|
||||
var_dump($parameters);
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
echo $e->getMessage().PHP_EOL;
|
||||
} catch (MethodNotAllowedException $e) {
|
||||
}
|
||||
|
||||
$parameters = $matcher->match('/');
|
||||
var_dump($parameters);
|
||||
|
||||
$sub = new RouteCollection();
|
||||
|
||||
Reference in New Issue
Block a user