0

When I try to execute something legitimate - it works, like

$result = `git tag`

returns me a list of available tags.

But when I do something that should return error, like

$result = `git clone https://`

it returns me NULL, but not message fatal: could not create work tree dir ''.: No such file or directory that I would see in the console.

How can I run a command and get error message from PHP?

UPD: It is not question "how to clone repo with using PHP", it is "How to retreive error message if something goes wrong" Does not matter what, in my example - "broken" repository link.

SmxCde
  • 5,053
  • 7
  • 25
  • 45
  • Check this answer http://stackoverflow.com/a/8562666/3081659 – Noman Aug 16 '16 at 05:46
  • Hm, sorry, I do not see how is it related to my question... it is not writing issue, the question is about getting text of error message back. – SmxCde Aug 16 '16 at 06:15

2 Answers2

5

Try this

/**
 * Executes a command and reurns an array with exit code, stdout and stderr content
 * @param string $cmd - Command to execute
 * @param string|null $workdir - Default working directory
 * @return string[] - Array with keys: 'code' - exit code, 'out' - stdout, 'err' - stderr
 */
function execute($cmd, $workdir = null) {

    if (is_null($workdir)) {
        $workdir = __DIR__;
    }

    $descriptorspec = array(
       0 => array("pipe", "r"),  // stdin
       1 => array("pipe", "w"),  // stdout
       2 => array("pipe", "w"),  // stderr
    );

    $process = proc_open($cmd, $descriptorspec, $pipes, $workdir, null);

    $stdout = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    $stderr = stream_get_contents($pipes[2]);
    fclose($pipes[2]);

    return [
        'code' => proc_close($process),
        'out' => trim($stdout),
        'err' => trim($stderr),
    ];
}

And then test

$res = execute('git --version')

Array
(
    [code] => 0
    [out] => git version 2.1.4
    [err] => 
)

This will give you what you want

$res = execute('git clone http://...')

Array
(
    [code] => 128
    [out] => 
    [err] => Cloning into '...'...
             fatal: unable to access 'http://.../': Could not resolve host: ..
)
Pavel
  • 3,967
  • 2
  • 29
  • 35
-1

Just use exec($result, $output);

$output is array of cli lines, but it can requir sleep() function to get time on script execution.

Lakremon
  • 787
  • 1
  • 8
  • 26
  • I tried `exec('git clone https://', $output);` and got empty array. Didn't get it about `sleep()` at what point should I use it and how long it should sleep? Thanks! – SmxCde Aug 16 '16 at 06:13
  • I don't know about sleep duration, it should be more your `git clone` usually run time. – Lakremon Aug 16 '16 at 06:56
  • Run git from PHP and use exec does not sounds right too. =) If you need solution for your production server, of couse it bad practic, and i can take another answer (it will require more time), but if you need debug your scrtipt it good solution. – Lakremon Aug 16 '16 at 07:33
  • Why is it bad idea to execute git commands from PHP? Let's say I develop something like builder/deployer using PHP, what is bad in cloning a repo, executing something like `git tag` from PHP? – SmxCde Aug 16 '16 at 08:45
  • So, becouse you can use Jenkins or TeamCity to build or deploy everithing. Becouse PHP is languege for web-page generation. Of couse you can develop desktop application on PHP, but why? Just use a right technology. I don't Like Django. It bad solution for web applications, becous PHP is better for that. And I don't like PHP workers/CGI/demons etc. Because we have more powerful languages for that. I did not want to hurt your feelings, it just my opinion. =) – Lakremon Aug 16 '16 at 09:38
  • Web pages may be different and PHP is perfectly capable of running console commands, BTW if you are interested in solution - check out Pavel's answer. – SmxCde Aug 17 '16 at 23:56