如何在Laravel控制器中向控制台输出内容?

115

我有一个Laravel控制器:

class YeahMyController extends BaseController {
    public function getSomething() {
        Console::info('mymessage'); // <-- what do I put here?
        return 'yeahoutputthistotheresponse';
    }
}

目前,我正在使用Artisan来运行该应用程序(它在幕后运行PHP内置的开发Web服务器):

php artisan serve

我想将控制台消息记录到 artisan 进程的 STDOUT 管道。


这是我见过的最好的答案,当你想要写入Laravel日志并在控制台中显示时:https://dev59.com/DVgQ5IYBdhLWcg3wtmSq#50939811 - Ryan
16个回答

144

3
更理想的方法是使用 Laravel 的内置日志,例如 Log::info('这是某些有用信息。'),请参考我的答案。 - wired00
17
这个问题特别在于如何写入到 artisan serve 控制台中。error_log() 可以实现,而 Log::info() 则不行。 - Tobia
2
正是我所需要的。快速而简单 - 完美适用于开发工作。 - dotnetCarpenter
如果您想要从Laravel中使用高级命令IO(例如样式、询问和表格),请查看我在这里的答案中的ConsoleCommand类。 - Tomeg
但它只打印字符串,我想要打印一个对象 :( - Tarek
@wired00,我不得不使用\Log::info('这是一些有用的信息。'); - Black

87

这个问题涉及到通过artisan进行服务,所以Jrop的回答在这种情况下是理想的。即使用error_log记录日志到apache日志中。

然而,如果你是通过标准的Web服务器提供服务,则只需使用Laravel特定的日志记录函数:

\Log::info('This is some useful information.');

\Log::warning('Something could be going wrong.');

\Log::error('Something is really going wrong.');

或者使用当前版本的 Laravel,像这样:

info('This is some useful information.');

这将记录到 Laravel 的日志文件,位于 /laravel/storage/logs/laravel-<date>.log (Laravel 5.0)。监视日志 - Linux/OSX: tail -f /laravel/storage/logs/laravel-<date>.log


15
如果你正在使用Artisan Web服务器,就不需要Apache。而且,如果使用Log::info命令,也不会将日志输出到STDOUT。 - melvinmt
1
@wired00 你说得对,但正如我在原问题中所述,我没有使用Apache,而是使用artisan web服务器。在这种情况下,error_log更有用。 - Jonathan Apodaca
@Jrop 是的,你说得对。我修改了我的答案以澄清这一点。 - wired00
如果你想要 Laravel 中的高级命令 IO(例如样式、询问和表格),那么请查看我在这里的答案中的 ConsoleCommand 类。 - Tomeg

45

我自己没有尝试过这个,但是快速搜索库表明你可以这样做:

$output = new \Symfony\Component\Console\Output\ConsoleOutput();
$output->writeln("<info>my message</info>");

我找不到这个的快捷方式,所以您可能希望创建一个外观以避免重复。


尽管我喜欢Jrop的回答,但我认为这也应该是被接受的答案。 - Mark Odey
文档参考 - Mark Odey
如果你想要 Laravel 中的高级命令 IO(例如样式、询问和表格),那么请查看我在这里的答案中的 ConsoleCommand 类。 - Tomeg
输出日志样式参考:信息、注释、问题、错误和自定义样式。 - undefined

29

非常简单。

您可以在应用程序的任何地方调用它。

$out = new \Symfony\Component\Console\Output\ConsoleOutput();
$out->writeln("Hello from Terminal");

1
你在终端里检查过了吗? - Googlian

29
在 Laravel 6 中有一个名为 'stderr' 的通道。请查看 config/logging.php 文件:
'stderr' => [
    'driver' => 'monolog',
    'handler' => StreamHandler::class,
    'formatter' => env('LOG_STDERR_FORMATTER'),
    'with' => [
        'stream' => 'php://stderr',
    ],
],
在您的控制器中:
use Illuminate\Support\Facades\Log;

Log::channel('stderr')->info('Something happened!');

2
简单易懂,谢谢。 - luisenricke
刚刚尝试了一下,效果棒极了!我在.env文件中添加了LOG_CHANNEL到stderr,这就是我需要做的全部了。 - undefined

12
为了更好地解释Dave Morrissey的答案,我已经为在Laravel外观中将代码包装到Console输出类中制作了以下步骤。
1)在您喜欢的文件夹中创建外观(在我的情况下是app\Facades):
class ConsoleOutput extends Facade {

 protected static function getFacadeAccessor() { 
     return 'consoleOutput';
 }

}

2)按照以下方式在app\Providers中注册新的服务提供者:

class ConsoleOutputServiceProvider extends ServiceProvider
{

 public function register(){
    App::bind('consoleOutput', function(){
        return new \Symfony\Component\Console\Output\ConsoleOutput();
     });
 }

}

3) 将所有这些内容添加到config\app.php文件中,注册提供程序和别名。

 'providers' => [
   //other providers
    App\Providers\ConsoleOutputServiceProvider::class
 ],
 'aliases' => [
  //other aliases
   'ConsoleOutput' => App\Facades\ConsoleOutput::class,
 ],

就这样,在您的Laravel应用程序的任何位置,只需以这种方式调用您的方法:

ConsoleOutput::writeln('hello');

希望这能帮助到你。


如果你想要 Laravel 中的高级命令 IO(例如样式、询问和表格),那么请查看我在这里的答案中的 ConsoleCommand 类。 - Tomeg

