Laravel以编写干净、可用和可调试的代码而为PHP开发人员所熟知。它还支持大量有时未记录的功能,或者它们存在并由于某种原因被删除。我已经在生产环境中使用Laravel2年了,我已经学会了如何让我的代码变得更好,而且从我第一次使用它开始我就充分利用了它。接下来,我将向您展示一些在Laravel中编写代码时可能会有所帮助的技巧。*在查询数据时使用本地范围Laravel有一种很棒的方法可以使用查询构建器编写查询。像这样:$orders=Order::where('status','delivered')->where('paid',true)->get();好的。这让我可以专注于编写更友好的代码而不是SQL语句。但是有了本地作用域,我们可以让这行代码好一点。本地范围允许我们在查询数据时创建自己的查询构建器方法链。例如,我们可以使用更简洁的->delivered()和->paid()来代替->where()。首先,在Order模型中,我们添加一些方法:}publicfunctionscopePaid($query){return$query->where('paid',true);}}声明局部作用域时,应使用scope[Something]作为名称。这样Laravel就会知道这是一个局部作用域并且可以在查询构建器中使用它。确保将第一个参数$query传递给该方法,这是Laravel自动注入的查询构建器实例。$orders=Order::delivered()->paid()->get();对于接受附加参数的查询,您可以使用动态范围。每个作用域都允许您传入额外的参数。classOrderextendsModel{...publicfunctionscopeStatus($query,string$status){return$query->where('status',$status);}}$orders=Order::status('delivered')->paid()->get();在本文后面,您将看到为什么数据库字段应该使用蛇形命名,但这是第一个原因:Laravel默认将scope[Something]替换为where[Something]。因此,您可以这样做,而不是scopeStatus范围:Order::whereStatus('delivered')->paid()->get();对于where[Something],Laravel将搜索数据库字段的蛇名版本。如果你的数据库中有一个状态字段,你可以使用上面的例子。如果有shipping_status字段,可以使用:Order::whereShippingStatus('delivered')->paid()->get();由你决定!必要时使用请求类Laravel提供了一种极好的方式来验证表单提交的数据。如果需要,它可以验证POST和GET请求。在控制器中,你可以这样做:publicfunctionstore(Request$request){$validatedData=$request->validate(['title'=>'required|unique:posts|max:255','body'=>'必需的',]);//Ifthisblogcontentisinvalid...}但是当controller中已经有很多代码的时候,再加上验证表单数据的代码会很乱。你想尽可能地减少控制器中的代码——至少这是我在控制器中编写大量逻辑时首先想到的。Laravel提供了一种可爱的方式来通过创建和使用专用的Request类而不是原始的Request来验证表单请求。你只需要创建你的请求类:phpartisanmake:requestStoreBlogPost你可以在app/Http/Requests/目录中找到你刚刚创建的请求类:classStoreBlogPostRequestextendsFormRequest{publicfunctionauthorize(){return$this->用户()->can('create.posts');}publicfunctionrules(){return['title'=>'required|unique:posts|max:255','body'=>'required',];现在,您应该用新创建的App\Http\Requests\StoreBlogPostRequest替换原来的Illuminate\Http\Request类:useApp\Http\Requests\StoreBlogPostRequest;publicfunctionstore(StoreBlogPostRequest$request){//如果这篇博文的内容无效...}请求类中的authorize()方法应该返回一个布尔值。如果返回false,它会抛出403异常,确保你在app/Exceptions/Handler.php的render()方法中捕获了这个异常:publicfunctionrender($request,Exception$exception){if($exceptioninstanceof\Illuminate\Auth\Access\AuthorizationException){//}returnparent::render($request,$exception);}请求类中还有一个messages()方法,当认证失败时,会返回一条消息包含一组错误消息:classStoreBlogPostRequestextendsFormRequest{publicfunctionauthorize(){return$this->user()->can('create.posts');}publicfunctionrules(){return['title'=>'required|unique:posts|max:255','body'=>'required',];}publicfunctionmessages(){return['title.required'=>'需要标题。','title.unique'=>'帖子标题已经存在。',...];}}@if($errors->any())@foreach($errors->all()as$error){{$error}}@endforeach@endif如果你想获取某个字段的校验信息,你可以这样做(当字段验证通过$errors->has()将返回一个false):@if($errors->has('title')){{$errors->first('title')}}@endifmagicrange构造查询时,可以使用已有的magicrange:根据created_at倒序查询:User::latest()->get();根据任何字段反向查询:User::latest('last_login_at')->get();随机查询(即SQL语句中的ORDERBYRAND())User::inRandomOrder()->get();使用关联而不是冗长的查询(或写得不好的查询)您是否曾经在查询语句中使用大量连接操作来获取更多信息?编写这样的SQL语句很困难,即使使用查询构建器也是如此,但数据模型已经使用关系来实现相同的功能。因为文档提供了太多信息,所以一开始您可能对关系不感兴趣。不熟悉,但这些内容可以帮助您更好地理解事物的工作原理,并使您的程序运行更流畅。在此处查看关系的文档。使用任务系统处理耗时任务Laravel的任务是在后台运行程序的强大工具。您要发送电子邮件吗?任务系统。你想广播消息吗?任务系统。你想处理图片?任务系统。任务系统可以帮助您减少用户在执行上述任务时的应用加载时间。这些任务可以放入命名队列中,并且可以确定它们的优先级。Laravel几乎在每个可能的地方都实现了队列:无论是在后台执行一些PHP任务,还是发送消息,广播事件,这些场景都会用到队列。出现在。您可以在此处查看队列的文档。使用队列时,我喜欢使用LaravelHorizo??n,因为它易于安装,它可以通过Supervisor工具或配置文件在后台运行,并且我可以告诉Horizo??n我希望每个队列产生多少个进程。遵循数据库标准和访问器Laravel从一开始就教你变量和方法应该以驼峰命名,如$camelCasecamelCase(),数据库字段应该以蛇形命名,如snake_case。为什么?因为它可以帮助我们构建更好的访问器。访问器是可以直接在模型中构建的自定义字段。如果我们的数据库包含first_name、last_name和age等字段,我们可以添加一个名为name的自定义字段来组合first_name和last_name。别担心,这个名字不会被写入数据库。它只是某个模型的自定义属性。所有访问器,如范围,都有自定义命名语法:getSomethingAttribute:classUserextendsModel{...publicfunctiongetNameAttribute():string{return$this->first_name.''.$this->last_name;}}当使用$user->name时,访问器将返回一个连接的字符串。*默认情况下,使用dd($user)无法看到name属性,但我们可以通过$appends变量使其始终可用:classUserextendsModel{protected$appends=['name',];...publicfunctiongetNameAttribute():string{return$this->first_name.''.$this->last_name;现在每次dd($user),我们都可以看到名字。(但是,这个属性仍然不是从数据库中获取的,而是在每次使用时从first_name和last_name连接起来的)。需要注意的是,如果你的数据库中已经有了name字段,情况会有点不同:不需要$appends数组中的name元素,然后accessor需要传入一个参数,也就是数据库名称中的值(意味着我们不再需要使用$this了)。例如,我们可能希望使用ucfirst()将名称的首字母大写:classUserextendsModel{protected$appends=[//];...publicfunctiongetFirstNameAttribute($firstName):string{returnucfirst($firstName);}}publicfunctiongetLastNameAttribute($lastName):string{returnucfirst($lastName);}}现在当我们使用$user->first_name时,它??会返回一个首字母大写的字符串。由于这个特性,数据库字段最好用snake_case命名。不要将与模型相关的静态数据存储在配置文件中我喜欢将与模型相关的静态数据存储在模型文件中。一起来看看吧。不要做这样的事情:BettingOdds.phpclassBettingOddsextendsModel{...}config/bettingOdds.phpreturn['sports'=>['soccer'=>'sport:1','tennis'=>'sport:2','篮球'=>'运动:3',...],];使用以下方式访问:config('bettingOdds.sports.soccer');我更喜欢这样做:BettingOdds.phpclassBettingOddsextendsModel{protectedstatic$sports=['soccer'=>'sport:1','tennis'=>'sport:2','basketball'=>'sport:3',...];}并访问它们:BettingOdds::$sports['soccer'];为什么是这样?因为这样有利于后续操作:classBettingOddsextendsModel{protectedstatic$sports=['soccer'=>'sport:1','tennis'=>'sport:2','basketball'=>'sport:3',...];publicfunctionscopeSport($query,string$sport){if(!isset(self::$sports[$sport])){return$query;}返回$query->where('sport_id',self::$sports[$sport]);现在我们可以使用范围查询:BettingOdds::sport('soccer')->get();改用集合替换原始数组处理在过去,我们以原始方式使用数组:$fruits=['apple','pear','banana','strawberry'];foreach($fruitsas$fruit){echo'我有'.$fruit;}现在,我们可以使用一种高级方法(译者注:集合法)来处理数组中的数据。我们可以过滤、转换、遍历和修改数组中的数据:)->toArray();['pear','banana','strawberry']有关详细信息,请参阅集合文档。使用查询生成器时,->get()方法返回一个Collection实例。但要注意不要混淆Collection和Querybuilder:从QueryBuilder中,我们无法获取任何数据。但是我们有大量与查询相关的方法可用:orderBy()、where()等。在->get()方法最终被调用,获取数据并消耗内存空间。它返回一个Collection实例。一些查询构建器不可用或可用但具有不同的方法名称,请参阅所有收集方法了解这些。如果您可以在查询生成器级别过滤数据,那就去做吧!在返回生成的Collection实例之前不要依赖过滤——您将消耗更多的内存空间。使用Limit来限制结果的数量,在DB层使用索引来加速查询。用好扩展包,不要重新发明轮子。以下是我正在使用的一些扩展包:LaravelBladeDirectivesLaravelCORS(跨域请求时,限制你的路由到指定域名访问)LaravelTagHelper(在BladeHTML标签中使用更方便)LaravelSluggable(生成slugs时很有用在Eloquent模型中)LaravelResponder(更容易构建JSONAPI)ImageIntervention(处理图像)Horizo??n(管理队列,配置很少)Socialite(集成第三方社交媒体登录,配置很少)Passport(集成OAuth路由)Spatie的ActivityLog(跟踪模型修改活动)Spatie'sBackup(备份文件和数据库)Spatie'sBlade-X(定义你自己的HTML标签;可以与LaravelTagHelper结合)Spatie'sMediaLibrary(快速将模型与文件关联)Spatie'sResponseCache(缓存完整响应controller的content)Spatie'sCollectionMacros(在集合中添加更多的宏)下面是我(原作者)写的一些扩展:Befriended(类似于社交媒体的Like、listen、block操作)Schedule(创建一个时间表并检查它在某个时间点是否可用)Rating(为模型添加评分功能)Guardian(易于使用的权限系统)太难理解?现在联系我!如果你有更多关于Laravel的问题,如果你需要操作方面的帮助,或者只是想说声谢谢,你可以在Twitter@rennokki上找到我!转自PHP/Laravel开发者社区https://laravel-china.org/top...