Php 从子类调用父类成员而不调用构造函数依赖项
我让我的基本控制器和我的内容控制器像下面那样扩展它,我得到一个Php 从子类调用父类成员而不调用构造函数依赖项,php,symfony,oop,Php,Symfony,Oop,我让我的基本控制器和我的内容控制器像下面那样扩展它,我得到一个调用null上的成员函数error(),所以我的问题是: 我必须调用父构造函数吗 如果“是”,那么是否最好有一个服务,因为父控制器有一些注入的依赖项,我不想通过调用父构造函数来注入这些依赖项 use Psr\Log\LoggerInterface; class BaseController extends AbstractController { /** @var LoggerInterface */ protect
调用null上的成员函数error(),所以我的问题是:
我必须调用父构造函数吗
如果“是”,那么是否最好有一个服务,因为父控制器有一些注入的依赖项,我不想通过调用父构造函数来注入这些依赖项
use Psr\Log\LoggerInterface;
class BaseController extends AbstractController
{
/** @var LoggerInterface */
protected $logger;
/**
* BaseController constructor.
*/
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
}
class ContentController extends BaseController
{
private $contentRepository;
private $breadcrumbService;
public function __construct(
ContentRepository $contentRepository,
BreadcrumbInterface $breadcrumbService
) {
$this->contentRepository = $contentRepository;
$this->breadcrumbService = $breadcrumbService;
}
public function contentPage(...)
{
try {
....
} catch (\Throwable $exception) {
$this->logger->error(...);
throw $exception;
}
}
您不需要调用构造函数。但是如果要使用它,您确实需要设置$logger
属性
class ContentController extends BaseController
{
private $contentRepository;
private $breadcrumbService;
public function __construct(
LoggerInterface $logger,
ContentRepository $contentRepository,
BreadcrumbInterface $breadcrumbService
) {
$this->contentRepository = $contentRepository;
$this->breadcrumbService = $breadcrumbService;
$this->logger = $logger;
}
}
使用上述方法,您不再需要调用父::\uu construct()
。但这只是一种良好的做法,无痛且无害:
只要做:
public function __construct(
LoggerInterface $logger,
ContentRepository $contentRepository,
BreadcrumbInterface $breadcrumbService
) {
$this->contentRepository = $contentRepository;
$this->breadcrumbService = $breadcrumbService;
parent::__construct($logger);
}
但是,如果BaseController
的唯一目的是提供一些日志记录方法,那么最好简单地将记录器服务注入ContentController
并直接使用它。是的,如果子类中有构造函数,则需要调用parent::\u construct()
。有一些东西可能值得一读——假设AbstractController是Symfony framework AbstractController,那么请注意,通过setController注入服务定位器(基本上是容器)有点不寻常。这就是抽象控制器在不干扰构造函数的情况下获取其所有服务的方式。如果需要BaseController的主要原因是为了logger服务,那么请调整BaseController::GetSubscribeServices方法以添加它。