Get project directory on command symfony 3.4
Asked Answered
O

3

6

Using symfony 3.4 In controller i can get project directory using this method :

$this->get('kernel')->getProjectDir()

I would like to get the project directory on command symfony (3.4) , what is the best practise to do it ?

Thanks

Officer answered 15/1, 2019 at 11:21 Comment(2)
Same approach, but it is better to inject Kernel into your Command directly and call getProjectDir() from itNovelize
Come on @Flying, you know better than that.Matted
M
9

Pretty sure this question has been asked many time but I'm too lazy to search for it. Plus Symfony has moved away from pulling parameters/services from the container to injecting them. So I am not sure if previous answers are up to date.

It is pretty easy.

namespace AppBundle\Command;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;

class ProjectDirCommand extends Command
{
    protected static $defaultName = 'app:project-dir';

    private $projectDir;

    public function __construct($projectDir)
    {
        $this->projectDir = $projectDir;
        parent::__construct();
    }
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Project Dir ' . $this->projectDir);
    }
}

Because your project directory is a string, autowire will not know what value to inject. You can either explicitly define your command as a service and manually inject the value or you can use the bind capability:

# services.yml or services.yaml
services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false
        bind:
            $projectDir: '%kernel.project_dir%' # matches on constructor argument name
Matted answered 15/1, 2019 at 14:19 Comment(0)
P
10

You can inject KernelInterface to the command just adding it to the constructor parameters and then get the project directory with $kernel->getProjectDir():

<?php

namespace App\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class FooCommand extends Command
{
    protected $projectDir;

    public function __construct(KernelInterface $kernel)
    {
        parent::__construct();
        $this->projectDir = $kernel->getProjectDir();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        echo "This is the project directory: " . $this->projectDir;
        //...
    }
}
Polygamous answered 10/1, 2020 at 19:15 Comment(0)
M
9

Pretty sure this question has been asked many time but I'm too lazy to search for it. Plus Symfony has moved away from pulling parameters/services from the container to injecting them. So I am not sure if previous answers are up to date.

It is pretty easy.

namespace AppBundle\Command;

use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Command\Command;

class ProjectDirCommand extends Command
{
    protected static $defaultName = 'app:project-dir';

    private $projectDir;

    public function __construct($projectDir)
    {
        $this->projectDir = $projectDir;
        parent::__construct();
    }
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $output->writeln('Project Dir ' . $this->projectDir);
    }
}

Because your project directory is a string, autowire will not know what value to inject. You can either explicitly define your command as a service and manually inject the value or you can use the bind capability:

# services.yml or services.yaml
services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false
        bind:
            $projectDir: '%kernel.project_dir%' # matches on constructor argument name
Matted answered 15/1, 2019 at 14:19 Comment(0)
D
2

Well, I would say, inject the %kernel.project_dir% or %kernel.root_dir% parameters directly in your command. No need to make your command dependent on the Kernel service.

And by the way you can also make your Command extends Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand which is an abstract class. So you can access the container within your command by just calling getContainer method.

But, I would not advice you to this actually. Better take benefit of autowiring or configure your service in a "yaml" way.

Dorcasdorcea answered 15/1, 2019 at 14:1 Comment(6)
As ContainerAwareCommand is deprecated since Sf 4.2, one should no longer use itDarendaresay
Is it also for 3.4? Because he is not using 4.2Dorcasdorcea
It's not, but it does not make sense to write code today that obviously needs to be changed on upgrading Symfony. By not using deprecated features in new code, you have less work laterDarendaresay
Well, yes but in this case be more precise when you speak because some people can understand that it is deprecated also for 3.4 and actually it is notDorcasdorcea
I've written very clearly that it is deprecated since 4.2Darendaresay
I meant, when you said it does not make sense to write code today that obviously needs to be changed on upgrading Symfony. By not using deprecated features in new code, you have less work later". You did not explain like this the first time so I would avoid answering you. Because this is what you think and maybe the guy who created the question does not think the same.Dorcasdorcea

© 2022 - 2024 — McMap. All rights reserved.