2017-05-09 76 views
0

我有一個控制器動作在一臺服務器上執行。此操作必須觸發兩個可以位於同一服務器或其他服務器上的其他服務(取決於配置的路由)。目前我總是使用HTTP請求。但是,如果服務在同一臺服務器上,我寧願直接調用適當的控制器(取決於url,尊重自定義路由)。Phalcon Micro:執行另一個控制器動作

我與請求的代碼看起來像:

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); 
} 
+0

因此,如何使用,如果HTTP請求路由在本地實例上不存在?這是你的問題嗎? –

+0

但是動作是一個動作,http端點,如果你希望它只是泛型方法,那麼將它移動到一些泛型方法,不會看到問題。 – Juri

+0

@Juri問題是我的路由器路由到不同的控制器,具體取決於url。如果我想調用適當的控制器和方法,我將不得不復制路由器的行爲。我希望Phalcon已經以某種方式實現了這一點(請參閱我更新後的僞代碼) – velop

回答

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']]; 
    } 
} 
相關問題