访问容器功能的最佳设计方法
Best design method to access container functions
我是 SLIM3 的新手,按照教程在容器中获取了一些我想从代码中的任何位置访问的函数。所以这是我初始化所有内容的 index.php
文件:
<?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
,dbteacher
和 dbagent
也是如此,但我只能在创建这些容器的地方执行此操作,当我从另一个 class 调用另一个函数时,我也希望能够访问它们,但我不想将它们传递给参数,因为这将很难维护,我也想拥有初始化这些容器和 $app
变量并在我使用的每个 class 中扩展它的 config.php
class 但这听起来不对。
解决此问题的最佳方法是什么?
你应该使用Slim3使用的依赖注入容器(Pimple)的功能。
话虽如此,我想说动态创建 "controller" 并不是那么好,抽象不应该存在,你应该只做 $response->getBody()->write($result);
或更简单的方法 $response->write($result);
在每个控制器中。另外,我不明白为什么这个结构需要一个完整的路由框架。
但无论如何,如果您想继续使用该解决方案,可以使用 Pimple,我将在示例中进行解释。
您有几个 类 具有不同的构造函数参数:
class A {
public function __construct($logger) {}
}
class B {
public function __construct($logger, $myHelper) {}
}
首先将它们全部添加到 Pimple 容器中:
$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']);
};
然后您可以通过在应用程序实例上的容器上调用 get 来将它们添加到您的路线中。
$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;
});
我是 SLIM3 的新手,按照教程在容器中获取了一些我想从代码中的任何位置访问的函数。所以这是我初始化所有内容的 index.php
文件:
<?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
,dbteacher
和 dbagent
也是如此,但我只能在创建这些容器的地方执行此操作,当我从另一个 class 调用另一个函数时,我也希望能够访问它们,但我不想将它们传递给参数,因为这将很难维护,我也想拥有初始化这些容器和 $app
变量并在我使用的每个 class 中扩展它的 config.php
class 但这听起来不对。
解决此问题的最佳方法是什么?
你应该使用Slim3使用的依赖注入容器(Pimple)的功能。
话虽如此,我想说动态创建 "controller" 并不是那么好,抽象不应该存在,你应该只做 $response->getBody()->write($result);
或更简单的方法 $response->write($result);
在每个控制器中。另外,我不明白为什么这个结构需要一个完整的路由框架。
但无论如何,如果您想继续使用该解决方案,可以使用 Pimple,我将在示例中进行解释。
您有几个 类 具有不同的构造函数参数:
class A {
public function __construct($logger) {}
}
class B {
public function __construct($logger, $myHelper) {}
}
首先将它们全部添加到 Pimple 容器中:
$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']);
};
然后您可以通过在应用程序实例上的容器上调用 get 来将它们添加到您的路线中。
$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;
});