译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/task-scheduling/properties-of-an-event 你添加的每个记录都将转换为 Illuminate\Console\Scheduling\Event 的实例,并存储在 Scheduler 的 $events 类属性中,Event 对象由以下内容组成: 命令运行 CRON 表达式 用于评估时间的时区 操作系统运行该命令的用户 命令应该运行的环境列表 维护模式配置 事件重叠配置 命令前台/后台运行配置 用于决定该命令是否运行的检查列表 如何处理输出的配置 命令运行后运行的回调 在命令运行前运行的回调 命令说明 命令的唯一 Mutex 命令可能像下面一种方式运行: 回调 在操作系统上运行的命令 artisan 命令 被调度的作业 使用回调 在回调的情况下,Container::call() 方法用于运行我们传递的值,这意味着我们可以传递一个可以调用或表示方法的字符串: protected function schedule(Schedule $schedule) { $schedule->call(function () { DB::table('recent_users')->delete(); })->daily(); } Or: protected function schedule(Schedule $schedule) { $schedule->call('MetricsRepository@cleanRecentUsers')->daily(); } 调用操作系统的命令 如果要运行操作系统的命令,可以使用 exec(): $schedule->exec('php /home/sendmail.php --user=10 --attachInvoice')->monthly(); 您还可以将数组作为参数:

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接 https://divinglaravel.com/task-scheduling/before-the-dive 想象这种情况,作为一个大型 SaaS 的开发者,您需要找到一种在周末每分钟选择 10 个随机客户的方式,并提供折扣升级,发送折扣的工作可能非常简单,但我们需要每分钟运行一次,为此我分享一些 CRON 的简要介绍给还不熟悉人。 CRON CRON 是一个守护进程,它驻留在你的 linux 服务器中,大部分时间都没有唤醒,但是每一分钟它都会睁开双眼,看看是否运行任何给定的任务,你使用 crontab 文件与该守护进程通信,在大多数常见的设置文件可以位于/etc/crontab,crontab 文件可能看起来像这样: 0 0 1 * * /home/full-backup 0 0 * * * /home/partial-backup 30 5 10 * * /home/check-subscriptions 在 crontab 文件中,每行表示一个计划任务作业,每个作业定义包含两部分: *部分代表该作业运行的计时器。 第二部分是应运行的命令 CRON 时序语法 5 个星号按顺序排列如下: 一小时内的分钟 一天内的小时 一个月内的日期 一年内的月份 一周的内的天 示例: 0 0 1 * * 在第一个例子中,表示该工作应在每月,每个月的第一个天,上午 12 点,每小时第一分钟运行。 或者简单地说,它应该在每月的第一天上午 12:00 运行。 0 * * * * 在第二个例子中,表示该工作应该每小时运行一次。 30 5 10 * * 表示该工作应该在每个月 10 日上午 5:30 运行 这里还有一些其他的示例:

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接https://divinglaravel.com/queue-system/pushing-jobs-to-queue 有几种方法可以将作业推送到队列中: Queue::push(new InvoiceEmail($order)); Bus::dispatch(new InvoiceEmail($order)); dispatch(new InvoiceEmail($order)); (new InvoiceEmail($order))->dispatch(); 调用Queue facade 是对应用程序使用的队列驱动的调用,如果你使用数据库队列驱动,调用push方法是调用Queue\DatabaseQueue类的push方法。 有几种有用的方法可以使用: // 将作业推送到特定的队列 Queue::pushOn('emails', new InvoiceEmail($order)); // 在给定的秒数之后推送作业 Queue::later(60, new InvoiceEmail($order)); // 延迟后将作业推送到特定的队列 Queue::laterOn('emails', 60, new InvoiceEmail($order)); // 推送多个作业 Queue::bulk([ new InvoiceEmail($order), new ThankYouEmail($order) ]); // 推送特定队列上的多个作业 Queue::bulk([ new InvoiceEmail($order), new ThankYouEmail($order) ], null, 'emails'); 调用这些方法之后,所选择的队列驱动会将给定的信息存储在存储空间中,供 workers 按需获取。 使用命令总线 使用命令总线调度作业进行排队可以给你额外控制权; 您可以从作业类中设置选定的connection, queue, and delay 来决定命令是否应该排队或立即运行,在运行之前通过管道发送作业,实际上你甚至可以从你的作业类中处理整个队列过程。 Bug facade 代理到Contracts\Bus\Dispatcher 容器别名,此别名解析为Bus\Dispatcher内的Bus\BusServiceProvider的一个实例: $this->app->singleton(Dispatcher::class, function ($app) { return new Dispatcher($app, function ($connection = null) use ($app) { return $app[QueueFactoryContract::class]->connection($connection); }); }); 所以Bus::dispatch() 调用的 dispatch() 方法是 Bus\Dispatcher 类的:

