分类 PHP 下的文章

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
MAIL_USERNAME=发送邮件的邮箱@163.com
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 = '接收邮箱@qq.com';
            $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

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

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',
        ],

修改Appuser.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 总结

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

Laravel框架中Session储存机制

0x01 起因

一次操作在Controller中删除了Session,然后立马来了一个dd(session(key));很惊讶的发现,Session是空的,但是因为中间键那里是进行了登陆判断的。虽然dd出来的Session是空的,然而访问其它页面居然毫无影响。我第一时间是以为中间键没弄好。经过仔细检查后,发现。。。。

0x02 经过

部分Session操作

//session的永久保存(在不过期范围内)  
Session::put('key', 'value');  
 
//等同于PHP的原生session  
$_SESSION['key'] = 'value';  
 
//get操作  
$value = Session::get('key', 'default');  
 
//去除操作并删除,类似pop概念  
$value = Session::pull('key', 'default');  
 
//检测是否存在key  
Session::has('users');  
 
//删除key  
Session::forget('key');  

虽然我删除了Session,但是Session好像并没有立即生效。

谷歌后,发现有个方法Session::save(),在销毁了Session后执行下这个,再dd,立马生效了。

在bootstrap/compiled.php中

class Middleware implements HttpKernelInterface  
{  
    ...  
    public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)  
    {  
        $this->checkRequestForArraySessions($request);  
        if ($this->sessionConfigured()) {  
            $session = $this->startSession($request); // 启动session  
            $request->setSession($session);  
        }  
        $response = $this->app->handle($request, $type, $catch); // 调用controller的method  
        if ($this->sessionConfigured()) {  
            $this->closeSession($session);         //关闭session  
            $this->addCookieToResponse($response, $session);  
        }  
        return $response;  
    }  
    ...  
 
    protected function closeSession(SessionInterface $session)  
    {  
        $session->save();    // 保存session  
        $this->collectGarbage($session);  
    }  
}  

可以看见,在调用完controller之后,调用了session->save()的方法,来主动的保存session。这样session才能落地保存起来,如果在controller或者view里面写了exit或者dd等;,那么session是不会被生效的,除非主动的写Session::save()才能手工的保存起来。因此在debug调试的时候千万要注意啊。

Laravel框架添加成功跳转提示页

0x01 背景

在写后台增删改查的时候,出于用户体验,每个操作都需要添加相应的提示,虽然Laravel有一定的提示。但是我个人感觉还是太繁琐不人性化,不便于后期维护。

Laravel自带的提示是在操作完成后添加一个一次性Session,然后再页面输出

return redirect('/')->with('message', 'Message sent!');

view输出的时候。

@if(Session::has('message'))
 <div class="alert alert-info"> {{Session::get('message')}} 
 </div> 
 @endif

这样写呢,我个人感觉,每一次操作都需要在每个页面写,如果我们后期进行更改的时候,需要每个页面的改,相对来说不便于维护。我由此方法进行了一下改造。

0x02 准备提示页面

新建一条路由,一个控制器,一个对应的view页面。

路由:

  Route::resource('/prompt','PromptController');

控制器:

<?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PromptController extends Controller
{
    public function index()
    {
        //验证参数
    if(!empty(session('message')) && !empty(session('url')) && !empty(session('jumpTime'))){
        $data = [
            'message' => session('message'),
            'url' => session('url'),
            'jumpTime' => session('jumpTime'),
            'status' => session('status')
        ];
    } else {
        $data = [
            'message' => '请勿非法访问!',
            'url' => '/',
            'jumpTime' => 3,
            'status' => false
        ];
    }
        return view('admin.prompt',['data' => $data]);
    }
}

view页面:

<body>

        <div class="wrapper-page">
            <div class="panel panel-color {{ $data['status']?'panel-inverse':'panel-danger' }}">

                <div class="panel-heading">
                   <h3 class="text-center m-t-10">{{ $data['message'] }}</h3>
                </div>

                <div class="panel-body">
                    <div class="text-center">
                        <div class="alert {{ $data['status']?'alert-info':'alert-danger' }} alert-dismissable">
                            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
                            浏览器页面将在<b id="loginTime">{{ $data['jumpTime'] }}</b>秒后跳转......
                        </div>
                        <div class="form-group m-b-0">
                            <div class="input-group">
                                {{--<input type="password" class="form-control" placeholder="Enter Email">--}}
                                <span class="input-group-btn"> <button type="submit" class="btn {{ $data['status']?'btn-success':'btn-danger' }}">点击立即跳转</button> </span>
                            </div>
                        </div>

                    </div>
                </div>
            </div>
        </div>
        <script src="/js/jquery.js"></script>
        <script type="text/javascript">
            $(function(){
                //循环倒计时,并跳转
                var url = "{{ $data['url'] }}";
                var loginTime = parseInt($('#loginTime').text());
                console.log(loginTime);
                var time = setInterval(function(){
                    loginTime = loginTime-1;
                    $('#loginTime').text(loginTime);
                    if(loginTime==0){
                        clearInterval(time);
                        window.location.href=url;
                    }
                },1000);
            })
//点击跳转
            $('.btn-success').click(function () {
                var url = "{{ $data['url'] }}";
                window.location.href=url;
            })
        </script>

    </body>

创建好以后,以后使用的时候,只需要在操作完成后来一句。

return redirect('/prompt')->with(['message'=>'添加会员失败!','url' =>'/users/create', 'jumpTime'=>3,'status'=>false]);

就可以像ThinkPHP一样的,跳转到提示页,再跳转到指定的URL了。

解释:
message:需要在提示页提示的内容。
url:需要最后跳转的url。
jumpTime:在提示页等待的时间,秒为单位。
status:状态,因为提示有正确提示与错误提示,不同的提示提示页面可以设置不同的CSS,从而达到区分。

0x03 结束

到这里就全部完成了,如果您有更好的方法,欢迎与我沟通。上方关于我有QQ。谢谢