You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slim框架父控制器容器复用问题及优化方案咨询

Slim框架控制器复用容器与避免重复代码的解决方案

我在使用Slim框架开发项目,现有HomeController继承自Controller类,代码可正常运行。为避免在每个控制器中重复编写构造代码,希望将HomeController构造函数中获取container、db、view的逻辑移至父Controller类,以便直接像访问$this->test一样访问$this->view和$this->db。但尝试后发现父类构造函数未执行,调用parent::__construct()时又出现参数不足错误,现寻求可复用容器、避免重复代码的最优实现方式。

原始相关代码

HomeController.php

<?php

namespace Controllers;

use DI\Container;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Views\Twig;


class HomeController extends Controller{

   private $db;

   private $view;

   private $container;

    public function __construct(Container $container){
    
      $this->container = $container;

       $this->db = $container->get('db');

       $this->view = $container->get('view');
    }

    public function index(Request $request, Response $response, $args){

      echo $this->test; // 'hello world'; This is from Controller.php

      echo $this->container->get('container-test'); // I am from container is the string i pass is container and i am getting output.

      echo $this->container_from_controller?'Captured':'Not Captured'; // Not Captured i.e the container in Controller.php is empty
      
      return $this->view->render($response, 'home/index.html', [

          'name' => 'from home controller'

      ]);
    }
}

Controller.php

<?php

namespace Controllers;

use DI\Container;



class Controller{

    protected $container_from_controller;

    protected $test = 'hello world';

    public function __construct(Container $container){
      
        $this->container_from_controller = $container;
    }


}

composer.json

{
    "require": {
        "slim/slim": "4.*",
        "slim/psr7": "^1.6",
        "php-di/slim-bridge": "^3.4",
        "dcblogdev/pdo-wrapper": "^2.0",
        "slim/twig-view": "^3.3"
    },
    "autoload": {
        "psr-4": {
            "Controllers\\": "src/Controllers"
        }
    }
}

问题原因

  1. 父类构造函数未自动执行:当子类定义了自己的构造函数时,PHP不会自动调用父类的构造函数,必须显式调用parent::__construct()才能触发父类构造逻辑。
  2. 参数不足错误:子类构造函数接收Container参数,但调用parent::__construct()时未传递该参数,导致父类构造函数因缺少必要参数而报错。

最优实现方案

将父类改为抽象基类BaseController,在基类构造函数中统一处理容器依赖的注入与资源获取,子类无需编写构造函数,直接继承基类即可使用已初始化的$this->db和$this->view。

修改后的BaseController.php

<?php

namespace Controllers;

use DI\Container;

abstract class BaseController{

    protected $db;

    protected $view;

    public function __construct(Container $container){
      
        $this->db = $container->get('db');
        $this->view = $container->get('view');
    }
}

修改后的HomeController.php

<?php

namespace Controllers;

use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class HomeController extends BaseController{

    public function index(Request $request, Response $response, $args){

      $sql = "SELECT * FROM list";
      $rows = $this->db->rows($sql);
      var_dump($rows);
      
      return $this->view->render($response, 'home/index.html', [
          'name' => 'from home controller'
      ]);
    }
}

方案说明

  • 抽象基类BaseController确保所有子类共享同一套资源初始化逻辑,避免重复代码。
  • PHP-DI容器会自动将Container实例注入基类的构造函数,子类无需手动处理参数传递。
  • 子类直接通过$this->db和$this->view访问资源,代码更简洁,可维护性更强。

内容的提问来源于stack exchange,提问作者Alaksandar Jesus Gene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 12:31:03