简体   繁体   中英

Call to a parent class member from child without calling constructor dependencies

I have my base controller and my content controller extending it like below, and I'm getting a Call to a member function error() on null so my question is:

Do I have to call the parent constructor?

If "yes" then is it better to have a service because the parent controller has some injected dependencies that I don't want to inject myself by calling the parent constructor

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;
    }
}

You do not need to call the constructor. But you do need to set the $logger property if you want to use it.

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;
    }

}

With the above you no longer need to call parent::__construct() . But it's simply good practice, painless and harmless:

Just do:

public function __construct(
        LoggerInterface $logger,
        ContentRepository $contentRepository,
        BreadcrumbInterface $breadcrumbService
) {
    $this->contentRepository = $contentRepository;
    $this->breadcrumbService = $breadcrumbService;
    parent::__construct($logger);
}

But if the only purpose of BaseController is to provide some logging methods, it's probably better to simply inject the logger service in ContentController and use it directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM