PHP-CLI记录进度/输出和捕获错误的最佳实践

时间:2018-08-27 18:46:30

标签: php php-7.2

我正在编写一个PHP CLI工具。该工具具有许多可用的命令行选项。这将是一堂课。我将加载一个实例,并使用传入的所有参数运行命令。

在捕获信息消息的过程中捕获错误并停止错误并输出到屏幕的最佳方法是什么?

什么是理想的PHP CLI示例?

2 个答案:

答案 0 :(得分:0)

我将类似这样的模板(用于足够简单的控制台脚本)用作模板:

$inputFile = null;
$outputFile = null;
try {
    // Checking command-line arguments
    if (1 === $argc) {
        throw new Exception('Missing input file path.');
    }

    $inputFilePath = $argv[1];
    if (!file_exists($inputFilePath) || !is_readable($inputFilePath)) {
        throw new Exception('Input file does not exist or cannot be read.');
    }

    $inputFile = fopen($inputFilePath, 'r');

    if (2 < $argc) {
        $outputFilePath = $argv[2];
        if (!is_writable($outputFilePath)) {
            throw new Exception('Cannot write to output file.');
        }

        $outputFile = fopen($outputFilePath, 'w');
    } else {
        $outputFile = STDOUT;
    }

    // Do main process (reading data, processing, writing output data)
} catch (Exception $e) {
    // Show usage info, output error message

    fputs(STDERR, sprintf('USAGE: php %s inputFilePath [outputFilePath]', $argv[0]) . PHP_EOL);
    fputs(STDERR, 'ERROR: ' . $e->getMessage() . PHP_EOL);
}

// Free resources

if ($inputFile) {
    fclose($inputFile);
}

if ($outputFile) {
    fclose($outputFile);
}

答案 1 :(得分:0)

我更喜欢使用一种观察者模式进行处理,并将错误处理留给控制台应用程序:

class ExampleService
{
    /**
     * @var array
     */
    private $params;

    public function __construct(array $params)
    {
        $this->params = $params;
    }

    /**
     * @param callable|null $listener
     */
    public function execute(callable $listener = null)
    {
        foreach (['long', 'term', 'loop'] as $item) {
            // do complex stuff
            $listener && $listener($item);
        }
    }
}

require_once __DIR__ . '/vendor/autoload.php';

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

$app = new Application;
$app->add($command = new Command('example'));

$command->addOption('opt1');
$command->addArgument('arg1');
$command->setCode(function(InputInterface $input, OutputInterface $output) {
    $service = new ExampleService($input->getOptions() + $input->getArguments());
    $service->execute(function($messages) use($output){
        $output->writeln($messages);
    });
});

$app->run();