Laravel5.5开发项目

Laravel5.5开发项目

参考:
https://laravel-china.org/docs/laravel-specification/5.5


环境说明
一般情况下,一个项目 应该 有以下三个基本的项目环境:

Local - 开发环境
Staging - 线上测试环境
Production - 线上生产环境

PHP 7
MySQL 5.7

目录结构
	app							应用程序的业务逻辑代码存放文件夹
		app/Console					存放自定义 Artisan 命令文件
		app/Http/Controllers		存放控制器文件
		app/Http/Middleware			存放「中间件」文件
	bootstrap					框架启动与自动加载设置相关的文件
	config						应用程序的配置文件
	database					数据库操作相关文件(数据库迁移和数据填充)
	node_modules				存放 NPM 依赖模块
	public						前端控制器和资源相关文件(图片、JavaScript、CSS)
	resources					应用资源
		resources/assets			未编译的应用资源文件(图片、JavaScript、CSS)
		resources/lang				多语言文件
		resources/views				视图文件
	routes 						路由
		routes/api.php				用于定义 API 类型的路由
		routes/channels.php			事件转播注册信息
		routes/console.php			用于定义 Artisan 命令
		routes/web.php				用于定义 Web 类型的路由(重点,大部分情况下本书会用到)
	storage						编译后的视图、基于会话、文件缓存和其它框架生成的文件
		storage/app					目录可用于存储应用程序使用的任何文件
		storage/framework			目录被用于保存框架生成的文件及缓存
		storage/logs				应用程序的日志文件
	tests						应用测试相关文件
	vendor						Composer 依赖模块
	webpack.mix.js				Laravel 的前端工作流配置文件
	yarn.lock					Yarn 依赖版本锁定文件
	.gitignore					被 Git 所忽略的文件
	.env						环境变量配置文件
	package.json				应用所需的 NPM 包配置文件
	phpunit.xml					测试工具 PHPUnit 的配置文件
	readme.md					项目介绍说明文件
	composer.json				应用依赖的扩展包
	composer.lock				扩展包列表,确保这个应用的副本使用相同版本的扩展包
	server.php					使用 PHP 内置服务器时的 URL 重写(类似于 Apache 的 "mod_rewrite" )


Production 生产环境
	Homestead
	出于安全考虑,线上环境 必须 只开放以下端口:

	80 HTTP
	443 HTTPS
	22 SSH

Local 开发环境
	所有项目 必须 使用 Homestead 作为应用程序运行的环境。请阅读 为什么必须使用 Homestead 来开发 Laravel 应用? 。

	统一使用域名 .test 作为后缀;
	统一使用 IP 192.168.10.10 作为 hosts 绑定地址,如:192.168.10.10 project-name.test
	统一使用 vm alias,见文档 通过 SSH 连接

Staging 线上测试环境
	除了域名等其他独立应用配置以外,环境 必须 跟 Production 保持高度一致性,可以的话 应该 与 Production 使用同台机器。

开发专用扩展

	说明
	我们都知道 Laravel 扩展包的注册会对应用造成消耗。有一些扩展包是开发环境中专用,生产环境中并不会使用到,为了避免无用的负载, 必须严格控制其安装和加载。

	安装
	安装开发专用扩展包时 必须 使用 --dev 参数,如:

	composer require laracasts/generators --dev
	加载
	开发专用的 provider 绝不在 config/app.php 里面注册,必须 在 app/Providers/AppServiceProvider.php 文件中使用如以下方式:

	public function register()
	{
	    if ($this->app->environment() == 'local') {
	        $this->app->register('Laracasts\Generators\GeneratorsServiceProvider');
	    }
	}

配置信息与环境变量
	存储在 .env 和 config/app.php 文件中,然后使用 config() 函数来读取,config()可以获取config目录下的所有配置
	.env 文件中设置:
		CDN_DOMAIN=cdndomain.com

	config/app.php 文件中设置:
		'cdn_domain' => env('CDN_DOMAIN', null),

	程序中两种获取 相同配置 的方法:
		env('CDN_DOMAIN')
		config('app.cdn_domain')
		在此统一规定:所有程序配置信息 必须 通过 config() 来读取,所有的 .env 配置信息 必须 通过 config() 来读取,绝不 在配置文件以外的范围使用 env()。