阅读全文

原文链接https://divinglaravel.com/queue-system/preparing-jobs-for-queue Every job we push to queue is stored in some storage space sorted by the order of execution, this storage place could be a MySQL database, Redis store, or a 3rd party service like Amazon SQS. 我们推送到队列的每个作业都存储在按执行顺序排序的某些存储空间中,该存储位置可以是 MySQL 数据库,Redis 存储或像 Amazon SQS 这样的第三方服务。 Later in this dive we’re going to explore how workers fetch these jobs and start executing them, but before that let’s see how we store our jobs, here are the attributes we keep for every job we store:

阅读全文

译文 GitHub https://github.com/yuansir/diving-laravel-zh 原文链接https://divinglaravel.com/queue-system/before-the-dive Laravel 接收请求,做一些工作,然后向用户返回响应,这是处理请求的 Web 服务器的正常同步工作流程,但有时您需要在后台执行不中断或减慢的一些流程,例如在订单之后向用户发送发票电子邮件,你不想让用户等待邮件服务器接收请求,构建电子邮件消息,然后分派给用户,你只要向屏幕发送“谢谢!”给用户,电子邮件在后台准备和发送,他继续做他自己的事。 Laravel 配有内置的队列系统,可帮助您在后台运行任务,并通过简单的 API 来配置系统在不同情况下起作用。 您可以在 config/queue.php中管理队列配置,默认情况下它有使用不同队列驱动的几个连接,您可以看到项目中可以有多个队列连接,也可以使用多个队列驱动程序。 我们将研究不同的配置,但请先看看 API: Queue::push(new SendInvoice($order)); return redirect('thank-you'); 队列Queue facade 是 queue 容器别名,如果我们看看Queue\QueueServiceProvider ,我们可以看到这个别名是如何注册的: protected function registerManager() { $this->app->singleton('queue', function ($app) { return tap(new QueueManager($app), function ($manager) { $this->registerConnectors($manager); }); }); } 所以 Queue facade 代理到在容器中注册为 Queue\QueueManager 类的单例,我们还将连接器注册到 Laravel 所支持使用的registerConnectors()的不同队列驱动程序中: public function registerConnectors($manager) { foreach (['Null', 'Sync', 'Database', 'Redis', 'Beanstalkd', 'Sqs'] as $connector) { $this->{"register{$connector}Connector"}($manager); } } 该方法只需调用注册 register{DriverName}Connector方法,例如注册一个 Redis 连接器:

阅读全文

Larvae 的配置都在 config 目录下非常方便管理,可以通过config()帮助函数来实现对配置项目的设置和获取,同时用 DotEnv 来实现项目内环境变量的控制,非常强大和方便。我们在日常开发中如果没有使用 Laravel 框架,比如写一些脚本,或者自己写的项目框架,但是想集成这样的配置管理。这里就讲讲如何集成illuminate/config 到自己的项目中实现 Laravel 那种 config 配置。 首先通过 composer 来安装illuminate/config 和 vlucas/phpdotenv,composer.json 如下: { "require": { "illuminate/config": "^5.2", "vlucas/phpdotenv": "^2.3" }, "autoload": { "psr-4": { "App\\": "app/" } } } 创建.env 文件,同时创建对应环境的 env 文件,为了解决不同环境加载不同配置的问题。比如: .env 里面只写入当前环境,比如local,develop , production .local.env 表示本地开发环境的配置项 .develop.env 表示测试环境的配置项 .production 表示生产环境的配置项 关于 Laravel 在不同环境加载不同配置的方法可以参考我的这篇文章《Laravel 在不同的环境调用不同的配置文件》 我们在新建一个配置文件,比如 config/app.php 或者 config/path/to.php 加载配置文件,新建 app/Config.php <?

