Laravel Artisan 除了自带的命令外,它也支持用户创建自己的命令。下面我们以创建一个 hash
命令为例来讲解如何创建自己的命令。
通过 make:command
创建命令
rtisan 提供了一个 make:command 命令用于创建用户自己的命令。它的使用很简单,接受一个 name 参数,用于指定生成的命令文件名及命令类名,还可指定一个 –command 选项,可用于指定命令名、命令参数及命令选项(会在下面详细讲到),make:command 命令的帮助说明如下:

首先打开终端,在项目根目录下执行以下命令:
php artisan make:command HashCommand
当看到
php artisan make:command HashCommand
Console command created successfully.
表示命令文件已经创建好了,我们可以在项目的 app/Console/Commands
目录中看到多了一个新生成的 Hash.php
文件,这就是我们的命令源文件。看下它的内容:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class HashCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:name';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
}
}
可以看到,HashCommand 类派生自 Illuminate\Console\Command 类,除了构造方法,HashCommand 类中还包含以下属性和方法:
$signature 属性,设置命令名、命令参数、命令选项;
$description 属性,设置命令的描述信息;
handle() 方法,包含实际的命令逻辑代码。
这个时候,我们已经可以执行这个命令了(尽管它还啥事都做不了),那么如何执行它呢?只要在 php artisan 后面带上 $signature 属性指定的命令名即可:
php artisan command:name
下面是php artisan command 的一个完整例子:定时任务同步处理订单异步回调
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Model\TransactionOrder;
use App\Model\Merchants;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ServerException;
use GuzzleHttp\Exception\ClientException;
class SyncStatusToMerchants extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'merchant-order:sync';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$orders = TransactionOrder::where('sync_status', 0)->where('status', TransactionOrder::ORDER_STATUS_COMPLETED)->orderBy('id', 'DESC')->limit(20)->get();
foreach ($orders as $order)
{
$_merchant = Merchants::find($order->merchants_id);
$_response = $this->doRequest($_merchant->notification_url, [
'incrementid' =>$order->increment_id,
'transaction_id'=>$order->transaction_id_3rd,
'status' =>$order->status
], $_merchant);
if (is_array($_response))
{
if ($_response['code'] == '00') {
$order->sync_status = 1;
} else {
$_order->sync_note = $_response['msg'];
}
$order->save();
$this->line('order id:' . $order->increment_id . ' status: ' . $order->sync_status . '--' . $order->status . 'response' . $_response['code'] . '-' . $_response['msg']);
} else {
$this->error('order id:' . $order->increment_id . ' status: ' . $order->sync_status . '--' . $order->status);
}
}
}
public function doRequest($url, $data, $_merchant)
{
$params = '?incrementid='.$data['incrementid'].'&transaction_id='.$data['transaction_id'].'&status='.$data['status'];
$sigStr = hash('sha512', $params . $_merchant->email . $_merchant->api_key, false);
$data['sig'] = $sigStr;
$_client = new Client();
try {
$_result = $_client->post($url, [
'form_params' => $data
]);
return json_decode($_result->getBody()->getContents(), true);
} catch (ClientException $e) {
// do something
$this->error('1: ' . $e->getMessage());
return false;
} catch (ServerException $e) {
// do something
$this->error('2: ' . $e->getMessage());
return false;
} catch (\Throwable $throwable) {
// do something
$this->error('3: ' . $throwable->getMessage());
return false;
}
}
}

有了上面的命令,我们需要在服务器上开启定时任务。在开启定时任务之前,我们可以把我们的命令交给 Kernel.php来执行。