Service Symfony3:服务无法获取参数

Service Symfony3:服务无法获取参数,service,dependency-injection,model,doctrine,symfony,Service,Dependency Injection,Model,Doctrine,Symfony,我已经做了一个服务,在我的模型中获得条令连接,不确定这是否是一个好方法,但我不想每次都将连接从控制器传递到模型构造函数 假设我想要控制器中的产品 public function getProductsAction(Request $request) { $product_model = new ProductModel(); return $product_model->getProducts(); } 我有一个产品模型,它将访问一个助手以获得数据库连接 use AppB

我已经做了一个服务,在我的模型中获得条令连接,不确定这是否是一个好方法,但我不想每次都将连接从控制器传递到模型构造函数

假设我想要控制器中的产品

public function getProductsAction(Request $request) {
    $product_model = new ProductModel();
    return $product_model->getProducts();
}
我有一个产品模型,它将访问一个助手以获得数据库连接

use AppBundle\Helper\ContainerHelper;

class ProductModel {
    function getProducts() {
        $helper = new ContainerHelper();
        $db = $helper->getDoctrine();

        $query = "SELECT * FROM customer_products;";
        $statement = $db->prepare($query);

        $statement->execute();
        $result = $statement->fetchAll(PDO::FETCH_ASSOC);
        return $result;
    }
}
现在,这个助手在src/AppBundle/helper/ContainerHelper.php中定义

namespace AppBundle\Helper;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;

class ContainerHelper {

    private $container;

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

    public static function getDoctrine() {
        $database_connection = $this->container->get('database_connection');
        return $database_connection;
    }

}
假设此服务需要服务容器,因此在app/config/services.yml中

services:
    app.container_helper:
        class: AppBundle\Helper\ContainerHelper
        arguments: ['@service_container']
AppBundle\Modal\:
   resource: '../../src/AppBundle/Modal/*'
   public: true
但它给了我一个错误:

可捕获致命错误:参数1传递给 AppBundle\Helper\ContainerHelper::\构造必须实现 接口Symfony\Component\DependencyInjection\ContainerInterface, 未给定,在\src\AppBundle\Model\ProductModel.php中调用 在第148行,定义了


虽然我相信我已经根据和正确地实施了它,但我肯定错过了什么,或者只是得到了整个坏主意。我需要知道它是否是一个正确的概念,或者我错过了什么,

当@pavlovich试图修复您现有的代码时,我真的认为您使它变得比必须的复杂得多。ProductModel本身应该是一个将数据库连接注入其中的服务

class ProductModel {
    public function __construct($conn) {
        $this->conn = $conn;
    }
    public function getProducts() {
        $stmt = $this->conn->executeQuery('SELECT * FROM customer_products');
        return $stmt->fetchAll();
   }

services:
    product_model:
        class: AppBundle\...\ProductModel
        arguments: ['@database_connection']

// controller.php
$productModel = $this->get('product_model'); // Pull from container
$products = $productModel->getProducts();

我建议使用构造函数注入和自动连接,而不是使用助手。它更安全,经得起未来考验,更易于扩展和测试

在这种情况下,您必须为ProductModel创建更加通用和标准的ProductRepository名称,并将其传递给控制器

1.控制器 3.服务注册
有关更多信息,您可以在此处看到类似的问题和答案:

在新版本的Symfony 3.3中,添加了一项新功能自动连接服务依赖项

使用此功能,我通过以下方式解决了此问题:

添加了一个新目录/src/AppBundle/Model 在此目录中添加了我的模型类

namespace AppBundle\Modal;

use Doctrine\ORM\EntityManagerInterface;

class ProductModal
{

   private $em;

   // We need to inject this variables later.
   public function __construct(EntityManagerInterface $entityManager)
   {
       $this->em = $entityManager;
   }

   // We need to inject this variables later.
   public function getProducts()
   {
       $statement = $this->em->getConnection()->prepare("SELECT * FROM product WHERE 1");
       $statement->execute();
       $results = $statement->fetchAll();

       return $results;
    }
}
已添加到我的app/config/services.yml中

services:
    app.container_helper:
        class: AppBundle\Helper\ContainerHelper
        arguments: ['@service_container']
AppBundle\Modal\:
   resource: '../../src/AppBundle/Modal/*'
   public: true
在我的控制器中,我可以像这样使用它

$products = $this->get(ProductModal::class)->getProducts();

注意:不要忘记添加使用AppBundle\Entity\Product\Product;在控制器中

感谢您的快速帮助。我知道我少了什么。额外的辅助层是为了避免注入到所有模型中。我必须为service.yml中的所有模型定义相同的注入。是否有其他可能的解决方法,比如其他框架,它们扩展基本模型,从而自动获得DB连接,因为我有更多的模型,service.yml将填充相同的重复内容,在回复特定评论时使用@Cerad之类的方法,这样此人将收到通知。这也是一种非常好且干净的方法。但并非始终可行。假设我需要客户控制器中的产品。还需要订单、代金券和其他许多东西。在构造函数上自动连接所有这些存储库不是一个好主意,我想为什么?许多依赖关系都会导致解耦和架构改进。拥有大约5个依赖项通常是可以的。超过10是做某事的警钟。
public function getProductsAction(Request $request) {
    $product_model = new ProductModel();
    return $product_model->getProducts();
}