Laravel 权限控制基础之Gate 和Policy

policy和Gate
php artisan make:policy PostPolicy –model=Post //特定model
//AuthServiceProvider.php在定义权限
//Gate::define(‘view-post’, ‘ClassName@methodOne’);
Gate::define(‘show-info’, function ($test, $post) {
return $test->owns($post);
});
//user.php
public function owns($post)
{
return $this->id == $post->user_id;
}
//控制器
use Gate;
auth()->loginUsingId(1);
$test = TestModel::findOrFail(1);
//Gate::allows();//判断是否允许
if(Gate::denies(‘show-info’,$test)) {
echo ‘禁止访问’;
} else {
echo ‘允许访问’;
}
//可以用policy替换Gate
//AuthServiceProvider.php
protected $policies = [
‘app\Models\TestModel’ => ‘app\Policies\PostPolicy’,
];
$user = auth()->loginUsingId(1);
$test = TestModel::findOrFail(1);
echo $user->id;
echo $test->user_id;
if ($user->cannot(‘show-info’, $test)) {
echo ‘禁止访问’;
} else {
echo ‘允许访问’;
}
对于Gate来定义和policy替换, 在一个项目中通常两种方式都使用,如果访问控制的逻辑非常简单,且只需用到一个方法,那么直接写成Gate的闭包即可,如果比较复杂,且需要对模型进行多个方法的权限控制,那么就写成policy

Laravel :notification使用笔记

php artisan make:notification PayFinish
php artisan notifications:table 创建通知表
//TestModel
namespace app\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
class TestModel extends Model
{
use Notifiable;
protected $table = ‘test’;
}
//PayFinish
public function via($notifiable)
{
return [‘database’];
}
//toDatabase和toArray格式化消息内容
public function toArray($notifiable)
{
return [
‘test_id’ => $this->id,
‘name’ => $this->data->name,
];
}
//使用
$user = TestModel::find(1);
//$user->notify(new PayFinish($user));
foreach ($user->notifications as $notification) {
print_r($notification->data);
}
foreach ($user->unreadNotifications as $notification) {
print_r($notification->data);
//$notification->markAsRead();//标记已读
}
//Notification::send($user, new PayFinish());

Laravel Migrate修改表和创建表

php artisan make:migration create_table_test –table=test_a 修改表

Schema::table(‘test’, function (Blueprint $table) {
$table->dropColumn([‘data’]);
$table->renameColumn(‘tttt’,’test’);
$table->addColumn(‘string’,’t_id’, [‘length’ => 200]);
});

php artisan make:migration create_table_test –create=test_a 创建表
Schema::create(‘users’, function (Blueprint $table) {
$table->increments(‘id’);
$table->string(‘name’);
$table->string(’email’, 150)->unique();
$table->string(‘password’);
$table->rememberToken();
$table->timestamps();
});

 

需要添加:

{"require": {"doctrine/dbal": "v2.5.5"}}

Laravel middleware中间件

Laravel Middleware 中间件

php artisan make:middleware TestMiddleware

public function handle($request, Closure $next)
{
if($request->input(‘id’) > 1) {
die( ‘hello world’ );
}
return $next($request);
}
注册中间件
app/Http/Kernel.php$middleware添加

控制器当中
$this->middleware(‘Test’);
路由器
Route::get(‘/’,’Test\\TestController@index’, [‘middleware’ => ‘Test’]);

Laravle Job 案例

make:job 创建一个新JOb类

protected $msg;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct($msg)
{
$this->msg = $msg;
}

/**
* Execute the job.
*
* @return void
*/
public function handle()
{
echo date(‘Y-m-d H:i:s’).”=>”.$this->msg .”\n”;
}
控制器使用案例
for($i = 0; $i < 10; $i ++) {
$job = new TestJob(‘hello ‘. $i);
$this->dispatch($job);
}

Laravel Command命令行

make:command php artisan make:command Test/Test生成新命令
在app/Console/Kernel.php文件当中注册命令
protected $commands = [
//
TestCommand::class,
];
编辑命令
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = ‘test:test {name} {date?} {default=default} {–op1=}’;
//{name} 必须参数 {date?} 非必须 {default=default}默认参数 {–op1}设置项
/**
* The console command description.
*
* @var string
*/
protected $description = ‘命令描述’;

/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}

/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$argument = $this->argument();
print_r($argument);
echo $this->option(‘op1’);
$this->info(‘提示信息’);
}
执行命令
php artisan test:test name1 date1 default –op1=option1
//程序调用
Artisan::call(“test:test”, array(‘name’ => ‘test’, ‘date’ => ‘date1’, ‘default’ => ‘def’,’–op1′ => ‘option’));

Laravel Event和Listener

make:event TestEvent 创建一个新事件类
php artisan make:listener TestListener –event TestEvent 创建一个listener类
注册事件TestEvent
/**
* Create a new event instance.
*
* @return void
*/
public function __construct($str)
{
$this->data = $str;
}