阅读全文

Laravel Tips 之 forelse

我们在 Laravel Blade 模板中经常在循环输出前先判断一下集合是否有值,然后再foreach 比如: @if ($posts->count()) @foreach ($posts as $post) <p>This is post {{ $user->id }}</p> @endforeach @else <p>No posts found.</p> @endif 其实在 Laravel Blade 中可以使用forelse: @forelse ($posts as $post) <p>This is post {{ $post->id }}</p> @empty <p>No posts found.</p> @endforelse 它的实现可以在Illuminate/View/Compilers/BladeCompiler.php找到: /** * Compile the forelse statements into valid PHP. * * @param string $expression * @return string */ protected function compileForelse($expression) { $empty = '$__empty_'.++$this->forelseCounter; return "<?

阅读全文

Docker 快速入门指引

Docker 是什么? Docker 是 Docker.Inc 公司开源的一个基于 LXC 技术之上构建的 Container 容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。 开发者可以搭建他们的应用仅仅一次,就能保证让这个应用保持一致的跑在任何地方。运营人员可以将他们的服务器配置一遍,就能跑任何应用。 What is Docker’s architecture? Docker uses a client-server architecture. The Docker *client* talks to the Dockerdaemon, which does the heavy lifting of building, running, and distributing your Docker containers. Both the Docker client and the daemon *can* run on the same system, or you can connect a Docker client to a remote Docker daemon.

阅读全文

Ubuntu LNMP 一键安装脚本

这两天整了个 Ubuntu(14.04 LTS)上安装配置 Nginx,MySQL,PHP 环境的一键安装的 shell 脚本,一劳永逸。 Github:ubuntu-lnmp-installer 包括的软件包: Jemalloc(4.2.0) PHP(7.07) MySQL(5.6.29) Nignx(1.10.0) Redis(3.2.0) Node.js(5.8.0) PM2 Beanstalkd Supervisor 使用方法: git clone cd ubuntu-lnmp-installer ./install.sh 转载请注明: 转载自Ryan 是菜鸟 | LNMP 技术栈笔记 如果觉得本篇文章对您十分有益,何不 打赏一下 本文链接地址: Ubuntu LNMP 一键安装脚本 本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

阅读全文

Laravel 集成 Monolog 来做日志处理,Monolog 非常强大,也容易扩展,其实它本身已经支持很多Handler了,你可以把日志发送到邮件或者其他日志收集服务器或者系统中,因为我们团队使用Bearychat 作为团队沟通工具,所以把 Laravel 项目的实时错误日志推送到 Bearychat 的一个讨论组中,方便组员迅速发现异常和解决问题 ,其实很简单没多少行代码就搞定了。 首先创建 BearyChatHandler <?php namespace App; use Monolog\Handler\AbstractProcessingHandler; use Monolog\Logger; use Monolog\Handler\Curl; class BearyChatHandler extends AbstractProcessingHandler { private $data; private $webhook; public function __construct($webhook, $channel, $level = Logger::NOTICE, $bubble = true) { $this->data['channel'] = $channel; $this->webhook = $webhook; parent::__construct($level, $bubble); } /** * {@inheritDoc} */ protected function write(array $record) { $postData = [ 'text' => $record['datetime']->format('Y-m-d H:i:s') .

阅读全文

作者的图片

Ryan是菜鸟 | LNMP技术栈笔记

一步一个脚印,一直在路上!记录LNMP技术栈,Web架构,区块链等笔记

菜鸟码农

南京