• TOC
    {:toc}

5.2 中间件

5.2.1 简介

laravel中间件提供一个方便的机制来过滤进入web应用的HTTP请求。

例如,laravel内置一个中间件来验证用户是否经过授权,如果用户没有经过授权,中间件会将用户重定向到登陆页面,否则如果用户经过授权,中间件就会允许请求继续往前进行下一步操作。

当然,除了认证之外,中间件还可以用来处理更多任务。

例如:CORS中间件可以为离开站点的响应添加合适的头,日记中间件可以记录所有进入站点的请求。

laravel框架自带了一些中间件,包括维护模式、认证、CSRF等等。所有的中间件都位于App/Http/Middleware目录中。


5.2.2 定义中间件

可以使用Artisan命令make:middleware创建一个新的中间件

php artisan make:middleware OldMiddleware

其中的OldMiddleware可以为任意名称。

命令会下app/Http/Middleware目录下创建一个新的中间件OldMiddlware,在这个中间件中,设定只允许age大于200的才能访问路由,否则,将用户重新定向到主页:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

namespace App\Http\Middleware;

use Closure;

class OldMiddleware
{
/**
* 返回请求过滤器
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->input('age') <= 200) {
return redirect('home');
}

return $next($request);
}

}

如果age<=200,中间件会返回一个HTTP重定向到客户端;否则,请求会被传统下去。将请求往下传递可以通过调用回调函数$next并传入$request

理解中间件最好的方式是将中间件看做HTTP请求,到达目标动作之前必须经过的,每一层都会检查请求并且可以完全拒绝它。

5.2.2.1 中间件之前/之后

一个中间件,在请求前执行还是请求后执行取决于中间件本身。

比如,下方中间件会在请求处理前执行一些任务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php

namespace App\Http\Middleware;

use Closure;

class OldMiddleware
{
/**
* 返回请求过滤器
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->input('age') <= 200) {
return redirect('home');
}

return $next($request);
}

}

下方中间件会在请求处理后执行任务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace App\Http\Middleware;

use Closure;

class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);

// 执行动作

return $response;
}
}

5.2.3 注册中间件

5.2.3.1 全局中间件

如果想要中间件放在每个HTTP请求期间被执行,只需要将相应的中间件类,设置到app/Http/Kernel.php$middleware属性中。

5.2.3.2 为路由指派中间件

如果想要分配中间件到指定路由,先要在app/Http/Kernel.php文件中分配给中间件一个简写的key,默认情况下,该类的$routeMiddleware属性包含了laravel内置的入口中间件,添加自己的中间件只需要将其追加到后面并为其分配一个key:

1
2
3
4
5
6
7
// 在 App\Http\Kernel 里中
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];

中间件在 HTTP Kernel 中被定义后,可以在路由选项数组中使用 $middleware 键来指定该中间件:

1
2
3
4
Route::get('admin/profile', ['middleware' => 'auth', function () {
//
}]);

使用数组分配多个中间件到路由,使用数组方式排列:

1
2
3
Route::get('/', ['middleware' => ['first', 'second'], function () {
//
}]);

处理使用数组外,还可以使用middleware方法链方式定义路由:

1
2
3
Route::get('/', function () {
//
})->middleware(['first', 'second']);

5.2.3.3 中间件群组

有时你可能想将多个中间件组成单一的键,让它可以简单的指派给路由。

这可以通过使用HTTP的$middlewareGroups实现。

laravel自带了webapi两个中间件组,包含可以应用到webUI和API路由的通用中间件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 应用的路由中间件组
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],

'api' => [
'throttle:60,1',
'auth:api',
],
];

中间件组可以被分配给路由和控制器动作,使用方法与单个中间件相同。

注意:中间件组只是让指派多个中间件变得简单

1
2
3
Route::group(['middleware' => ['web']], function () {
//
});

5.2.4 中间件参数

中间件还可以接收额外的自定义参数。

例如,应用要先检查使用者是否有权限,后执行特定的操作。

可以建立RoleMiddleware来接收使用者名称作为额外的参数。

额外的中间件参数会在$next参数之后传入中间件:

注意:下方代价中指 Closure $next

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php

namespace App\Http\Middleware;

use Closure;

class RoleMiddleware
{
/**
* 运行请求过滤器
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string $role
* @return mixed
* translator http://laravelacademy.org
*/
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// Redirect...
}

return $next($request);
}

}

中间件参数可以在定义路由时通过:分隔中间件名和参数名来指定,多个中间件参数可以通过,分隔:

1
2
3
Route::put('post/{id}', ['middleware' => 'role:editor', function ($id) {
//
}]);

5.2.5 可终止的中间件

有时中间件需要在HTTP响应发送到浏览器后做一些工作。

例如,让Session中间件在响应发送到浏览器后,将Session中的数据写到存储器中。

为了实现这个,定义一个终止中间件,并在其中使用terminable方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

namespace Illuminate\Session\Middleware;

use Closure;

class StartSession
{
public function handle($request, Closure $next)
{
return $next($request);
}

public function terminate($request, $response)
{
// Store the session data...
}
}

这个terminate方法要接受$request$response。一旦使用终止中间,应将其添加到Http Kernel作为全局变量使用。

当调用中间件中的terminate方法时,laravel将从服务器容器中取出这个中间件的新实例。

如果想在调用handleterminate使用同一中间件实例,需要使用container(容器)singleton方法将中间注入到容器。

这里实例可以理解为数据包。

  • TOC
    {:toc}

5 基本功能

5.1 路由

5.1.1 基本路由

laravel所有的路由都可以定义在App/Http/routes.php文件,它会被App/Providers/RouteServiceProvider类载入。

下方是一个最基本的getpostget接收URL,post为一个闭包。

1
2
3
4
5
6
7
Route::get('foo', function () {
return 'Hello World';
});

Route::post('foo', function () {
//
});

默认情况下,routes.php文件包含单个路由和一个套用web中间件的路由组。

