Laravel - 将函数的一部分转换为排队的语句

时间:2015-06-22 20:10:43

标签: php laravel laravel-5 task-queue

我想在我的控制器中排队部分函数,​​主要是因为它访问第三方API并从所述请求中计算某些信息。我也想这样做以增加我对队列的了解!

我想要排队的代码是:

使用此if statement推送的唯一变量是$postcode$clinic ID(在声明上方计算出来)。

if($clinic->postcode != $postcode)
    {

     $client = new Client([ 'base_uri' => 'https://api.postcodes.io/','timeout' => 2.0, 'verify' => false ]);
     $response = $client->get('postcodes/'.$postcode)->getBody();

     $input = json_decode($response);

     $clinic->latitude   = $input->result->latitude;
     $clinic->longitude  = $input->result->longitude;
     $clinic->save();
}

到目前为止,我已经创建了queue表并迁移了它。

然后我运行了命令:php artisan make:job GetClinicLatAndLongPoints --queued

我的问题是,如何将此函数放在GetClinicLatAndLongPoints中,包括传递两个变量?

我到目前为止:

public function handle(Clinic $clinic, $postcode)
    {

    }

但我不确定如何解决问题!任何指导都会非常感激。

1 个答案:

答案 0 :(得分:0)

您可以将Clinic模型的实例和邮政编码传递给作业的构造函数,这可能看起来像

namespace App\Jobs;

use App\Clinic;
use App\Jobs\Job;
use GuzzleHttp\Client;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Bus\SelfHandling;
use Illuminate\Contracts\Queue\ShouldQueue;

class GetClinicLatAndLongPoints extends Job implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    private $clinic;
    private $postcode;

    public function __construct(Clinic $clinic, $postcode)
    {
        $this->clinic = $clinic; // Laravel will automatically deserialize the model instance
        $this->postcode = $postcode;
    }

    public function handle()
    {
        $coordinates = $this->getCoordinates($this->postcode);

        if (! is_null($coordinates)) {
            // You may want to add error handling
            $this->clinic->latitude   = $coordinates['latitude'];
            $this->clinic->longitude  = $coordinates['longitude'];
            $this->clinic->save();
        }
    }

    private function getCoordinates($postcode)
    {
        $client = new Client(['base_uri' => 'https://api.postcodes.io/','timeout' => 2.0, 'verify' => false]);
        $response = json_decode($client->get('postcodes/'.$postcode)->getBody()->getContents());
        if (! $response || json_last_error() !== JSON_ERROR_NONE) {
            return null;
        }
        if ($response->status == 200 &&
            isset($response->result->latitude) &&
            isset($response->result->longitude)) {
            return [
                'latitude' => $response->result->latitude,
                'longitude' => $response->result->longitude
            ];
        }
        return null;
    }
}

在你的控制器中你派遣你的工作

if ($clinic->postcode != $postcode) {
    $this->dispatch(new GetClinicLatAndLongPoints($clinic, $postcode));
}

旁注:虽然Laravel附带了数据库队列驱动程序,但在生产中使用它并不是一个好主意。最好使用其中一个job queues,即beanstalkd