共计 6637 个字符,预计需要花费 17 分钟才能阅读完成。
用 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);
}
自定义验证
比方罕用的手机号验证:
php artisan make:rule Mobile
而后改一下:
/**
* Mobile 次要代码
* 验证是否通过
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
//
return preg_match('/^1\d{10}$/', $value);
}
/**
* 错误信息
*
* @return string
*/
public function message()
{return '手机号格局不正确';}
而后这么用起来:
$columns = [
'college' => 'required|max:32',
'mobile' => ['required', new Mobile()],
'qq' => 'required',
];
ORM
关联查问
- 一对一
// Model 定义,关联外键
class User extends Model
{
...
public function userIntegral()
{return $this->hasOne('App\Models\UserIntegral', 'user_id', 'id');
}
}
// 应用 with 查问
(new User())->with('userIntegral')->orderBy('id', 'desc')->paginate($limit);
- 一对多
//Model
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Hotel extends Model
{public function orders()
{return $this->hasMany('App\Models\Order');
}
}
// 应用,比方查问某个 Hotel 下 status=30 的 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 表
/**
* 工作失败的处理过程
*
* @param Exception $exception
* [@return](https://learnku.com/users/31554) void
*/
public function failed(Exception $exception)
{// 解决}
重试队列
有时候代码有破绽可能会有队列执行失败的情况,这时候咱们就须要重试。
- 查看所有失败
php artisan queue:failed
- 重试所有失败
php artisan queue:retry all
- 重试单个失败
php artisan queue:retry 13
- 清空失败(重要的队列数据万不可这么操作)
php artisan queue:flush
另外,手动去操作的确不太不便,你能够设置个 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()]]);
}
}
}
/**
* 上传 oss
* @param $filePath 以后门路
* @param $object 预约义文件名,可含文件夹
* [@return](https://learnku.com/users/31554) array
*/
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'), // 应用 ssl 这里设置如: https://oss-cn-beijing.aliyuncs.com'bucket'=> env('OSS_BUCKET'),'isCName'=> env('OSS_IS_CNAME', false), // 如果 isCname 为 false,endpoint 应配置 oss 提供的域名如:`oss-cn-beijing.aliyuncs.com`,否则为自定义域名,,cname 或 cdn 请自行到阿里 oss 后盾配置并绑定 bucket'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);
}
过程锁
- 一般版本
// $autoDel 字段删除,$ttl 过期工夫,秒
public function processLock($key, $autoDel = true, $ttl = 60)
{
$key = 'processLock:'.$key;
// 不同版本或 redis 扩大,会有稍微不同,自行调整下代码即可
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 true;
}
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';
/**
* Create a new job instance.
*
* @param $title
* @param string $content
* @param string $type text, markdown
* @param int $robot
*/
public function __construct($title, $content = '', $type ='markdown', $robot = 1)
{
// 独自应用 SystemNotify 队列
$this->queue = 'SystemNotify';
$this->title = $title;
$this->content = $content;
$this->type = $type;
$this->robot = $robot;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// 能够不应用关键字,倡议钉钉机器人应用 IP 段设置,更为平安
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
]);
}
// 对应不同的钉钉群告诉,批改 access_token 参数即可
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 配合 MaatwebsiteExcel 实现 Excel 导入
Laravel6 配合 MaatwebsiteExcel 实现 Excel 导出
陆续补充中 …
正文完