2017-08-18 9 views
1

私はSLIM3を初めて使用し、チュートリアルに続いて、コード内のどこからでもアクセスしたいコンテナ内のいくつかの関数を取得します。コンテナ関数にアクセスするための最善の設計方法

<?php 
use \Psr\Http\Message\ServerRequestInterface as Request; 
use \Psr\Http\Message\ResponseInterface as Response; 

// Require for loading the vendor libraries installed by composer 
require 'vendor/autoload.php'; 


$config['displayErrorDetails'] = true; 
$config['addContentLengthHeader'] = false; 

$app = new \Slim\App(["settings" => $config]); 
$container = $app->getContainer(); 

// Monolog initalisation. To use it write: $this->logger->addInfo("what you want to write here"); 
$container['logger'] = function($c) { 
    $logger = new \Monolog\Logger('eq_logger'); 
    $file_handler = new \Monolog\Handler\StreamHandler("logs/app.log"); 
    $logger->pushHandler($file_handler); 
    return $logger; 
}; 

// Database connections 
$container['dbteacher'] = function ($c) { 
    $pdo = new PDO($_SERVER['PGSQL_CONNECTION_STR']); 
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
    return $pdo; 
}; 
$container['dbagent'] = function ($c) { 
    $pdo = new PDO($_SERVER['PGSQL_CONNECTION_STR_AGENT']); 
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
    return $pdo; 
}; 

$app->post('/{controller}/{function}', function (Request $request, Response $response) { 
    $headers = $request->getHeaders(); 
    $params = $request->getParsedBody(); 

    $classname = $request->getAttribute('controller'); 
    $controller = new $classname($this->logger); 
    $function = $request->getAttribute('function'); 

    $result = $controller->$function($params); 

    $response->getBody()->write($result); 
    return $response; 
}); 

$app->run(); 

ここで私は、$this->loggerを入力してloggerにアクセスすることができます同じことがdbteacherdbagentのために行くが、私は唯一の私はときに、これらのコンテナが作成される場所の内側にあることを行うことができますので、ここで私はすべてをinitalise私index.phpファイルです別のクラスから別の関数を呼び出すこともできますが、それらにもアクセスできるようにしたいのですが、パラメータを渡すのは難しいでしょうから、維持するのが難しいでしょうから、config.phpクラス$app変数を使用し、使用するすべてのクラスで拡張しますが、それは正しいとは言えません。 これにはどのような方法が最適ですか?

答えて

5

Slim3が使用する依存性注入容器(Pimple)の機能を使用する必要があります。

ダイナミックに作成する「コントローラー」はそれほど素晴らしいものではなく、抽象化はそこにあるべきではないと言いたいと思います。$response->getBody()->write($result);またはより単純な方法$response->write($result);コントローラ。また、私はなぜこの構造のためにルーティングフレームワーク全体が必要であるのかわかりません。

しかし、もしあなたがその解決策にとどまることができなければ、あなたはPimpleを使うことができます。私はその例について説明します。

class A { 
    public function __construct($logger) {} 
} 

class B { 
    public function __construct($logger, $myHelper) {} 
} 

は、まずあなたがpipleコンテナにそれらすべてを追加します:

$container['A'] = function($c) { // or $container[A::class] for type safety 
    return new A($c['logger']); 
}; 
$container['B'] = function($c) { 
    return new A($c['logger'], $c['myHelper']); 
}; 

をそしてあなたが得る呼び出すことによって、あなたのルートでそれらを得ることができます

あなたは別のコンストラクタのパラメータを持ついくつかのクラスを持っていますアプリケーションインスタンス上のコンテナ。

$app->post('/{controller}/{function}', function (Request $request, Response $response) { 
    $headers = $request->getHeaders(); 
    $params = $request->getParsedBody(); 

    $classname = $request->getAttribute('controller'); 
    $controller = $this->getContainer()->get($classname); 
    $function = $request->getAttribute('function'); 

    $result = $controller->$function($params); 

    $response->getBody()->write($result); 
    return $response; 
}); 
+0

答えをいただきありがとうございます。apiは、それぞれ異なるapiエンドポイントを持つ異なるモジュール(ダッシュボード、クラスビュー、学生ビューなど)を持つ角度のあるアプリに接続します。私が開発しようとしているのは、各モジュール(コントローラ)のクラスとフロントエンドが呼び出すクラス内の関数を持つことで、開発者が新しい関数を書くべき場所を特定するのに役立ちます。 それに加えて、この1つの$ app-> postを使用すると、データが関数に渡る前にデータを検証したり、ユーザーを認証したりすることができます。 それを知っている... –

+0

...各apiエンドポイント関数に$ app-> postを付けることをお勧めしますか?なぜですか? –

+1

@NaguibIhab jup、あなたは[このような構造](https://stackoverflow.com/a/45197291/4244993)を行うことができますが、それでもクラスには関数があります。認証のようなものについては、[ミドルウェア](https://www.slimframework.com/docs/concepts/middleware.html)を使うことができます。 – jmattheis

関連する問題