这个中间件路由组提供了session状态以及CSRF保护。

一般情况下,会将全部路由放置在这个路由组。

5.1.1.1 有效的路由方法

注册路由来响应任何HTTP请求:

下方是HTTP请求方法:

1
2
3
4
5
6
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请求:

1
2
3
4
5
6
7
Route::match(['get', 'post'], '/', function () {
//
});

Route::any('foo', function () {
//
});

当路由过多时,使用控制器是个好方法。


5.1.2 路由参数

5.1.2.1 基础路由参数

有时可能需要在路由中捕获URL片段。比如,要从URL中捕获用户ID,需要通过下方代码定义路由参数:

1
2
3
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});

可以按照需要在路由中定义多个路由参数:

1
2
3
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
//
});

路由参数总是通过{ }进行包裹,这些参数在路由被执行时会被传递到路由的闭包。

注意:路由参数不能包含-,要使用_替换。

5.1.2.2 选择性路由参数

有时候可能需要指定可选的路由参数,这可以通过在参数后加?标记来实现,这种情况下需要指定变量的默认值:

下方代码先设定name可以为空,再设定默认name为John

1
2
3
4
5
6
7
Route::get('user/{name?}', function ($name = null) {
return $name;
});

Route::get('user/{name?}', function ($name = 'John') {
return $name;
});

5.1.2.3 正则约束

路由设置中可以使用where方法来约束路由参数。where方法接收参数名和一个正则表达式来定义参数如何被约束:

1
2
3
4
5
6
7
8
9
10
11
Route::get('user/{name}', function ($name) {
//
})->where('name', '[A-Za-z]+');

Route::get('user/{id}', function ($id) {
//
})->where('id', '[0-9]+');

Route::get('user/{id}/{name}', function ($id, $name) {
//
})->where(['id' => '[0-9]+', 'name' => '[a-z]+']);

5.1.2.4 全局约束

如果想要全局约束,可以使用pattern方法。在RouteServiceProvider类的boot方式中定义约束:

1
2
3
4
5
6
7
8
9
10
11
/**
* 定义路由模型绑定,模式过滤器等
*
* @param \Illuminate\Routing\Router $router
* @return void
* @translator http://laravelacademy.org
*/
public function boot(Router $router){
$router->pattern('id', '[0-9]+');
parent::boot($router);
}

一旦模式被定义,将会自动应用到所有包含参数名的路由中:

1
2
3
Route::get('user/{id}', function ($id) {
// 只有当 {id} 是数字时才会被调用
});

上方例子中限定id只能是数字。


5.1.3 命令路由

命令路由为生成URL或重新定向提供方便。在定义路由是使用as指定路由名称:

1
2
3
Route::get('user/profile', ['as' => 'profile', function () {
//
}]);

此外,还可以为控制器动作指定路由名称:

1
2
3
Route::get('user/profile', [
'as' => 'profile', 'uses' => 'UserController@showProfile'
]);

还有另一种,路由命名的方法,比如使用name方式来实现:

1
2
3
Route::get('user/profile',function () {
//
})->name('profile');

5.1.3.1 路由群组 & 命名路由

如果你在使用路由群组,可以通过在路由群组的属性数组中指定as关键字来为群组的路由设置一个共用的路由名前缀:

1
2
3
4
5
Route::group(['as' => 'admin::'], function () {
Route::get('dashboard', ['as' => 'dashboard', function () {
// 路由被命名为 "admin::dashboard"
}]);
});

5.1.3.2 为命名路由生成URL

如果为给定路由进行了命名,就可以通过全局route函数为该命名路由生成对应URL,或者重新定向:

1
2
$url = route('profile');		//产生URL
$redirect = redirect()->route('profile'); //重新定向

如果命名路由定义了参数,可以将该参数作为第二个参数穿传递给route函数。路由参数会自动插入URL中。

1
2
3
4
Route::get('user/{id}/profile', ['as' => 'profile', function ($id) {
//
}]);
$url = route('profile', ['id' => 1]);

5.1.4 路由群组

路由组允许共享路由属性,比如中间件与命名空间等。这样利用路由群组套用这些属性到多个路由,而不需要在每个路由都设定一次。

共享属性被要求为数组格式。共享属性作为第一个参数被传递给Route::group方法。

5.1.4.1 中间件

要给路由组中所有路由分配中间件,可以在群组属性中使用middleware。中间件将会按照数组中定义的顺序依次执行:

1
2
3
4
5
6
7
8
9
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// 使用 Auth 中间件
});

Route::get('user/profile', function () {
// 使用 Auth 中间件
});
});

5.1.4.2 命名空间

另一个例子,指定相同的PHP命名空间下多个控制器,可以在分组属性数组中使用namespace来指定群组中所有控制器的公共命名空间:

1
2
3
4
5
6
7
Route::group(['namespace' => 'Admin'], function(){
// 控制器在 "App\Http\Controllers\Admin" 命名空间下

Route::group(['namespace' => 'User'], function(){
// 控制器在 "App\Http\Controllers\Admin\User" 命名空间下
});
});

默认情况下,RouteServiceProvider会在命名空间群组内导入routes.php文件,让你不用指定完整App/Http/Controllers命令空间,就能注册控制器。所有,只需要指定在App/Http/Controllers之后的命名。

5.1.4.3 子域名路由

子域名可以像URL一样被分配给路由参数,从而允许捕获子域名的部分用于路由或者控制器,子域名可以通过群组属性中的domani来指定:

1
2
3
4
5
Route::group(['domain' => '{account}.myapp.com'], function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});

注意:其中的{account}可以随意修改的。{id}也是可以随意更改的。

5.1.4.4 路由前缀

prefix群组属性,用来为群组中每个路由添加一个给定URL前缀。

例如,你可以为所有路由URL添加admin前缀:

1
2
3
4
5
Route::group(['prefix' => 'admin'], function () {
Route::get('users', function () {
// 匹配 "/admin/users" URL
});
});