辅助函数
	存放位置
	Laravel 提供了很多 辅助函数,有时候我们也需要创建自己的辅助函数。
	定义的时候先判断一下:
		if (! function_exists('ends_with')) {
		    function ends_with($haystack, $needles)
		    {
		        
		    }
		}

	必须 把所有的『自定义辅助函数』存放于 bootstrap 文件夹中。

	并在 bootstrap/app.php 文件的最顶部进行加载:

	<?php

	require __DIR__ . '/helpers.php';

路由器
	路由闭包
		绝不 在路由配置文件里书写『闭包路由』或者其他业务逻辑代码,因为一旦使用将无法使用 路由缓存 。

		路由器要保持干净整洁,绝不 放置除路由配置以外的其他程序逻辑。
	
	Restful 路由
		必须 优先使用 Restful 路由,配合资源控制器使用.

	resource 方法正确使用
		一般资源路由定义:
			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 更加直观。路由使用白名单有利于养成『安全习惯』。

	单数 or 复数?
		资源路由路由 URI 必须 使用复数形式,如:

		/photos/create
		/photos/{photo}
		错误的例子如:

		/photo/create
		/photo/{photo}

	路由模型绑定
		在允许使用路由 模型绑定 的地方 必须 使用。

		模型绑定代码 必须 放置于 app/Providers/RouteServiceProvider.php 文件的 boot 方法中:

		    public function boot()
		    {
		        Route::bind('user_name', function ($value) {
		            return User::where('name', $value)->first();
		        });

		        Route::bind('photo', function ($value) {
		            return Photo::find($value);
		        });

		        parent::boot();
		    }

	全局路由器参数
		出于安全考虑,应该 使用全局路由器参数限制,详见 文档。

		必须 在 RouteServiceProvider 文件的 boot 方法里定义模式:

		/**
		 * 定义你的路由模型绑定,模式过滤器等。
		 *
		 * @param  \Illuminate\Routing\Router  $router
		 * @return void
		 */
		public function boot(Router $router)
		{
		    $router->pattern('id', '[0-9]+');

		    parent::boot($router);
		}

		模式一旦被定义,便会自动应用到所有使用该参数名称的路由上:
		Route::get('users/{id}', 'UsersController@show');
		Route::get('photos/{id}', 'PhotosController@show');
		只有在 id 为数字时,才会路由到控制器方法中,否则 404 错误。

	路由命名
		除了 resource 资源路由以外,其他所有路由都 必须 使用 name 方法进行命名。

		必须 使用『资源前缀』作为命名规范,如下的 users.follow,资源前缀的值是 users.:

		Route::post('users/{id}/follow', 'UsersController@follow')->name('users.follow');

	获取 URL
		获取 URL 必须 遵循以下优先级:

		$model->link()
		route 方法
		url 方法
		
		在 Model 中创建 link() 方法:

		public function link($params = [])
		{
		    $params = array_merge([$this->id], $params);
		    return route('models.show', $params);
		}	

		所有单个模型数据链接使用:

		$model->link();

		// 或者添加参数
		$model->link($params = ['source' => 'list'])

		『单个模型 URI』经常会发生变化,这样做将会让程序更加灵活。

		除了『单个模型 URI』,其他路由 必须 使用 route 来获取 URL:

		$url = route('profile', ['id' => 1]);
		无法使用 route 的情况下,可以 使用 url 方法来获取 URL:

		url('profile', [1]);

