如何巧妙地处理Artisan Commands中的异常 - php

使用Lumen创建API-喜欢Laravel,但是它附带的所有View对于我正在创建的项目来说都是过分的。

无论如何,我做出了一系列命令,这些命令可以收集数据并将其存储到数据库中。

<?php 

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;

use App\User;

class GetItems extends Command {

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'GetItems';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = "Get items and store it into the Database";

    /**
     * Execute the console command.
     *
     * @return void
     */
    public function fire()
    {
        $this->info("Collecting ...");

       $users = User::all();

       foreach( $users as $user)
       {
           $user->getItems();
       }

   }

    /**
     * Get the console command options.
     *
     * @return array
     */
    protected function getOptions()
    {
        return [];
    }

}

我有3个类似的命令,每个命令收集略有不同的数据集。

有什么方法可以注入一个中间层,该中间层捕获命令中来自每个fire()函数的异常?我当时正在考虑扩展Command类-但想看看是否已经有框架创建者推荐的方法(文档/搜索没有帮助)。

我知道另一种选择是将所有命令组合到一个文件中并使用选项,但这会使它变得凌乱且难以协作。

有什么建议?

参考方案

答案取决于当命令引发异常时我们希望应用程序执行的操作。该问题并未描述处理异常的理想方式,因此让我们看一些选项。

Laravel和Lumen项目包含一个中心异常Handler类,我们可以使用它来定义不同异常的行为。此类处理从Web请求和控制台命令冒出的所有异常。

Laravel使用app / Exceptions / Handler.php中的report()方法来确定如何记录异常。我们可以在此处为错误报告添加逻辑:

public function report(Exception $e)  
{
    if ($e instanceof CustomConsoleException) {
        // do something specific...
    }
    ...
}

renderForConsole()方法使我们可以定制显示控制台命令的错误和异常消息的方式。项目的异常Handler通常不包含此方法定义,但是如果需要,我们可以在app / Exceptions / Handler.php中覆盖它:

public function renderForConsole($output, Exception $e)
{
    $output->writeln('Something broke!'); 

    (new ConsoleApplication)->renderException($e, $output);
}

在上面的示例中,$output是对Symfony\Component\Console\Output \OutputInterface对象的引用,我们可以使用该对象将文本写入控制台命令的输出流。

就像我们从上面可能会猜到的那样,中央异常处理程序旨在处理我们的代码未在较低级别处理的未捕获异常,因此当我们需要在异常之后执行某些特定操作时,它并不是很有用。以类似的方式,我们可以覆盖reportException()中的renderException()app/Console/Kernel.php方法。

如果除了确认一条命令通过显示一条消息引发了异常外,我们还需要做一些特定的事情,那么我们确实应该在命令本身中编写此逻辑。为了避免重复的代码,我们可以使用一个抽象类,该类似类的三个命令为以下操作提供了具体的实现:

abstract class AbstractGetItems extends Command 
{
    ...
    final public function fire() 
    {
        try {
            $this->getItems();
        } catch (Exception $e) {
            // handle exception... 
        }
    }

    abstract protected function getItems();
}

此抽象命令强制子类实现getItems()方法,该类在fire()中自动调用。我们可以将任何其他共享逻辑添加到此类。子命令仅需定义getItems()的特定实现,父类将为其处理异常:

class GetSpecificItems extends AbstractGetItems 
{ 
    ... 
    protected function getItems() 
    {
        // fetch specific items...
    }
}

PHP-将日期插入日期时间字段 - php

我已在数据库中使用datetime字段存储日期,使用PHP将“今天的日期”插入该字段的正确方法是什么?干杯, 参考方案 我认为您可以使用php date()函数

Laravel 5错误报告抑制 - php

在Laravel 4中,抑制E_NOTICE消息很容易;我似乎无法做到这一点,因为如果我添加error_reporting(E_ALL ^ E_NOTICE) 它只是被覆盖的任何地方。这似乎发生在这里:(index.php)$response = $kernel->handle( $request = Illuminate\Http\Request::…

PHP getallheaders替代 - php

我正在尝试从服务器上的apache切换到nginx。唯一的问题是我在PHP脚本中使用的getallheaders()函数,该函数不适用于Nginx。我已经尝试过用户在getallheaders函数上的php站点上提供的注释,但这并不返回所有请求标头。请告诉我如何解决这个问题。我真的想切换到Nginx。 参考方案 您仍然可以使用它,但是您必须像这里一样重新定义…

php Singleton类实例将在多个会话中保留吗? - php

举一个简单的例子,如果我想计算一个不使用磁盘存储的脚本的命中次数,我可以使用静态类成员来执行此操作吗?用户1:<?php $test = Example::singleton(); $test->visits++; ?> 用户2:<?php $test = Example::singleton(); $test->visits+…

更改默认的URL PHP - php

如何更改默认网址。例如www.example.com/index.php-> www.example.com现在,我要将其设置为www.example.com/test.php。我应该在php.ini中进行更改吗? 参考方案 假设您正在使用apache,则可以通过DirectoryIndex指令执行此操作。Check out the docs。