还可以使用prefix参数为路由组指定公共路由参数:

1
2
3
4
5
Route::group(['prefix' => 'accounts/{account_id}'], function () {
Route::get('detail', function ($account_id) {
// 匹配 accounts/{account_id}/detail URL
});
});

5.1.5 CSRF保护

5.1.5.1 简介

CSRF指跨网站请求伪造。跨网站请求伪伪造是一种恶意攻击,透过经身份验证的使用者身份执行未经授权的命令。

laravel会自动产生一个CSRF令牌给每个被应用管理的有效的用户,该令牌用于验证授权用户和发起请求者是否为同一个人。

想要生成包含CSRF令牌的隐藏输入字段,可以使用csrf_field函数来实现:

1
<?php echo csrf_field(); ?>

csrf_field函数会生成如下HTML:

1
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

当然推荐使用Blade引擎模板提供的方式:

1
{!! csrf_field() !!}

不需要自己编写代码去验证POST、PUT或者DELETE请求的CSRF令牌,因为Laravel自带的HTTP中间件VerfyCsrfToken会完成这些工作。

只要将请求中的输入token和Session中存储的token作对比来进行验证。

5.1.5.2 不受 CSRF 保护的 URIs

有时需要从CSRF保护中排除一些URL。比如,如果使用Stripe来处理支付并用到他们的webhook系统,这时就需要从laravel的CSRF保护中排除webhook处理路由。

要实现这一目的,需要在VerifyCsrfToken中间件中将要排除的URL添加到$except属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

class VerifyCsrfToken extends BaseVerifier
{
/**
*从CSRF验证中排除的URL
*
* @var array
*/
protected $except = [
'stripe/*',
];
}

5.1.5.3 X-CSRF-Token

除了检查当前POST参数的CDSRF令牌外,在laravel的VerifyCsrfToken中介层也会确认请求头部中的X-CSRF-Token

例如,可以将其存储在meta标签中:

1
<meta name="csrf-token" content="{{ csrf_token() }}">

一旦建立了meta标签,就可以使用jQuery之类的函数库,将令牌加入到所有请求头部。

这为基于AJAX的应用提供了简单、方便的方式来避免CSRF攻击。

1
2
3
4
5
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

5.1.5.4 X-XSRF-Token

laravel还会将CSRF令牌保存到名为XSRF-TOKEN的Cookie中,可以使用该Cookie值来设置X-XSRF-TOKEN请求头。

一些javascript框架,比如Angular,会为你自动进行设置,基本上不太需要手动设置这个值。


5.1.6 路由模型绑定

laravel路由模型绑定提供了一个方便的方式来注入类至路由中。

例如,可以将匹配到ID的整个User类注入到路由中,而不是直接注入用户ID。

5.1.6.1 隐式绑定

laravel会自动解析定义在路由或控制器动作(变量名匹配路由片段)中的Eloquent模型类型声明,例如:

1
2
3
Route::get('api/users/{user}', function (App\User $user) {
return $user->email;
});

这个例子中,路由URL的user符合$user实例的ELoquent模型,所以laravel会自动注入与请求URL的ID对应的模型实例。

如果找不到对应的模型实例,会自动生成HTTP404响应。

  • 自定义键名

    如果想要隐式模型绑定,使用数据表的其他字段,可以重写Eloquent模型类的getRouteKeyName方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    /**
    * Get the route key for the model.
    *
    * @return string
    */
    public function getRouteKeyName()
    {
    return 'slug';
    }

    现在就可以使用slug作为键值了,可以用来模糊关键字

5.1.6.2 显式绑定

要注册显式绑定,需要使用路由的model方法来为给定参数指定绑定类。

必须在RouteServiceProvider::boot方法中定义模型绑定。

  • 绑定参数到模型

    1
    2
    3
    4
    5
    public function boot(Router $router)
    {
    parent::boot($router);
    $router->model('user', 'App\User');
    }

    接下来,定义一个包含user参数的路由:

    1
    2
    3
    $router->get('profile/{user}', function(App\User $user) {
    //
    });

    由于已经绑定{user}参数到App\User模型,User实例会被注入到该路由。因此,如果请求URL是profile/1,就会注入一个用户ID为1的User实例。

    如果匹配的模型实例在数据库不存在,会自动生成并返回HTTP404响应。

  • 自定义解析逻辑

    如果想要使用自定义的解析逻辑需要使用Route::bind方法,传递到bind方法的闭关会获取到URL请求的参数中的值,并返回你想要在该路由中注入的类实例:

    1
    2
    3
    $router->bind('user', function($value) {
    return App\User::where('name', $value)->first();
    });
  • 自定义”Not Found”

    如果想要指定自己的Not Found行为,将封装该行为的闭包作为第三个参数传递给model方法

    1
    2
    3
    $router->model('user', 'App\User', function() {
    throw new NotFoundHttpException;
    });

5.1.7 表单方法伪造

HTML表单不支持PUT、PATCH或者DELETE请求方法。当使用这些路由时,需要添加一个隐藏的_method字段到表单中,其值被用作该表单的HTTP请求方法:

1
2
3
4
<form action="/foo/bar" method="POST">
<input type="hidden" name="_method" value="PUT">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>

还可以使用辅助函数method_field来实现这一目的:

1
<?php echo method_field('PUT'); ?>

当然,也支持Blade模板引擎:

{method——field('PUT')}  

  • TOC
    {:toc}

4 快速入门进阶版

4.1. 安装

4.1.1 使用composer

$ composer create-project laravel/laravel quickstart --prefer-dist

4.1.2 使用git克隆完整包

$ git clone https://github.com/laravel/quickstart-intermediate quickstart
$ cd quickstart
$ composer install
$ php artisan migrate

4.2 准备数据库

4.2.1 数据迁移

需要用到users表与tasks表。

users表的已经在database/migratiions目录下。

tasks表,需要使用命令创建一个:

