Laravel消息队列异步执行-发送邮件

0x01 配置

1、修改.env,我这里是采用的数据库,一般是用的异步服务器或者redis。我这里只是用作测试

QUEUE_DRIVER=database

2、添加数据库,执行

php artisan queue:table

php artisan queue:failed-table

php artisan migrate  

3、创建队列任务,我这里使用的是发送邮件的例子

php artisan make:job SendReminderEmail

0x02 控制器

use Mail;
use App\Jobs\SendReminderEmail;  

public function email()
{
        $datas = \DB::table('data_email')->get();
        foreach($datas as $data){
            dispatch(new SendReminderEmail($data->name,$data->email));
        }
        return redirect('/users');
}

0x03 队列文件
编辑队列文件SendReminderEmail.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Mail;

class SendReminderEmail implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    protected $name;
    protected $email;
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($name, $email)
    {
        $this->name = $name;
        $this->email = $email;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

        // 如果参试大于三次
        if ($this->attempts() > 3) {
            \Log::info($this->name.'邮件参试失败过多');
        }else{
            // 每次进来休息3秒钟
            sleep(3);
            $flag = Mail::send('emails.test',['name'=>$this->name],function($message){
                $message ->to($this->email)->subject('邮件测试');
            });
            echo $this->name;
            if($flag){
                \Log::info($this->name.'邮件发送成功');
            }else{
                \Log::info($this->name.'邮件发送失败');
            }
        }
    }

    public function failed()
    {
        \Log::error($this->name.'队列任务执行失败'."\n".date('Y-m-d H:i:s'));
    }
}

0x04 开始并查看记录

在网站根目录执行,开始监听:

 php artisan queue:listen

查看storage/logs/laravel.log

[2017-05-14 02:06:25] local.INFO: 亲6邮件发送成功  
[2017-05-14 02:06:30] local.INFO: 亲7邮件发送成功  
[2017-05-14 02:06:35] local.INFO: 亲1邮件发送成功  
[2017-05-14 02:06:40] local.INFO: 亲2邮件发送成功  
[2017-05-14 02:06:45] local.INFO: 亲3邮件发送成功  
[2017-05-14 02:06:50] local.INFO: 亲4邮件发送成功  
[2017-05-14 02:06:55] local.INFO: 亲5邮件发送成功  

测试成功。。。。

Laravel原生SQL打印之SQL监听

0x01 创建SQL监听器

Laravel 5.1版本:

php artisan make:listener QueryListener --event=illuminate.query  

Laravel 5.2、5.3、5.4版本:

php artisan make:listener QueryListener --event=Illuminate\\Database\\Events\\QueryExecuted   

0x02 注册SQL监听事件

Laravel 5.1版本:

打开 app/Providers/EventServiceProvider.php,在 $listen 中添加 illuminate.query 事件的监听器为 QueryListener
头部引入 use App\Listeners\QueryListener;
protected $listen = [  
        'illuminate.query' => [
            QueryListener::class,
        ],
    ];

Laravel 5.2、5.3、5.4版本:

打开 app/Providers/EventServiceProvider.php,在 $listen 中添加 Illuminate\Database\Events\QueryExecuted 事件的监听器为 QueryListener

protected $listen = [  
        'Illuminate\Database\Events\QueryExecuted' => [
            'App\Listeners\QueryListener',
        ],
    ];

0x03 编写SQL打印逻辑代码
Laravel 5.1版本
编辑app/Listeners/QueryListener.php文件

/**
     * 日志打印方法.
     *
     * @param  illuminate.query  $event
     * @return void
     */
    public function handle($sql, $params)
    {
        // 如果env中属于本地开发则进入该判断
        if (env('APP_ENV', 'production') == 'local') {
            foreach ($params as $index => $param) {
                if ($param instanceof \DateTime) {
                    $params[$index] = $param->format('Y-m-d H:i:s');
                }
            }
            $sql = str_replace("?", "'%s'", $sql);
            array_unshift($params, $sql);
            // dd($params);
            \Log::info('SQL语句输出------------>'.call_user_func_array('sprintf', $params));
        }
    }

Laravel 5.2、5.3、5.4版本

/**
     * 日志打印方法.
     *
     * @param  illuminate.query  $event
     * @return void
     */
    public function handle(QueryExecuted $event)
    {
        if (env('APP_ENV', 'production') == 'local') {
            $sql = str_replace("?", "'%s'", $event->sql);

            $log = vsprintf($sql, $event->bindings);

            Log::info($log);
        }
    }

0x04 查看效果

打开storage/logs/laravel.log可查看到所有的SQL语句

[2017-05-14 00:43:22] local.INFO: select count(*) as aggregate from `data_users` where `status` = '1'  
[2017-05-14 00:43:22] local.INFO: select * from `data_users` where `status` = '1' order by `addtime` desc limit 10 offset 0  

Laravel框架使用任务调度发送邮件

0x01 准备工作

1、准备一个邮箱,开通SMTP服务。这里我使用的网易163邮箱

2、我这里使用的是Laravel 5.4框架测试

3、我的测试环境是:ubuntu 16.04 nginx php 7.0

4、修改.env文件,配置SMTP进行邮件发送

MAIL_DRIVER=smtp
MAIL_HOST=smtp.163.com
MAIL_PORT=25
[email protected]
MAIL_PASSWORD=密码
MAIL_ENCRYPTION=tls

0x02 使用任务调度

1、在服务器上添加定时循环命令

crontab -e

2、在出来的页面,最下面添加laravel的任务调度命令