/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return [];
}
监听时间TestListener
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}

/**
* Handle the event.
*
* @param TestEvent $event
* @return void
*/
public function handle(TestEvent $event)
{
file_put_contents(‘/data/tmp/test.log’, $event->data, FILE_APPEND);
}
注册应用关联事件EventServiceProvider.php
protected $listen = [

‘app\Events\TestEvent’ => [
‘app\Listeners\TestListener’,
],
];
触发事件
$str = ‘test….’;
Event::fire(new TestEvent($str));
event(new TestEvent($str));

php artisan event:generate 批量生成event和listen 编辑EventServiceProvider.php

备注:事件可以广播,通过websocket服务,依赖Redis的pub和sub模式

artisan详解一

php artisan 详解

php artisan optimize
php artisan optimize –force
Since Laravel 5.5 will be PHP 7.0+ it makes sense to remove this feature, since the best way to optimize performance in PHP 7 is just to correctly configure opcache to what’s best for your server and websites.
在php7已经废弃了!!!!

php artisan tinker
//查看定义模型database/factories/ModelFactory.php
factory(app\User::class, 10)->create(); //注意大小写
App\User::all();//查看记录
App\User::count();
更多内容参考:https://yii.im/posts/tinker-with-the-data-in-your-laravel-apps-with-php-artisan-tinker/

php artisan config:cache 创建一个加载配置的缓存文件bootstrap/cache/config.php
php artisan db:seed 迁移填充数据
php artisan migrate:refresh –seed 重新填充

Larave php artisan 命令集

Ubuntu添加Laravel命令
1、composer global require “laravel/installer”
2、export PATH=$PATH:/root/.config/composer/vendor/bin

php artisan –version 查看应用版本
可用命令
clear-compiled 清除编译的类文件
down 开启维护模式
env 查看当前运行环境
help 帮助
inspire 显示一个启发灵感的引用
list 命令列表
migrate 运行数据库迁移
optimize 为了更好的框架去优化性能
serve 在php开发服务器中服务这个应用(PHP本身可以提供web server服务)
tinker 应用交互
up 关闭维护模式
app:name 设置应用程序命名空间
auth:clear-resets 清除过期的密码重置密钥
cache:clear 清除应用程序缓存
cache:forget 移除指定缓存
cache:table 创建一个数据表缓存的迁移
config:cache 创建一个加载配置的缓存文件
config:clear 删除配置的缓存文件
db:seed 发送数据库的详细记录
event:generate 在记录上生成错过的事件和基础程序
ide-helper:generate 生成_ide_helper.php
ide-helper:meta 生成metadata for PhpStorm
ide-helper:models 生成models文件
key:generate 设置应用key
make:auth 生成登录和注册路由、视图等
make:command php artisan make:command Test/Test生成新命令
make:controller 创建一个新的控制器类
make:event 创建一个新事件类
make:job 创建一个新JOb类
make:listener 创建一个listener类
make:mail 创建一个mail类
make:middleware 创建一个中间件类
make:migration 创建一个新的数据库迁移文件
make:model 创建一个新Model类
make:notification 创建一个Notification类
make:policy 创建一个代理类
make:provider 创建服务提供类
make:request 创建一个Request类
make:seeder 创建一个seeder类
make:test 创建一个测试类
migrate:install 安装migration版本库
migrate:refresh 复位并重新运行所有的迁移
migrate:reset 回滚全部数据库迁移
migrate:rollback 回滚最后一个数据库迁移
migrate:status 数据库迁移状态
notifications:table 创建通知类表
queue:failed 列出队列失败的Job
queue:failed-table 创建一个队列失败表
queue:flush 清除全部失败的队列工作
queue:forget 删除队列当中失败任务
queue:listen 监听一个确定的队列工作
queue:restart 重启现在正在运行的所有队列工作
queue:retry 重试一个失败的队列工作
queue:table 创建队列table
queue:work 进行下一个队列任务
route:cache 为了更快的路由登记,创建一个路由缓存文件
route:clear 清除路由缓存文件
route:list 列出全部的注册路由
schedule:run 运行预定命令
session:table 创建一个迁移的SESSION数据库工作表
storage:link 创建软连接 “public/storage” to “storage/app/public”
vendor:publish Publish any publishable assets from vendor packages
view:clear 清理视图缓存

MYSQL死锁问题

如果insert或update用到了同样的索引也会造成死锁
比如
update table_a set name = ‘test1’ where id = 300; //用到了table_a的id主键索引
insert into table_b (a_id,`name`) (select id,name from table_a where id >=200)
ON DUPLICATE KEY UPDATE a_id = values(a_id)//同样用到了table_a的id主键
所以会导致死锁

行级锁并不是直接锁记录,而是锁索引,如果一条SQL语句用到了主键索引,mysql会锁住主键索引;如果一条语句操作了非主键索引,mysql会先锁住非主键索引,再锁定主键索引。

排查可以执行如下命令查看

show engine innodb status