$ php artisan make:migration create_tasks_table --create=tasks

在生成的文件中加入

1
2
$table->integer('user_id')->index();
$table->string('name');

->index()标识增加索引。user_id用于建立tasks表与user表之间的关联。

使用下方命令导入数据库

$ php artisan migrate

4.2.2 Eloquent模型

user模型

laravel中自带了user模块。

Task模型

使用下方命令创建task模型。

$ php artisan make:model Task

Task模型中,声明name属性支持批量赋值

批量赋值:将一个数组发送到模型类用于创建新模型实例是使用。

laravel有两种批量赋值属性,一种是$fillable可以通过批量赋值进行赋值。另一种是$guarded在批量赋值时会被过滤掉。

添加到app/Task.php

protected $fillable = ['name'];

4.2.3 Eloquent关联关系

tasks关联关系

user模型中定义tasks关联关系。这里使用一对多关系,laravel的ELoquent中提供了hasMany方法。

app/user.php文件中添加:

use App\Task;

public function tasks()
{
    return $this->hasMany(Task::class);
}

user关联关系

要定义与hasMany相对的关联关系,需要在子模型中定义一个关联方法去调用belongsTo方法:

添加到app/Task.php

use App\User;

public function user()
{
    return $this->belongsTo(User::class);
}

4.3 路由

routes.php中可以使用闭包定义所有的业务逻辑。实际上,大部分应用都会使用控制器来组织路由。

4.3.1 显示视图

使用view函数从路由中返回一个模板:

1
2
3
Route::get('/', function () {
return view('welcome');
});

4.3.2 用户认证

web中用户认证工作是非常乏味的,laravel提供一个auth组件让他变得轻松。

可以直接使用Artisan指令做完成auth的创建。

$ php artisan make:auth --views

随后只需要将auth添加到路由列表。

1
Route::auth();

4.3.3 任务控制器

接下来建立TaskController控制器,来处理任务。默认情况下控制器放置在app/Http/controllers目录下。使用下方命令创建:

$ php artisan make:controller TaskController

现在添加一些对应控制器的路由,在app/Http/routes.php中添加:

1
2
3
Route::get('/tasks', 'TaskController@index');
Route::post('/task', 'TaskController@store');
Route::delete('/task/{task}', 'TaskController@destroy');

设置所有任务路由需要登录才能访问

我们希望用户必须登陆到系统才能创建新任务。所以需要限制访问用户,为登陆用户。

laravel使用中间件来处理这种限制。

1
2
3
4
public function __construct()
{
$this->middleware('auth');
}

4.4 创建布局与视图

布局方案与之前的版本相同。

4.4.1 定义布局

共用模板在resources/views/layouts/app.blade.php

@yield('content')为使用blade模板要插入的功能模块。

4.4.2 定义子视图

随后定义resources/views/tasks/index.blade.php。它会对应TaskController控制器的index方法。

随后在TaskController控制其中添加index方法的返回视图。

1
2
3
4
5
6

public function index(Request $request)
{
return view('tasks.index');
}

4.5 添加任务

4.5.1 验证表单输入

编写TaskController@store路由对应的处理方法,处理一个表单请求并创建一个新任务。

1
2
3
4
5
6
7
public function store(Request $request){
$this->validate($request, [
'name' => 'required|max:255',
]);

// Create The Task...
}

在控制器中,可以直接使用ValidatesRequests类中的validate方法。

而不用手动判断验证失败后的重定向,如果验证失败,用户会自动被重定向到来源页面,而错误信息也会存放到一次性Session中。

$errors

使用@include('common.errors')来渲染表单验证错误信息。

文件位置resources/views/common/errors.blade.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<strong>Whoops! Something went wrong!</strong>

<br><br>

<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif

4.5.2 创建任务

验证完成后,要新建一个任务。当任务新建完成,页面会跳转到/tasks

laravel的关联提供了save方法,该方法接收一个关联模型实例,并且会在保存的数据库之前自动设置外键值到关联模型上。

这里save方法会自动将当前用户的,用户ID赋予给定的user_id属性。通过$request->user()获取当前用户实例:

1
2
3
4
5
$request->user()->tasks()->create([
'name' => $request->name,
]);

return redirect('/tasks');

4.6 显示己存在的任务

现在需要编辑TaskController@index传递所有已存在任务到视图。view函数接收一个数组作为第二个参数,数组中的每个值都会在视图中作为变数。

1
2
3
4
5
6
7
8
public function index(Request $request)
{
$tasks = Task::where('user_id', $request->user()->id)->get();

return view('tasks.index', [
'tasks' => $tasks,
]);
}

4.6.1 依赖注入

laravel的服务容器是整个框架中最重要的特性。

创建Repository

正如之前说的,我们要定义一个TaskRepository来处理所有对Task模式的数据访问,随着应用的增长,需要在应用中共享一些Eloquent查询时,就变得特别有用。

创建app/Repositories目录并在其中创建一个TaskRepository类。记住,laravel项目的app文件夹下的所有目录都是使用PSR-4自动加载标准,所以可以随意创建需要的目录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

namespace App\Repositories;

use App\User;
use App\Task;

class TaskRepository{
/**
* Get all of the tasks for a given user.
*
* @param User $user
* @return Collection
*/
public function forUser(User $user)
{
return Task::where('user_id', $user->id)
->orderBy('created_at', 'asc')
->get();
}
}

注入Repository

Repository创建好之后,通过在TaskController的构造函数以类型提示的方式注入该Repository,然后就可以在index方法中使用。

由于laravel使用容器来解析所有控制器,所以依赖会被自动注入到控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php

namespace App\Http\Controllers;

use App\Task;use App\Http\Requests;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Repositories\TaskRepository;

