用Laravel也有不短的时间了,也用过不少版本了,以下代码是在日常项目中收集,作为笔记,也分享出来,希望对你有点用处。 注:版本没标注,若有不兼容的问题,微调即可。
验证 不太习惯单独弄个Request验证类,比较习惯下面的写法:
use Illuminate \Http \Request ;use Illuminate \Support \Facades \Validator ; $inputData = $request ->only (['name' , 'address' , 'mobile' , 'draw_id' ]); $messages = [ 'required' =>':attribute为必填项' , 'int' =>':attribute参数类型错误' , 'max' =>':attribute长度不得超过 :size' , ]; $validator = Validator ::make ($inputData , [ 'draw_id' => 'required|int' , 'name' => 'required' , 'mobile' => 'required' , 'address' => 'required' , ], $messages ,[ 'name' =>'收货人姓名' , 'mobile' =>'手机号码' , 'address' =>'收货地址' , ]); if ($validator ->fails ()) { return self ::response ([], current ($validator ->errors ()->all ()), 2 ); }
ORM 关联查询
一对一
class User extends Model { ... public function userIntegral ( ) { return $this ->hasOne ('App\Models\UserIntegral' , 'user_id' , 'id' ); } } (new User ())->with ('userIntegral' )->orderBy ('id' , 'desc' )->paginate ($limit );
一对多
namespace App \Models ;use Illuminate \Database \Eloquent \Model ;class Hotel extends Model { public function orders ( ) { return $this ->hasMany ('App\Models\Order' ); } } $hotel = Hotel ::with (['orders' => function ($query ) { $query ->where ('status' , 30 ); }])->find (4 );
统一异常处理 这个可以参见之前的文章Laravel 统一错误处理为 JSON
队列 失败队列入库
生成表 生成failed_jobs表
php artisan queue:failed-table php artisan migrate
单独处理
可以在Job中单独处理失败,Job失败也会写入上面生成的failed_jobs表
public function failed (Exception $exception ) { }
重试队列 有时候代码有漏洞可能会有队列执行失败的状况,这时候我们就需要重试。
查看所有失败
重试所有失败php artisan queue:retry all
重试单个失败php artisan queue:retry 13
清空失败(重要的队列数据万不可这么操作)
另外,手动去操作确实不太方便,你可以设置个cron,定时重试所有失败,但务必要注意消息提醒,以免队列一直重试一直失败,往复运行,影响了正常的队列性能。
其他常用代码 文件上传OSS <?php namespace App \Http \Controllers ;use Illuminate \Http \Request ;use Controller ;use Illuminate \Support \Facades \Storage ;use Illuminate \Support \Facades \Validator ;use OSS \OssClient ;use OSS \Core \OssException ;class UploadController extends Controller { public function index (Request $request ) { $file = $request ->file ('file' ); if ($file ->isValid ()) { $ext = $file ->getClientOriginalExtension (); $realPath = $file ->getRealPath (); $filepath = config ('app.env' ).'/' . md5 (uniqid ('' , true )); $result = $this ->uploadOss ($realPath , $filepath ."." .$ext ); if ($result ['code' ]) { return response (['code' => 2 , 'msg' => $result ['msg' ]]); } else { return response (['code' => 0 , 'msg' => '上传成功' , 'data' => [ 'filepath' => $result ['data' ]['url' ], 'data' => $request ->all () ]]); } } } public function uploadOss ($filePath , $object ) { $accessKeyId = config ('filesystems.disks' )[config ('filesystems.default' )]['access_key' ]; $accessKeySecret = config ('filesystems.disks' )[config ('filesystems.default' )]['secret_key' ]; $endpoint = config ('filesystems.disks' )[config ('filesystems.default' )]['endpoint' ]; $bucket = config ('filesystems.disks' )[config ('filesystems.default' )]['bucket' ]; $url = config ('filesystems.disks' )[config ('filesystems.default' )]['host' ]; try { $ossClient = new OssClient ($accessKeyId , $accessKeySecret , $endpoint ); $ossClient ->uploadFile ($bucket , $object , $filePath ); return [ 'code' => 0 , 'data' => [ 'url' => $url .'/' .$object ] ]; } catch (OssException $e ) { return [ 'code' => 1 , 'msg' => $e ->getMessage () ]; } } } 'oss' => [ 'driver' => 'oss' , 'root' => '' , 'access_key' => env ('OSS_ACCESS_KEY' ), 'secret_key' => env ('OSS_SECRET_KEY' ), 'endpoint' => env ('OSS_ENDPOINT' ), 'bucket' => env ('OSS_BUCKET' ), 'isCName' => env ('OSS_IS_CNAME' , false ), 'host' => env ('OSS_HOST' , '' ) ],
json输出 protected static $code = 0 ;protected static $msg = 'ok' ;public function response ($data = [], $msg = '' , $code = 0 ) { if (is_null ($data )) { $data = new \stdClass (); } return response ()->json ([ 'code' => $code ? $code : self ::$code , 'msg' => $msg ? $msg : self ::$msg , 'data' => $data , ], 200 ); }
进程锁
普通版本
public function processLock ($key , $autoDel = true , $ttl = 60 ) { $key = 'processLock:' .$key ; if (Redis ::Command ('set' , [$key , 1 , 'EX' , $ttl , 'NX' ])) { if ($autoDel ) { register_shutdown_function (function () use ($key ) { Redis ::del ($key ); }); } return true ; } return false ; }
lua版本
public function getScript ( ) { return <<<LUA local ret = Redis.call("setnx", KEYS[1], ARGV[1]) if ret == 1 then return Redis.call("expire", KEYS[1], ARGV[2]) else return 0 end LUA ; } public function processLock ($key , $autoDel = true , $ttl = 60 ) { if (Redis ::eval ($this ->getScript (), 1 , $key , 1 , $ttl )) { if ($autoDel ) { register_shutdown_function (function () use ($key ) { Redis ::del ($key ); }); } } return false ; }
说明:Redis::eval行第一个1表示key的数量,是为了区分KEYS和ARGV。
JWT Laravel 配合 jwt 使用
系统通知到钉钉 我们可以使用队列,把一些重要的通知投到钉钉,主要代码如下:
<?php namespace App \Jobs ;use Illuminate \Bus \Queueable ;use Illuminate \Contracts \Queue \ShouldQueue ;use Illuminate \Foundation \Bus \Dispatchable ;use Illuminate \Queue \InteractsWithQueue ;use Illuminate \Queue \SerializesModels ;use Illuminate \Support \Facades \Log ;use GuzzleHttp \Client ;class SystemNotify implements ShouldQueue { use Dispatchable , InteractsWithQueue , Queueable , SerializesModels ; private $title ; private $content ; private $type ; private $robot ; const DD_URL = 'https://oapi.dingtalk.com' ; public function __construct ($title , $content = '' , $type = 'markdown' , $robot = 1 ) { $this ->queue = 'SystemNotify' ; $this ->title = $title ; $this ->content = $content ; $this ->type = $type ; $this ->robot = $robot ; } public function handle ( ) { switch ($this ->type){ case 'markdown' : $params = [ 'msgtype' => $this ->type, $this ->type => [ 'title' => $this ->title.'[关键字]' , 'text' => $this ->content ] ]; break ; default : $params = [ 'msgtype' => $this ->type, $this ->type => [ 'content' => $this ->content.'[关键字]' , ] ]; break ; } $params = json_encode ($params , JSON_UNESCAPED_UNICODE); $uri = self ::URL_MAPPING [$this ->robot]; $this ->getClient ()->request ('POST' , $uri , [ 'headers' => [ 'Content-Type' => 'application/json;charset=utf-8' ], 'body' => $params ]); } const URL_MAPPING = [ 1 => '/robot/send?access_token=@1' , 2 => '/robot/send?access_token=@2' ]; public function getClient ( ) { return new Client ([ 'base_uri' => 'https://oapi.dingtalk.com' , 'timeout' => 30 , 'verify' => false ]); } }
说明:通知内容可以自定义,添加智能机器人操作比较简单就不赘述了
后台操作日志 利用 Laravel 中间件给后台加个操作日志
Excel Laravel6 配合 Maatwebsite\Excel 实现 Excel 导入
Laravel6 配合 Maatwebsite\Excel 实现 Excel 导出
陆续补充中…