放置位置
	所有的数据模型文件,都 必须 存放在:app/Models/ 文件夹中。
	命名空间:
	namespace App\Models;

	User.php
		Laravel 5.1 默认安装会把 User 模型存放在 app/User.php,必须 移动到 app/Models 文件夹中,并修改命名空间声明为 App/Models,同上。
		为了不破坏原有的逻辑点,必须 全局搜索 App/User 并替换为 App/Models/User。

	使用基类
		所有的 Eloquent 数据模型 都 必须 继承统一的基类 App/Models/Model,此基类存放位置为 /app/Models/Model.php,内容参考以下:

		<?php

		namespace App\Models;

		use Illuminate\Database\Eloquent\Model as EloquentModel;

		class Model extends EloquentModel
		{
		    public function scopeRecent($query)
		    {
		        return $query->orderBy('created_at', 'desc');
		    }
		}

		以 Photo 数据模型作为例子继承 Model 基类:
		<?php

		namespace App\Models;

		class Photo extends Model
		{
		    protected $fillable = ['id', 'user_id'];

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

	命名规范
		数据模型相关的命名规范:

		数据模型类名 必须 为「单数」, 如: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

	利用 Trait 来扩展数据模型
		有时候数据模型里的代码会变得很臃肿,应该 利用 Trait 来精简逻辑代码量,提高可读性,类似于 Ruby China 源码。

		借鉴于 Rails 的设计理念:「Fat Models, Skinny Controllers」。

		存放于文件夹:app/Models/Traits 文件夹中。

	Repository
		绝不 使用 Repository,因为我们不是在写 JAVA 代码,太多封装就成了「过度设计(Over Designed)」,极大降低了编码愉悦感,使用 MVC 够傻够简单。

		代码的可读性,维护和开发的便捷性,直接关系到程序员开发时的愉悦感,直接影响到项目推进效率和程序 Debug 的速度。

	关于 SQL 文件
		绝不 使用命令行或者 PHPMyAdmin 直接创建索引或表。必须 使用 数据库迁移 去创建表结构,并提交版本控制器中;
		绝不 为了共享对数据库更改就直接导出 SQL,所有修改都 必须 使用 数据库迁移 ,并提交版本控制器中;
		绝不 直接向数据库手动写入伪造的测试数据。必须 使用 数据填充 来插入假数据,并提交版本控制器中。

	全局作用域
		Laravel 的 Model 全局作用域 允许我们为给定模型的所有查询添加默认的条件约束。

		所有的全局作用域都 必须 统一使用 闭包定义全局作用域,如下:

		/**
		 * 数据模型的启动方法
		 *
		 * @return void
		 */
		protected static function boot()
		{
		    parent::boot();

		    static::addGlobalScope('age', function(Builder $builder) {
		        $builder->where('age', '>', 200);
		    });
		}

	控制器
		资源控制器
		单数 or 复数?
			必须 使用资源的复数形式,如:

			类名:PhotosController
			文件名:PhotosController.php
			错误的例子:

			类名:PhotoController
			文件名:PhotoController.php
			保持短小精炼
			必须 保持控制器文件代码行数最小化,还有可读性。

			不应该 为「方法」书写注释,这要求方法取名要足够合理,不需要过多注释;
			应该 为一些复杂的逻辑代码块书写注释,主要介绍产品逻辑 - 为什么要这么做。;
			不应该 在控制器中书写「私有方法」,控制器里 应该 只存放「路由动作方法」;
			绝不 遗留「死方法」,就是没有用到的方法,控制器里的所有方法,都应该被使用到,否则应该删除;
			绝不 在控制器里批量注释掉代码,无用的逻辑代码就必须清除掉。

	视图
		优先使用 Blade
			视图文件 必须 优先考虑使用 .blade.php 后缀来指定使用 Blade 模板引擎。
		保持目录清晰
			layouts - 页面布局文件 必须 放置于此目录下;
			common - 存放页面通用元素;
			pages - 简单的页面存放文件夹,如:about、contact 等;
			resources - 对应 Restful 路由的资源路径名称,以 URI photos/create 为例,对应 create.blade.php 文件,存放在文件夹 photos 下。
			必须 避免在 resources/views 目录下直接放置视图文件。
		局部视图
			局部视图文件 必须 使用 _ 前缀来命名,如:photos/_upload_form.blade.php
		视图命名要释义
			为了和 Restful 路由器和资源控制器保持一致,视图命名也 必须 使用资源视图的命名方式。以 photos 为例:

			photos/index.blade.php
			内容列表视图
			对应路由器 /photos,命名 photos.index
			控制器方法 PhotosController@index
			photos/show.blade.php
			单个内容视图
			对应路由器 /photos/{id},命名 photos.show
			控制器方法 PhotosController@show
			photos/create.blade.php
			内容创建视图
			对应路由器 /photos/create,命名 photos.create
			控制器方法 PhotosController@create
			photos/edit.blade.php
			内容编辑的视图
			对应路由器 /photos/edit,命名 photos.edit
			控制器方法 PhotosController@edit

		create_and_edit 视图
			很多情况下,创建和编辑视图里的页面结构接近相似,在这种情况下,应该 使用 create_and_edit 视图。以 photos 为例:

			PhotosController@create - 对应视图:/photos/create_and_edit.blade.php
			PhotosController@edit - 对应 视图:/photos/create_and_edit.blade.php
			这样一来,通常情况下,一个完整的 photos 资源对应的视图文件为以下:

			├── photos
			│   ├── create_and_edit.blade.php
			│   ├── index.blade.php
			│   └── show.blade.php

表单验证
	表单请求验证类
	必须 使用 表单请求 - FormRequest 类 来处理控制器里的表单验证。

	验证类的 authorize
	绝不 使用 authorize() 方法来做用户授权,用户授权我们会单独使用 Policy 授权策略 来实现。

	使用基类
	所有 FormRequest 表验证类 必须 继承 app/Http/Requests/Request.php 基类。基类文件如下:
	<?php

	namespace App\Http\Requests;

	use Illuminate\Foundation\Http\FormRequest;

	class Request extends FormRequest
	{
	    public function authorize()
	    {
	        // Using policy for Authorization
	        return true;
	    }
	}

	验证类命名
	FormRequest 表验证类 必须 遵循 资源路由 方式进行命名,photos 对应 app/Http/Requests/PhotoRequest.php 。

	类文件参考
	FormRequest 表验证类文件请参考以下:
	<?php

	namespace App\Http\Requests;

	class PhotoRequest extends Request
	{
	    public function rules()
	    {
	        switch($this->method())
	        {
	            // CREATE
	            case 'POST':
	            {
	                return [
	                    // CREATE ROLES
	                ];
	            }
	            // UPDATE
	            case 'PUT':
	            case 'PATCH':
	            {
	                return [
	                    // UPDATE ROLES
	                ];
	            }
	            case 'GET':
	            case 'DELETE':
	            default:
	            {
	                return [];
	            };
	        }
	    }

	    public function messages()
	    {
	        return [
	            // Validation messages
	        ];
	    }
	}

	授权策略
		必须 使用 授权策略 类来做用户授权。

		使用基类
		所有 Policy 授权策略类 必须 继承 app/Policies/Policy.php 基类。基类文件如下:

		<?php

		namespace App\Policies;

		use Illuminate\Auth\Access\HandlesAuthorization;

		class Policy
		{
		    use HandlesAuthorization;

		    public function __construct()
		    {
		        //
		    }

		    public function before($user, $ability)
		    {
		        if ($user->isAdmin()) {
		            return true;
		        }
		    }
		}

		授权策略命名
		Policy 授权策略类 必须 遵循 资源路由 方式进行命名,photos 对应 /app/Policies/PhotoPolicy.php 。

		类文件参考
		Policy 授权策略类文件内容请参考以下:

		<?php

		namespace App\Policies;

		use App\Models\User;
		use App\Models\Photo;

		class PhotoPolicy extends Policy
		{
		    public function update(User $user, Photo $photo)
		    {
		        return $user->isAuthorOf($photo);
		    }

		    public function destroy(User $user, Photo $photo)
		    {
		        return $user->isAuthorOf($photo);
		    }
		}

		自动判断授权策略
		应该 使用 自动判断授权策略方法,这样控制器和授权类的方法名就统一起来了。

		/**
		 * 更新指定的文章。
		 *
		 * @param  int  $id
		 * @return Response
		 */
		public function update($id)
		{
		    $post = Post::findOrFail($id);

		    // 会自动调用 `PostPolicy` 类中的 `update` 方法。
		    $this->authorize($post);

		    // 更新文章...
		}


数据填充
	factory 辅助函数
	必须 使用 factory 方法来做数据填充,因为是框架提倡的,并且可以同时为测试代码服务。

	运行效率
	开发数据填充时,必须 特别注意 php artisan db:seed 的运行效率,否则随着项目的代码量越来越大,db:seed 的运行时间会变得越来越长,有些项目多达几分钟甚至几十分钟。

	原则是:

	Keep it lighting speed.

	只有当 db:seed 运行起来很快的时候,才能完全利用数据填充工具带来的便利,而不是累赘。

	批量入库
	所有假数据入库操作,都 必须 是批量操作,配合 factory 使用以下方法:

	$users = factory(User::class)->times(1000)->make();
	User::insert($users->toArray());

Artisan 命令行
	所有的自定义命令,都 必须 有项目的命名空间。

	如:

	php artisan phphub:clear-token
	php artisan phphub:send-status-email
	...
	错误的例子为:

	php artisan clear-token
	php artisan send-status-email
	...

日期和时间
	Laravel 5.3 及以上版本的 diffForHumans,只需要在 config/app.php 文件中配置 locale 选项即可 :

	'locale' => 'zh-CN',

前端开发
	必须 使用 Laravel 官方前端工具做前端开发自动化;
	必须 保证页面只加载一个 .css 文件;
	必须 保证页面只加载一个 .js 文件;
	必须 为 .css 和 .js 增加 版本控制;
	必须 使用 SASS 来书写 CSS 代码;

中间件
	Auth 中间件
	Auth 中间件 必须 书写在控制器的 __construct 方法中,并且 必须 使用 except 黑名单进行过滤,这样当你新增控制器方法时,默认是安全的。

	public function __construct()
	{
	    $this->middleware('auth', [            
	        'except' => ['show', 'index']
	    ]);
	}

Laravel 安全实践
	关闭 DEBUG
	Laravel Debug 开启时,会暴露很多能被黑客利用的服务器信息,所以,生产环境下请 必须 确保:

	APP_DEBUG=false

	XSS
	跨站脚本攻击(cross-site scripting,简称 XSS),具体危害体现在黑客能控制你网站页面,包括使用 JS 盗取 Cookie 等,关于 XSS 的介绍请前往 IBM 文档库:跨站点脚本攻击深入解析 。

	默认情况下,在无法保证用户提交内容是 100% 安全的情况下,必须 使用 Blade 模板引擎的 {{ $content }} 语法会对用户内容进行转义。

	Blade 的 {!! $content !!} 语法会直接对内容进行 非转义 输出,使用此语法时,必须 使用 HTMLPurifier for Laravel 5 来为用户输入内容进行过滤。使用方法参见: 使用 HTMLPurifier 来解决 Laravel 5 中的 XSS 跨站脚本攻击安全问题

	SQL 注入
	Laravel 的 查询构造器 和 Eloquent 是基于 PHP 的 PDO,PDO 使用 prepared 来准备查询语句,保障了安全性。

	在使用 raw() 来编写复杂查询语句时,必须 使用数据绑定。

	错误的做法:

	Route::get('sql-injection', function() {
	    $name = "admin"; // 假设用户提交
	    $password = "xx' OR 1='1"; // // 假设用户提交
	    $result = DB::select(DB::raw("SELECT * FROM users WHERE name ='$name' and password = '$password'"));
	    dd($result);
	});
	以下是正确的做法,利用 select 方法 的第二个参数做数据绑定:

	Route::get('sql-injection', function() {
	    $name = "admin"; // 假设用户提交
	    $password = "xx' OR 1='1"; // // 假设用户提交
	    $result = DB::select(
	        DB::raw("SELECT * FROM users WHERE name =:name and password = :password"),
	        [
	            'name' => $name,
	            'password' => $password,
	        ]
	    );
	    dd($result);
	});
	DB 类里的大部分执行 SQL 的函数都可传参第二个参数 $bindings

	批量赋值
	Laravel 提供白名单和黑名单过滤($fillable 和 $guarded),开发者 应该 清楚认识批量赋值安全威胁的情况下合理灵活地运用。

	批量赋值安全威胁,指的是用户可更新本来不应有权限更新的字段。举例,users 表里的 is_admin 字段是用来标识用户『是否是管理员』,某不怀好意的用户,更改了『修改个人资料』的表单,增加了一个字段:

	<input name="is_admin" value="1" />
	这个时候如果你更新代码如下:

	Auth::user()->update(Request::all());
	此用户将获取到管理员权限。可以有很多种方法来避免这种情况出现,最简单的方法是通过设置 User 模型里的 $guarded 字段来避免:

	protected $guarded = ['id', 'is_admin'];

	CSRF
	CSRF 跨站请求伪造是 Web 应用中最常见的安全威胁之一,具体请见 Wiki - 跨站请求伪造 或者 Web 应用程序常见漏洞 CSRF 的入侵检测与防范。

	Laravel 默认对所有『非幂等的请求』强制使用 VerifyCsrfToken 中间件防护,需要开发者做的,是区分清楚什么时候该使用『非幂等的请求』。

	幂等请求指的是:'HEAD', 'GET', 'OPTIONS',既无论你执行多少次重复的操作都不会给资源造成变更。

	所有删除的动作,必须 使用 DELETE 作为请求方法;
	所有对数据更新的动作,必须 使用 POST、PUT 或者 PATCH 请求方法。

Laravel 程序优化
	1. 配置信息缓存
	生产环境中的 应该 使用『配置信息缓存』来加速 Laravel 配置信息的读取。

	使用以下 Artisan 自带命令,把 config 文件夹里所有配置信息合并到一个文件里,减少运行时文件的载入数量:

	php artisan config:cache
	缓存文件存放在 bootstrap/cache/ 文件夹中。

	可以使用以下命令来取消配置信息缓存:

	php artisan config:clear
	注意:配置信息缓存不会随着更新而自动重载,所以,开发时候建议关闭配置信息缓存,一般在生产环境中使用。可以配合 Envoy 任务运行器 使用,在每次上线代码时执行 config:clear 命令。

	2. 路由缓存
	生产环境中的 应该 使用『路由缓存』来加速 Laravel 的路由注册。

	路由缓存可以有效的提高路由器的注册效率,在大型应用程序中效果越加明显,可以使用以下命令:

	php artisan route:cache

	缓存文件存放在 bootstrap/cache/ 文件夹中。另外,路由缓存不支持路由匿名函数编写逻辑,详见:文档 - 路由缓存。

	可以使用下面命令清除路由缓存:

	php artisan route:clear
	注意:路由缓存不会随着更新而自动重载,所以,开发时候建议关闭路由缓存,一般在生产环境中使用。可以配合 Envoy 任务运行器 使用,在每次上线代码时执行 route:clear 命令。

	3. 类映射加载优化
	optimize 命令把常用加载的类合并到一个文件里,通过减少文件的加载,来提高运行效率。生产环境中的 应该 使用 optimize 命令来优化类的加载速度:

	php artisan optimize --force
	以上命令会在 bootstrap/cache/ 文件夹中生成缓存文件。你可以通过修改 config/compile.php 文件来添加要合并的类。在 production 环境中,参数 --force 不需要指定,文件就会自动生成。

	要清除类映射加载优化,请运行以下命令:

	php artisan clear-compiled
	此命令会删除上面 optimize 生成的两个文件。

	注意:此命令要运行在 php artisan config:cache 后,因为 optimize 命令是根据配置信息(如:config/app.php 文件的 providers 数组)来生成文件的。

	4. 自动加载优化
	此命令不止针对于 Laravel 程序,适用于所有使用 composer 来构建的程序。此命令会把 PSR-0 和 PSR-4 转换为一个类映射表,来提高类的加载速度。

	composer dumpautoload -o
	注意:php artisan optimize --force 命令里已经做了这个操作。

	5. 使用 Memcached 来存储会话
	每一个 Laravel 的请求,都会产生会话,修改会话的存储方式能有效提高程序效率。会话的配置文件是 config/session.php。生产环境中的 必须 使用 Memcached 或者 Redis 等专业的缓存软件来存储会话,应该 优先选择 Memcached:

	'driver' => 'memcached',
	6. 使用专业缓存驱动器
	「缓存」是提高应用程序运行效率的法宝之一,Laravel 默认缓存驱动是 file 文件缓存,生产环境中的 必须 使用专业的缓存系统,如 Redis 或者 Memcached。应该 优先考虑 Redis。应该 避免使用数据库缓存。

	'default' => 'redis',
	7. 数据库请求优化
	关联模型数据读取时 必须 使用 延迟预加载 和 预加载 。

	临近上线时 必须 使用 Laravel Debugbar 或者 Clockwork 留意每一个页面的总 SQL 请求条数,进行数据库请求调优。

	8. 为数据集书写缓存逻辑
	应该 合理的使用 Laravel 提供的缓存层操作,把从数据库里面拿出来的数据集合进行缓存,减少数据库的压力,运行在内存上的专业缓存软件对数据的读取也远远快于数据库。

	$hot_posts = Cache::remember('posts.hot_posts', $minutes = 30, function()
	{
	    return Post::getHotPosts();
	});
	remember 甚至连数据关联模型也都一并缓存了,多么方便呀。

	9. 使用即时编译器
	可以 使用 OpCache 进行优化。OpCache 都能轻轻松松的让你的应用程序在不用做任何修改的情况下,直接提高 50% 或者更高的性能,PHPhub 之前做过一个实验,具体请见:使用 OpCache 提升 PHP 5.5+ 程序性能。

	10. 前端资源合并
	作为优化的标准:

	一个页面 应该 只加载一个 CSS 文件;
	一个页面 应该 只加载一个 JS 文件。
	另外,为了文件要能方便走 CDN,需要文件名 应该 随着修改而变化。

	Laravel Elixir 提供了一套简便实用的方案,详细请见文档:Laravel Elixir 文档。

代码生成器
	遵照此规范,在实际操作中,有许多重复。接下来推荐一款专为本规范量身定做的代码生成器 Laravel 5.x Scaffold Generator。

	本扩展支持 5.1 ~ 5.5 版本的 Laravel。

	只需要一个命令,
		php artisan make:scaffold Projects --schema="name:string:index,description:text:nullable,subscriber_count:integer:unsigned:default(0)"
	即可生成:

		----------- scaffolding: Project -----------

		+ ./database/migrations/2017_05_23_070517_create_projects_table.php
		+ ./database/factories/ModelFactory.php
		+ ./database/seeds/ProjectsTableSeeder.php
		+ ./database/seeds/DatabaseSeeder.php (Updated)
		+ ./app/Models/Model.php (Updated)
		+ ./app/Models/Project.php
		+ ./app/Http/Controllers/ProjectsController.php
		+ ./app/Http/Requests/Request.php
		+ ./app/Http/Requests/ProjectRequest.php
		+ ./app/Observers/UserObserver.php (Skipped)
		+ ./app/Observers/ProjectObserver.php
		+ ./app/Providers/AppServiceProvider.php (Updated)
		+ ./app/Policies/Policy.php
		+ ./app/Policies/ProjectPolicy.php
		+ ./app/Providers/AuthServiceProvider.php (Updated)
		+ ./routes/web.php (Updated)

		--- Views ---
		   + create_and_edit.blade.php
		   + index.blade.php
		   + show.blade.php
		+ ./resources/views/layouts/app.blade.php
		+ ./resources/views/common/error.blade.php
		Migration table created successfully.
		Migrated: 2014_10_12_000000_create_users_table
		Migrated: 2014_10_12_100000_create_password_resets_table
		Migrated: 2017_05_23_070517_create_projects_table

		----------- -------------------- -----------
		-----------   >DUMP AUTOLOAD<    -----------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值