Loading... > 本文所说的Laravel 2018使用数据分析,指的是 `Laravel Shift`的作者 `Jason McCreary`,基于使用 `Laravel Shift`的超过8000个laravel应用所做的分析。(`Laravel Shift`是一个自动升级你的laravel版本的付费应用,比如你的项目版本是5.1,使用它呢可以自动给你升级到5.6,这期间省去你手动升级的繁琐和烦恼。) 截至到2018年7月,`Laravel Shift`里有超过8500个上传的laravel apps,每一次版本的升级,`Laravel Shift`都会生成一个日志文件以用于debug,基于这些日志文件,产生了今天我们提到的laravel使用数据。下面是 `Laravel Shift`里日志文件一瞥: ```bash *** _Shift_ version: 0281cff03fee62f250253f1e485dc7a790209866 *** Cloning app... >>> _Shift_ 5.2 Event: app did not contain references to SelfHandling >>> _Shift_ 5.2 Event: could not upgrade middleware Data: ["app\/Http\/Middleware\/Authenticate.php","app\/Http\/Middleware\/EncryptCookies.php","app\/Http\/Middleware\/RedirectIfAuthenticated.php"] >>> _Shift_ 5.2 Event: could not upgrade app/Providers/RouteServiceProvider.php >>> _Shift_ 5.2 Event: could not patch app/Providers/RouteServiceProvider.php >>> _Shift_ 5.2 Event: could not find User model path >>> _Shift_ 5.2 Event: found additional uses of Event names >>> _Shift_ 5.2 Event: matched core file: phpunit.xml with version: 5.1.11 >>> _Shift_ 5.2 Event: matched core file: tests/TestCase.php with version: 5.1.33 >>> _Shift_ 5.2 Event: matched core file: database/migrations/2014_10_12_100000_create_password_resets_table.php with version: 5.1.33 >>> _Shift_ 5.2 Event: matched core file: public/.htaccess with version: 5.1.33 >>> _Shift_ 5.2 Event: matched core file: config/broadcasting.php with version: 5.1.11 >>> _Shift_ 5.2 Event: matched core file: config/cache.php with version: 5.1.33 >>> _Shift_ 5.2 Event: matched core file: config/compile.php with version: 5.1.33 >>> _Shift_ 5.2 Event: matched core file: config/database.php with version: 5.1.11 >>> _Shift_ 5.2 Event: matched core file: config/filesystems.php with version: 5.1.33 >>> _Shift_ 5.2 Event: matched core file: config/queue.php with version: 5.1.11 >>> _Shift_ 5.2 Event: matched core file: config/view.php with version: 5.1.33 >>> _Shift_ 5.2 Event: could not upgrade config files Data: {"1":"config\/auth.php","2":"config\/mail.php","3":"config\/services.php","4":"config\/session.php"} >>> _Shift_ 5.2 Event: could not upgrade package.json >>> _Shift_ 5.2 Event: app contained phpspec/phpspec requirement of ~2.1 >>> _Shift_ 5.2 Event: found customized namespace *** _Shift_ ran in: 212.209509 ``` 从这些日至里可以看到哪些文件被升级了,用到了哪些功能、哪些组件,等等。 ### (一)最流行的Laravel版本——5.3 很多apps停留在了5.3,可能因为PHP版本的要求,因为到了5.4测试想转换到Dusk,或者auth组件的变化等。 这应该符合现实情况,因为laravel在5.2~5.3期间一方面做了很多变动,大家要逐步适应和学习,另一方面这些人性化的变动也让laravel更加流行和易用,laravel被大批量地用于生产环境,同时这些变动本身,也逐渐使laravel趋于成熟,满足了大家实际项目的大部分需要。可能没有了特殊的功能需要,大家也就不会那么急迫地更新版本,本身laravel 5.4开始的更新变动也相对小了很多。 当然,也可以说大家的项目还都在“升级的过程中”,取决于升级的时间、人力成本等因素,如果可以的话,可能大家都还想升到laravel 5.5,也即第二个LTS版本。 ### (二)最流行的第三方组件 需要注意的是,接下来的数据样本,laravel 5.5及以上版本的要小一些,同时laravel自身的核心组件,都被排除在外了。 * `58%` of apps use `guzzlehttp/guzzle` * `36%` of apps use `predis/predis` * `34%` of apps use `laravelcollective/html` * `32%` of apps use `league/flysystem-aws-s3-v3` * `27%` of apps use `intervention/image` * `25%` of apps use `maatwebsite/excel` * `24%` of apps use `spatie/laravel-backup` * `23%` of apps use `laravel/horizon` * `22%` of apps use `bugsnag/bugsnag-laravel` * `21%` of apps use `laravel/socialite` * `20%` of apps use `laravel/passport` * `19%` of apps use `sentry/sentry-laravel` * `15%` of apps use `spatie/laravel-permission` * `14%` of apps use `laravel/scout` * `14%` of apps use `league/csv` 流行的开发辅助组件: * **35%** of apps use `barryvdh/laravel-debugbar` * **28%** of apps use `barryvdh/laravel-ide-helper` * **19%** of apps use `laravel/dusk` * **11%** of apps use `laravel/browser-kit-testing` 编者点评: * 值得一提的是,早在两年前(2016年),这里面的一些对于初学者来说比较关键的第三方组件,在我们的Laravel系列课程里也都带领大家使用过了,比如必备的表单组件 `laravelcollective/html`,在我们[《Laravel实战:任务管理系统(一)》](https://study.163.com/course/courseMain.htm?courseId=1003163020&share=2&shareId=1018568251)就跟大家见面了; * 处理图片必备的 `intervention/image`,也在我们[《Laravel实战:任务管理系统(一)》](https://study.163.com/course/courseMain.htm?courseId=1003163020&share=2&shareId=1018568251)中大量使用,后来出现了很多其他的图片相关组件,但往往背后也是基于的 `intervention/image`,比如说近来流行的 `spatie/laravel-medialibrary`; * 项目备份必备的 `spatie/laravel-backup`,是我们在[《Laravel&Vue实战:任务管理系统二》](https://study.163.com/course/courseMain.htm?courseId=1003227034&share=2&shareId=1018568251)一开始就使用的,当时该组件还名不见经传; * 关于权限,可以说一开始首屈一指的是 `Zizaco/entrust`,为此呢我们还专门出了免费的公开课[《Laravel Entrust角色权限管理》](https://ke.qq.com/course/310428),但是呢entrust的作者突然从去年开始不怎么活跃了,于是 `santigarcor/laratrust`作为entrust的维护版本出现,已经安装了entrust的可以无缝迁移到 `laratrust`上,当然这期间另一个权限组件 `spatie/laravel-permission`凭借其强大的活跃也流行起来了,Laravel也推出了自身的权限功能——Policy。所以权限这块,其实用哪个功能就取决于你自己了,都不错,都可以,那么如果你权限这块感觉有障碍,还是推荐我们的免费的公开课[《Laravel Entrust角色权限管理》](https://ke.qq.com/course/310428),了解了原理以后,你可以自行在 `santigarcor/laratrust`或 `spatie/laravel-permission`之间选择。 * 搜索必备组件 `laravel/scout`,这个背后的driver默认基于的是付费服务 `<span> </span>Algolia`,在国内我们更喜欢开源的 `Elasticsearch`,`laravel/scout`与 `Elasticsearch`搭配来开发实时搜索相关的功能,可以看我们的[《Laravel & Elastic全文搜索实战》](https://study.163.com/course/courseMain.htm?courseId=1004832038&share=2&shareId=1018568251)课程。 * 关于 `guzzlehttp/guzzle`排第一位,可能是因为这两年api开发开始流行,传统上我们经常用guzzle来处理http请求,由于数据来源大部分都是5.3及以下的,这个时候 `passport`与 `axios`还刚开始流行,所以这一点上,可能后期我们会看到 `passport`的排名将攀升,`axios`因为是前端组件,可能就会被排除在统计数据之外了,但是我们绝不能忽视它的日发流行。 ### (三)改动最多的文件——config config文件是改动最多的,虽然这很合理,但是呢改动默认的config文件,也容易导致升级障碍。通常,你可以有其他的方式来处理这些改动,从而使config文件保持默认的样子。 这期间一定记得通过 `ENV`环境变量来改动config文件的值。很多应用喜欢改变config文件当中的默认值,而不是设置 `ENV`,比如假设 `config/mail.php`: ```bash php 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'shift@laravelshift.com'), 'name' => env('MAIL_FROM_NAME', 'Laravel _Shift_'), ], ``` 这样呢并不好,还是得设置 `ENV`,让config文件保持默认: ```bash php 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], ``` 当你有很多的配置选项需要设置时,再一种方式就是创建你自己的config文件,比如创建 `config/system.php`, `config/settings.php`,这样你就不用分别改动多个config文件了。 ### (四)不推荐自定义的全局namespace 使用默认的 `APP` namespace就好。有9%的apps使用了自定义的namespace,而这个数值应该是0. 如果你更改过namespace,可以这样来改回: `artisanapp:nameApp` 当然这并不能改回你在数据库当中,使用到多极对应关系(polymorphic relationships)时的记录,那个你得自己通过sql query来改变了。 编者按: 这个呢,其实在5.3及以下版本,如果通过 `artisan app:name`改变了namespace,实际上是会发生很多莫名bug的,所以不推荐出于好奇随便设置 `app:name`,除非你知道自己在干什么。 ### (五)apps的目录结构 接下来是在 `app`目录下发现的非laravel官方文件夹: * 36% of apps contain `app/Models` * 29% of apps contain `app/Services` * 29% of apps contain `app/Helpers` * 25% of apps contain `app/Traits` * 20% of apps contain `app/Rules` * 18% of apps contain `app/Repositories` * 17% of apps contain `app/helpers.php` 在laravel 4时代,是默认有 `app/Models`文件夹的,到了5, laravel作者特意将其删掉,因为model这个词在不同的人那里理解不一样,有的人认为一个app的model是其整个的业务逻辑,有的人认为model是一些与关系型数据库进行交互的class,为了不限制大家,干脆删掉,让开发者自己决定该怎么安置model,也即你可以自己创建 `app/Models`文件夹,然后遵循MVC框架的传统方式,也可以“面向业务(service)”,搞一个DDD(Domain-Driven Design)。 当然,这里手动创建 `app/Models`的,一般都是model数量超过了10个。但是,这里我们想更进一步地,如果model数量超过50个呢?这个时候还是简单地放在 `app/Models`里,还有特别的意义吗? `app/Services`文件夹一般放置一些独立的业务相关的逻辑,可以用来将你的某一部分业务逻辑独立出来,使业务逻辑模块化,甚至方便后期将其独立成为单独的package给其他的项目使用,或者成为一个microservice,关于面向service,或者说package开发,就需要你对laravel底层及其原理有足够的掌握了,这里就推荐我们的[《Laravel底层核心技术实战揭秘》](https://study.163.com/course/courseMain.htm?courseId=1003575006&share=2&shareId=1018568251) `app/Helpers`和 `app/helpers.php`应该大同小异,前者放置一些辅助功能的class,后者放置一些全局的helper function,这个在我们的[《Laravel&Vue实战:任务管理系统二》](https://study.163.com/course/courseMain.htm?courseId=1003227034&share=2&shareId=1018568251)中也给大家介绍过了。 `app/Rules`,这个文件夹严格来说是laravel本身的,因为它是我们执行 `artisan make:rule`后产生的,关于laravel 5.5以后创建自定义的验证规则,也即rule,如果有不懂的同学,可以看我们之前给大家提供的文章:[【Laravel 5.5新特性】更方便地创建自定义的数据验证规则](https://www.pilishen.com/posts/Custom-Validation-Rules-in-laravel-5-5) 和 [Laravel的unique和exists验证规则的优化](https://www.pilishen.com/posts/Improvements-to-the-Laravel-unique-and-exists-validation-rules) 关于repository,是否放置在 `app/Repositories`内不是关键,关键是你是否使用,`Repository Design Pattern`可以说是laravel本身以及其众多第三方组件的命脉之一,`Repository Design Pattern`对于你分离业务逻辑,或者开发package,也非常关键。repository在laravel刚出来的时候,曾经在国外社区盛极一时,可谓是学laravel必学的,大概在2014年左右可以说是成为一种规范和标准在推行,甚至官方非常简单的起步项目都要介绍和使用,但是呢国内laravel流行的较晚一些,等到国内开始追逐laravel的时候,国外社区都“懒得提”repository了,加上很多国内材料或教程有意无意地躲避repository,说太复杂了不适合新手,没必要让新手学之类的。但其实不是,并不复杂,也并不需要向所谓的新手藏着掖着,否则新手怎么成为高手? 如果你对repository还感到陌生,不知道是咋回事,那么请务必看看我们的[《Laravel实战:任务管理系统(一)》](https://study.163.com/course/courseMain.htm?courseId=1003163020&share=2&shareId=1018568251),该课程可谓是国内唯一在初学阶段就让你轻松尝鲜 `Repository Design Pattern`的,让你在初学阶段就打下日后成为高手的根基,当然如果你想真真正正掌握 `Repository Design Pattern`的全貌,还是推荐我们的[《Laravel底层核心技术实战揭秘》](https://study.163.com/course/courseMain.htm?courseId=1003575006&share=2&shareId=1018568251) ### (六)改造基本的继承关系 这个一般是指自己额外创建一个 `BaseController` 或者 `BaseModel` class,让它们继承laravel默认的controller或model,然后自己的具体的controller或者model再继承这个 `BaseController` 或者 `BaseModel`,这期间就可以在 `BaseController` 或者 `BaseModel`里做一些自己的逻辑。 有23%的应用这么做了,这个呢其实也是不推荐的,这种做法往往在早期的一些国外教程或材料中能看到,但是新近的都不会这么搞,同时这个应该在国内不是很大的问题。 就比如说model,当我们想扩展其功能的时候,更优雅的办法是使用 `trait`,而不是写到 `BaseModel`里,这符合我们编程设计原则里常说的“composition over inheritance” ### (七)Facade的滥用 57%的应用滥用,或者说过度使用facade。Facade本身已然是laravel社区内一个极具争议的话题,或者说是laravel备受非议的一个话题,关于这一点,如果有不了解的,可以看看我们之前给大家写的扩展文章[PHP中的facade pattern(外观模式)](https://www.pilishen.com/posts/facade-pattern-in-php)。那么大部分的apps乱用facade,无异于火上浇油了。最大的争议发生在 `controller`和 `middleware`当中滥用 `Request`和 `Auth` 比如一起看一下这个 `controller`逻辑: ```bash php public function store() { $data = Request::only('product_id', 'token'); if (Auth::check()) { $data['email'] = Auth::user()->email; } // ... } ``` 这里呢使用 `Request`来获取请求数据,使用 `Auth`来获取当前用户。但是呢,无论是 `controller`还是 `middleware`,都可以注入一个 `request`实例: ```php public function store(Request $request) { $data = $request->only('product_id', 'token'); if ($request->user()) { $data['email'] = $request->user()->email; } // ... } ``` 这样就不用调用两个facade,而只通过一个request object。关于方法注入、或者依赖注入、或者依赖解析等,无论是我们的初级课程[《Laravel实战:任务管理系统(一)》](https://study.163.com/course/courseMain.htm?courseId=1003163020&share=2&shareId=1018568251),还是我们的高级课程[《Laravel底层核心技术实战揭秘》](https://study.163.com/course/courseMain.htm?courseId=1003575006&share=2&shareId=1018568251),都有大量的讲解和使用,这些也是掌握laravel、成为高手的关键。 当然,如果你有真正学习了我们的[《Laravel底层核心技术实战揭秘》](https://study.163.com/course/courseMain.htm?courseId=1003575006&share=2&shareId=1018568251),或者在阅读[PHP中的facade pattern(外观模式)](https://www.pilishen.com/posts/facade-pattern-in-php)之余做足了功夫,那么你会明白,上面的代码也并不能完全解决facade滥用的问题,因为毕竟 `Request`本身也是一个facade,但是毕竟降低了问题的程度,从而在更好的程序设计和测试过程中,能更大程度地解耦。 ### (八)View视图中的query查询 24%的应用在view中存在数据查询,这自然是bad practice,视图层不应该直接交互Model,确保使用Controller来传递相关的数据 ### (九)不要直接调用ENV变量值 42%的应用直接调用ENV变量。Laravel提供了 `artisan config:cache`来提高性能,为了充分利用这一功能,不要直接调用env数据,而是在config文件中调用。因此,你必须得通过config来间接获取env数值 ### (十)CRUD型Controller 77%的应用还没有采用 `CRUD型Controller`。所谓CRUD型Controller,指的是将controller里的方法限制为默认的CRUD这四类,或者说是默认的resourceful controller,也即里面只有 `index()`、`create()`、`store()`、`update()`、`edit()`、`show()`、`destroy()`这七个方法,任何多出来的方法都可以重构到单独的一个controller,这符合坊间“所有的操作其实归根到底都是CRUD操作”的说法。 当然这一理念呢,还比较新颖,属于是2017年的laravel国际会议laracon上才开始推荐,所以大部分的应用还没有真正地实践,应该国内的开发者也大都对此陌生,不过不要紧,在近期的课程更新中,我们将会在[《Laravel底层核心技术实战揭秘》](https://study.163.com/course/courseMain.htm?courseId=1003575006&share=2&shareId=1018568251)中给大家介绍类似的一些流行做法。 ### (十一)Controller内的数据验证(Validation) 89%的应用在Controller内进行数据验证,这也是不好的实践——正如我们在入门课程[《Laravel实战:任务管理系统(一)》](https://study.163.com/course/courseMain.htm?courseId=1003163020&share=2&shareId=1018568251)里就讲过的,Controller只是一个“指挥者”,它正常来说不负责任何具体的逻辑,所以此处的数据验证,最好是放到单独的Request文件中,正如我们在入门课程里提倡的那样。 ### (十二)Blade相关的命令 71%的应用还没有使用Laravel提供的一些blade命令。用的最少,但往往最有用的是 `@auth`,`@guest`,`@json`,`@method`,`@csrf`。 当然,这一项所提到的blade命令,其实大都是laravel 5.5才新出的,甚至有些呢文档上也没有提及,所以大家可能还不熟悉。自然,我们在blade里面可以使用原生的PHP标签,但是那样就有可能没有充分利用起来laravel给我们提供的便利与优雅,所以blade当中,我们经常也提倡尽可能地不用原生php标签。 关于blade命令,我们之前也给大家写过两篇文章:[【Laravel 5.5新特性】可以在blade中自定义if判断的简略标签](https://www.pilishen.com/posts/Custom-Blade-if-Directives-in-laravel-5-5) 和 [Laravel Blade中的@each用法](https://www.pilishen.com/posts/laravel-blade-ateach-directive) ### (十三)额外的一些数据分析 最后呢是一些附加的统计数据,注意的是,该项数据样本相对较小,而且只是限于laravel 5.5及更新版本,该项数据的生成使用的是[stefanzweifel/laravel-stats](https://github.com/stefanzweifel/laravel-stats)这个组件。 ```mysql +-------------------+-------+---------+---------------+------------+ | Name | Usage | Classes | Methods/Class | LoC/Method | +-------------------+-------+---------+---------------+------------+ | Commands | 66% | 6.37 | 2.42 | 9.68 | | Controllers | 67% | 20.91 | 4.10 | 6.28 | | Events | 29% | 5.63 | 1.64 | 7.69 | | Jobs | 31% | 4.11 | 2.36 | 11.84 | | Listeners | 39% | 5.35 | 1.89 | 5.16 | | Mails | 39% | 6.72 | 2.06 | 6.71 | | Middleware | 100% | 4.22 | 0.12 | 4.93 | | Models | 99% | 17.80 | 3.75 | 3.79 | | Notifications | 39% | 4.57 | 3.80 | 3.71 | | Policies | 19% | 5.09 | 3.96 | 2.88 | | Requests | 58% | 11.04 | 2.07 | 2.52 | | Resources | 7% | 14.75 | 0.94 | 4.95 | | Rules | 17% | 2.40 | 3.07 | 2.86 | | Service Providers | 100% | 6.28 | 1.97 | 4.61 | | PHPUnit Tests | 100% | 9.96 | 2.02 | 6.63 | | Dusk Tests | 18% | 5 | 3.00 | 6.67 | | Browserkit Tests | 3% | 13 | 4.16 | 6.05 | +-------------------+-------+---------+---------------+------------+ | Total | | 144.54 | 2.18 | 5.72 | +-------------------+-------+---------+---------------+------------+ ``` * 相对来讲,`Jobs`、`Controller`和 `Events`中的每一个method中包含了最多的代码 * 虽然 `phpunit test`显示的是100%的使用,但实际的情况是,大部分都只是laravel默认自带的示例测试文件。其他的数据显示,只有27%的应用里包含有自定义的测试 * 可能是 `laravel-stats`这个组件本身的bug,因为显示的是67%的应用使用controller,实际上不可能这么低 ### 结语 看了这些数据,你的laravel学对了吗?用对了吗?希望这些数据能给你的laravel使用与学习,提供更好的参考与建议~ 值得自豪的是,通过这些数据,可以看到两年前我们[pilishen.com](https://www.pilishen.com/)出品的[laravel从入门到高手系列课程](https://study.163.com/provider/1018568251/index.htm),两年后的今天,依然可以说是始终保持在laravel规范使用的前列,因此凡是认真学习了我们系列课程的小伙伴,应该也可以自豪地说自己的laravel用得很优雅、没问题,在此祝贺你们,同时感谢一往的支持。 这些数据,是过去的两三年内全球范围内Laravel使用情况的一个缩影,下一个时代,或者说下一个阶段,应该就是Laravel 5.5的时代了。值得庆祝的是,我们的[这些系列课程](https://study.163.com/provider/1018568251/index.htm),将于近期统统升级重录,更新到laravel 5.5及更新的版本,以保证小伙伴们继续领先下一个时代,下一个未来的两三年。此次更新,将不只是简单地版本更新,不是简单地把已有项目再做一遍,而是一次系统性的经典升华,升级后的课程将不仅包含本文数据里提到的这些最佳实践与建议,而且将包含大量这些数据里都不曾提到的更优实践,以此来切实保证咱们的小伙伴们真真正正地领先同行。而且,我们已经上车的小伙伴们,将完完全全免费获得更新后的所有课程,不止过去,包括将来,相信你们都是国内laravel开发者中的佼佼者~ Last modification:March 7, 2023 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