class TaskController extends Controller{
/**
* The task repository instance.
*
* @var TaskRepository
*/
protected $tasks;

/**
* Create a new controller instance.
*
* @param TaskRepository $tasks
* @return void
*/
public function __construct(TaskRepository $tasks)
{
$this->middleware('auth');
$this->tasks = $tasks;
}

/**
* Display a list of all of the user's task.
*
* @param Request $request
* @return Response
*/
public function index(Request $request)
{
return view('tasks.index', [
'tasks' => $this->tasks->forUser($request->user()),
]);
}

4.6.2 显示任务

tasks/index.blade.php中以表格形式显示所有任务。Blade中使用@foreach处理循环数据。

4.7 删除任务

4.7.1 添加删除按钮

当一个DELETE /task请求被发送到应用,它会触发TaskController@destroy方法:

在表单中同样要使用方法欺骗。

4.7.2 路由模型绑定

定义TaskControllerdestroy方法。但是首先,重新查看路由的定义以及控制器方法。

4.7.3 用户授权

现在要将Task实例注入到destroy方法。然而为了保证当前登录用户是给定任务的用。

例如:一些恶意请求可能尝试通过传统随机任务ID到/tasks/{task}链接删除另一个用户的任务。

所有需要使用laravel的授权功能来确保,当前登录用户拥有操作Task实例的权限。

创建Policy

laravel使用策略来将授权组织到单个类中,通常,每个策略都对应一个模型。

因此,使用Artisan命令创建一个TaskPolicy,生成的文件位于app/Policies/TaskPolicy.php:

$ php artisan make:policy TaskPolicy

随后将destroy方法添加到策略中,该方法会获取一个user实例和task实例,检查用户ID和任务的user_id是否相同。

实际上,所有的策略方法都会返回truefalse:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

namespace App\Policies;

use App\User;
use App\Task;
use Illuminate\Auth\Access\HandlesAuthorization;

class TaskPolicy{
use HandlesAuthorization;

/**
* Determine if the given user can delete the given task.
*
* @param User $user
* @param Task $task
* @return bool
*/
public function destroy(User $user, Task $task)
{
return $user->id === $task->user_id;
}
}

最后,需要关联Task模型和TaskPolicy,通过在app/Providers/AuthServiceProvider.phppolicies属性添加注册实现。

注册后会告知Laravel无论何时尝试授权到Task实例时,该使用哪个策略类进行判断:

1
2
3
protected $policies = [
'App\Task' => 'App\Policies\TaskPolicy',
];

授权动作

编写好策略后,在destroy方法中使用它。所有的laravel控制器都可以调用authorize方法,该方法由AuthorizesRequest提供:

app/Controllers/TaskController.php文件。

1
2
3
4
public function destroy(Request $request, Task $task){
$this->authorize('destroy', $task);
// Delete The Task...
}

4.7.4 删除任务

最后在destroy方法中实际删除任务。使用Eloquent的delete方法从数据库中删除给定的模型实例。

删除后返回/tasks连接:

app/Controllers/TaskController.php文件中完整的TaskController@destroy方法。

1
2
3
4
5
public function destroy(Request $request, Task $task){
$this->authorize('destroy', $task);
$task->delete();
return redirect('/tasks');
}

