前言
Composer安装
这里不做赘述
laravel LTS ( LTS 表示长期支持维护)速查表
laravel 基于composer 的搭建
服务器要求
PHP >= 7.0.0
PHP OpenSSL 扩展
PHP PDO 扩展
PHP Mbstring 扩展
PHP Tokenizer 扩展
PHP XML 扩展
安装 Laravel
-
通过 Laravel 安装器 安装
参考: https://laravelacademy.org/post/7620.html
-
通过 Composer Create-Project 安装
执行: composer create-project --prefer-dist laravel/laravel blog [5.5.*] 【5.5.* 表示的是安装的laravel的版本,不写表示安装最新版本的laravel】 注意: 通过 composer 安装的 laravel项目,在删除文件后,建议使用composer dump-autoload 或者composer dumpautoload 或者 composer dump 进行更新下
配置 Laravel
待更新。。。
学习并熟练运用laravel5.5的必备能力
必须 熟记 Laravel 5.5 官方文档,查阅时能快速定位,5 遍以上;
必须 熟记 Laravel 5.5 API 文档 的类结构,查阅时能快速定位;
必须 熟记所有 PSR 通过的标准;
PSR 目前还未通过的标准,也要 应该 知晓 http://www.php-fig.org/psr/#draft
应该 熟悉 PHP 最佳实践
应该 了解 『Rails 信条』
一、laravel主要特色:
1、简洁而清晰地路由定义方式
2、强大的IoC容器
3、合理的框架结构
4、丰富的第三方库
二、学习laravel前的准备
1、仔细阅读laravel开发文档,地址:https://laravelacademy.org/laravel-docs-5_5
2、需要扎实的PHP基础
3、具备oop面向对象的思想
4、熟练使用composer依赖管理
5、熟悉PHP版本新特性【PHP版本7.0以上】
6、熟悉PSR规范
三、laravel的文件目录结构及描述
为了快速上手laravel框架,首要先了解它的目录结构。
应用根目录
App目录: 包含了应用的核心代码,你为应用编写的代码绝大多数也会放到这里,后面详细介绍子目录;
Bootstrap目录:用于框架的启动和自动载入配置,初学者暂不需了解;
Config目录:包含了应用所有的配置文件,建议通读一遍这些配置文件以便熟悉 Laravel 所有默认配置项;
Database目录:数据库迁移 与数据填充文件;
Public目录:WEB 部署目录(对外访问目录,也称项目入口目录),里面还包含静态资源文件;
Resources目录:包含了视图的原始资源文件视图;
Routes目录:路由文件,包含应用定义的所有路由文件;默认提供了四个路由文件用于给不同的入口使用:web.php、api.php、 console.php 和 channels.php。
Storage目录:编译后的模板文件 和其他缓存文件;
Tests目录:自动化测试目录;
Vendor目录:包含了应用所有通过 Composer 加载的依赖。
App目录:
Console目录:包含应用所有自定义的 Artisan 命令;
Events目录:该目录默认不存在,该目录用于存放事件类;
Exceptions目录:目录包含应用的异常处理器,同时还是处理应用抛出的任何异常的好地方;
Http目录:目录包含了控制器、中间件以及表单请求等,几乎所有通过 Web 进入应用的请求处理都在这里进行;
Jobs目录:该目录默认不存在,目录用于存放队列任务;
Listeners目录:这个目录默认不存在,目录包含处理事件的类(事件监听器);
Mail目录:这个目录默认不存在, 目录包含应用所有邮件相关类;
Notifications目录:这个目录默认不存在,目录包含应用发送的所有通知;
Policies目录:这个目录默认不存在,目录包含了应用所有的授权策略类;
Providers目录:目录包含应用的所有服务提供者;
Rules目录:该目录默认不存在,目录包含应用的自定义验证规则对象;
四、路由
※ 重要知识点
路由的作用: 把各种请求分流到各个控制器,换句话说,我们需要注册路由来响应任何http请求动作。
对于分析一个Web框架,其中最重要的一环就是对这个Web框架的路由进行分析。如果你玩不懂它的路由机制,那你也就不可能玩通整个Web框架。可见路由机制在整个Web框架中的地位和重要性。
※ 建议性规范
1. 绝不 在路由配置文件里书写『闭包路由』或者其他业务逻辑代码,因为一旦使用将无法使用 路由缓存 。
2. 路由器要保持干净整洁,绝不 放置除路由配置以外的其他程序逻辑。
3. 必须 优先使用 Restful 路由,配合资源控制器使用。
超出 Restful 路由的,应该 模仿上图的方式来定义路由。
4. 使用 resource 方法时,如果仅使用到部分路由,必须 使用 only 列出所有可用路由。
绝不 使用 except,因为 only 相当于白名单,相对于 except 更加直观。路由使用白名单有利于养成『安全习惯』。
5. 除了 resource 资源路由以外,其他所有路由都 必须 使用 name 方法进行命名。
必须 使用『资源前缀』作为命名规范,如下的 users.follow,资源前缀的值是 users.
4.1 路由的基本使用
在laravel5.5中,路由文件的路径是:/app/routes,其中包含四种route文件,分别对应不同的情况
api.php 【一般接口开发会用到该路由,在 api.php 定义的路由被分配到了 api 中间件组,该中间件组下的路由主要用于第三方 API 请求,无需进行 CSRF 检查】
web.php 【一般web开发会用到该路由,在web.php定义的路由被分配到了 web 中间件组,从而可以使用 session 和 csrf 保护等功能】
console.php
channels.php
下面将讲述到在实际项目开发中,常用的路由及写法
get:
// 闭包路由
Route::get('/', function(){
return 'Hello World';
});
// 路由带参数 【{id}:必填参数, {name?}: 非必填参数】
Route::get('user/{id}/{name?}', function($id,$name='lucy'){
return 'User '.$id;
});
// 正则约束
Route::get('user/{name}', function ($name) {
// name 必须是字母且不能为空
})->where('name', '[A-Za-z]+');
Route::get('user/{id}/{name}', function ($id, $name) {
// 同时指定 id 和 name 的数据格式
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);
post:
// 闭包路由
Route::post('posts', function(){
return 'Hello World';
});
match:
//
Route::match(['get', 'post'], 'foo', function () {
return 'This is a request from get or post';
});
any:
Route::any('bar', function () {
return 'This is a request from any HTTP verb';
});
路由重定向:
Route::redirect('/here', '/there', 301);
路由视图:
Route::view('/welcome', 'welcome');
Route::view('/welcome', 'welcome', ['name' => '学院君']);
这里不过多阐述,而且上述讲述的都可在laravel中文文档上搜索的到,且文档中提及了很多的其他路由系列(如命名路由,路由分组,路由前缀,路由模型绑定等),且路由的参数这块还有一些约束,不仅限制于当前路由,还可以全局约束。路由的注册,一般情况下,跟中间件绑定使用的情景很多,关于中间件,参考第5节。
※ 关于路由这块,建议掌握命名路由、路由分组、资源路由。
4.2 项目开发中的实用路由
-
路由闭包:
绝不在路由配置文件里书写『闭包路由』或者其他业务逻辑代码,因为一旦使用将无法使用 路由缓存 。 路由器要保持干净整洁,绝不 放置除路由配置以外的其他程序逻辑。
-
Restful 路由:
必须 优先使用 Restful 路由,配合资源控制器使用
[图片上传失败...(image-f519cb-1652941229691)]
资源路由(resource)
-
一般资源路由定义:
// 资源路由路由 URI 必须 使用复数形式 Route::resource('photos', 'PhotosController');
等于以下路由定义:
Route::get('/photos', 'PhotosController@index')->name('photos.index'); Route::get('/photos/create', 'PhotosController@create')->name('photos.create'); Route::post('/photos', 'PhotosController@store')->name('photos.store'); Route::get('/photos/{photo}', 'PhotosController@show')->name('photos.show'); Route::get('/photos/{photo}/edit', 'PhotosController@edit')->name('photos.edit'); Route::put('/photos/{photo}', 'PhotosController@update')->name('photos.update'); Route::delete('/photos/{photo}', 'PhotosController@destroy')->name('photos.destroy');
-
使用 resource 方法时,如果仅使用到部分路由,必须 使用 only 列出所有可用路由:
Route::resource('photos', 'PhotosController', ['only' => ['index', 'show']]); 【绝不 使用 except,因为 only 相当于白名单,相对于 except 更加直观。路由使用白名单有利于养成『安全习惯』。】
-
五、中间件
※ 重要知识点
对于一个Web应用来说,在一个请求真正处理前,我们可能会对请求做各种各样的判断,然后才可以让它继续传递到更深层次中。而如果我们用if else这样子来,一旦需要判断的条件越来越来,会使得代码更加难以维护,系统间的耦合会增加,而中间件就可以解决这个问题。我们可以把这些判断独立出来做成中间件,可以很方便的过滤http请求。
5.1 定义中间件
php artisan make:middleware 中间件名称
【定义(创建中间件,并不会被使用,需要在 app/Http/Kernel.php 中注册中间件,才能被使用)】
5.2 三种中间件
注册中间件有三种:
-
$middleware属性:
全局中间件,要对所有的请求要做一些处理的时候,就适合定义在该属性内。(比如统计请求次数这些)
-
$routeMiddleware属性:
路由中间件,有些个别的请求,我们需要执行特别的中间件时,就适合定义在这属性里面。
-
$middlewareGroups属性:
中间件组,比如我们项目有api请求和web的请求的时候,就要把两种类型的请求中间件分离开来,这时候就需要我们中间件组啦。
5.3 中间件的使用场景
1. laravel 自身的中间件(例如身份验证、csrf保护等)
2. 操作权限验证
六、CSRF保护
6.1 定义:
Laravel 可以轻松地保护应用程序免受 跨站请求伪造 (CSRF) 的攻击。跨站请求伪造是一种恶意的攻击,它凭借已通过身份验证的用户身份来运行未经过授权的命令。
Laravel 会自动为每个活跃用户的会话生成一个 CSRF「令牌」。该令牌用于验证经过身份验证的用户是否是向应用程序发出请求的用户。
任何情况下当你在应用程序中定义 HTML 表单时,都应该在表单中包含一个隐藏的 CSRF 令牌字段,以便 CSRF 保护中间件可以验证该请求
※ 关于CSRF保护,详情参考laravel中文文档
七、控制器
※ 建议性规范
1. 必须 保持控制器文件代码行数最小化,还有可读性。
2. 不应该 为「方法」书写注释,这要求方法取名要足够合理,不需要过多注释。
3. 应该 为一些复杂的逻辑代码块书写注释,主要介绍产品逻辑 - 为什么要这么做。
4. 不应该 在控制器中书写「私有方法」,控制器里 应该 只存放「路由动作方法」。
5. 绝不 遗留「死方法」,就是没有用到的方法,控制器里的所有方法,都应该被使用到,否则应该删除。
6. 绝不 在控制器里批量注释掉代码,无用的逻辑代码就必须清除掉。
7.1 创建控制器
目录路径: 在 app/Http/Controllers/ 路径下
创建命令: php artisan make:controller [模块名/]控制器名 [--resource]
7.2 控制器与路由
在实际的项目开发中,一般不会有路由闭包的,基本上都是控制器与路由相互绑定的。
通俗的说,路由是请求的链接地址指向的就是控制器里面的方法。
八、请求
8.1
8.2 常用请求的方法
获取请求路径
$request->path(): 返回请求的路径信息
获取请求的 URL
$request->url(): 返回不带有查询字符串的 URL (string)
$request->fullUrl(): 返回值带有查询字符串的 URL
获取请求方法
$request->method(): 返回请求的方法,eg. GET,POST (string)
验证 HTTP 的请求方式
$request->isMethod('post'): 返回 true , false (boolean)
获取所有输入数据
$request->all(): 返回所有的输入数据 (array)
$request->input(): 返回所有的输入数据 (array)
获取指定输入值
$request->input(参数1【 ,参数2】) : 返回值,如果参数1 的值存在,则返回参数1的值,如果参数1 的值不存在,将参数2 作为参数1 的返回值返回。
获取 GET 请求的输入值
$request->query(): 返回 GET 请求查询字符串的输入数据 (array)
获取 POST 请求的输入值
$request->post(): 返回 POST 请求的输入数据 (array)
获取部分输入数据
$request->only(参数);参数为一维数组,返回值为所有你指定的键值对(array)
$request->except(参数);参数为一维数组,返回值为所有非你指定的键值对(array)
判断是否存在输入值
$request->has(参数): 返回 true , false (boolean)
判断是否存在值并且不为空
$request->filled(参数): 返回 true , false (boolean)
疑问点:input() 方法跟all() 方法,暂时不清楚,如何获取所有输入参数的范围(官网文档说的是 query + request)
九、HTTP 会话机制
9.1 cookie会话机制
9.2 session会话机制
-
应用:
由于 HTTP 协议本身是无状态的,上一个请求与下一个请求无任何关联,为此我们引入 Session 来存储用户请求信息以解决特定场景下无状态导致的问题(比如登录、购物)。
-
配置:
文件路径位置: config/session.php
默认情况下,Laravel 使用的 Session 驱动为 file 驱动,这对许多应用而言是没有什么问题的。在生产环境中,你可能考虑使用 memcached 或者 redis 驱动以便获取更佳的 Session 性能,尤其是线上同一个应用部署到多台机器的时候,这是最佳实践。
-
使用:
session的数据处理方式:
①、全局的辅助函数 session ②、Request 实例(启动过程中会将 Session 数据设置到请求实例的 session 属性中)
设置 session 值:
// 全局辅助函数 # 新存/修改 session(['key' => 'value']); # 指定一个默认值... session('key', 'default'); // Request 实例 #新存数据 $request->session()->put('key', 'value') # 在原有的session数组中,新加(追加)数据 $request->session()->push('key.arguments', 'developers'); // 闪存数据 #有时候你仅想在下一个请求之前在 Session 中存入数据,你可以使用 flash 方法。使用这个方法保存在 session 中的数据,只会保留到下个 HTTP 请求到来之前,然后就会被删除。 $request->session()->flash('key', 'value');
获取 session 值:
// 全局辅助函数 session('key'); // Request 实例 # 获取所有 $request->session()->all(); # 获取指定 key 值的数据,【参数二: 如果不存在,默认值】 $request->session()->get('key'[,'value']); # 获取并删除(session)数据,【参数二: 如果不存在,默认值】 $value = $request->session()->pull('key'[, 'default']);
判断 session 中是否存在某个值
$request->session()->has('key'): 返回 true(值存在且不为 null), false (boolean) $request->session()->exists('key'): 返回 true(值存在), false (boolean)
删除 session 值
// 删除指定的 session 数据 $request->session()->forget('key'); // 删除所有 session 数据 $request->session()->flush();
-
注释:
$_SESSION 无法获取 session 值:
Laravel 并没有使用 PHP 内置的 Session 功能,而且自己实现了一套更加灵活更加强大的 Session 机制,核心逻辑请参考 Illuminate\Session\Middleware\StartSession 这个中间件。
Laravel 的控制器构造函数中无法获取应用 Session 数据:
因为 Laravel 的 Session 通过 StartSession 中间件启动,既然是中间件就会在服务容器注册所有服务之后执行,而控制器们的构造函数都是在容器注册服务的时候执行的,所以这个时候 Session 尚未启动,所有无法获取数据。
解决办法是将获取 Session 数据逻辑后置或者在构造函数中引入在 StartSession 之后执行的中间件。
十、表单验证机制
※ 建议性规范
1. 必须 使用 表单请求 - FormRequest 类 来处理控制器里的表单验证。
2. 绝不 使用 authorize() 方法来做用户授权,用户授权我们会单独使用 Policy 授权策略 来实现。
3. 所有 FormRequest 表验证类 必须 继承 app/Http/Requests/Request.php 基类
4. FormRequest 表验证类 必须 遵循 资源路由 方式进行命名
eg. photos 对应 app/Http/Requests/PhotoRequest.php 。
十一、视图
※ 建议性规范
1. 视图文件 必须 优先考虑使用 .blade.php 后缀来指定使用 Blade 模板引擎。
2. 保持目录清晰
layouts - 页面布局文件 必须 放置于此目录下;
common - 存放页面通用元素;
pages - 简单的页面存放文件夹,如:about、contact 等;
resources - 对应 Restful 路由的资源路径名称,以 URI photos/create 为例,对应 create.blade.php 文件,存放在文件夹 photos 下。
3. 必须 避免在 resources/views 目录下直接放置视图文件。
4. 局部视图
局部视图文件 必须 使用 _ 前缀来命名,如:photos/_upload_form.blade.php
5. 视图命名要释义
为了和 Restful 路由器和资源控制器保持一致,视图命名也 必须 使用资源视图的命名方式
6. create_and_edit 视图
很多情况下,创建和编辑视图里的页面结构接近相似,在这种情况下,应该 使用 create_and_edit 视图
Blade 是 Laravel 提供的一个简单而又强大的模板引擎。和其他流行的 PHP 模板引擎不同,Blade 并不限制你在视图中使用原生 PHP 代码。所有 Blade 视图文件都将被编译成原生的 PHP 代码并缓存起来,除非它被修改,否则不会重新编译,这就意味着 Blade 基本上不会给你的应用增加任何负担。Blade 视图文件使用 .blade.php 作为文件扩展名,被存放在 resources/views 目录。
11.1 Blade模板
主要优点
模板继承 和 区块 。
主布局
定义一个主体的主布局,文件路径: resources/views/layouts/main.blade.php 【文件只是举例】
应用程序名称 - @yield('title')
@section('sidebar')
这是主布局的侧边栏。
@show
@yield('content')
# 在主视图中的需要知道的命令
@section: 定义了视图的一部分内容。
@yield: 用来显示指定部分的内容。
@show: 定义并立即生成该区块。
继承布局
当定义子视图时,你可以使用 Blade 提供的 @extends 命令来为子视图指定应该 「继承」 的布局。文件路径: resources/views/layouts/child.blade.php 【文件只是举例】
@extends('layouts.app')
@section('title', 'Page Title')
@section('sidebar')
@parent
这将追加到主布局的侧边栏。
@endsection
@section('content')
这是主体内容。
@endsection
# 在子视图中的需要知道的命令
@extends: 为子视图指定想要 「继承」 的布局。
@section的两种命令解析:
①、将内容注入于主布局的 @section 中。
②、「主」布局中使用 @yield 的地方会显示这些子视图中的 @section 间的内容,展示方式有两种:
【1. @section('title', 'Page Title')】
【2. @section('content')
这是主体内容。
@endsection
】
@parent: 追加内容【在原来的主布局中,追加内容】
11.2 Components & Slots (组件&插槽)
组件和插槽给内容片段(section)和布局(layout)带来了方便,不过,有些人可能会发现组件和插槽的模型更容易理解。
我们假设有一个可复用的“alert”组件,我们想要在整个应用中都可以复用它。
# 简单的组件
// 定义组件 【文件路径:/resources/views/alert.blade.php】
{{ $slot }}
// 使用组件
@component('alert')
这是想要注入组件的内容 // {{ $slot }} 变量包含了我们想要注入组件的内容
@endcomponent
# 多个插槽的组件
// 定义组件 【文件路径:/resources/views/alert.blade.php】
{{ $title }}
{{ $slot }}
// 使用组件
@component('alert')
@slot('title')
插槽的值
@endslot
这是想要注入组件的内容
@endcomponent
11.3 数据显示
数据在视图中的展示,一般是通过两个花括号包裹变量来显示传递到视图的。
eg. 【Blade 的 {{}} 语句已经经过 PHP 的 htmlentities 函数处理以避免 XSS 攻击】
# 在视图中输出 name 变量的内容
{{ $name }}
# 三元运算符 【如果 $name 变量存在,其值将会显示,否则将会显示 Default。】
{{ isset($name) ? $name : 'Default' }}
【针对三元操作符,Blade 还提供了更简单的方式: {{ $name or 'Default' }} 】
# 原样输出 【 Blade 的 {{ }} 语句已经通过 PHP 的 htmlentities 函数处理以避免 XSS 攻击,如果你不想要数据被处理,比如要输出带 HTML 元素的富文本 】
{!! $name !!}
【输出用户提供的内容时要当心,对用户提供的内容总是要使用双花括号包{{}}裹以避免直接输出 HTML 代码。】
# 数据在js文件中的展示
var app = ; // 这就是在js文件使用原生的PHP语法。
【显然,我们有更简洁的方式,使用Blade 的 @json 指令:var app = @json($array);】
11.4 Blade & JavaScript 框架
由于很多 JavaScript 框架也是用花括号来表示要显示在浏览器中的表达式,如 Vue,我们可以使用 @ 符号来告诉 Blade 渲染引擎该表达式应该保持原生格式不作改动。
@{{ name }}
【在本例中,@ 符在编译阶段会被 Blade 移除,但是,{{ name }} 表达式将会保持不变,从而可以被 JavaScript 框架正常渲染。】
@verbatim指令
【如果你在模板中有很大一部分篇幅显示 JavaScript 变量,那么可以将这部分 HTML 封装在 @verbatim 指令中,这样就不需要在每个 Blade 输出表达式前加上 @ 前缀:】
@verbatim
Hello, {{ name }}.
@endverbatim
11.5 流程控制在模板中的使用
除了模板继承与数据显示的功能以外,Blade 还提供了常见的 PHP 流程控制语句,比如条件表达式和循环语句。这些语句与 PHP 语句的相似,与其一样清晰简明。
If 语句
@if (count($records) === 1)
我有一条记录!
@elseif (count($records) > 1)
我有多条记录!
@else
我没有任何记录!
@endif
# 为了方便,Blade 还提供了一个 @unless 命令
@unless (Auth::check())
你尚未登录。
@endunless
# @isset 和 @empty 指令也可以视为与 PHP 函数有相同的功能:
@isset($records)
// $records 被定义并且不为空...
@endisset
@empty($records)
// $records 是「空」的...
@endempty
身份验证快捷方式
@auth 和 @guest 指令可用于快速判断当前用户是否登录。
@auth
// 用户已登录...
@endauth
@guest
// 用户未登录...
@endguest
Switch 语句
@switch($i)
@case(1)
First case...
@break
@case(2)
Second case...
@break
@default
Default case...
@endswitch
for 循环语句
@for ($i = 0; $i < 10; $i++)
当前的值为 {{ $i }}
@endfor
foreach 循环语句
@foreach ($users as $user)
用户编号为 {{ $user->id }}
@endforeach
forelse 循环语句
@forelse ($users as $user)
用户名{{ $user->name }}
@empty
暂无用户
@endforelse
while 循环语句
@while (true)
无限循环
@endwhile
continue & break 语句
# 用法1 【结束循环或跳出当前迭代】
@foreach ($users as $user)
@if ($user->type == 1)
@continue
@endif
{{ $user->name }}
@if ($user->number == 5)
@break
@endif
@endforeach
# 用法2 【引入条件】
@foreach ($users as $user)
@continue($user->type == 1)
{{ $user->name }}
@break($user->number == 5)
@endforeach
$loop 变量
在循环的时候,可以在循环体中使用 $loop 变量,该变量提供了一些有用的信息,比如当前循环索引,以及当前循环是不是第一个或最后一个迭代。
$loop 变量还提供了其他一些有用的属性:
属性 描述
$loop->index 当前循环迭代索引 (从0开始)
$loop->iteration 当前循环迭代 (从1开始)
$loop->remaining 当前循环剩余的迭代
$loop->count 迭代数组元素的总数量
$loop->first 是否是当前循环的第一个迭代
$loop->last 是否是当前循环的最后一个迭代
$loop->depth 当前循环的嵌套层级
$loop->parent 嵌套循环中的父级循环变量
注释
Blade 还允许你在视图中定义注释,然而,不同于 HTML 注释,Blade 注释并不会包含到 HTML 中被返回:
{{-- This comment will not be present in the rendered HTML --}}
PHP
在一些场景中,嵌入 PHP 代码到视图中很有用,你可以使用 @php 指令在模板中执行一段原生 PHP 代码:
@php
# code
@endphp
【尽管 Blade 提供了这个特性,如果过于频繁地使用它意味着你在视图模板中嵌入了过多的业务逻辑,需要注意。】
引入子视图
你可以使用 Blade 的 @include 命令来引入一个已存在的视图,所有在父视图的可用变量在被引入的视图中都是可用的。
@include('shared.errors')
十二、数据库操作
※ 建议性规范
1. 所有的数据模型文件,都 必须 存放在:app/Models/ 文件夹中。
命名空间: namespace App\Models;
2. 所有的 Eloquent 数据模型 都 必须 继承统一的基类 App/Models/Model
此基类存放位置为 /app/Models/Model.php
3. 数据模型相关的命名规范:
数据模型类名 必须 为「单数」, 如:App\Models\Photo
类文件名 必须 为「单数」,如:app/Models/Photo.php
数据库表名字 必须 为「复数」,多个单词情况下使用「Snake Case」 如:photos, my_photos
数据库表迁移名字 必须 为「复数」,如:2014_08_08_234417_create_photos_table.php
数据填充文件名 必须 为「复数」,如:PhotosTableSeeder.php
数据库字段名 必须 为「Snake Case」,如:view_count, is_vip
数据库表主键 必须 为「id」
数据库表外键 必须 为「resource_id」,如:user_id, post_id
数据模型变量 必须 为「resource_id」,如:$user_id, $post_id
4. 绝不 使用 Repository,因为我们不是在写 JAVA 代码,太多封装就成了「过度设计(Over Designed)」,极大降低了编码愉悦感,使用 MVC 够傻够简单。
5. 关于 SQL 文件
绝不 使用命令行或者 PHPMyAdmin 直接创建索引或表。必须 使用 数据库迁移 去创建表结构,并提交版本控制器中;
绝不 为了共享对数据库更改就直接导出 SQL,所有修改都 必须 使用 数据库迁移 ,并提交版本控制器中;
绝不 直接向数据库手动写入伪造的测试数据。必须 使用 数据填充 来插入假数据,并提交版本控制器中。
6. 全局作用域
Laravel 的 Model 全局作用域 允许我们为给定模型的所有查询添加默认的条件约束。
所有的全局作用域都 必须 统一使用 闭包定义全局作用域
传统
12.1.1 简介
Eloquent ORM
12.2.1 简介
Laravel 内置的 Eloquent ORM 提供了一个美观、简单的与数据库打交道的 ActiveRecord 实现,每张数据表都对应一个与该表进行交互的模型(Model),通过模型类,你可以对数据表进行查询、插入、更新、删除等操作。
12.2.2 创建模型
创建:artisan命令
php artisan make:model [Models/]User [-m|--migration]
【laravel 没有提供Models目录,所以在创建模型的时候,顺带着把Models目录也创建了】
【如果想要在生成模型时生成数据库迁移,可在命令后台带上 --migration 或 -m】
Eloquent 模型约定
1. 表名:
Eloquent 默认规则是小写的模型类名复数格式作为与其对应的表名
【除非在模型类中明确指定了其它名称:protected $table = '自定义数据表名';】
2. 主键:
Eloquent 默认每张表的主键名为 id
【如果不是,你可以在模型类中定义一个 $primaryKey 属性来覆盖该约定:protected $primaryKey = '主键名';】
3. 时间戳:
Eloquent 默认 '字段' created_at 和 updated_at 已经存在于数据表中。
【如果你不想要这些 Laravel 自动管理的数据列,在模型类中设置 $timestamps 属性为 false:public $timestamps = false;】
4. 数据库连接:
默认情况下,所有的 Eloquent 模型使用应用配置中的默认数据库连接
【如果你想要为模型指定不同的连接,可以通过 $connection 属性来设置:protected $connection = 'connection-name';】
12.2.3
十四、单元测试
(待更新...)
十五、异常处理 & 错误日志
(待更新...)
十六、引入自定义类或扩展
我们在开发项目中,常常会用到自定义的类文件或扩展文件,例如阿里云短信服务、语音服务,websocket消息推送,信鸽推送restfulAPI接口类文件,自定义的支付接口类文件等等。这些自定义类或扩展,在项目中需要有一个固定的地方来存放他们,下面我们就来设置文件的存放位置。
第一步:创建文件夹
创建自定义或第三方相关扩展的文件夹:
在 app 目录下自定义一个名为 Extend 的文件夹【文件夹命名随自己喜好,非特定命名约束】
创建爱你自定义类的文件夹:
在 app 目录下自定义一个名为 Service 的文件夹【文件夹命名随自己喜好,非特定命名约束】
第二步:在 composer.json 文件中追加自动加载文件
一般在 composer.json 文件下的第 40 行上下 ,会存在:
"autoload": {
"psr-4": {
"App\\": "app/"
},
"files": [
"app/Common/common.php"
],
"classmap": [
"database/seeds",
"database/factories",
"app/Extend", // 这里表示要自动加载自定义或第三方相关扩展文件夹
"app/Service" // 这里表示要自动加载自定义类的文件夹
]
},
第三步:执行 composer dump 命令,重新加载整个项目
在项目根目录下,执行 composer dump 即可。
第四步:在相关控制器或模型下,引入即可使用
延伸:卸载同样也很简单,将创建的时候步骤重推一下即可
1. 删除相关文件夹
2. 删除 composer.json 文件下的相关自动加载
3. 执行 composer dump 命令用来生成自动加载文件
4. 结束
附录1:Artisan工具
Artisan 是 Laravel 中自带的命令行工具的名称。它提供了一些对您的应用开发有帮助的命令。它是由强大的 Symfony Console 组件驱动的。为了查看所有可用的 Artisan 的命令,您可以使用 list 命令来列出它们:
php artisan list
在项目开发中,常见的命令:
利用artisan工具创建控制器:php artisan make:controller [模块名/]控制器名
eg. php artisan make:controller IndexController
eg. php artisan make:controller Home/IndexController
利用artisan工具创建模块:php artisan make:model [模块定义的目录/]模块名
eg. php artisan make:model Test
eg. php artisan make:model Models/Test
// laravel默认是没有models目录的,所以官方推荐,将Models目录存放在app目录下
利用artisan工具创建中间件:php artisan make:middleware TestMiddleware
利用artisan工具查看路由:php artisan route:list
其他常用命令:
php artisan: // 显示详细的命令行帮助信息,同 php artisan list
php artisan –help: // 显示帮助命令的使用格式,同 php artisan help
php artisan –version: // 显示当前使用的 Laravel 版本
php artisan changes: // 列出当前版本相对于上一版本的主要变化
php artisan down: // 将站点设为维护状态
php artisan up: // 将站点设回可访问状态
php artisan optimize: // 优化应用程序性能,生成自动加载文件,且产生聚合编译文件 bootstrap/compiled.php
php artisan dump-autoload: // 重新生成框架的自动加载文件,相当于 optimize 的再操作
php artisan clear-compiled: // 清除编译生成的文件,相当于 optimize 的反操作
php artisan migrate: // 执行数据迁移
php artisan routes: // 列出当前应用全部的路由规则,同 php artisan routes list
php artisan serve: // 使用 PHP 内置的开发服务器启动应用 【要求 PHP 版本在 5.4 或以上】
php artisan tinker: // 进入与当前应用环境绑定的 REPL 环境,相当于 Rails 框架的 rails console 命令
php artisan cache:clear: // 清除应用程序缓存
php artisan command:make 命令名://在 app/commands 目录下生成一个名为 命令名.php 的自定义命令文件
php artisan db:seed: // 对数据库填充种子数据,以用于测试
php artisan key:generate: // 生成一个随机的 key,并自动更新到 app/config/app.ph 的 key 键值对
php artisan migrate:install: // 初始化迁移数据表
php artisan migrate:make 迁移名://这将在 app/database/migrations 目录下生成一个名为 时间+迁移名.php 的数据迁移文件,并自动执行一次 php artisan dump-autoload 命令
php artisan migrate:refresh: // 重置并重新执行所有的数据迁移
php artisan migrate:reset: // 回滚所有的数据迁移
php artisan migrate:rollback: // 回滚最近一次数据迁移
php artisan session:table: // 生成一个用于 session 的数据迁移文件
附录2:Laravel 安全实践
没有绝对安全,只有相对安全。Laravel 相较于其他框架在安全方面已经做得很优秀,不过作为开发者,我们要在日常开发中对『安全』需怀着敬畏之心,积极培养自己的安全意识。以下是一些 Laravel 安全相关的规范。
关闭 DEBUG
Laravel Debug 开启时,会暴露很多能被黑客利用的服务器信息,所以,生产环境下请 必须 确保 APP_DEBUG=false
跨站脚本攻击(XSS)
1. 跨站脚本攻击(cross-site scripting,简称 XSS),具体危害体现在黑客能控制你网站页面,包括使用 JS 盗取 Cookie 等,关于 XSS 的介绍请前往 IBM 文档库:跨站点脚本攻击深入解析 。
2. 默认情况下,在无法保证用户提交内容是 100% 安全的情况下,必须 使用 Blade 模板引擎的 {{ $content }} 语法会对用户内容进行转义。
3. Blade 的 {!! $content !!} 语法会直接对内容进行 非转义 输出,使用此语法时,必须 使用 HTMLPurifier for Laravel 5 来为用户输入内容进行过滤。使用方法参见: 使用 HTMLPurifier 来解决 Laravel 5 中的 XSS 跨站脚本攻击安全问题
SQL 注入
1. Laravel 的 查询构造器 和 Eloquent 是基于 PHP 的 PDO,PDO 使用 prepared 来准备查询语句,保障了安全性。
2. 在使用 raw() 来编写复杂查询语句时,必须 使用数据绑定(占位符)。
跨站请求伪造(CSRF)
1. CSRF 跨站请求伪造是 Web 应用中最常见的安全威胁之一,Laravel 默认对所有『非幂等的请求』强制使用 VerifyCsrfToken 中间件防护,需要开发者做的,是区分清楚什么时候该使用『非幂等的请求』。
※ 幂等请求指的是:'HEAD', 'GET', 'OPTIONS',既无论你执行多少次重复的操作都不会给资源造成变更。
2. 所有删除的动作,必须 使用 DELETE 作为请求方法;
3. 所有对数据更新的动作,必须 使用 POST、PUT 或者 PATCH 请求方法。
附录3:Laravel 程序优化
作为优秀的开发者,在日常编码中,应积极培养书写高执行效率代码的意识。不过项目运行效率是一个系统性工程,不应该只停留在代码层面上,有时更应该考虑整个项目架构,包括项目中使用的软件等。
本文罗列了一些常见的优化项目,并且对其做了约束。
配置信息缓存
1. 生产环境中的 应该 使用『配置信息缓存』来加速 Laravel 配置信息的读取。
2. 使用以下 Artisan 自带命令,把 config 文件夹里所有配置信息合并到一个文件里,减少运行时文件的载入数量:
执行命令: php artisan config:cache
3. 可以使用以下命令来取消配置信息缓存:
执行命令: php artisan config:clear
4. 注释:
a). 缓存文件存放在 bootstrap/cache/ 文件夹中。
b). 配置信息缓存不会随着更新而自动重载,所以,开发时候建议关闭配置信息缓存,一般在生产环境中使用。可以配合 Envoy 任务运行器 使用,在每次上线代码时执行 config:clear 命令
路由缓存
1. 生产环境中的 应该 使用『路由缓存』来加速 Laravel 的路由注册。
2. 路由缓存可以有效的提高路由器的注册效率,在大型应用程序中效果越加明显,可以使用以下命令:
执行命令: php artisan route:cache
3. 可以使用下面命令清除路由缓存:
执行命令: php artisan route:clear
4. 注释:
a). 缓存文件存放在 bootstrap/cache/ 文件夹中。另外,路由缓存不支持路由匿名函数编写逻辑
b). 路由缓存不会随着更新而自动重载,所以,开发时候建议关闭路由缓存,一般在生产环境中使用。可以配合 Envoy 任务运行器 使用,在每次上线代码时执行 route:clear 命令
类映射加载优化
1. optimize 命令把常用加载的类合并到一个文件里,通过减少文件的加载,来提高运行效率。
2. 生产环境中的 应该 使用 optimize 命令来优化类的加载速度:
执行命令: php artisan optimize --force
3. 要清除类映射加载优化,请运行以下命令:
执行命令: php artisan clear-compiled
4. 注释:
a). 以上命令会在 bootstrap/cache/ 文件夹中生成缓存文件。你可以通过修改 config/compile.php 文件来添加要合并的类。在 production 环境中,参数 --force 不需要指定,文件就会自动生成。
b). 此命令要运行在 php artisan config:cache 后,因为 optimize 命令是根据配置信息(如:config/app.php 文件的 providers 数组)来生成文件的。
自动加载优化
1. 此命令不止针对于 Laravel 程序,适用于所有使用 composer 来构建的程序。此命令会把 PSR-0 和 PSR-4 转换为一个类映射表,来提高类的加载速度。
执行命令: composer dumpautoload -o
2. 注意:
php artisan optimize --force 命令里已经做了这个操作。
使用 Memcached 来存储会话
1. 每一个 Laravel 的请求,都会产生会话,修改会话的存储方式能有效提高程序效率。会话的配置文件是 config/session.php。
2. 生产环境中的 必须 使用 Memcached 或者 Redis 等专业的缓存软件来存储会话,应该 优先选择 Memcached:
配置项参数: 'driver' => 'memcached',
使用专业缓存驱动器
1. 「缓存」是提高应用程序运行效率的法宝之一,Laravel 默认缓存驱动是 file 文件缓存。
2. 生产环境中的 必须 使用专业的缓存系统,如 Redis 或者 Memcached。应该 优先考虑 Redis。应该 避免使用数据库缓存。
配置项参数: 'default' => 'redis',
数据库请求优化
关联模型数据读取时 必须 使用 延迟预加载 和 预加载 。
临近上线时 必须 使用 Laravel Debugbar 或者 Clockwork 留意每一个页面的总 SQL 请求条数,进行数据库请求调优。
为数据集书写缓存逻辑
应该 合理的使用 Laravel 提供的缓存层操作,把从数据库里面拿出来的数据集合进行缓存,减少数据库的压力,运行在内存上的专业缓存软件对数据的读取也远远快于数据库。
使用即时编译器
可以 使用 OpCache 进行优化。OpCache 都能轻轻松松的让你的应用程序在不用做任何修改的情况下,直接提高 50% 或者更高的性能。
前端资源合并
1. 作为优化的标准:
一个页面 应该 只加载一个 CSS 文件;
一个页面 应该 只加载一个 JS 文件。
2. 另外,为了文件要能方便走 CDN,需要文件名 应该 随着修改而变化。