Laravel
Api
REST 是所有 Web 应用都应该遵守的架构设计指导原则。 Representational State Transfer,翻译是”表现层状态转化”。
面向资源是 REST 最明显的特征,对于同一个资源的一组不同的操作。资源是服务器上一个可命名的抽象概念,资源是以名词为核心来组织的,首先关注的是名词。REST 要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。
动作
1 | GET (SELECT):从服务器检索特定资源,或资源列表 |
命名
路径又称"终点"(endpoint),表示 API 的具体网址。
在 RESTful 架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表名对应。一般来说,数据库中的表都是同种记录的"集合"(collection),所以 API 中的名词也应该使用复数。
举例来说,有一个 API 提供动物园(zoo)的信息,还包括各种动物和雇员的信息,则它的路径应该设计成下面这样。
接口尽量使用名词,禁止使用动词,下面是一些例子。
1 | GET /zoos:列出所有动物园 |
再比如,某个 URI 是/posts/show/1,其中 show 是动词,这个 URI 就设计错了,正确的写法应该是/posts/1,然后用 GET 方法表示 show。
版本
应该将 API 的版本号放入 URL。如:
1 | https://api.example.com/v1 |
过滤
如果记录数量很多,服务器不可能都将它们返回给用户。API 应该提供参数,过滤返回结果。 下面是一些常见的参数。
1 | ?limit=10:指定返回记录的数量 |
状态码
1 | 200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。 |
响应格式
从可读性和通用性来讲 JSON
是最好的响应数据格式,下面是一个错误消息响应数据结构。
1 | { |
- message:表示在 API 调用失败的情况下详细的错误信息,这个信息可以由客户端直接呈现给用户
- errors:参数具体错误,比如字段较对错误内容
- code:自定义错误码
- status_code:http 状态码
- debug:debug 调试信息
错误返回值根据情况进行删减
Postman
postman 可以高效的测试和维护接口。https://www.getpostman.com/apps
Dingo
Dingo Api 是致力于提供给开发者一套工具,帮助你方便快捷的建造你自己的 API。这个包的目标是保持尽可能的灵活,它并不能覆盖所有的情况,也不能解决所有的问题。
官网:https://github.com/dingo/api/
文档:https://github.com/dingo/api/wiki/Configuration
安装组件
1 | composer require dingo/api:2.0.0-alpha2 |
执行下面命令生成配置文件 /config/api.php
1 | php artisan vendor:publish |
配置说明
配置统一定义在 config/api.php
文档中
1 | #接口围绕:[x]本地和私有环境 [prs]公司内部app使用 [vnd]公开接口 |
prefix 与 domain 只能二选一
接口版本
在 routes/api.php
文件定义
1 | $api = app(\Dingo\Api\Routing\Router::class); |
基础控制器
1 | php artisan make:controller Api/Controller |
修改内容如下
1 | namespace App\Http\Controllers\Api; |
Transformers
Transformers 允许你便捷地、始终如一地将对象转换为一个数组。通过使用一个 transformer 你可以对整数和布尔值,包括分页结果和嵌套关系进行类型转换。
基本使用
一个 transformer 是一个类,它会获取原始数据并将返回一个格式化之后的标准数组。
1 | namespace App\Transformers; |
返回单个数据
1 | return $this->response->item(User::find(1),new UserTransformer()); |
返回集合
1 | return $this->response->collection(User::get(),new UserTransformer()); |
分页数据
1 | return $this->response->paginator(User::paginate(2),new UserTransformer()); |
include
获取文章时我们希望获取文章的栏目数据,include 的特性就非常方便了。
下面是 ContentTransformer 中的定义,
1 | class ContentTransformer extends TransformerAbstract |
当我们调用 {host}/api/contents?include=category
接口时,栏目数据也一并会返回
1 | return $this->response->paginator(Content::paginate(1),new ContentTransformer()); |
返回结果如下
1 | { |
响应结果
设置响应状态码
1 | return $this->response->array(User::get())->setStatusCode(200); |
错误响应
1 | // 一个自定义消息和状态码的普通错误。 |
限制请求数
使用 api.throttle
中间件结合 limit、expires
参数可实现接口次数限制。下面是定义在 routes/api.php
路由文件中的示例。
1 | $api->version('v1', ['namespace' => '\App\Api'], function ($api) { |
限制 1 分钟只能访问 2 次。
身份验证
可以通过 api.auth
路由中间件来启用路由或者路由群组的保护,我们使用下面讲解的 jwt 组件完成接口验证。
在所有的路由上启用
1 | $api->version('v1', ['middleware' => 'api.auth'], function ($api) { |
特定的路由上启用
1 | $api->version('v1', function ($api) { |
控制器上进行身份验证
Laravel
可以在控制器里启用中间件。您可以在构造函数里使用 middleware
的方法。
1 | class UserController extends Illuminate\Routing\Controller |
Jwt
Jwt 是高效简单的接口验证组件,使用非常广泛。
GitHub:https://github.com/tymondesigns/jwt-auth
Packagist:https://packagist.org/packages/tymon/jwt-auth
在线文档: http://jwt-auth.readthedocs.io/en/develop/quick-start/
安装组件
目前 2.0 版本正在开发中还不可以正常使用,所以我们使用 1.0.2。
1 | composer require tymon/jwt-auth:1.0.2 |
生成配置文件
1 | php artisan vendor:publish |
生成密钥
这是用来给你的 token 签名的钥匙,使用以下命令生成一个密钥:
1 | php artisan jwt:secret |
这将用 JWT_SECRET=foobar
更新.env 文件
配置说明
JWT 配置文件是 config/jwt.php
,下面有部分配置项进行说明:
1 | 令牌过期时间(单位分钟),设置null为永不过期 |
更新用户模型
首先,您需要在用户模型上实现 Tymon\JWTAuth\Contracts\JWTSubject
契约,它要求您实现两个方法 getJWTIdentifier()
和 getJWTCustomClaims()
。
下面的示例应该能让您了解这可能是什么样子的。显然,您应该根据需要进行任何更改,以满足自己的需要。
1 | <?php |
配置验证守卫
修改 config/auth.php
文件以使用 jwt 保护来为接口身份验证提供支持。
1 | 'guards' => [ |
修改 dingo 配置文件 config/api.php
文件中的身份验证提供者
1 | 'auth' => [ |
验证操作
路由定义
1 | $api = app(\Dingo\Api\Routing\Router::class); |
控制器定义
1 | class AuthController extends Controller |
使用令牌
当请求需要验证的 api 时必须带有 token,下面是使用 header 头携带令牌数据
1 | Authorization: Bearer 令牌数据 |
Laravel
介绍
Laravel 是一套简洁、优雅的 PHP Web 开发框架(PHP Web Framework)。它可以让你从面条一样杂乱的代码中解脱出来;它可以帮你构建一个完美的网络 APP,而且每行代码都可以简洁、富于表达力。
Laravel 是 基于 PHP 语言的 Web 开源框架,采用了 MVC 的架构模式,在 2011 年 6 月正式发布了首个版本。 深度集成 PHP 强大的扩展包(Composer)生态与 PHP 开发者广大的受众群,让 Laravel 在发布之后的短短几年时间得到了极其迅猛的发展。我们通过 Google Trends 提供的趋势图(图 1.1)可以看出,Laravel 框架在过去十年,其增长速度迅猛。
版本
Lts
Long-Term Support,长期技术支持(版本),该版本拥有较长的维护周期,是商业项目优先考虑使用的版本。
常规版
提供 6 个月的 bug 修复,维护周期短但功能较新,学习为了使用新功能可采用这个版本。
全新安装
使用 Composer 安装 Laravel 框架
1 | composer create-project --prefer-dist laravel/laravel blog |
安装完 Laravel 之后,你必须将 web 服务器更目录指向 public
目录。该目录下的 index.php
文件将作为所有进入应用程序的 HTTP 请求的前端控制器。
需要修改 .env
配置文件中的 APP_NAME
与 APP_URL
1 | APP_NAME=Laravel |
MySQL 低版本
如果你是在版本低于 5.7.7 的 MySQL release 上创建索引,那就需要你手动配置迁移生成的默认字符串长度。
在 AppServiceProvider.php 文件里的 boot 方法里设置
1 | public function boot() |
下载团队项目
检出别人的项目时,因为.env、verdor、node_moduels 文件或目录是不提交到版本库的,造成检出后项目不能正常运行。需要以下几步处理:
- composer install
- cnpm install
- 复制 .env.example 文件为 .env 文件
- 执行
php artisan key:generate
生成应用秘钥 - 修改 .env 配置文件其他数据为你网站数据(比如数据库配置等)
基本使用
路由
Laravel 的路由类型很多,先看路由的基础使用
修改 routes/web.php
路由表文件
1 | Route::get('/home', 'TestController@home'); |
控制器
创建控制器命令
1 | php artian make:controller TestController |
创建的控制器内容如下
1 |
|
浏览器中访问http://laravel.kk/lists
显示内容如下
1 | App\Http\Controllers\TestController::lists |
以上就是 laravel 中基本路由与控制器的操作流程。
视图
视图就是我们显示的页面,视图保存在 resources/views
文件夹中。
继承
模版继承是为了公用相同页面的代码,减少代码冗余
下面定义 views/layouts/master.blade.php 文件
1 |
|
然后在子模板中引入父模板,并使用 section 替换父模板中 yield 定义的占位内容。
1 | @extends('layouts.master') |
include
include 用于加载外部模板
1 | @include('user.show') |
被引入的视图会继承父视图中的所有数据,同时也可以向引入的视图传递额外的数组数据:
1 | @include('view.name', ['some' => 'data']) |
includeIf
当然,如果尝试使用 @include
去引入一个不存在的视图,Laravel 会抛出错误。如果想引入一个可能存在或可能不存在的视图,就使用 @includeIf
指令:
1 | @includeIf('view.name', ['some' => 'data']) |
includeWhen
如果要根据给定的布尔条件 @include
视图,可以使用 @includeWhen
指令:
1 | @includeWhen($boolean, 'view.name', ['some' => 'data']) |
stack
Blade 可以被推送到在其他视图或布局中的其他位置渲染的命名堆栈。这在子视图中指定所需的 JavaScript 库时非常有用:
父模版
1 | <head> |
子模版
1 | @push('scripts') |
component&slot
组件相比 @extends 更灵活些,下面是定义一个 modal
组件。
组件中的变量可以在调用组件时传参数
1 | @component('components.modal',['title'=>'你好','url'=>route('home')]) |
也可以使用 slot
标签赋值
1 | @slot('footer') |
示例
定义一个模态框组件 view/components/modal.blade.php
1 | <form action="{{$url}}" method="post" {!!isset($id)?"id=\"$id\"":''!!}> |
模板中调用 modal
组件
1 | @component('components.modal',['title'=>'你好','url'=>route('home'),'method'=>'PUT']) |
动态视图目录
有时我们需要经常改变视图目录
1 | $finder = app('view')->getFinder(); |
脚手架
安装 cnpm 使用国内镜像,安装速度快
1 | npm install -g cnpm --registry=https://registry.npm.taobao.org |
根据 packagist.json 安装前端库
1 | cnpm install |
我们需要在 resources/assets 目录下的 js 与 css 目录中编写前端文件。
执行编译
需要执行编译操作,生成可供浏览器访问的文件,默认生成在 public/css 与 public/js 目录中
1 | npm run dev |
引入编译好的样式文件
1 | <link rel="stylesheet" href="/css/app.css"> |
文件监听
每次修改都手动编译效率很低,执行以下命令后 Webpack 会在检测到文件更改时自动重新编译资源:
1 | npm run watch |
在某些环境中,当文件更改时,Webpack 不会更新。如果系统出现这种情况,请考虑使用 watch-poll
命令:
1 | npm run watch-poll |
Bootstrap
Laravel6.x 引入前端框架 Bootstrap & jQuery
1 | cd /path/of/your/project |
在 app.scss 文件中定义:
1 | @import '~bootstrap/scss/bootstrap'; |
路由别名
进入路由跳转使用 /home
等形式可以正常进行,但如果我们有很多页面 使用了这种方式,后期我们将 /home
更改为了 /root
,就要修改多个页面,显然不是很方式 。这时我们可以为路由起别名。
1 | Route::get('/home', 'TestController@home')->name('home'); |
页面中使用调用即可
1 | <a class="nav-link" href="{{ route('home') }}">网站首页</a> |
数据迁移
迁移就像是数据库的版本控制, 允许团队简单轻松的编辑并共享应用的数据库表结构。
迁移文件默认保存在 database/migrations
文件夹中。
如果使用 homestead 配置,要保证.env 配置正确,并保证主机客户端连接正常
运行迁移
使用 Artisan 命令 migrate
方法来运行所有未完成的迁移:
1 | php artisan migrate |
回滚迁移
若要回滚最后一次迁移, 可以使用 rollback
命令。 此命令将回滚最后一次“迁移”的操作,其中可能包含多个迁移文件:
1 | php artisan migrate:rollback |
关键外键约束
下面是文章表 category_id 与栏目表的 id 关联约束设置,当栏目删除时栏目下的所有文章自动删除。
1 | $table->unsignedInteger('category_id')->comment('栏目'); |
Seeder 自动填充测试数据
1 | # 运行填充器 |
模型
Laravel 的 Eloquent ORM 提供了漂亮、简洁的 ActiveRecord 实现来和数据库交互。每个数据库表都有一个对应的「模型」用来与该表交互。你可以通过模型查询数据表中的数据,并将新记录添加到数据表中
定义模型
首先,创建一个 Eloquent 模型,默认生成的模型通常放在 app
目录中。
创建模型实例的最简单方法是使用 Artisan 命令 make:model
:
1 | php artisan make:model Article |
如果要在生成模型时生成 数据库迁移 ,可以使用 --migration
或 -m
选项:
1 | php artisan make:model Article -m |
数据库表名称
可以通过在模型上定义 table
属性,来指定自定义数据表。如果不指定时使用模型名加 s,如 Article 对应表名为 articles
1 | protected $table = 'articles'; |
时间戳
默认情况下,Eloquent 会默认数据表中存在 created_at
和 updated_at
这两个字段。如果你不需要这两个字段,则需要在模型内将 $timestamps
属性设置为 false
:
1 | // 该模型是否被自动维护时间戳 |
本地作用域
本地作用域能定义通用的约束集合以便在应用中复用。
1 | class User extends Model |
使用方法
1 | $users = App\User::active(1)->get(); |
associate
当更新 belongsTo
关联时,可以使用 associate
方法。此方法将会在子模型中设置外键:
1 | $account = App\Account::find(10); |
软删除
软件删除不是真正删除数据,只是在表中更改 deleted_at 状态完成,步骤如下:
修改模型
在模型上使用 Illuminate\Database\Eloquent\SoftDeletes
trait 并把 deleted_at
字段加入 $dates
属性:
1 | ... |
修改迁移文件
1 | Schema::create('videos', function (Blueprint $table) { |
现在,模型调用 delete
方法,当前日期时间会写入 deleted_at
字段。同时,查询出来的结果也会自动剔除软删除的模型。
包括软删除的模型
1 | App\Videos::withTrashed()->get(); |
withTrashed
方法也可以用在关联查询:
只检索软删除的模型
1 | App\Videos::onlyTrashed()->get(); |
恢复软删除模型
1 | App\Videos::get()->restore(); |
永久删除
1 | $videos->forceDelete(); |
基本上软删除都可以用在关联操作中
Laravel & Lumen 之 Eloquent ORM 使用速查-高级部分
https://segmentfault.com/a/1190000005792734
登录历史跳转
使用系统 auth 验证时,会自动 记录当前的 url,然后登录成功后使用以下代码就会跳转到来源地址。
1 | return redirect()->intended('/'); |
inteded 方法参数默认为 /
,即没有历史来源时的跳转地址。
如果是自定义的验证,则需要使用以下代码记录来源地址。登录成功后还是使用上面代码跳转就可以了。
1 | return redirect()->guest(route('login'))->with('error', '请登录后操作'); |
guest 参数必填即登录地址。
如果想自行定义登录后的回调地址使用下面方法
1 | session(['url.intended'=>$request->getRequestUri()]); |
分页
1 | $users = User::paginate(10); |
模板中显示分页列表
1 | $users->links(); |
分页时传递 GET 参数
1 | $users->appends(Request::except('page'))->links() |
监听 SQL
1 | DB::enableQueryLog(); |
TINKER
使用 laravel 提供的 tinker 可以方便的在命令行进行调试。
进入 tinker 环境
1 | php artisan tinker |
新增用户练习
1 | >>> use \App\User |
bcrypt 是用来对密码进行加密
查看用户
1 | >>> User::first() |
修改记录
下面使用 save 方法操作
1 | >>> $user = User::first() |
下面使用 update 批量更新
1 | >>> $user = User::first() |
路由参数
比如我们定义下面的路由规则,其中 {user} 和 {name} 为路由中的参数变量
1 | Route::get('/user/{user}/{name}','UserController@show')->name('user.show'); |
控制器中获取参数方式如下:
1 | namespace App\Http\Controllers; |
隐性路由模型绑定
Laravel 会自动解析定义在路由或控制器行为中与类型提示的变量名匹配的路由段名称的 Eloquent 模型。例如:
1 | Route::get('api/users/{user}', function (App\User $user) { |
在这个例子中,由于 $user
变量被类型提示为 Eloquent 模型 App\User
,变量名称又与 URI 中的 {user}
匹配,因此,Laravel 会自动注入与请求 URI 中传入的 ID 匹配的用户模型实例。如果在数据库中找不到对应的模型实例,将会自动生成 404 异常。
资源控制器
Laravel 遵从 RESTful 架构的设计原则,将数据看做一个资源。Laravel 资源路由将典型的「CRUD」路由分配给具有单行代码的控制器。
使用 Artisan 命令 make:controller
来快速创建控制器:
1 | php artisan make:controller ArticleController --resource |
接下来,你可以给控制器注册一个资源路由:
1 | Route::resource('photos', 'PhotoController'); |
资源控制器方法说明:
动作 | URI | 行为 | 路由名称 |
---|---|---|---|
GET | /photos |
index | photos.index |
GET | /photos/create |
create | photos.create |
POST | /photos |
store | photos.store |
GET | /photos/{photo} |
show | photos.show |
GET | /photos/{photo}/edit |
edit | photos.edit |
PUT/PATCH | /photos/{photo} |
update | photos.update |
DELETE | /photos/{photo} |
destroy | photos.destroy |
可以使用
php artisan route:list
查看已经定义的路由
指定资源模型
如果你使用了路由模型绑定,并且想在资源控制器的方法中使用类型提示,你可以在生成控制器的时候使用 --model
选项:
1 | php artisan make:controller PhotoController --resource --model=Photo |
伪造表单方法
因为 HTML 表单不能生成 PUT
、 PATCH
或者 DELETE
请求,所以你需要添加一个隐藏的 _method
输入字段来伪造这些 HTTP 动作。辅助函数 method_field
可以帮你创建这个字段:
1 | {{ method_field('PUT') }} |
表单验证
下面是控制器中的 store 方法
1 | public function store(Request $request) |
常用规则
规则 | 说明说明 | 示例 |
---|---|---|
confirmed | 验证的字段必须和 foo_confirmation 的字段值一致。例如,如果要验证的字段是 password ,输入中必须存在匹配的 password_confirmation 字段。 |
|
size | 验证的字段必须具有与给定值匹配的大小。对于字符串来说,value 对应于字符数。对于数字来说,value 对应于给定的整数值。对于数组来说, size 对应的是数组的 count 值。对文件来说,size 对应的是文件大小(单位 kb )。 |
|
max | 验证中的字段必须小于或等于 value。字符串、数字、数组或是文件大小的计算方式都用 size 方法进行评估。 |
|
min | 验证中的字段必须具有最小值。字符串、数字、数组或是文件大小的计算方式都用 size 方法进行评估。 |
|
unique | unique:table,column,except,idColumn验证的字段在给定的数据库表中必须是唯一的。如果没有指定 column ,将会使用字段本身的名称 |
'email' => 'unique:users,email_address' |
required | 验证的字段必须存在于输入数据中,而不是空。如果满足以下条件之一,则字段被视为「空」: 该值为 null . 该值为空字符串。 该值为空数组或空的 可数 对象。 该值为没有路径的上传文件。 |
|
验证的字段必须符合 e-mail 地址格式。 | ||
sometimes | 只有在该字段存在时, 才对字段执行验证 | |
nullable | 如果你不希望验证程序将 null 值视为无效的,那就将「可选」的请求字段标记为 nullable ,也可以理解为有值时才验证。 |
1 | $request->validate([ |
在这个例子里,我们指定 publish_at
字段可以为 null
或者一个有效的日期格式。如果 nullable
的修饰词没有被添加到规则定义中,验证器会认为 null
是一个无效的日期格式。
更多验证规则使用时请查阅手册 https://laravel.com/docs/6.x/validation
显示验证错误
如果表单验证失败,laravel 会向分配错误信息到 $errors
中,那么我们就可在模板中使用以下代码展示验证错误。
1 | @if (count($errors) > 0) |
表单验证请求
面对更复杂的验证情境中,你可以创建一个「表单请求」来处理更为复杂的逻辑。
创建验证请示
1 | php artisan make:request StoreBlogPost |
下面是一个示例
1 | class UserRequest extends FormRequest |
表单函数
csrf
laravel (跨站请求伪造),Laravel 为了安全考虑,会让我们提供一个 token(令牌)来防止我们的应用受到 CSRF(跨站请求伪造)的攻击。放置在表单(form)体内。
1 | {{csrf_field()}} |
old
old
函数获取一次性存放在 session 中的值,用在表单的 value 属性中。这样当我们输出错误回调页面时,原来输入的值还存在。
1 | <input type="text" class="form-control" name="name" value={{old('name')}}> |
表单请求验证
面对更复杂的验证情境中,你可以创建一个「表单请求」来处理更为复杂的逻辑
1 | php artisan make:request StoreBlogRequest |
新生成的类保存在 app/Http/Requests
目录下。
1 |
|
在控制器的方法中依赖注入就可以使用了
1 | public function store(UserRequest $request){ |
重定向
redirect
函数返回一个 HTTP 重定向响应,如果调用时没有传入参数则返回 redirector 实例:
1 | return redirect('/home'); |
传递路由参数
1 | $user = User::first() |
假设路由规则为 Route::get('user/show/{user}')
,上例中的[$user]
会自动提出 $user 模型对象的主键做为路由参数。
闪存数据
有时候你仅想在下一个请求之前在 Session 中存入数据,你可以使用 flash
方法。使用这个方法保存在 Session 中的数据,只会保留到下个 HTTP 请求到来之前,然后就会被删除。闪存数据主要用于短期的状态消息:
1 | session()->flash('status', 'Task was successful!'); |
判断与获取闪存数据
1 | @if (session()->has($msg)) |
公共提示消息
开发中经常用到消息提示,比如登录成功、退出成功等。使用 闪存数据定义一个公共的提示信息组件,就可以解决这个问题。
控制器
1 | public function store(UserRequest $request) |
公共消息模板 resource/view/layouts/_message.blade.php
1 | @foreach (['success','error','danger'] as $msg) |
需要用到的页面能过 @include
引入即可
1 | @include('layouts._message') |
登录验证
使用 Auth::attempt
可以进行用户手动登录
1 | public function authenticate() |
重定向器上的 intended
方法将重定向到用户尝试访问的 URL。如果该 URL 无效,会给该方法传递回退 URI。
传递历史表单,withInput
用于把历史表单返回给页面,这样页面中就可以使用 old()
函数显示历史输入数据了。
1 | return redirect()->back()->withInput(); |
完整示例
1 | class LoginController extends Controller |
判断用户是否已经登录
1 | Auth::check(); |
如果需要将现有用户进行登录,可以使用用户实例调用 login
方法。可以实现用户注册完就登录。
1 | $user = User::first(); |
用户退出
1 | public function logout(){ |
资源路由传参
下面是资源路由中生成编辑资源 url 的方法。
1 | {!! route('user.edit',$user->id) !!} |
历史跳转
intended
方法将重定向到用户尝试访问的 URL。如果该 URL 无效,会给该方法传递回退 URI。比如当用户编辑资料时,但用户没有登录,会先跳到用户登录页面。使用 intended 方法后登录成功后会回调到,编辑资料页面。如果没有历史,则跳转到 intended 指定的参数路由。
1 | return redirect()->intended('home'); |
模型事件
Eloquent 的模型触发了几个事件,可以在模型的生命周期的以下几点进行监控: retrieved
、creating
、created
、updating
、updated
、saving
、saved
、deleting
、deleted
、restoring
、restored
。事件能在每次在数据库中保存或更新特定模型类时轻松地执行代码。
如果要给某个模型监听很多事件,则可以使用观察器将所有监听器分组到一个类中。观察器类里的方法名应该对应 Eloquent 中你想监听的事件。 每种方法接收 model 作为其唯一的参数。Laravel 没有为观察器设置默认的目录,所以你可以创建任何你喜欢你的目录来存放:
定义事件
下面是 User 模型的观察器
1 |
|
声明事件
在 AppServiceProvicer 服务提供者的 boot
方法执行以下代码
1 | User::observe(UserObserver::class) |
或者在模型中定义
1 | namespace App; |
权限策略
策略是在特定模型或者资源中组织授权逻辑的类。例如,针对用户的更新、修改操作就可以使用策略进行权限控制。
创建策略
1 | php artisan make:policy UserPolicy --model=User |
下面是一个策略类中的方法,$user为当前登录用户,$model 为调用策略时传递的用户模型实例。表示如果当前登录用户与用户实例相同可以更新。
1 | public function update(User $user, User $model) |
声明策略
在 app/Providers/AuthServiceProvider.php
类的 $policies
属性中声明策略
1 | protected $policies = [ |
控制器中使用策略
1 | $this->authorize('update', $user); |
友好显示
当开启 DEBUG 时会抛出异常,关注后并定义 403.blade.php
模板后可以显示友好的提示。
1 | errors/403.blade.php |
邮件
配置
下面是针对 qq 邮箱的配置,其他邮箱请自行参考。
登录 mail.qq.com
你的邮箱。查找 设置>帐户>POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
开启 pop3 并获取授权码。
可以在 config/mail.php
文件或.env 开发文件中设置,下面是.env 中的配置项
1 | MAIL_DRIVER=smtp |
MAIL_PASSWORD 为 QQ 邮箱提供的摄权码
Mailable
在 Laravel 中,每种类型的邮件都代表一个「Mailable」对象。这些对象存储在 app/Mail
目录中。如果在你的应用中没有看见这个目录,别担心,在首次使用 make:mail
命令创建 Mailable 类时这个目录会被创建。
1 | php artisan make:mail regMail |
1 | namespace App\Mail; |
发送
执行以下代码就可以发送邮件了。
1 | \Mail::to(User::first())->send(new \App\Mail\RegMail(User::find(1))); |
to:指发送给谁,字段中必须存在 email 和 name,send: 指使用的邮件处理器
集合
contains
contains
方法判断集合是否包含给定的项目
1 | $collection = collect(['name' => 'Desk', 'price' => 100]); |
pluck
pluck
方法可以获取集合中给定键对应的所有值:
1 | $collection = collect([ |
slice
slice
方法返回集合中给定值后面的部分:
1 | $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); |
has
has
方法判断集合中是否存在给定的键:
1 | $collection = collect(['account_id' => 1, 'product' => 'Desk']); |
each
each` 方法将迭代集合中的内容并将其传递到回调函数中:
1 | $collection = $collection->each(function ($item, $key) { |
count
count
方法返回该集合内的项目总数:
1 | $collection = collect([1, 2, 3, 4]); |
多对多关联
attach
我们假设一个用户可以拥有多个角色,并且每个角色都可以被多个用户共享。给某个用户附加一个角色是通过向中间表插入一条记录实现的,可以使用 attach
方法完成该操作:
1 | $user = App\User::find(1); |
detach
有时也需要移除用户的角色。可以使用 detach
移除多对多关联记录。detach
方法将会移除中间表对应的记录;但是这 2 个模型都将会保留在数据库中:
1 | // 移除用户的一个角色... |
sync
sync
方法接收一个 ID 数组以替换中间表的记录。中间表记录中,所有未在 ID 数组中的记录都将会被移除。所以该操作结束后,只有给出数组的 ID 会被保留在中间表中:
1 | $user->roles()->sync([1, 2, 3]); |
如果你不想移除现有的 ID,可以使用 syncWithoutDetaching
方法:
1 | $user->roles()->syncWithoutDetaching([1, 2, 3]); |
allRelatedIds
allRelatedIds
用来获取关联模型的 ID 集合。
1 | $user->roles()->allRelatedIds(); |
toggle
toggle
方法用于「切换」给定 ID 数组的附加状态。 如果给定的 ID 已被附加在中间表中,那么它将会被移除,同样,如果如果给定的 ID 已被移除,它将会被附加:
1 | $user->roles()->toggle([1, 2, 3]); |
消息通知
创建通知
1 | php artisan make:notification FindPasswordNotify |
这个命令会在 app/Notifications
目录下生成一个新的通知类
数据库通知
database
通知渠道在一张数据库表里存储通知信息。该表以自定义的 JSON 格式,存储如通知类型等描述通知的信息。需要先创建一个数据库表来存放这些通知。
1 | php artisan notifications:table |
修改通知类的 via
方法为数据库通知
1 | public function via($notifiable) |
然后定义 toArray
方法返回用于储存到数据表中的通知数据。
存取通知
Laravel 的默认模型 App\User
已经引入了 Trait Illuminate\Notifications\Notifiable
,它包含了一个 Eloquet 关系 notifications
,可以为实体返回通知。
1 | $user = App\User::find(1); |
如果你仅仅想检索所有「未读」通知,你需要使用 unreadNotifications
关系。
1 | $user = App\User::find(1); |
通知标记已读
1 | $user = App\User::find(1); |
你可以直接使用 markAsRead
方法操作一个通知集合,而不是遍历处理每个通知:
1 | $user->unreadNotifications->markAsRead(); |
邮件通知
修改通知类中的 toMail
与 __construct
方法
1 | public function __construct($token) |
自定义模板
你可以通过发布通知包的资源来修改 HTML 模板和纯文本模板。运行这个命令后,邮件通知模板就被放在了 resources/views/vendor/notifications
文件夹下:
1 | php artisan vendor:publish --tag=laravel-notifications |
发送通知
使用 Notifiable Trait
通知可以通过两种方法发送: Notifiable
trait 的notify
方法或 Notification
facade。首先,让我们探索使用 trait :
1 | namespace App; |
默认的 App\User
模型中使用了这个 trait,它包含着一个可以用来发通知的方法:notify
。 notify
方法需要一个通知实例做参数:
1 | use App\Notifications\InvoicePaid; |
使用 Notification Facade
另外,你可以通过 Notification
facade
来发送通知。它主要用在当你给多个可接收通知的实体发送通知的时候,比如给用户集合发通知。要用 facade 发送通知的话,要把可接收通知的实体和通知的实例传递给 send
方法:
1 | Notification::send($users, new InvoicePaid($invoice)); |
队列化通知
发送通知可能很耗时,尤其是是当频道需要一个额外的 API 来发送通知。要加速你的应用响应时间,让你的通知继承 ShouldQueue
接口 并且在你的类中添加 Queueable
trait。这些接口和 trait 已经被使用 make:notification
生成的所有通知引入了,所以你可以直接将他们添加到你的通知类:
1 | <?php |
做好一上操作并正常配置好队列后,系统将自动使用异步队列发送通知
自定义函数
有时我们需要加载自定义的函数文件,在 composer.json
文件中定义如下:
1 | "autoload": { |
命令行执行 composer dump-autoload
重新生成加载配置
Redis
在 homestead 中的 redis 允许的 IP 为 127.0.0.1
如果想让 windows 或 mac 的 GUI 工具可访问需要执行以下几步:
1 | 修改redis配置文件,将127.0.0.1 改为 0.0.0.0 |
重起 redis 服务
1 | sudo service redis restart |
Gui 图形管理工具
- Mac http://getmedis.com/
- Win\Mac\Linux https://redisdesktop.com/
队列
队列用于异步执行消耗时间多的工作,比如发送邮件,商城定单处理等操作,好处是可以快速为客户响应结果,具体处理异步后台操作。
下面的操作使用高效的 redis 完成处理,所以需要安装相应扩展包
1 | composer require "predis/predis:~1.0" |
配置
修改 config/queue.php
队列配置文件。
1 | 'default' => env('QUEUE_DRIVER', 'sync'), |
sync 为同步可更改为 database 或 redis 即为后台异步操作 ,需要先在 config/database.php
文件中将连接设置好。
处理失败任务
有时你的队列任务会失败。Laravel 包含了一个便捷的方式指定任务会被最大尝试的次数。在一个任务达到了它最大尝试次数后,它会被放入 failed_jobs
表。要创建 failed_jobs
表你可以使用 queue:failed-table
命令:
1 | php artisan queue:failed-table |
创建任务
1 | php artisan make:job TestJob |
在生成的类中的 handle
方法设置任何具体动作,下面是一个简单的示例。
1 | protected $user; |
分发任务
1 | TestJob::dispatch(User::find(1)); |
队列处理器
队列处理器用于执行推送到队列中的任务
1 | php artisan queue:work |
要使
queue:work
在后台运行需要使用下面讲到的Supervisor
(生产环境必用)
Laravel 队列监控面板
Horizon 提供了一个漂亮的仪表盘,并且可以通过代码配置你的 Laravel Redis 队列,同时能够让你轻松地监控你的队列系统中诸如任务吞吐量,运行时间和失败任务等关键指标。
安装
1 | composer require laravel/horizon |
启动执行任务监听
只需一条命令语句即可启动队列执行进程。如果修改了任何代码需要重起 horizon
监听(需要在 homestead 系统执行)
1 | php artisan horizon |
可以通过路由 /horizon
以图形界面查看任何状态
Supervisor
Supervisor 是一个进程控制系统,用于让我们的队列任务在后台运行,并自动维护进行如果挂了就自动重起。
修改配置文件
1 | sudo vi /etc/supervisor/conf.d/laravel-worker.conf |
内容如下
1 | [program:laravel-worker] |
注意 command 与 stdout_logfile 配置根据环境自行更改
运行
依次执行下面命令加载配置并运行 Supervisor
1 | sudo supervisorctl reread |
这样我们就不需要执行
php artisan queue:work
命令了,交给Supervisor
自动维护吧
Repository
组件库 Github:https://github.com/houdunwang/repository
Repository 模式主要思想是建立一个数据操作代理层,把 controller 里的数据操作剥离出来。
Repository 模式是架构模式,在设计架构时,才有参考价值。应用 Repository 模式所带来的好处,远高于实现这个模式所增加的代码。只要项目分层,都应当使用这个模式。
这样做有几个好处:
- 把数据处理逻辑分离使得代码更容易维护
- 数据处理逻辑和业务逻辑分离,可以对这两个代码分别进行测试
- 减少代码重复
- 降低代码出错的几率
- 让 controller 代码的可读性大大提高
Service 服务化
为了体现无尽的复用原则,应该将可用的功能服务器。比如邮箱发送、图片处理、上传功能等。
创建目录 app\Services
上传服务
创建服务类
1 |
|
控制器中使用
控制器中使用依赖注入服务就可正常使用了。
1 | ... |
图片处理服务
阅读下面的 插件>图片处理
文档安装图片处理插件。
1 |
|
控制器中使用
1 | public function show(User $user,ImageService $image,Request $request) |
任务调度
在过去,开发者必须在服务器上为每个任务生成单独的 Cron 项目。而令人头疼的是任务调度不受源代码控制,而且必须通过 SSH 连接到服务器上来增加 Cron 项目。
编辑 crontab 计划任务(artisan 设置成你的项目地址)
1 | export EDITOR=vi && crontab -e |
Laravel Plugin
在 phpstorm 中安装 laravel plugin
插件.
1 | Settings > Languages & Frameworks > PHP > Laravel` 点击开启 `Enable for this project |
laravel-ide-helper
laravel-ide-helper 用于实现方便的代码提示功能。
使用 composer 安装插件
1 | composer require barryvdh/laravel-ide-helper |
在 config\app.php
文件 providers 添加
1 | Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class, |
在 app/Providers/AppServiceProvider.php 文件中注册
1 | public function register() |
生成代码跟踪支持
1 | php artisan ide-helper:generate |
laravel artisan 命令提示
1 | settings>Tools>Command Line Tool Support |
多语言
语言包
默认表单提示是英文的,我们可以安装中文语言包进行汉化。
1 | composer require caouecs/laravel-lang:~4.0 |
包含大多数语言,语言包位于vendor/caouecs/larvel-lang/src
目录中。
使用
-
根据需要复制语言包到
resources/lang
目录中。 -
修改
config/app.php
配置文件1
'locale' => 'zh-CN',
JSON 语言包
在 resources/lang
目录下定义 zh-CN.json
文件
1 | { |
在模板中就可以使用 __('Login')
调用了,Laravel 默认的登录模板大量使用了 JSON 语言包
SESSION
默认 Laravel 使用文件管理会话,下面是我们改为更高效的数据库管理。
创建数据表
1 | php artisan session:table |
修改.env 中的驱动
1 | ... |
验证码
https://github.com/mewebstudio/captcha
安装
1 | composer require mews/captcha |
配置文件 config/captcha.php
使用
1 | #前台 |
用户认证
重定向未认证用户
当 auth
中间件判定某个用户未认证,会返回一个 JSON 401
响应,或者,如果不是 Ajax 请求的话,将用户重定向到 login
命名路由。
你可以通过在 app/Exceptions/Handler.php
文件中定义一个 unauthenticated
方法来改变这一行为:
1 | use IlluminateAuthAuthenticationException; |
事件
Laravel 在认证过程中引发了各种各样的事件。你可以在 EventServiceProvider
中对这些事件做监听:
1 | /** |
异常处理 Excepton
异常处理通常是防止未知错误产生所采取的处理措施。异常处理的好处是你不用再绞尽脑汁去考虑各种错误,这为处理某一类错误提供了一个很有效的方法,使编程效率大大提高。
创建异常类
1 | php artisan artisan make:exception UploadException |
定义类内容如下
1 |
|
异常日志
当发生异常时会在 storage/logs/laravel.log
文件中记录异常。
如果不想执行异常记录需要在 app/Exceptions/Handler.php
异常处理器文件的 $dontReport
属性声明。
1 | class Handler extends ExceptionHandler |
全站动态
使用 https://github.com/spatie/laravel-activitylog 组件构成,可查看 https://docs.spatie.be/laravel-activitylog/v3/introduction 文档学习使用该组件。
安装组件
1 | composer require spatie/laravel-activitylog |
创建数据迁移文件并执行
1 | php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="migrations" |
记录动态
基本使用
1 | activity() |
设置自定义属性
1 | activity() |
记录模型事件
程序包可以自动记录事件,例如创建,更新和删除模型时。
1 | use Illuminate\Database\Eloquent\Model; |
如果要记录$fillable
对模型的所有属性的更改,可以protected static $logFillable = true;
1 | $newsItem = NewsItem::create([ |
自定义要记录的事件
默认情况下,包将记录created
,updated
,deleted
的事件。您可以通过$recordEvents
在模型上设置属性来修改此行为。
1 | use Illuminate\Database\Eloquent\Model; |
自定义日志名称
指定$logName
使模型使用除默认名称之外的其他名称。
1 | use Illuminate\Database\Eloquent\Model; |
Markdown 转 HTML
Parsedown 组件用于将 markdown
内容转为 html
安装组件
1 | composer require erusev/parsedown |
模型中使用
1 | class Article extends Model |
角色权限
https://docs.spatie.be/laravel-permission/v3/introduction/
安装
1 | composer require spatie/laravel-permission |
基本使用
缓存角色和权限数据以加速性能。当你使用提供的方法来操作角色和权限时,缓存会自动为您重置:
1 | $user->assignRole('writer'); |
但是,如果直接在数据库中操作“权限/角色”数据而不是调用提供的方法,则除非手动重置缓存,否则不会在应用程序中看到反映的更改。
手动缓存重置
缓存角色和权限数据以加速性能。当你使用提供的方法来操作角色和权限时,缓存会自动为您重置。
要手动重置此软件包的缓存,请运行:
1 | php artisan cache:forget spatie.permission.cache |
代码删除缓存
1 | app()['cache']->forget('spatie.permission.cache'); |
模型动作
在 User
等模型中引入 use Spatie\Permission\Traits\HasRoles
可以拥有所有权限操作方法
1 | use Spatie\Permission\Traits\HasRoles; |
新建角色
1 | use Spatie\Permission\Models\Role; |
删除角色
1 | $user->removeRole('writer'); |
角色也可以同步:
1 | //所有当前角色将从用户中删除,并替换为给定的数组中的角色 |
添加权限
1 | use Spatie\Permission\Models\Permission; |
可以使用以下方法之一将多个权限同步到一个角色:
1 | $role->syncPermissions($permissions); |
删除权限
1 | $role->revokePermissionTo($permission); |
一次性撤消并添加新的权限:
1 | $user->syncPermissions(['edit articles', 'delete articles']); |
添加用户角色
1 | // 单个角色 |
添加用户权限
1 | // 为用户添加『直接权限』 |
检查用户角色
1 | // 是否是超级管理员 |
检查权限
1 | //用户是否拥有权限 |
或者你可以传递一个代表权限 ID 的整数
1 | $user->hasPermissionTo('1'); |
如果用户有任何一个权限即通过:
1 | $user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']); |
用户必须拥有所有权限时通过:
1 | $user->hasAllPermissions(['edit articles', 'publish articles', 'unpublish articles']); |
你也可以传递整数以通过权限 ID 进行查找
1 | $user->hasAnyPermission(['edit articles', 1, 5]); |
使用 Laravel 默认的 can
功能测试用户是否拥有权限:
1 | $user->can('edit articles'); |
获取用户权限
1 | //获取直接分配给用户的所有权限的列表 |
获取用户角色
1 | $roles = $user->getRoleNames(); // 返回一个集合 |
根据权限或角色获取用户
HasRoles
特征(trait)还为您的模型添加了一个“角色”范围,以便将查询范围限定为某些角色或权限:
仅返回具有角色 'writer' 的用户
1 | $users = User::role('writer')->get(); |
仅返回具有 'edit articles' (继承或直接)权限的用户
1 | $users = User::permission('edit articles')->get(); |
Blade 和角色
测试一个特定的角色:
1 | @role('writer') |
同上
1 | @hasrole('writer') |
测试列表中的任何角色:
1 | @hasanyrole($collectionOfRoles) |
测试所有角色:
1 | @hasallroles($collectionOfRoles) |
Blade 和权限
此软件包不会添加任何特定于权限的 Blade 指令。 因此,使用 Laravel 原生的 @can
指令来检查用户是否具有某种权限。
1 | @can('edit articles') |
or
1 | @if(auth()->user()->can('edit articles') && $some_other_condition) |
图片处理
spatie/image
https://docs.spatie.be/image/v1/usage/basic-usage 用于提供丰富的图片处理方式
Intervention/image
https://github.com/Intervention/image 用于裁切缩放等图片处理操作
安装
1 | $ composer require intervention/image |
使用
1 | $img = Image::make('public/foo.jpg'); |
spatie/image
https://github.com/spatie/image
日期处理
https://carbon.nesbot.com/ 无需安装 Laravel 已经内置。
中文文档:https://segmentfault.com/a/1190000012716974#articleHeader2
下面是中文本地化的设置:
1 | $user->created_at->diffForHumans() |
在 app/Providers/AppServiceProvider.php
的 boot
方法中设置:
1 | \Carbon\Carbon::setLocale('zh'); |
Debugbar
https://github.com/barryvdh/laravel-debugbar
安装
1 | composer require barryvdh/laravel-debugbar --dev |
修改 .env
配置文件
1 | DEBUGBAR_ENABLED=true |
模块化设计
https://nwidart.com/laravel-modules/v6/introduction
https://github.com/houdunwang/laravel-module
组件介绍
通过使用模块来管理大型 Laravel 项目,模块就像一个 laravel 包非常方便的进行添加或移除。
nwidart/laravel-modules
是一个 Laravel 软件包,创建该软件包是为了使用模块管理大型 Laravel 应用。模块就像 Laravel 包一样,它具有一些视图,控制器或模型。Laravel 5 支持并测试了该软件包。
此软件包是pingpong / modules的重新发布,重新组织和维护的版本,不再维护。该软件包在AsgardCMS 中使用。
原始软件包没有的一大额外奖励:tests。
注意:
如果从以前的版本升级到 v6,请运行以下命令:
1 | php artisan module:v6:migrate |
安装组件
要通过 Composer 安装,运行以下命令
1 | composer require nwidart/laravel-modules |
通过运行以下命令来发布程序包的配置文件
1 | php artisan vendor:publish --provider="Nwidart\Modules\LaravelModulesServiceProvider" |
自动加载
默认情况下,模块类不会自动加载。您可以使用来自动加载模块psr-4
composer.json
1 | { |
创建模块
运行以下命令创建模块
1 | php artisan module:make <module-name> |
也可以在一个命令中创建多个模块
1 | php artisan module:make Blog User Auth |
默认情况下,当您创建新模块时,该命令将自动添加一些资源,例如控制器,种子类,服务提供者等。如果您不需要这些,则可以添加--plain
标志,以生成普通模块
1 | php artisan module:make Blog --plain |
webpack
laravel 前端使用 webpack 工具构建,我们介绍几个常用动作
复制目录
1 | mix.copyDirectory('assets/img', 'public/img'); |
Doctrine/dbal
dbal 是用于管理数据表结构的组件库。
Active 状态
在我们构建页面的过程中,经常会根据 url 的参数设置页面元素的 active
属性,将其渲染为「选中」状态。
官网 https://www.hieule.info/products/laravel-active-version-3-released
安装
Require this package as your dependencies:
1 | composer require hieu-le/active |
Append this line to your providers
array in config/app.php
1 | HieuLe\Active\ActiveServiceProvider::class, |
Append this line to your aliases
array in config/app.php
1 | 'Active' => HieuLe\Active\Facades\Active::class, |
语法
1 | function active_class($condition, $activeClass = 'active', $inactiveClass = '') |
使用
此扩展包提供了一批函数让我们更方便的进行 $condition
判断:
- if_uri() - 判断当前的 url 是否满足指定的 url;
- if_uri_pattern() - 判断当前的 url 是否含有指定的字符;
- if_query() - 判断指定的 GET 变量是否符合设置的值;
- if_route() - 判断当前对应的路由是否是指定的路由;
- if_route_pattern() - 判断当前的路由是否包含指定的字符;
- if_route_param() - 判断当前的 url 有无指定的路由参数。
1 | <a class="{{ active_class(if_route('users.index')) }}" href="">会员</a> |
XSS 过滤
https://github.com/mewebstudio/Purifier
安装
1 | composer require mews/purifier |
配置文件
1 | config/purifier.php |
使用
1 | clean(Input::get('inputname'),'default'); |
Guzzle
Guzzle 是一个 PHP 的 HTTP 客户端,用来轻而易举地发送请求,并集成到我们的 WEB 服务上。
http://guzzle-cn.readthedocs.io/zh_CN/latest/
sudo-su 用户切换
https://github.com/viacreative/sudo-su
安装软件包
1 | composer require viacreative/sudo-su |
Add the package's service provider to your app in your project's AppServiceProvider
:
1 | class AppServiceProvider extends ServiceProvider |
发布
1 | php artisan vendor:publish |
配置
修改配置文件 config/sudosu.php
添加允许使用的域名后缀
1 | 'allowed_tlds' => ['dev', 'local','hd'], |
guard
如果用户模型不是 User 也需要在配置文件中修改
1 | 'user_model' => \Modules\Admin\Entities\Admin::class |
使用
在模板中使用
1 | @if (config('app.debug')) |
simditor 编辑器
simditor 是一款简单快速的编辑器。
下载 https://github.com/mycolorway/simditor/archive/v2.3.16.zip
配置
-
复制
site/assets/scripts
目录为 Laravel 项目的resources/plugin/simditor/scripts
目录 -
复制
site/assets/styles
目录为 Laravel 项目的resource/plugin/simditor/styles
目录 -
修改
webpack.mix.js
1
.mix.copy('resources/plugin','public/plugin')
创建控制器
1 | artisan make:controller Components/UploadController |
下面是控制器内容,使用了 UploadService
服务(参考上面Service 服务化
文档)
1 | ... |
配置路由
1 | Route::post('upload/image','Components\UploadController@editorImage')->name('upload.image'); |
使用
1 | <script type="text/javascript" src="{{asset('js/simditor/module.js')}}"></script> |
Mailhog
Mailhog (homestead
已经内置)可以轻松的抓取到你发送的电子邮件并进行检查,而无需将邮件真正发送给收件人. 开始之前, 请更新你的 .env
文件并使用如下邮件设置:
1 | MAIL_DRIVER=smtp |
访问
1 | http://domain:8025 |
china-area-data
中国行政区域数据 https://www.npmjs.com/package/china-area-data
predis
redis 队列驱动
Github:https://github.com/nrk/predis
安装
1 | composer require "predis/predis:~1.0" |
判断设备
判断移动、平板设备等场景还是很常见的。
Github:https://github.com/hisorange/browser-detect
宝塔设置
域名设置
Laravel 使用 public 目录访问,需要将域名绑定在 public 目录
打包上传
- 将本地 Laravel 项目打成 zip 包
- 在宝塔中的文件菜单选择你的网站目录,然后上传 zip 文件
- 上传后解压释放即可
伪静态
在网站菜单选择需要修改的网站,进行以下设置
MySQL
宝塔的 mysql 版本低,运行会出错。
-
先在宝塔后台升级 mysql
-
在 Laravel 的 AppServiceProvider.php 文件里的 boot 方法里设置
1
2
3
4public function boot()
{
\Schema::defaultStringLength(191);
}
常见错误
- 有时执行 composer 意外中断或卡住,删除 vendor 与 composer.lock 后重新执行
- 使用模块化开发时模块下的 node_modules 严重影响 composer 执行,可以先删除模块下的 node_modules 再执行 composer install 、composer dumpautoload 等命令
Swoole 加速
安装 Swoole 扩展
Swoole 扩展到 GitHub 首页下载 Swoole 扩展源码,地址:https://github.com/swoole/swoole-src 下载后按照标准的 PHP 扩展编译方式进行编译和安装。
1 | unzip swoole-master.zip |
编译安装完后,修改 php.ini 加入 extension=swoole.so 开启 swoole 扩展
安装 laravel-swoole 组件
组件地址:https://github.com/swooletw/laravel-swoole
1 | composer require swooletw/laravel-swoole |
然后,添加服务提供者: 如果你使用 Laravel ,在 config/app.php 服务提供者数组添加该服务提供者:
1 | [ |
启动 swoole 服务
现在,你可以执行以下的命令来启动 Swoole HTTP 服务。
1 | /usr/local/php/bin/php artisan swoole:http start |
然后你可以看到以下信息:
1 | Starting swoole http server... |
现在可以通过访问 http://127.0.0.1:1215 来进入 Laravel 应用
Laravel-swoole 命令
1 | 启动 |
配合 Ngnix 使用
1 | gzip on; |
Artisan 命令
1 | php artisan make:controller HomeController |