Phalcon \ Micro:执行另一个控制器操作

时间:2017-05-09 10:46:50

标签: phalcon phalcon-routing

我有一个控制器动作,可以在一台服务器上执行。此操作必须触发两个其他服务,这些服务可以位于同一服务器或其他服务器上(具体取决于配置的路由)。目前我总是使用HTTP请求。但是如果服务在同一台服务器上,我宁愿直接调用适当的控制器(取决于url,尊重自定义路由)。

我的请求代码如下:

public function buildMultiple($platform, $name, $limit = null, $offset = null) {
    $config = $this->getDI()->get('config');

    $workerUrl = "{$config->application->WorkerUrl}/$platform/$name/compute/multiple/$limit/$offset";
    $response = HttpRequest::get($workerUrl);
    $data = json_decode($response)->data;

    $clientUrl = "{$config->application->ClientUrl}/$platform/$name/update/multiple";

    //TODO if the routes for the client are activated on this server then directly execute the controller
    //if($config->application->ClientRoutes) {
        // pseudocode:
        // $cont = $this->router->getControllerFromUri($clientUrl);
        // $result = $this->dispatcher($cont)->call($params, $postData);
        // return $result;
    //}
    // else:

    return HttpRequest::post($clientUrl, $data);
}

1 个答案:

答案 0 :(得分:0)

我找到了一个可能的解决方案:

public function buildMultiple($platform, $name, $limit = null, $offset = null) {
    $workerUrl = "/$platform/$name/compute/multiple/$limit/$offset";

    if($config->application->mviewWorkerRoutes) {
        $response = RoutesToControllerMapper::call($this, $workerUrl, [$platform, $name, $limit, $offset]);
        $data = $response['data'];
    }
    else {
        $response = HttpRequest::get($config->application->mviewWorkerUrl.$workerUrl, ['changed' => $changedFields]);
        $data = json_decode($response)->data;
    }

    $clientUrl = "/$platform/$name/update/multiple";

    return $config->application->mviewClientRoutes ?
        RoutesToControllerMapper::call($this, $clientUrl, [$platform, $name, $data]) :
        HttpRequest::post($config->application->mviewClientUrl.$clientUrl, $data);
}

而RoutesToControllerMapper看起来像:

class RoutesToControllerMapper
{
    public static function call($controller, $url, $arguments) {
        /** @var Micro $app */
        $app = $controller->getDI()->getApplication();
        /** @var Micro\LazyLoader $loader */
        list($loader, $method) = RoutesToControllerMapper::map($app, $url);
        return $loader->callMethod($method, $arguments);
    }

    /**
     * @param Micro $app
     */
    public static function map($app, $uri) {
        foreach($app->getRouter()->getRoutes() as $route) {
            if(preg_match($route->getCompiledPattern(), $uri) === 1) {
                $lastMatchedRoute = $route;
            }
        }

        if(!isset($lastMatchedRoute)) {
            return null;
        }

        $handler = $app->getHandlers()[$lastMatchedRoute->getRouteId()];
        /** @var Micro\LazyLoader $lazyLoader */
        $lazyLoader = $handler[0];
        return [$lazyLoader, $handler['1']];
    }
}