2017-05-09 2 views
0

Ich habe eine Controller-Aktion, die auf einem Server ausgeführt wird. Diese Aktion muss zwei weitere Dienste auslösen, die sich auf demselben oder einem anderen Server befinden können (abhängig von den konfigurierten Routen). Derzeit verwende ich immer HTTP-Anfragen. Wenn sich die Dienste jedoch auf demselben Server befinden, möchte ich lieber den entsprechenden Controller (abhängig von der URL, unter Berücksichtigung der benutzerdefinierten Routen) direkt aufrufen.Phalcon Micro: Führe eine andere Controller-Aktion in Aktion aus

mit Anfragen Mein Code wie folgt aussieht:

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

So wie HTTP-Anforderungen zu verwenden, wenn die Routen existieren nicht in der lokalen Instanz? Ist das deine Frage? –

+0

Aber Aktion ist eine Aktion, http-Endpunkt, wenn Sie möchten, dass es nur eine generische Methode ist, dann verschieben Sie es auf eine generische Methode, sehen Sie nicht wirklich Problem. – Juri

+0

@Juri das Problem ist, dass mein Router Routing zu verschiedenen Controllern, abhängig von der URL. Wenn ich den passenden Controller und die Methode aufrufen möchte, müsste ich das Verhalten des Routers duplizieren. Ich würde hoffen, Phalcon hat dies schon irgendwie umgesetzt (siehe meinen aktualisierten Pseudocode) – velop

Antwort

0

ich eine mögliche Lösung gefunden:

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

während RoutesToControllerMapper wie folgt aussehen:

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']]; 
    } 
} 
Verwandte Themen