  • TOC
    {:toc}

3. 跟随快速入门

官方地址

中文版地址

台湾版地址

开始前先创建一个新的数据库,并添加到.env文件中。

3.1 创建quickstart项目

3.1.1 使用composer

$ composer create-project laravel/laravel quickstart --prefer-dist

3.1.2 克隆整个快速入门文档

$ git clone https://github.com/laravel/quickstart-basic quickstart
$ cd quickstart
$ composer install
$ php artisan migrate

3.2 准备数据库

laravel有一种简单的定义与修改数据表的方法。

现在使用make:migration生成tasks新的数据表:

$ php artisan make:migration create_tasks_table --create=tasks

make:migration自动添加了id时间戳

手动增加一个条码:

1
$table->string('name');

随后使用下方命令将tasks写入数据表。

$ php artisan migrate

注意:如果数据库中以及存在tasks数据表,会报错。

3.3 Eloquent ORM模型

laravel 使用默认ORM是Eloquent,[ORM:物件关联对应],每一个Eloquent模型都有一个对应的数据表。

所有创建tasks对应的Task模型,使用Artisan命令来生成模型。

$ php artisan make:model Task

模型在app目录下,默认情况下,模型类是空的。不需要说明Eloquent模型要对应哪张数据表,它会假设数据表是模型的复数形态。

这里Task对应的是tasks

3.4 路由

3.4.1 建置路由

默认情况下,所有的路由都定义在app/Http/routes.php

这个需要至少三个路由:显示所有任务的路由,添加新任务的路由,以及删除己存在任务的路由。

下面再app/Http/routse.php中创建这三个路由。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

use App\Task;
use Illuminate\Http\Request;

/**
* Display All Tasks
*/
Route::get('/', function () {
//
});

/**
* Add A New Task
*/
Route::post('/task', function (Request $request) {
//
});

/**
* Delete An Existing Task
*/
Route::delete('/task/{id}', function ($id) {
//

3.4.2 显示视图

laravel的全部,HTML模板都存放在resources/view目录下,使用view函数从路由中返回一个模板。

1
2
3
Route::get('/', function () {
return view('tasks');
});

现在要在创建一个对应的视图模板resources/views/tasks.blade.php作为View对象。

3.5 创建布局&视图

下图中使用了Bootstrap CSS样式

3.5.1 定义布局

几乎所有的web应用都在不同的页面中共享同一个布局。

例如,这个应用在视图顶部的导航条,这个导航条在每个页面都会出现。

laravel通过在每个页面中使用Blade布局让共享这些公共特性变得简单。

resources/views/layouts/app.blade.php中定义一个新布局,.blade.php表明使用Blade模板引擎来渲染视图。

也可以使用PHP原生模板然而,Blade提供的标签语法可以编写简洁的模板。

app.blade.php的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// resources/views/layouts/app.blade.php
<!DOCTYPE html><html lang="en">
<head>
<title>Laravel Quickstart - Basic</title>

<!-- CSS And JavaScript -->
</head>

<body>
<div class="container">
<nav class="navbar navbar-default">
<!-- Navbar Contents -->
</nav>
</div>

@yield('content')
</body>
</html>

布局中的@yield('content')部分,是一个Blade指令,用于指定继承布局的子页面,在这里可以注入自己的内容。

3.5.2 定义子视图

现在定义resources/views/tasks.blade.php视图。Bootstrap CSS的样本文件可以到github下载

tasks.blade.php内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//resources/views/tasks.blade.php

@extends('layouts.app')

@section('content')

<!-- Bootstrap Boilerplate... -->

<div class="panel-body">
<!-- Display Validation Errors -->
@include('common.errors')

<!-- New Task Form -->
<form action="/task" method="POST" class="form-horizontal">
{{ csrf_field() }}

<!-- Task Name -->
<div class="form-group">
<label for="task" class="col-sm-3 control-label">Task</label>

<div class="col-sm-6">
<input type="text" name="name" id="task-name" class="form-control">
</div>
</div>

<!-- Add Task Button -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-plus"></i> Add Task
</button>
</div>
</div>
</form>
</div>

<!-- TODO: Current Tasks -->
@endsection

注意:

使用@extends告诉Blade要使用在resources/views/layouts/app.blade.php的布局。

@section('content')@endsection之间的内容会被注入到app.blade.php@yield('contents')位置。

@include('common.errors')指令将会加载resources/views/common/errors.blade.php中的内容,目前还没有定义。

现在可以设置路由:

1
2
3
Route::get('/', function () {
return view('tasks');
});

3.6 添加任务

3.6.1 验证

验证表单,在POST /task路由中编写代码,处理表单请求,我们需要验证表单输入,然后才能创建一个新任务。

对这个表单而言,将name字段设置为必填项,而长度不超过255个字符。如果表单验证失败,将会跳转到前一个页面,并将错误信息存入一次性的Session中:

1
2
3
4
5
6
7
8
9
10
11
12
13
Route::post('/task', function (Request $request) {
$validator = Validator::make($request->all(), [
'name' => 'required|max:255',
]);

if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}

// Create The Task...
});

$errors

->withErrors($validator)将验证错误信息存放在一次性的session中,以便视图通过$errors访问。

errors.blade.php文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// resources/views/common/errors.blade.php

@if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<strong>Whoops! Something went wrong!</strong>

<br><br>

<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif

注意:

errors变量可用于每个laravel的视图中。如果没有验证错误信息存在,那么他就是一个空的ViewErroeBag实例。

3.6.2 创建任务

接下来开始创建一个新任务。一旦新任务创建成功,页面会跳转到/。要创建任务,可以有Eloquent模式提供的save方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Route::post('/task', function (Request $request) {
$validator = Validator::make($request->all(), [
'name' => 'required|max:255',
]);

if ($validator->fails()) {
return redirect('/')
->withInput()
->withErrors($validator);
}

$task = new Task;
$task->name = $request->name;
$task->save();

return redirect('/');
});

3.6.3 显示己存在的任务

添加代码到视图来显示所有任务列表。

需要编辑/路由传递所有已存在任务到视图,view函数接收一个数组作为第二个参数,我们可以将数据通过该数组传递到视图中:

1
2
3
4
5
6
7
Route::get('/', function () {
$tasks = Task::orderBy('created_at', 'asc')->get();

return view('tasks', [
'tasks' => $tasks
]);
});

数据被传递到视图后,我们可以在tasks.blade.php中以表格形式显示所有任务。Blade中使用@foreach处理循环数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
@extends('layouts.app')

@section('content')
<!-- Create Task Form... -->

<!-- Current Tasks -->
@if (count($tasks) > 0)
<div class="panel panel-default">
<div class="panel-heading">
Current Tasks
</div>

<div class="panel-body">
<table class="table table-striped task-table">

<!-- Table Headings -->
<thead>
<th>Task</th>
<th>&nbsp;</th>
</thead>

<!-- Table Body -->
<tbody>
@foreach ($tasks as $task)
<tr>
<!-- Task Name -->
<td class="table-text">
<div>{{ $task->name }}</div>
</td>

<td>
<!-- TODO: Delete Button -->
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endif
@endsection

3.7 删除任务

3.7.1 添加删除按钮

我们在tasks.blade.php视图中留了一个“TODO”注释用于放置删除按钮。当删除按钮被点击时,DELETE /task请求被发送到应用后台:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<tr>
<!-- Task Name -->
<td class="table-text">
<div>{{ $task->name }}</div>
</td>

<!-- Delete Button -->
<td>
<form action="/task/{{ $task->id }}" method="POST">
{{ csrf_field() }}
{{ method_field('DELETE') }}

<button>Delete Task</button>
</form>
</td>
</tr>

方法伪造

尽管我们使用的路由是Route::delete,但我们在删除按钮表单中使用的请求方法为POST,HTML表单只支持GETPOST两种请求方式,因此我们需要使用某种方式来伪造DELETE请求。

我们可以在表单中通过输出method_field('DELETE')来伪造DELETE请求,该函数生成一个隐藏的表单输入框,然后Laravel识别出该输入并使用其值覆盖实际的HTTP请求方法。生成的输入框如下:

3.7.2 删除任务

最后,让我们添加业务逻辑到路由中执行删除操作,我们可以使用Eloquent提供的findOrFail方法从数据库通过ID获取模型实例,如果不存在则抛出404异常。获取到模型后,我们使用模型的delete方法删除该模型在数据库中对应的记录。记录被删除后,跳转到/页面:

1
2
3
4
Route::delete('/task/{id}', function ($id) {
Task::findOrFail($id)->delete();
return redirect('/');
});

  • TOC
    {:toc}

laravel 5 学习指南

1.部署Laravel Homestead

1.1. 必要软件安装

软件 下载地址
vagrant 地址
virtualbox 地址
git 地址

composer 在虚拟机中有提供,但为了能正常安装laravel需要自备梯子

Laravel 官方指南地址

1.2.下载Laravel Homestead虚拟机文件

Git Bash中输入命令

$ vagrant box add laravel/homestead        //安装Laravel Homestead

随后会要求选择使用的虚拟机。virtualbox为1 ,Vmware 为2 。

注意:如果使用VMware需要购买vagrant的插件。

确认后,开始下载。

注意:需要梯子

1.3. 安装Laravel Homestead

下载完成后,需要使用git,克隆Laravel Homestead的安装设置文件。

切换到想要建立项目的目录,使用克隆命令。

$ git clone https://github.com/laravel/homestead.git Homestead

1.4. 设置Laravel Homestead

首先需要有SSH密钥,如果没有使用下方命令创建

$ ssh-keygen

克隆完整后,载入Laravel Homestead设置文件。

$ bash init.sh   //载入 Laravel Homestead 设置文件

之后设置文件映射,

C:\Windows\System32\drivers\etc\hosts 负责DNS的文件

C:\Users\Keleven\.homestead\Homestead.yaml 负责Laravel Homestead设置的文件

Homestead.yaml修改

ip: "192.168.20.10"        //映射的ip地址
memory: 2048            //虚拟机内存大小
cpus: 1                    //虚拟机CUP数量
provider: virtualbox    //虚拟机供应商

authorize: ~/.ssh/id_rsa.pub   //SSH 公钥地址

keys:                            
    - ~/.ssh/id_rsa                //SSH 私钥地址

folders:                            //项目的主文件夹
    - map: J:\laravel\web  # pc          //PC端 文件地址
      to: /home/vagrant/webCode  #vbox    //Vbox端 地址 

sites:
    - map: web.app                               //网站名称
      to: /home/vagrant/webCode/web/public       //laravel 入口
    - map: back.app                                 //网站名称
      to: /home/vagrant/webCode/back/public      //laravel 入口
databases:                                       // web数据库名称
    - webdb

hosts中添加

192.168.20.10 web.app
192.168.20.10 back.app

注意:IP:地址用没有使用的IP段

1.5.运行Laravel Homestead

在克隆的的Homestead目录下。启动虚拟机。

不要再Vbox中启动,不要再Vbox中启动,不要再Vbox中启动。

$ vagrant up 

加载完成会就可以使用了,使用下方命令与虚拟机建立SSH链接。

$ vagrant ssh

进去虚拟机的第一件事,解除Composer的xdebug模式,否则严重影响下载包的速度。

解除方法:

找到/etc/php/7.0/mods-available/下的xdebug.ini打开后加注释。

$ sudo nano /etc/php/7.0/mods-available/xdebug.ini  // 使用nano编辑xdebug.ini文件

zend_extension=xdebug.so前方加;

sudo nano /etc/php/5.6/mods-available/下的xdebug.ini进行同样操作。

sudo nano /etc/php/5.6/mods-available/xdebug.ini

1.6.安装laravel到目录

安装目录在Homestead.yaml设置过,本地目录与虚拟机的目录是共享的。

即安装完成后,可以直接修改本地目录中的文件。

使用Git Bash进入项目目录。使用composer安装laravel

$ composer create-project --prefer-dist laravel/laravel [blog]

[blog]可以是任意的项目名称。

注意:项目名称要与Homestead.yaml中设置对应

安装完成后,在浏览器中输入web.app,就可以看到laravel在正常运行了。

1.7. 关机

先使用exit推出SSH链接。

在关闭虚拟机:

$ vagrant halt

2. 正常安装Laravel

在ubuntu desktop环境下安装。

安装nginx + php7 + mysql + redis


2.1 安装nginx

$ sudo apt-get update
$ sudo apt-get install nginx

显示防护墙列表

$ sudo ufw app list

结果如下

可用应用程序:
  CUPS
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  • Nginx Full: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • Nginx HTTP: This profile opens only port 80 (normal, unencrypted web traffic)
  • Nginx HTTPS: This profile opens only port 443 (TLS/SSL encrypted traffic)

设置防火墙规则

$ sudo ufw allow 'Nginx Full'

查看防火墙状态

$ sudo ufw status

网站目录在var/www/html

根据情况修改/etc/nginx/nginx.conf中的keepalive_timeout值。


2.2 安装php7.0-fpm

参考地址

$ sudo apt-get install php7.0-fpm

现在还不能访问.php文件,要进行如下设置:

$ sudo nano /etc/nginx/sites-available/default
  • server_name _ 服务器名,可以不填。

  • root /var/www/html 网站目录地址。可以手动修改。

    增加index.php

  • location ~ \.php$php支持,需要解除注释。

    fastcgi_pass 127.0.0.1:9000;fastcgi_pass unix:/run/php/php7.0-fpm.sock;选一个否则冲突。

之后重新读取nginx设置,

$ sudo service nginx reload

修改/etc/php/7.0/fpm/php.ini

$ sudo nano /etc/php/7.0/fpm/php.ini

设置 cgi.fix_pathinfo=1

重启php7.0-fpm服务

$ sudo service php7.0-fpm reload

网站目录下建立任意.php文件测试。

文件内容如下

1
2
3
<?php
phpinfo();
?>

随后输入127.0.0.1/[文件名].php

通过命令定位php7.0的其他包:

$ sudo apt-cache search php7.0

选择安装的如下:

$ sudo apt-get install php7.0-cli php7.0-common php7.0 php7.0-mysql php7.0-curl php7.0-gd php7.0-bz2 php7.0-mcrypt php7.0-zip php7.0-mbstring php7.0-xml

其他让php7.0使用TCP连接

修改文件/etc/php/7.0/fpm/pool.d/www.conf/etc/nginx/sites-available/default

/etc/php/7.0/fpm/pool.d/www.conf文件

;listen = /var/run/php5-fpm.sock       //注释掉
listen = 127.0.0.1:9000                    // 增加

/etc/nginx/sites-available/default文件

[...]
        location ~ \.php$ {
 include snippets/fastcgi-php.conf;

 # With php7.0-cgi alone:
 fastcgi_pass 127.0.0.1:9000;
 # With php7.0-fpm:
 # fastcgi_pass unix:/run/php/php7.0-fpm.sock;
 }
[...]

重新读取nginx

service nginx reload

2.3 安装MySql

$ sudo apt-get install mysql-server-5.7 php7.0-mysql

2.4 安装composer

下载地址

随后会得到一个composer.phar文件,可以直接放入任意目录,终端输入composer使用。

当然为了方便可以设置为全局可以用。

$ sudo mv composer.phar /usr/local/bin/composer
$ sudo chmod +x /usr/local/bin/composer

2.5 安装laravel 5

文档地址

2.5.1 方法1

$ composer create-project --prefer-dist laravel/laravel [blog]

[blog]可以为项目名

2.5.2 方法2

需要使用bashzsh测试无效

$ composer global require "laravel/installer"

$ export PATH="~/.config/composer/vendor/bin:$PATH"

进入想要创建项目的目录

$ laravel new [blog]

[blog]可以为项目名

注意:需要梯子!需要梯子!需要梯子!

日期:2016年7月13日

今日记录

  1. mysql禁止了root用户登录,所以新建一个高权限用户吧!参考地址

  2. 学习laravel快速入门

今日计划完成度

    1. 学习gulp与sass
  • [1/2] 2. 定制玩家天赋

    1. laravel 学习
    1. 学习数据结构
    1. 设置jekyll分页以及disqus模块

明日计划

    1. 学习gulp与sass
    1. 定制玩家天赋
    1. laravel 学习
    1. 学习数据结构

vim 使用指南

1.vim 插件管理器

1.1 Vundle git仓库

安装文档有中文指南。

1.2 第一步

$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

1.3 第二步

.vimrc文件进行设置。

begin()end()之间的为可以添加的插件。

插件添加支持多种格式。

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()

Plugin 'VundleVim/Vundle.vim'
Plugin 'tpope/vim-fugitive'
Plugin 'L9'
Plugin 'wincent/command-t'
Plugin 'godlygeek/tabular'
Plugin 'plasticboy/vim-markdown'
Plugin 'suan/vim-instant-markdown'

call vundle#end()            
filetype plugin indent on

1.4 第三步

在vim中输入:PluginInstall来安装插件。


2.vim 常用插件指南

2.1 Command-t

插件地址

插件需要安装ruby,安装完成后,进入目录~/.vim/bundle/command-t/ruby/command-t

执行下方命令:

ruby extconf.rb
make

之后进入Vim,输入命令:CommandT查看效果。

如果提示vim不支持ruby,则安装vim-nox

$ sudo apt-get install vim-nox

下图,为正常运行图

简要使用说明

tab为选择切换到文件选择。方向键用了选择文件。enter确认选择。


2.2 vim中编写markdown与预览

需要安装的插件有三个。

Plugin 'godlygeek/tabular'
Plugin 'plasticboy/vim-markdown'
Plugin 'suan/vim-instant-markdown'

其中vim-instant-markdown需要安装nodejsnpmxdg-utilsnodejs-legacy

安装instant-markdown-d

$ sudo npm -g install instant-markdown-d

其他需要组件:

$ sudo apt-get install nodejs
$ sudo apt-get install npm
$ sudo apt-get install xdg-utils
$ sudo apt-get install nodejs-legacy

实现的效果为浏览器预览markdown语法高亮

安装完成后效果如下图:


2.3 nerdTree

参考地址

nerdtree-git-plugin git语法提示

vim-nerdtree-tabs NERDTree tag控制

Plugin 'scrooloose/nerdTree'
Plugin 'Xuyuanp/nerdtree-git-plugin'
Plugin 'jistr/vim-nerdtree-tabs'

vim中输入PluginInstall,输入NERDTree检查是否运行

.vimrc中添加设置

" NERDTRee config NERDTree 设置

autocmd vimenter * NERDTree  “ 当指定文件时,自动随VIM启动。

"未指定文件时,加载NERDTree

autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif

"隐藏与显示快捷键[Ctrl+n]

map <C-n> :NERDTreeToggle<CR>

"左侧只有一个窗口时,随Vim一起关闭

autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif

日期:2016年7月12日

今日记录

在ubuntu中安装gulpsass

安装nginx+php7.0+mysql。

明日计划

    1. 学习gulp与sass
    1. 定制玩家天赋
    1. laravel 学习
    1. 学习数据结构

about gulp

安装node

sudo apt install nodejs

安装 nodejs-legacy

sudo apt install nodejs-legacy

安装npm

sudo apt install npm

安装gulp

sudo npm install -g gulp

查看node 版本

node -v

查看npm 版本

npm -v

查看gulp 版本

gulp -v

测试gulp时,需要package.jsongulpfile.js文件

安装gulp-sass

npm install gulp-sass

1.jekyll

jekyll官方地址

jekyll中文

1.1安装jekyll必要组件

下文是在ubuntu上安装与设置

$ sudo apt-get install ruby ruby-dev make gcc nodejs

1.2安装jekyll

$ sudo gem install jekyll

之后查看jekyll版本

$ jekyll -v

1.3jekyll使用

首先要设置_config.yml文件

随后build为site。

$ jekyll build

build后网站文件在_site

使用jekyll server运行测试。

$ jekyll server

浏览器输入localhost:4000可以查看网站运行情况。

_post文件下位文章列表,可以将文章放入后build。

注意:文件的头部要使用下方格式

---
layout: post
title: Blogging Like a Hacker
---

2. kramdown 语法说明

2.1 TOC连接[文章目录]

* TOC
{:toc}

生成目录带自动锚点

2.2 删除线

~~删除线~~

2.3 数学公式

需要增加js用于公式解析

<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>

3. disqus

添加disqus代码到_layouts/post.html

0%