前言
laravel是目前最火的php框架,之前用过thinkphp3.2和thinkphp5.1,最近接触laravel
我这里使用的laravel版本是5.6
最新文档请参考:https://github.com/johncxf/Documents/blob/master/Manual/laravel.md
安装
环境要求
官方文档给的环境要求**
- PHP> = 7.1.3
- OpenSSL PHP扩展
- PDO PHP扩展
- Mbstring PHP扩展
- Tokenizer PHP扩展
- XML PHP扩展
- Ctype PHP扩展
- JSON PHP扩展
composer安装
需要先在自己电脑安装composer,网上有许多教程。国外镜像较慢,可以安装国内镜像
在站点安装laravel,可以指定版本安装,如下blog是项目别名,可以自己设置,后面版本不加则安装默认版本
composer create-project --prefer-dist laravel/laravel blog "5.6.*"
安装语言包
composer安装语言包
composer require caouecs/laravel-lang:~3.0
安装完成可以在/vendor
目录中多了caouecs
目录
在/vendor/caouecs/src
中复制需要的语言包目录到/resources/lang
目录中
修改/config/app.php
中的'locale' => 'en'
locale' => 'en' 改成 locale' => 'zh-CN'
目录结构
开始学习框架第一步应该先了解他的目录结构,接下来学习起来才能得心应手
以下是laravel的目录结构,app下的部分目录是我后期生成的,初始安装不自带
| app 应用程序目录
| | Console 控制台目录
| | Http Http目录
| | Providers 服务目录
| | Exceptions 异常处理
| | Mail 邮件目录
| | Notifications 通知目录
| | Providers 策略目录
| bootstrap Bootstrap目录
| | cache 服务缓存文件
| | app.php 路由文件
| config 配置目录
| database 数据库目录
| | factories 工厂类
| | migrations 数据迁移文件
| | seeds
| public 公共目录
| | css css文件
| | js js文件
| resources 资源目录
| | assets
| | lang
| | views 视图文件
| routes 路由目录
| storage 存储目录
| tests 测试目录
| vendor 供应商目录
| .env 全局配置文件
| .env.example 配置文件样例
| .gitattributes指定费文本文件的对比合并方式
| .gitignore git忽略文件
| _ide_helper.php
| artisan 控制文件
| composer.json composer依赖文件
| composer.lock composer锁定文件
| package.json 依赖文件
| package-lock.json
| phpunit.xml
| readme.md 说明文档
| server.php 服务文件
| webpack.mix.js资源编译文件
以下是安装laravel的初始目录截图,node_modules是composer安装的前端文件
快速创建文件
模型
php artisan make:model Blog
控制器
//创建控制器
php artisan make:controller BlogController
//资源控制器
php artisan make:controller --resource BlogController
//资源控制器并指定模型
php artisan make:controller --resource --model=Blog BlogController
路由
基本路由
路由存放在routes
目录中,以下是基本路由
Route::get('foo', function () {
return 'Hello World';
});
可用路由方法
路由器允许您注册响应任何HTTP动词的路由:
Route::get($uri, $callback);
Route::post($uri, $callback);
Route::put($uri, $callback);
Route::patch($uri, $callback);
Route::delete($uri, $callback);
Route::options($uri, $callback);
时您可能需要注册响应多个HTTP谓词的路由。您可以使用该match
方法执行此操作。或者,您甚至可以使用以下any
方法注册响应所有HTTP谓词的路由:
Route::match(['get', 'post'], '/', function () {
//
});
Route::any('foo', function () {
//
});
重定向路由
如果要定义重定向到另一个URI的路由,则可以使用该方法。此方法提供了方便的快捷方式,因此您无需为执行简单重定向定义完整路由或控制器:Route::redirect
Route::redirect('/here', '/there', 301);
路由别名
使用name()
方法
Route::get('/home', 'TestController@home')->name('home');
路由参数
比如我们定义下面的路由规则,其中 {user} 和 {name} 为路由中的参数变量
Route::get('/user/{user}/{name}','UserController@show')->name('user.show');
视图
视图文件存放在resources/views
中
模型
默认生成的模型通常放在 app
目录中,可以直接使用artisan命令创建
php artisan make:model Article
数据表命名
可以通过在模型上定义 table
属性,来指定自定义数据表。如果不指定时使用模型名加s,如Article 对应表名为articles
protected $table = 'articles';
时间戳
默认情况下,Eloquent 会默认数据表中存在 created_at
和 updated_at
这两个字段。如果你不需要这两个字段,则需要在模型内将 $timestamps
属性设置为 false
:
//该模型是否被自动维护时间戳
public $timestamps = false;
模型事件
Eloquent 的模型触发了几个事件,可以在模型的生命周期的以下几点进行监控: retrieved
、creating
、created
、updating
、updated
、saving
、saved
、deleting
、deleted
、restoring
、restored
。事件能在每次在数据库中保存或更新特定模型类时轻松地执行代码。
如果要给某个模型监听很多事件,则可以使用观察器将所有监听器分组到一个类中。观察器类里的方法名应该对应 Eloquent 中你想监听的事件。 每种方法接收 model 作为其唯一的参数。Laravel 没有为观察器设置默认的目录,所以你可以创建任何你喜欢你的目录来存放:
定义事件
下面是User模型的观察器
<?php namespace app\Observers;
use App\User;
class UserObserver{
public function creating(User $user){
$user->active_token = str_random(20);
}
public function saving(User $user){}
}
声明事件
在AppServiceProvicer服务提供者的 boot
方法执行以下代码
User::observe(UserObserver::class);
或者在模型中定义
namespace App;
use App\Observers\UserServer;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
...
protected static function boot()
{
parent::boot();
User::observe(UserServer::class);
}
}
控制器
存放在app/Http/Controllers
目录中
定义控制器
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* @param int $id
* @return Response
*/
public function show($id)
{
return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
您可以定义到此控制器操作的路由,如下所示:
Route::get('user/{id}', 'UserController@show');
资源控制器
Laravel 遵从 RESTful 架构的设计原则,将数据看做一个资源。Laravel 资源路由将典型的「CRUD」路由分配给具有单行代码的控制器。
使用 Artisan 命令 make:controller
来快速创建控制器:
php artisan make:controller ArticleController --resource
接下来,你可以给控制器注册一个资源路由:
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
选项:
php artisan make:controller PhotoController --resource --model=Photo
伪造表单方法
因为 HTML 表单不能生成 PUT
、 PATCH
或者 DELETE
请求,所以你需要添加一个隐藏的 _method
输入字段来伪造这些 HTTP 动作。辅助函数 method_field
可以帮你创建这个字段:
@method('DELETE')
分页
控制器中
$users = User::paginate(10);
模板中显示分页列表
$users->links();
分页时传递GET参数
$users->appends(Request::except('page'))->links()
策略
创建策略文件
artisan make:policy --model=User UserPolicy
在新建策略文件中对应的方法中编写策略
在App\Providers\AuthServiceProvider
中注册
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
'App\User' => UserPolicy::class,
'App\Blog' => BlogPolicy::class,
];
表单
表单函数
csrf
laravel (跨站请求伪造),Laravel 为了安全考虑,会让我们提供一个 token(令牌)来防止我们的应用受到CSRF(跨站请求伪造)的攻击。放置在表单(form)体内。
<form method="POST" action="/profile">
@csrf
...
</form>
old
old
函数获取一次性存放在session中的值,用在表单的value属性中。这样当我们输出错误回调页面时,原来输入的值还存在。
<input type="text" class="form-control" name="name" value={{old('name')}}>
表单验证
下面是控制器中的 store 方法
public function store(Request $request)
{
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
// 文章内容是符合规则的,存入数据库
}
常用规则
规则 | 说明说明 | 示例 |
---|---|---|
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 ,也可以理解为有值时才验证。 |
$request->validate([
'title' => 'required|unique:posts|max:255',
'body' => 'required',
'publish_at' => 'nullable|date',
]);
在这个例子里,我们指定 publish_at
字段可以为 null
或者一个有效的日期格式。如果 nullable
的修饰词没有被添加到规则定义中,验证器会认为 null
是一个无效的日期格式。
更多验证规则使用时请查阅手册 https://laravel.com/docs/5.6/validation
显示验证错误
如果表单验证失败,laravel会向分配错误信息到 $errors
中,那么我们就可在模板中使用以下代码展示验证错误。
@if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
表单请求验证
面对更复杂的验证情境中,你可以创建一个「表单请求」来处理更为复杂的逻辑
php artisan make:request StoreBlogRequest
新生成的类保存在 app/Http/Requests
目录下。
<?php namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserRequest extends FormRequest
{
//权限验证
public function authorize()
{
return true;
}
//验证规则
public function rules()
{
return [
'name'=>'required|max:20',
'email'=>'required|email|unique:users|max:255',
'password'=>'required|confirmed|min:5',
];
}
//提示信息
public function messages()
{
return [
'name.required' => '名称不能为空',
'email.required' => '邮箱不能为空',
];
}
}
在控制器的方法中依赖注入就可以使用了
public function store(UserRequest $request){
}
重定向
redirect
函数返回一个 HTTP 重定向响应,如果调用时没有传入参数则返回 redirector 实例:
return redirect('/home');
return redirect()->route('route.name');
传递路由参数
$user = User::first()
return redirect()->route('user.show',[$user]);
假设路由规则为 Route::get('user/show/{user}')
,上例中的[$user]
会自动提出 $user模型对象的主键做为路由参数。
数据填充
普通方式
phpstorm使用命令输入artisan make:seeder UserSeeder
就会在database/seeds/
下生成UserSeeder.php
然后在DatabaseSeeder
注册
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(userSeeder::class);
}
在UserSeeder.php
写入
public function run()
{
\App\User::create([
'name' => 'cxf',
'email' => 'cxf@qq.com',
'password' => bcrypt('admin')
]);
}
命令执行
artisan db:seed
模型工厂
在database/factories/
中自带的UserFactory.php
命令运行
artisan tinker
输入指令生成数据(数据表数据没有生成,只是展示测试)
factory(App\User::class,20)->make()
生成数据
factory(App\User::class,20)->create()
调用模型工程
新建seeder文件,在database\seeds
中
php artisan make:seeder BlogSeeder
写入创建数量
public function run()
{
factory(\App\Blog::class, 200)->create();
}
在database\seeds\DatabaseSeeder.php
中调用
public function run()
{
// $this->call(UsersTableSeeder::class);
$this->call(userSeeder::class);
$this->call(BlogSeeder::class);
}
执行重置
php artisan migrate:refresh --seed
消息通知
创建通知
php artisan make:notification FindPasswordNotify
这个命令会在 app/Notifications
目录下生成一个新的通知类。
数据库通知
database
通知渠道在一张数据库表里存储通知信息。该表以自定义的 JSON 格式,存储如通知类型等描述通知的信息。需要先创建一个数据库表来存放这些通知。
php artisan notifications:table
php artisan migrate
修改通知类的 via
方法为数据库通知
public function via($notifiable)
{
return ['database'];
}
然后定义 toArray
方法返回用于储存到数据表中的通知数据。
存取通知
Laravel 的默认模型 App\User
已经引入了 Trait Illuminate\Notifications\Notifiable
,它包含了一个 Eloquet 关系 notifications
,可以为实体返回通知。
$user = App\User::find(1);
foreach ($user->notifications as $notification) {
echo $notification->type;
}
如果你仅仅想检索所有「未读」通知,你需要使用 unreadNotifications
关系。
$user = App\User::find(1);
foreach ($user->unreadNotifications as $notification) {
echo $notification->type;
}
通知标记已读
$user = App\User::find(1);
foreach ($user->unreadNotifications as $notification) {
$notification->markAsRead();
}
你可以直接使用 markAsRead
方法操作一个通知集合,而不是遍历处理每个通知:
$user->unreadNotifications->markAsRead();
邮件通知
修改通知类中的 toMail
与 __construct
方法
public function __construct($token)
{
$this->token=$token;
}
public function toMail($notifiable)
{
return (new MailMessage)
->subject('验证邮箱')
->greeting(config('app.name'))->line('点击下面的链接重设密码')
->action('重置密码',url(route('password.change', $this->token)))
->line('感谢使用后盾人');
}
自定义模板
你可以通过发布通知包的资源来修改 HTML 模板和纯文本模板。运行这个命令后,邮件通知模板就被放在了 resources/views/vendor/notifications
文件夹下:
php artisan vendor:publish --tag=laravel-notifications
发送通知
使用 Notifiable Trait
通知可以通过两种方法发送: Notifiable
trait 的notify
方法或 Notification
facade。首先,让我们探索使用 trait :
<?php namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
}
默认的 App\User
模型中使用了这个 trait,它包含着一个可以用来发通知的方法:notify
。 notify
方法需要一个通知实例做参数:
use App\Notifications\InvoicePaid;
$user->notify(new InvoicePaid($invoice));
使用 Notification Facade
另外,你可以通过 Notification
facade
来发送通知。它主要用在当你给多个可接收通知的实体发送通知的时候,比如给用户集合发通知。要用 facade 发送通知的话,要把可接收通知的实体和通知的实例传递给 send
方法:
Notification::send($users, new InvoicePaid($invoice));
队列化通知
发送通知可能很耗时,尤其是是当频道需要一个额外的 API 来发送通知。要加速你的应用响应时间,让你的通知继承 ShouldQueue
接口 并且在你的类中添加 Queueable
trait。这些接口和 trait 已经被使用 make:notification
生成的所有通知引入了,所以你可以直接将他们添加到你的通知类:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
class InvoicePaid extends Notification implements ShouldQueue
{
use Queueable;
// ...
}
做好一上操作并正常配置好队列后,系统将自动使用异步队列发送通知。
。。。