简体   繁体   English

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

[英]PHP-CLI Best Practice for Logging Progress/Output and Catching Errors

I am writing a PHP CLI tool. 我正在编写一个PHP CLI工具。 Tool has a number of command lines options available. 该工具具有许多可用的命令行选项。 It will be a class. 这将是一堂课。 I will load an instance and run the command with all the arguments passed in. 我将加载一个实例,并使用所有传入的参数运行命令。

What are best ways to capture info messages as it progresses as well as catching errors and halting on errors with output to screen? 在捕获信息消息的过程中以及捕获错误和停止错误并输出到屏幕时,最好的方法是什么?

Whats the ideal PHP CLI example? 什么是理想的PHP CLI示例?

I use as a template something like this (for simple enough console scripts): 我使用如下模板作为模板(用于足够简单的控制台脚本):

$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);
}

I prefer to use a kind of observer-pattern for processing, and leave error-handling to the console application: 我更喜欢使用一种观察者模式进行处理,并将错误处理留给控制台应用程序:

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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM