【问题标题】:try .. catch with system() command php on laravel 5.0尝试 .. 在 laravel 5.0 上使用 system() 命令 php 捕获
【发布时间】:2016-04-27 11:23:34
【问题描述】:

我有一个在 laravel 5.0 上使用 try .. 捕获并使用系统命令的命令应用程序代码。当出现异常时,我的 catch 不起作用。

use Illuminate\Support\Facades\Log;
...
try {
  system('.dump master | sqlite3 ' . $older . ' > ' . storage_path() . '/tmp/' . $tabla . '.sql' );
} catch ( \Exception $e) {
  Log::alert('Problem import old table '. $tabla . $e->GetMessage());
}

我在 shell 上看到了我的错误,但没有写在我自己的 laravel 日志上。 (日志:警报)

【问题讨论】:

  • 外部/系统调用本身不会产生异常。
  • '.dump master?您是否希望系统在$PATH 中搜索.dump 可执行文件,或者您的意思是./dump master 即执行当前工作目录中的dump?无论如何,我建议构建绝对路径。例如:$cmd = __DIR__ . '/../somewhere/dump master'$cmd = YOUR_ROOT_DIR . '/bin/dump master'
  • 我不问错误。我询问try..catch。我知道这是什么错误。

标签: php exception laravel-5 try-catch catch-block


【解决方案1】:

您必须通过STDERR 和可能的STDOUT 获得访问权限。使用proc_open,例如:

$desc = [
  1 => ['pipe', 'w'], // STDOUT
  2 => ['pipe', 'w'], // STDERR
];

$proc = proc_open('ls -l . something', $desc, $pipes);
if (is_resource($proc)) {

  if ($out = stream_get_contents($pipes[1])) {
    echo $out;
  }
  fclose($pipes[1]);


  if ($err = stream_get_contents($pipes[2])) {
    fprintf(STDERR, "Error: %s\n", $err);
  }
  fclose($pipes[2]);

  // You can also check the process exit status
  // 0 means success, otherwise error.
  $exit_status = proc_close($proc);
}

当然,STDOUT 管道中不需要,如果命令将其重定向到文件。

是的,system() 不会抛出异常。显然,您可以实现自己的类,如果进程退出状态不为零,或者在STDERR 管道中捕获到某些东西,则会抛出异常:

class MyShellException extends \Exception {}

class MyShell {
  public static function execute($command, &$out = null) {
    if (func_num_args() > 1) {
      $desc[1] = ['pipe', 'w'];
    } else {
      $desc[1] = ['file', '/dev/null'];
    }

    $desc[2] = ['pipe', 'w'];

    $proc = proc_open($command, $desc, $pipes);
    if (is_resource($proc)) {
      if (isset($pipes[1])) {
        $out = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
      }

      if ($err = stream_get_contents($pipes[2])) {
        fclose($pipes[2]);
        throw new MyShellException("Command $command failed: $err");
      }

      if ($exit_status = proc_close($proc)) {
        throw new MyShellException("Command $command exited with non-zero status");
      }
    }
  }
}


try {
  MyShell::execute('ls -l . something', $out);
  echo "Output: $out\n";
} catch (MyShellException $e) {
  if (!empty($out)) {
    echo "Output: $out\n";
  }
  fprintf(STDERR, "MyShell error: " . $e->getMessage());
  exit(1);
}

【讨论】:

    【解决方案2】:

    在 php 中使用抛出异常。 Here is the reference link 使用和示例:

    <?php
    /*
     * 
     * opcode number: 108
     */
    try {
        $error = 'Always throw this error';
        throw new Exception($error);
    
        // Code following an exception is not executed.
        echo 'Never executed';
    
    } catch (Exception $e) {
        echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
    
    // Continue execution
    echo 'Hello World';
    ?>
    

    【讨论】:

      猜你喜欢
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 2021-09-27
      • 2011-03-21
      • 1970-01-01
      • 2014-05-11
      • 1970-01-01
      相关资源
      最近更新 更多