7

I'm using Symfony 2.0.

I have created a command in Symfony and I want to take its output and write it to a file.

All I want is to take everything that is written on the standard output (on the console) and to have it in a variable. By all I mean things echoed in the command, exceptions catched in other files, called by the command and so on. I want the output both on the screen and in a variable (in order to write the content of the variable in a file). I will do the writing in the file in the end of the execute() method of the command.

Something like this:

protected function execute(InputInterface $input, OutputInterface $output)
{
    // some logic and calls to services and functions
    echo 'The operation was successful.';

    $this->writeLogToFile($file, $output???);
}

And in the file I want to have:

[Output from the calls to other services, if any]
The operation was successful.

Can you please help me?

I tried something like this:

   $stream  = $output->getStream();
   $content = stream_get_contents($stream, 5);

but the command doesn't finish in that way. :(

Faery
  • 4,552
  • 10
  • 50
  • 92
  • You can write your own Base `Application` Class and implement your writer that implement the `OutputInterface` you can see something [here](http://symfony.com/doc/2.0/cookbook/console/logging.html#enabling-automatic-exceptions-logging) – Matteo Oct 07 '14 at 11:10

3 Answers3

14

You could just forward the command output using standard shell methods with php app/console your:command > output.log. Or, if this is not an option, you could introduce a wrapper for the OutputInterface that would write to a stream and then forward calls to the wrapped output.

kix
  • 3,290
  • 27
  • 39
1

I needed the same thing, in my case, I wanted to email the console output for debug and audit to email, so I've made anon PHP class wrapper, which stores the line data and then passes to the original output instance, this will work only for PHP 7+.

protected function execute(InputInterface $input, OutputInterface $output) {
    $loggableOutput = new class {
        private $linesData;
        public $output;

        public function write($data) {
            $this->linesData .= $data;
            $this->output->write($data);
        }

        public function writeln($data) {
            $this->linesData .= $data . "\n";
            $this->output->writeln($data);
        }

        public function getLinesData() {
            return $this->linesData;
        }
    };

    $loggableOutput->output = $output;

    //do some work with output

    var_dump($loggableOutput->getLinesData());
}

Note this will only store the data written using write and writeln OutputInterface methods, this will no store any PHP warnings etc.

nacholibre
  • 3,874
  • 3
  • 32
  • 35
1

Sorry for bringing this up again. I'm in a similar situation and if you browse the code for Symfony versions (2.7 onwards), there already is a solution.

You can easily adapt this to your specific problem:

    // use Symfony\Component\Console\Output\BufferedOutput;
    // You can use NullOutput() if you don't need the output
    $output = new BufferedOutput();
    $application->run($input, $output);

    // return the output, don't use if you used NullOutput()
    $content = $output->fetch();

This should neatly solve the problem.

maschmann
  • 191
  • 1
  • 5