![](/img/trans.png)
[英]Implementating Dependency Injection for better routing in mvc or mvvm in php using DICE
[英]Using Dependency Injection in MVC PHP
對於加載類,我使用PSR-4自動加載。 在我的index.php
我使用FastRoute組件。 在該index.php
我創建$ db連接並將其傳遞給控制器。
call_user_func_array([new $class($db), $method], $vars);
在控制器中,我將其接收並傳遞給模型並在其中使用。 我知道這是不好的方法。 在index.php
中創建的數據庫連接如何在我的模型中使用它而不通過控制器等傳遞,並且沒有單例連接實例? 如何使用DI或DIC在index.php
建立數據庫連接並進入所有模型?
index.php:
<?php
require_once 'vendor/autoload.php';
$db = new DbConnection(new DbConfig($config));
$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
$r->addRoute('GET', '/users', 'UserController/actionGetAllUsers');
$r->addRoute('GET', '/users/{id:\d+}', 'UserController/actionGetUserById');
});
// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
$uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::NOT_FOUND:
// ... 404 Not Found
break;
case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
$allowedMethods = $routeInfo[1];
// ... 405 Method Not Allowed
break;
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
list($class, $method) = explode("/", $handler, 2);
$module = strtolower(str_replace('Controller', '', $class));
$class = 'Vendorname\\' . $module . '\\controllers\\' . $class;
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
call_user_func_array([new $class($db), $method], $vars);
break;
}
控制器:
class UserController extends BaseApiController
{
protected $db;
public function __construct($db)
{
$this->db = $db;
parent::__construct();
}
public function actionGetAllUsers()
{
$model = new User($this->db);
echo json_encode($model->getAllUsers());
}
模型:
class User
{
protected $db;
public function __construct($db)
{
$this->db = $db;
}
public function getAllUsers()
{
$stmt = $this->db->prepare('SELECT * FROM user');
$stmt->execute();
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
首先,您必須了解,“依賴注入”和“依賴注入容器”是兩個不同的東西:
看來,您已經通過數據庫連接的方式很不好。 確切的技術原因可以描述為違反LoD 。 基本上,您的$db
變量跨越了兩層邊界。
但是,解決方案不是 :“僅添加DI容器”。 那不會解決問題。 相反,您應該改進模型層的設計。 您可以在此處進行快速閱讀,但在這里我會給出一個簡短的版本:
DB應該是datamapper的依賴項,它是專門為處理用戶實例而設計的(更多信息請參見 )。 該映射器應該是“帳戶管理服務”的直接依賴項(認為是好名聲),或者是使用該服務內部的工廠構造的(然后該工廠就是該服務的依賴項)。
PS至於“選擇哪個DIC”,我個人使用Symfony的獨立容器,但這純粹是個人喜好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.