* * * * * php /项目路径(绝对地址)/artisan schedule:run 1>> /dev/null 2>&1

3、在网站根目录执行,添加任务调度用的控制器

php artisan make:command Stat_Test

4、该命令会在app下的Console下的Commands目录生成一个Stat_Test.php文件,里面用来书写需要执行的代码,导入Mail,编写邮件发送用的控制器,下面是Stat_Test.php文件的全部内容

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Mail;

class Stat_Test extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'stat:test';   // 这里必须要改,不然下一步无法操作

    /**
     * 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()
    {
        $this->mail();
    }

    public function mail()
    {
        $name = '亲';
        $flag = Mail::send('emails.test',['name'=>$name],function($message){
            $to = [email protected]';
            $message ->to($to)->subject('邮件测试');
        });
        if($flag){
            \Log::info('邮件发送成功.');
        }else{
            \Log::info('邮件发送失败.');
        }
    }
}

5、App目录下的Console下的Kernel.php全部文件。

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    /**
     * The Artisan commands provided by your application.
     *
     * @var array
     */
    protected $commands = [
        // 将文件导入进来
        '\App\Console\Commands\Stat_Test',
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // 如果在Stat_Test.php文件中不设置protected $signature = 'stat:test';这里将无法使用
        $schedule->command('stat:test')->everyMinute();
    }

    /**
     * Register the Closure based commands for the application.
     *
     * @return void
     */
    protected function commands()
    {
        require base_path('routes/console.php');
    }
}

0x03 结语

到这里基本就可以使用了,记录了日志,可以进入

storage/logs/laravel.log

如果数量太多,可以清空在等一分钟查看是否成功

Winodws 10下安装weex-toolkit躺过的坑

0x01 问题

按照官网的安装方式:

cnpm install -g weex-toolkit

这里使用的是cnpm,国内镜像,本以为会方便很多,可是,才发现坑刚刚才开始。

安装完成后,输入weex命令,报错。

C:\Users\admin\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\.[email protected]@xtoolkit\src\package\NpmPackage.js:50
                throw new Error('resolve path error:'+this.path)
                ^

Error: resolve path error:C:\Users\admin\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\._weex-previewer
    at NpmPackage.resolve (C:\Users\admin\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\.[email protected]@xtoolkit\src\package\NpmPackage.js:50:23)
    at Command.run (C:\Users\admin\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\.[email protected]@xtoolkit\src\Command.js:43:13)
    at XToolkit._done (C:\Users\admin\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\.[email protected]@xtoolkit\src\xtoolkit.js:149:36)
    at process.nextTick (C:\Users\admin\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\.[email protected]@xtoolkit\src\xtoolkit.js:90:22)
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)
    at Module.runMain (module.js:606:11)
    at run (bootstrap_node.js:393:7)
    at startup (bootstrap_node.js:150:9)
    at bootstrap_node.js:508:3

但是输入weex -v 却可以显示版本号。

可以初始化项目,但是访问的时候页面空白,js报错。各种纠结。。。

0x02 解决

先使用:

cnpm uninstall -g weex-toolkit

卸载掉cnpm安装的weex,然后执行:

npm install -g weex-toolkit

进行安装,如果安装失败,多安装几次,有墙。

当再次输入weex命令的时候就OK了。

哎。镜像始终是镜像啊/////

Laravel框架JWT-auth使用实例

0x01 安装

composer require tymon/jwt-auth 0.5.*

0x02 配置

安装完成后,需要在config/app.php中注册相应的服务提供者:

providers下:

Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,

aliases下:

'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class

然后发布相应配置文件:

php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"

生成密钥:

php artisan jwt:generate

修改API验证方式:

config/auth.php中的

'api' => [
            'driver' => 'jwt',//原来是token
            'provider' => 'users',
        ],

修改App\user.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * 白名单 $fillable 属性指定了哪些字段支持批量赋值
     * @var array
     */
    protected $fillable = ['guid', 'username', 'tel', 'password', 'pic', 'balance', 'status', 'addtime'];
    /**
     * 模型所使用的数据库表
     * @var string
     */
    protected $table = 'data_users';//改为你的用户表
    /**
     * 自定义主键
     */
    protected $primaryKey = 'guid';//改为你的主键

    /**
     * 关闭 递增
     */
    public $incrementing = false;
    /**
     * 关闭 创建时间 与 更新时间的自动维护
     */
    public $timestamps = false;

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

路由:

Route::group(['namespace' => 'Home','middleware' => ['api','response']],function (){
    //商品列表+详情
    Route::resource('/goodslist','GoodsController');
    //商品分类
    Route::resource('/class','ClassController');
    //需要登陆才能查看的接口
    Route::group(['middleware' => ['jwt.auth']],function (){
        //购物车
        Route::resource('/cart','CartController');
    });
});

0x03 创建token

需要引入的:
use App\user;
use JWTAuth;

//查询一条数据,并输出token
 $user = User::first();

    $token = JWTAuth::fromUser($user);

0x04 获取token




public function index(Response $response)
    {
        //获取用户信息
        $user = JWTAuth::toUser(Input::get('token'));
        //获取购物车信息
        $cart = self::$cartService->getCart($user->id);
        //判断是否有值
        if (empty($cart) || ($cart->count() <= 0)){
            return $response->setStatusCode(404);
        }
        return $cart;
    }

0x05 总结

不知道是我打开方式不对还是什么情况,其中有很多地方我都不小心踩过坑。。。哎。如有问题或者不同的建议,请点击上方的关于我,联系!