10

我希望我的日志信息能够发送到标准输出,因为Amazon的容器服务(ECS)可以轻松地将标准输出收集并发送到CloudWatch Logs。所以为了让它正常工作,我在config/logging.php文件中添加了一个新的标准输出条目,如下所示:

    'stdout' => [
        'driver' => 'monolog',
        'handler' => StreamHandler::class,
        'with' => [
            'stream' => 'php://stdout',
        ],
        'level' => 'info',
    ],

接下来我只需要将 'stdout' 添加为堆栈日志通道之一:

    'default' => env('LOG_CHANNEL', 'stack'),

    'stack' => [
        'driver' => 'stack',
        'channels' => ['stdout', 'daily'],
    ],

这样,我仍然可以在本地开发时(甚至在实例上如果您可以访问它),将日志记录到文件中,但更重要的是它们会被发送到stdout,而stdout会保存在CloudWatch Logs中。


8
如果你想要使用Laravel中fancy 命令IO(比如样式、问答和表格),那么我已经创建了下面这个类。请按照以下步骤操作:我没有完全验证它是否是最干净的解决方案等,但它很好用(但我只在Laravel 5.5中的单元测试用例中进行了测试)。所以你很可能可以随意使用它:
$cmd = new ConsoleCommand;

$cmd->error("Aw snap!");
$cmd->table($headers, $rows);
$answer = $cmd->ask("Tell me, what do you need?");

//even Symfony's progress bar
$cmd->outputStyle->progressStart(5);  //set n = 100% (here 100% is 5 steps)
$cmd->outputStyle->progressAdvance(); //you can call it n times
$cmd->outputStyle->progressFinish();  //set to 100%

当然,您也可以将其包装在自己的门面中,或一些静态单例等中,或任何您希望的方式。
类本身
class ConsoleCommand extends \Illuminate\Console\Command
{
    protected $name = 'NONEXISTENT';
    protected $hidden = true;

    public $outputSymfony;
    public $outputStyle;

    public function __construct($argInput = null)
    {
        parent::__construct();

        $this->input = new \Symfony\Component\Console\Input\StringInput($argInput);

        $this->outputSymfony = new \Symfony\Component\Console\Output\ConsoleOutput();
        $this->outputStyle = new \Illuminate\Console\OutputStyle($this->input, $this->outputSymfony);

        $this->output = $this->outputStyle;
    }

}

2
谢谢您提供这个好主意。对于当前的 Laravel 版本(使用 7.x),我认为应该是 public function __construct($argInput = "") - dude2511

4

如果您想要将日志记录到STDOUT,您可以使用Laravel提供的任何方法;例如(来自wired00的答案):

Log::info('This is some useful information.');

STDOUT魔法可以使用以下代码实现(您需要设置文件以便将info信息输出到该文件中):

Log::useFiles('php://stdout', 'info');

警告:这仅用于调试。不要在生产中使用你完全不理解的任何东西。


这对于迁移和其他artisan命令的内联调试也非常有效。 - Stuart Wagner

3

有点晚了……我很惊讶没有人提到Symfony的VarDumper组件,Laravel部分地将其包含在dd()(以及不那么常用的dump())实用函数中。

$dumpMe = new App\User([ 'name' => 'Cy Rossignol' ]);

(new Symfony\Component\VarDumper\Dumper\CliDumper())->dump( 
    (new Symfony\Component\VarDumper\Cloner\VarCloner())->cloneVar($dumpMe)
);

需要一些额外的代码,但是我们可以在控制台中得到漂亮格式化、易于阅读的输出——尤其适用于调试复杂的对象或数组:

App\User {#17
  #attributes: array:1 [
    "name" => "Cy Rossignol"
  ]
  #fillable: array:3 [
    0 => "name"
    1 => "email"
    2 => "password"
  ]
  #guarded: array:1 [
    0 => "*"
  ]
  #primaryKey: "id"
  #casts: []
  #dates: []
  #relations: []
  ... etc ...
}

更进一步,我们甚至可以给输出着色!在项目中添加这个帮助函数可以节省一些打字时间:

function toConsole($var) 
{
    $dumper = new Symfony\Component\VarDumper\Dumper\CliDumper();
    $dumper->setColors(true);

    $dumper->dump((new Symfony\Component\VarDumper\Cloner\VarCloner())->cloneVar($var));
}

如果我们在完整的Web服务器(如Apache或Nginx,而不是artisan serve)后运行应用程序,我们可以稍微修改此函数以将转储器的漂亮输出发送到日志中(通常为storage/logs/laravel.log):

function toLog($var) 
{
    $lines = [ 'Dump:' ];
    $dumper = new Symfony\Component\VarDumper\Dumper\CliDumper();
    $dumper->setColors(true);
    $dumper->setOutput(function ($line) use (&$lines) { 
        $lines[] = $line;
    });

    $dumper->dump((new Symfony\Component\VarDumper\Cloner\VarCloner())->cloneVar($var));

    Log::debug(implode(PHP_EOL, $lines));
}

当然,您可以使用以下方式查看日志:

$ tail -f storage/logs/laravel.log

PHP的error_log()函数适用于快速、一次性地检查简单值,但上面展示的函数可以帮助您调试Laravel更复杂的类,省去了很多繁琐的工作。


1
我喜欢使用CliDumper()这个解决方案!谢谢 :) - boryn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接