小旅行者

雇用 Top 3%自由划船大黄开发商

Toptal.是Top Laravel开发商,工程师,程序员,编码器,建筑师和顾问的市场。顶级公司和初创公司选择Toptal Laravel Freelancers为他们的关键任务软件项目。

无风险审判,仅在满意时付款。

客户率 Toptal. Laravel Developers4.4 / 5.0平均截至237日,截至2001年3月27日

通过领先的品牌和初创公司信任

聘请自由职业者Laravel开发商和工程师

Philip Bennett.

自由划船小径开发商

德国Toptal. Member Since September 13, 2017

菲尔是一家经验丰富的Web开发人员,拥有17年的PHP和WordPress经验。重点关注高质量的超级性能交付,菲尔是一家务实的技术专家,他们选择了合适的技术,并有效地适用于按时和预算提供项目。菲尔有一个平衡的全堆栈知识,目前正在为大型跨国公司提供基于WordPress的网站。

展示更多

大卫梁

自由划船小径开发商

美国Toptal. Member Since October 23, 2017

David是一名全堆栈工程师,拥有超过12年的Web开发经验,管理开发过程的各个方面。他'S在50多个项目工作,并解决了各种行业的复杂业务问题,包括营销,医疗保健,电子商务,房地产和汽车保险。大卫在增加利润时一直节省成本。他'准备好机会使用他的技能指数增长您的收入。

展示更多

迈克尔斯蒂瓦省

自由划船小径开发商

马耳他Toptal. Member Since June 13, 2018

Mike拥有超过七年的经验,开发强大的基于Web的应用程序,并专注于使用现代测试驱动的开发实践构建性能的Laravel应用。他的经验范围从开发团队工作,按时提供复杂的项目,运行一个数字部门,他的想法和沟通技巧使他与客户和其他服务提供商协调工作。

展示更多

Brian Danchilla

自由划船小径开发商

加拿大Toptal. Member Since November 15, 2013

Brian是一个拥有超过15年的经验的全堆叠软件开发人员。在过去的十年中,他已经运行了自己的咨询业务,它提供了最前沿解决方案和遗留系统维护。布莱恩努力写清洁,现代,可靠的代码。始终磨练他的工艺,Brian与迅速变化的行业相信。

展示更多

Aleksandar Nikolic.

自由划船小径开发商

塞尔维亚Toptal. Member Since June 2, 2014

Aleksandar是高级Web开发人员和系统架构师。他很有动力,致力于提供高质量的代码,并不断改进每个项目。他以效率为荣,拥有众多工具,并在过去的10年里完成了各种项目。

展示更多

Jonathan Serle.

自由划船小径开发商

以色列Toptal. Member Since July 24, 2014

Jonathan是一个高度动力的开发人员和建筑师,具有独特的优势:他的沟通技巧和理解从自上而下的软件项目的能力。他的经验通过了各种各样的开发环境,从起始到财富500强。

展示更多

Aleksei Fedorenko.

自由划船小径开发商

俄罗斯Toptal. Member Since July 21, 2017

在过去的6年以上,Aleksei为一个在线服务公司,数字代理商工作,作为偏远的自由职业者。他建立了与HTML,CSS和现代JavaScript框架的干净且可靠的用户接口。 Aleksei在持续维护大型项目和短期内,使用巨大的前端技术范围的快速发展效果。

展示更多

布莱斯托特

自由划船小径开发商

美国Toptal. Member Since April 17, 2014

近20年作为工程师,建筑师,副总裁,副总裁,CTO,布莱斯深入了解任何项目的企业软件,管理和技术战略。他的专业包括亚马逊网络服务,实时系统,商业智能,大数据,企业网络应用,可扩展性,教育和开源软件。

展示更多

尼克库恩

自由划船小径开发商

美国Toptal. Member Since February 20, 2017

尼克在笨拙的经验中有十年多,并建立了一些最大,最识别的Drupal网站,如Fox.com和Americanidol.com。具有很大宽的技能集,他与任何大小的团队完全适合任何大小的团队,以及任何角色。他与Acquia合作,并制定了今天社区使用的几个最佳实践。在他的腰带下有超过50个项目,他拥有现实生活经验,需要成功地使应用程序成功。

展示更多

Alain Schlesser.

自由划船小径开发商

德国Toptal. Member Since September 17, 2016

Alain是一个自由职业者软件工程师,WordPress顾问和Google开发人员专家(GDE),专门从事企业级WordPress开发,规划可扩展的架构以及重构遗留代码,以使其适合未来十年。他超过25年的开发工作跨越了众多语言和平台,具有Oracle SQL和SharePoint的认证等。 Alain目前侧重于现代面向对象的PHP和域驱动的设计。

展示更多

立即注册以查看更多档案。

开始招聘

招聘指南

聘请伟大的Laravel开发商指南

小旅行者是强大而雄辩的;新手开发人员通常可以与它相当遥远。但在错误的手中,即使是最好的工具也可用于制造不可规划,不可能的产品。招聘真实专家意味着在这一综合招聘指南中所涉及的Laravel基础知识和最佳实践的手柄。

阅读招聘指南
TrustPilot.
Toptal. in the press

...允许公司快速组装具有特定项目的合适技能的团队。

尽管对编码人员的需求加速了,Toptaltal旨在自行为几乎常春藤联盟级审查。

我们的客户
构建一个全球使用的跨平台应用程序
Thierry Jakicevic.
构建一个全球使用的跨平台应用程序
1
2
3
为游戏创建一个应用程序
Conor Kenney.
为游戏创建一个应用程序
1
2
3
领导数字转型
Elmar Platzer.
领导数字转型
1
2
3
推荐书

三普国不会'T存在没有顶尖。顶部项目使我们能够用产品经理,铅开发商和高级设计师迅速发展我们的基础。在60多天内,我们从概念到阿尔法。速度,知识,专业知识和灵活性是秒数。 Toptaltal团队作为三级队员的三级队员的一部分。他们贡献并就像其他人一样贡献并获得了发展的所有权。我们将继续使用TOPTAL。作为一个启动,他们是我们的秘密武器。

布兰特利步长,首席执行官& Co-Founder

三级

我对Toptaltal的经验非常满意。我必须与我一起工作的专业人士在几个小时内与我一起。我知道在与他讨论我的项目后,他是我想要的候选人。我立即雇了他,他浪费了浪费时间来到我的项目,甚至通过添加一些优秀的设计元素来加强额外的英里,以增强我们的整体外观。

Paul Fenley,导演

k dunn.& Associates

我与令人难以置信的 - 聪明,驱动和响应性的开发人员。它曾经很难找到优质的工程师和顾问。现在它是't.

Ryan Rockefeller,CEO

辐射群

Toptal.立即了解我们的项目。我们与阿根廷的特殊自由职业者与阿根廷,从第1天沉浸在我们的行业中,与我们的团队无缝混合,理解我们的愿景,并产生了顶级缺口结果。 Toptal与卓越的开发人员和程序员相连,非常容易。

Jason Kulik,联合创始人

PROHATCH.

作为一个有限资源的小公司,我们可以'不起赚得昂贵的错误。 Toptal为我们提供了一个经验丰富的程序员,他们能够击中地面运行并立即开始贡献。这是一个伟大的经历和我们'd再次在心跳中重复。

斯图尔特Pocknee,校长

站点特定的软件解决方案

我们使用Toptal聘请开发人员,具有广泛的亚马逊网络服务体验。我们采访了四名候选人,其中一个候选人竟然有适合我们的要求。该过程快速有效。

ABNERGUZMÁNVILLA,CTO和首席科学家

照片kharma.

Sergio是一个令人敬畏的开发人员。顶级陷波,响应,并有效地完成了工作。

Dennis Baldwin,首席技术专家和联合创始人

PriceBlink.

与马林一起工作是一种快乐。他是有能力,专业,灵活的,非常快速地了解所需的内容以及如何实现它。

andréFischer,CTO

发布

我们需要一个专家工程师,他们可以立即启动我们的项目。辛巴纳斯与他的工作超出了我们的期望。不得不采访和追逐专家开发商是一个优秀的时光,让每个人都对我们的选择感到更加舒适,以改变平台来利用更强大的语言。 Toptog易于方便地制作了该过程。 Toptal现在是我们寻找专家级别帮助的第一名。

网页开发的高级VP德里克未成年人

Networld Media Group.

Toptal.'S开发人员和建筑师都非常专业,易于使用。他们生产的解决方案相当定价和最高品质,减少了推出的时间。再次感谢,Toptal。

Jeremy Wessels,CEO

Kognosi.

我们拥有Toptal的伟大体验。他们将我们与完美的开发人员配对,为我们的应用程序并使过程非常容易。它也很容易超出初始时间范围,我们能够在我们的项目中保持相同的承包商。我们绝对推荐顶尖,用于快速和无缝地找到高质量的人才。

Ryan Morrissey,CTO

应用业务技术,LLC

I'M Toptal令人难以置信地印象深刻。我们的开发人员每天与我沟通,是一个非常强大的编码器。他'真正的专业人士,他的工作很棒。顶部5星。

Pietro Casoar,CEO

Ronin Play Pty Ltd

与Toptal一起工作是一个很好的体验。在使用它们之前,我花了很长时间采访其他自由职业者和尚未'找到我需要的东西。与Toptal一起参与后,他们在几天内与完美的开发人员匹配。开发商I.'m不仅可以提供质量代码,而且他还提出了我达到的事情的建议't thought of. It'对我来说清楚,阿拉夫里知道他在做什么。强烈推荐!

乔治城,首席执行官

Buravard,Inc。

作为顶级合格的前端开发人员,我也运营了自己的咨询练习。当客户来找我来帮助填补他们的团队上的关键角色时,Toptal是我唯一舒适的推荐的地方。 Toptal.'整个候选池是最好的。 Toptal是我的最佳价值我'在近一年的专业在线工作中发现了。

Ethan Brooks,CTO

Langlotz专利&商标作品,Inc。

在嘻嘻哈哈'早期,我们以及时的方式,我们需要一流的开发商,以实惠的价格。 Toptal送货!

Lara Aldag,CEO

h

Toptal.让候选人非常容易,让您能使他们有能使他们有能力提供。我肯定会向寻求高技能开发人员的人推荐他们的服务。

Michael Gluckman,数据经理

mxit.

Toptal.迅速匹配我们的项目与最佳开发人员的能力只是一流的。开发商已成为我们团队的一部分,我对他们中的每一个都证明了专业承诺的水平。对于那些希望远程工作的人与最好的工程师来说,看起来不仅仅是Toptaltal。

Laurent Alis,创始人

临身

Toptal.让找到合格的工程师微风。我们需要经验丰富的ASP.NET MVC架构师来指导我们的启动应用程序的开发,并在不到一周内为我们提供三位伟大的候选人。在我们选择后,工程师立即在线并击中地面运行。它比我们自己发现和兽医候选人更快和更容易。

杰夫凯利,联合创始人

协调解决方案

我们需要在Scala中的一些短期工作,Toptal在24小时内发现了我们一个伟大的开发人员。这不仅仅是通过任何其他平台都无法实现。

Franco Arda,联合创始人

whatadswork.com.

Toptal.为正在进行快速发展和规模的企业提供禁令解决方案。每个工程师我们'通过Toptal签约已经很快集成到我们的团队中,并将其工作持有最高标准的质量,同时保持炽热的发展速度。

Greg Kimball,联合创始人

nifti.com.

如何通过Toptal雇用Laravel开发人员

1

与我们的行业专家交谈

Tophteal Engineering主任将与您合作,了解您的目标,技术需求和团队动态。
2

与手工选择的人才合作

在几天内,我们'LL为您的项目介绍您的Laravel开发人员。平均匹配时间在24小时内。
3

右边合身,保证

与您的新小狗开发人员合作进行试用期(仅在满意的情况下付款),确保他们'在开始参与之前,右边适合。

常见问题解答

  • Toptal Laravel开发人员如何不同?

    在Toptal,我们彻底屏蔽了我们的LARavel开发人员,以确保我们只与您匹配最高口径的人才。每年申请加入Toptal Network的100,000多人,削减少于3%。您将与工程专家(从不泛化招聘人员或人力资源代表)合作,了解您的目标,技术需求和团队动态。最终结果:来自我们网络的专家审计人才,习惯符合您的业务需求。 现在开始。

  • 我可以在不到48小时穿过Toptal雇用Laravel开发人员吗?

    根据可用性以及您可以进行的速度,您可以在注册的48小时内开始使用Laravel开发人员。 现在开始。

  • Toptal Laravel开发商的无风险试用期是多少?

    我们确保您与您的LARavel开发人员之间的每次参与开始于最多两周的试用期。这意味着您有时间确认订婚将是成功的。如果您对结果完全满意,我们会为您收取时间并继续接触,只要您想要。如果你没有完全满意,你将不会收取费用。从那里,我们可以通过部分方式,或者我们可以为您提供可能更适合的另一个专家,并与我们将开始第二名,无风险的审判。 现在开始。

分享
小旅行者

如何聘请伟大的Laravel开发商

自2011年初始发布以来,Laravel的使用和开发人员对其的兴趣呈指数级增长,并将其作为目前可用的最受欢迎的开源PHP框架建立。贡献因素是其极其丰富的功能集,优秀的文档,码优雅,以及所有的简约令人难以置信。

虽然从开发人员的角度来看,所有这些听起来都很棒,而且它真正的是Laravel发展的平面学习曲线意味着雇主需要采取额外的步骤来确保他们雇用能够提供质量,可扩展的兼职或全职开发人员。代码。本文将侧重于引入Laravel的广泛功能集以及一些核心编程概念,该概念将装备面试官构建有效的问题,并以适当的经验和专业知识为他们的项目要求识别开发人员。

概念

在我们进入Laravel细节之前,我们将介绍一些编程和Web应用程序概念。重要的采访者熟悉这些概念,因为我们稍后会参考他们,并理解它们也将使您能够衡量潜在的员工的编程知识。

模型 - 视图 - 控制器(MVC)

MVC是一种软件设计模式。简单地说,它决定了所有应用程序代码应分为三层:

  • 数据层(型号) 基于控制器的说明书存储和/或准备数据。
  • 呈现层(视图) 显示到最终用户从控制器接收的数据。
  • “胶水”层(控制器) 处理传入的请求,并指示数据层对请求数据处理的内容。基于该请求,它可以获得准备新数据的数据层,然后将其发送到呈现图层进行呈现。

小旅行者框架基于MVC模式,但它不强制开发人员使用MVC。这意味着一种不熟悉MVC而不是尊重最佳实践的开发人员可能会导致书面代码不佳,无论框架如何。

让我们来看看书面知之笔和书面代码的例子:

<html>
<head>
</head>
<body>

    <?php
    
    $pdo = new PDO('mysql:host=localhost;dbname=laraveldb', 'root', 'pass');
    $query = $pdo->query('select * from articles');
    $results = $query->fetchAll(PDO::FETCH_ASSOC);
    
    ?>

    <?php foreach ($results as $articleData): ?>

    <div>
        <h2><?php echo $articleData['title']; ?></h2>
        <p><?php echo $articleData['content']; ?></p>
    </div>

    <?php endforeach; ?>

</body>
</html>

在此示例中,我们将直接在呈现图层中与数据库进行交互。我们也没有文章表的模型,或者将数据发送到视图的控制器。让我们在Laravel中重写这一点。

Article model:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    //
}

Our controller, which will pass all of the Articles to the view:

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use App\Article;

class ArticleController extends Controller
{
    public function index()
    {
        return view('articlesList', ['articles' => Article::all()]);
    }
}

Now, the $articles variable will be available in our articlesList view:

<html>
<head>
</head>
<body>

    @foreach ($articles as $article)

    <div>
        <h2>{{ $article->title }}</h2>
        <p>{{ $article->content }}</p>
    </div>

    @endforeach

</body>
</html> 

代码的每个部分现在分为其相应的图层,使其清洁和可维护。

Note: This example uses syntax like Article::all() and @foreach that will be explained later in the guide.

依赖注入

依赖项注入是一种软件设计概念,其指出客户端(对象)应该只知道它需要执行某些功能的依赖性(例如,服务),但不应该知道谁提供了这些依赖项或它们的构造方式。这允许 松散的联轴器,这使得代码更灵活,不太容易出错。我们稍后会谈谈这一点。

让我们来看看一个例子:

class Article
{
    protected $contentFormatter;
    protected $content;

    public function __construct($content)
    {
        $this->contentFormatter = new ContentFormatter;
        $this->content = $content;
    }

    public function getFormattedContent()
    {
        return $this->contentFormatter->format($this->content);
    }
}

$article = new Article('Lorem Ipsum Content');
$formattedContent = $article->getFormattedContent();

We can see how the Article class is responsible for instantiating the ContentFormatter, when all it should really care about is providing the formatted content. Let’s implement dependency injection:

class Article
{
    protected $contentFormatter;
    protected $content;

    public function __construct($contentFormatter, $content)
    {
        $this->contentFormatter = $contentFormatter;
        $this->content = $content;
    }

    public function getFormattedContent()
    {
        return $this->contentFormatter->format($this->content);
    }
}

$contentFormatter = new ContentFormatter;
$article = new Article($contentFormatter, 'Lorem Ipsum Content');
$formattedContent = $article->getFormattedContent();

这可能似乎并不重要,但它将变得更加明显,这种技术如何解决架构问题,并在我们介绍本指南的“服务容器”部分后,更容易维护。

对象关系映射(ORM)

ORM是一种用于将数据从关系数据库表转换为对象的技术,反之亦然。一旦构造,这些对象然后可以通过通过ORM实现提供的API来操纵数据,并将其保存到数据库中。这大大简化了通过代码与数据库交互,并且在大多数情况下,不需要写入任何SQL。

以下是其工作原理的一些示例:

Article::where('is_active', 1)->get();
// select * from articles where is_active = 1


Article::create([
    'title' => 'Some Article Title', 
    'content' => 'Lorem ipsum content'
]);
// insert into articles (title, content) values 
// ("Some Article Title", "Lorem ipsum content")

User::whereIsNull('email')->delete();
// delete from users where email is null

小旅行者 Core Architecture

到目前为止,现在使用我们谈到的一切,到目前为止,管理人员应该能够制作面试问题,让开发人员对一些核心规划概念的了解,并帮助杂草缺乏缺乏建立公司的经验的人项目。但Laravel的具体架构和功能呢?

服务容器

服务容器是Laravel依赖注入实施的主要组成部分。它提供了注册不同类型的绑定的几种方法。也许最常用的容器的功能绑定到给定实现的接口。

app()->bind(
    'App\Contracts\PaymentGateway',
    'App\Services\StripePaymentGateway'
);

This code instructs the container to inject StripePaymentGateway when PaymentGateway service is required by a class:

class PaymentController
{
    protected $paymentGateway;

    public function __construct(PaymentGateway $paymentGateway)
    {
        $this->paymentGateway = $paymentGateway;
    }
}

Provided our PaymentController is resolved from the service container, its $paymentGateway property will be an instance of StripePaymentGateway. Remember the 松散的联轴器 we mentioned earlier? This is it. We’ve decoupled the client from the PaymentGateway implementation, which means, if at some point we decide to replace Stripe with some other payment gateway, we can just bind PaymentGateway interface to our new SomeOtherPaymentGateway implementation, and everything else will work without changing any of the code.

服务供应商

Service providers serve the purpose of bootstrapping a Laravel application. This includes registering different bindings, event listeners, or routes, as well as configuring things like macros. All service providers must be registered within the config/app.php config file.

Service providers include two methods: register and boot. The register method should only be used to bind things into the service container. The boot method is called after all the service providers have been registered, meaning its code has access to all the dependencies registered in any service provider. This method also supports type-hinting dependencies:

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\SomeService;

class PaymentGatewayServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(
            'App\Contracts\PaymentGateway',
            'App\Services\StripePaymentGateway'
        );
    }

    public function boot(SomeService $someService)
    {
        $someService->bootstrap();
    }
}

小旅行者 bootstraps all of its components through service providers, and by default ships with an empty provider (AppServiceProvider) so developers can use it for any additional custom bootstrapping. In larger applications, additional bootstrapping can be split between any number of different custom service providers.

请求生命周期

所有HTTP请求都由HTTP内核处理。在内部,HTTP内核在实际处理请求之前运行所有必需的引导者,包括加载所有服务提供商。接下来,请求传递给路由器。路由器运行所有适用的中间件 - 我们将稍后讨论 - 然后将请求调制到指定的控制器。

概括

了解Laravel的架构是编写清洁,灵活和可维护的代码的键之一。开发人员应该知道代码的某些部分属于哪些部分以及框架的不同组件如何一起工作。他们回答这些主题的问题的能力应该让面试官信心。

示出通过内核,路由器和控制器的请求的流程图。内核加载服务提供商(Auth,Cache,Cookie,Route),路由器运行特定于路由的中间件,并将请求与控制器方法匹配并调度,并且控制器基于请求准备响应数据并返回对响应的响应数据并返回响应用户。

小旅行者 Fundamentals

随着Laravel的核心架构清晰,让我们继续前进到Laravel的广泛功能集,每个经验丰富的开发人员都应该熟悉。这些模块中的每一个都很可能在大多数基于Laravel的应用中使用,因此面试官应确保候选人了解本节中的所有概念。

路由

路由是一种基于请求的URL指导对控制器方法的请求的方式。虽然Laravel的路由器是一个非常强大的工具,但我们不会详细介绍其所有功能。相反,我们将在审查候选人的代码时查看其基本功能以及您应该注意的事情。

以下是简单路由定义的示例:

Route::get('posts')->uses('[email protected]');

That route will direct all /posts GET requests to the index method of PostController.

By default, Laravel comes with web.php and api.php routes, located in the /routes folder, and, as we mentioned before, a sensible set of middleware assigned to these routes via the RouteServiceProvider.

注册路由支持所有HTTP动脉:

Route::get(...);
Route::post(...);
Route::put(...);
Route::patch(...);
Route::delete(...);
Route::options(...);

也可以匹配多个或所有动词:

Route::match(['get', 'post'], ...);

Route::any(...);

路由还接受关闭而不是控制器操作:

Route::get('post', function() {
    $posts = Post::all();

    return view('postList')->with(['posts' => $posts]);
});

...然而,在大多数情况下,这被认为是不良的做法,不应使用。它禁止代码并阻止路由缓存。与Laravel相当熟悉的开发人员将知道并避免它。

When defining routes, you’ll often need access to parts of the route URI called parameters. Parameters are segments encased within {}, can be optional ({param?}), and are automatically sent to the controller method:

Route::get('user/{userId}/posts/{postId?}')->uses('[email protected]');

// ...

// UserPostController's show method
public function show($userId, $postId = null) { ... }

路由器的另一个功能名为路由:

Route::get('posts')->name('posts')->uses('Pos[email protected]');

这使得可以轻松地为我们的视图中的路由生成URL:

<a href="{{ route('dashboard') }}">Dashboard</a>

或者,例如,在成功登录后重定向用户:

return redirect()->route('dashboard');

虽然路由器提供了更多功能,但这会达到基本的功能。熟练使用这些功能应该毫不费力地为经验丰富的Laravel开发商毫不费力地毫无努力。

中间件

中间件是一种过滤层,即在进入应用程序之前必须通过HTTP请求。例如,如果未登录用户,身份验证中间件可以拒绝请求,角色中间件可以基于其用户角色等重定向用户。

By default, Laravel ships with a web middleware group, which contains several useful middleware like session handling and cookie handling. It’s applied to all web requests by the RouteServiceProvider.

让我们看看中间件类可能的样子:

namespace App\Http\Middleware;

use Closure;

class UserIsAdmin
{
    public function handle($request, Closure $next)
    {
        if (! $request->user()->isAdmin()) {
            abort(403);
        }

        return $next($request);
    }
}

应用于路由时,此中间件将确保不拒绝非管理员用户访问该路由(我们将更多地讨论有关路由的更多信息)。

中间件 can be applied globally for every request, and per route as a single piece of middleware or a group of middleware. All middleware should be registered in the /app/Http/Kernel.php class.

To run a piece of middleware for every HTTP request, add it to the list in the $middleware property of the HTTP kernel class.

To assign middleware to a particular route, coders need to first add them to the list in the $routeMiddleware property:

// App\Http\Kernel Class

protected $routeMiddleware = [

    // Other middleware here...

    'admin' => App\Http\Middleware\UserIsAdmin::class,
];

Now, the 'admin' middleware can be assigned to a route:

Route::get('administration')->uses('[email protected]')->middleware('admin');

When assigning multiple middleware to a route, developers may want to group it first under a single key in the $middlewareGroups property:

protected $middlewareGroups = [
    'activeAdmin' => [
        App\Http\Middleware\UserIsActive::class,
        App\Http\Middleware\UserIsAdmin::class
    ]
];

然后使用该密钥将其分配给路由:

Route::get('administration')->uses('[email protected]')->middleware('activeAdmin');

Let’s look at our [email protected] method before applying the middleware:

// AdminController

public function index(Request $request)
{
    if (! $request->user()->isAdmin()) {
        abort(403);
    }

    return view('user.profile', ['user' => User::findOrFail($id)]);
}

Imagine if we had several methods in the AdminController which only admin users should have access to. We’d have to check for that condition in every single method, which would unnecessarily clutter the code and make it harder to maintain. After applying the admin middleware to our administration routes, we can clean up the code by getting rid of the condition check in the controller methods:

public function index(Request $request)
{
    return view('user.profile', ['user' => User::findOrFail($id)]);
}

在浏览候选人的代码示例时,这是一个详细的经理会做得很好。

控制器

在演示和数据层之间用作胶水,控制器是MVC模式的关键组件之一。指向控制器方法的路由允许您在控制器类中轻松组织请求处理逻辑,这显着提高了代码可读性。

控制器方法可以返回几种类型的响应。让我们列出最常见的:

// View:
return view('homepage')->with(['someVariable' => 'some value']);

// Response object:
return response($content)->header('Some-Header', 'Header-Value')->cookie('cookieName', 'cookieValue', $minutes);

// JSON:
return response()->json(['data' => $data]);

// File download:
return response()->download($filePath)->deleteFileAfterSend();

// Redirect
return redirect()->route('dashboard');

还有一些可能不用使用的响应类型:

// String
return 'Success';

// Array
return [1, 2, 3];

// Redirect to a controller action:
return redirect()->action('[email protected]');

// Redirect to external links:
return redirect()->away('//www.wybyqm.icu/');

早些时候,我们谈到将中间件分配到路线。还有另一种分配中间件的方法:直接在控制器的构造函数中。以这种方式指定中间件也支持仅将中间件附加到特定方法,或省略其特定方法。让我们来看看一个例子:

public function __construct()
{
    $this->middleware('something');
    $this->middleware('auth')->except('logout');
    $this->middleware('guest')->only('logout');
}

在控制器达到依赖注入时,可以解决一个重要的事情。在构造控制器对象时,Laravel的服务容器将在其构造函数中注入类型暗示的依赖项:

public function __construct(GuzzleHttp\Client $client)
{
    $this->client = $client;
}

…and in the called methods, where the most common injected dependency will be the Request instance:

public function update(Illuminate\Http\Request $request)
{
    // ...
}

这涵盖了Laravel控制器的基本特征。了解控制器如何工作和能够有效地使用它们的功能是每个专用Laravel开发人员的必备。

会议

会话提供了一种在多个HTTP请求中保留信息的方法:用户身份验证状态,表单数据没有完全验证等。Laravel支持多个会话驱动程序:

  • file
  • cookie
  • database
  • memcached
  • redis

这 default driver is file, because that will work out of the box on basically any setup, and is adequate for most applications. But memcached and redis are preferred because they’re 在记忆中 司机,因此非常表现。

这re are two ways to use the session feature provided by Laravel: Firstly, if we have access to the Request instance, we can call the session methods in the following way:

$request->session()->get('key');

Alternatively, we can use the session() helper, which will work anywhere:

session('key');

让我们来看看用于操纵会话数据的最常用方法:

// Get value for 'key', or default value if it doesn't exist:
session('key', 'default');

// Get all data in the session
session()->all();

// Store value for 'key':
$request->session()->put('key', 'value');
session()->put('key', 'value');
session(['key' => 'value']);

// Delete key
session()->forget('key');

// Delete all session data:
session()->flush();

由于维护跨多个请求的状态是Web开发的关键功能之一,因此开发人员熟悉支持的会话驱动程序之间的会话和差异很重要。

验证

验证是一种针对一组规则检查传入请求数据的方法。 Laravel提供了一个简单而强大的API,可以使用许多支持的规则进行验证。与许多其他Laravel主题一样,这个是广泛的,所以我们将介绍应该是每个良好的Laravel程序员工具集的一部分的基础知识。

这re are three different ways of using the validator. Firstly, if we have access to the Request instance, we can call the validate() method on it:

public function update(Request $request)
{
    $validatedData = $request->validate([
        'name' => 'required|string|max:150',
        'email' => 'required|email|max:150'
    ]);

    // Use the validated data...
}

其次,我们可以在控制器方法中键入表单请求。表单请求是自定义请求类,开发人员可以放置验证逻辑,并且它们显着减少了控制器中的杂波。这是在大多数情况下执行验证的首选方法:

public function update(UpdateUser $request)
{
    // The request is automatically validated against the rules
    // defined in the rules() method in the UpdateUser class

    // Fetch the validated data
    $validated = $request->validated();
}

This is what the rules() method would look like:

public function rules(Request $request)
{
    return [
       'name' => 'required|string|max:150',
       'email' => 'required|email|max:150'
    ];
}

Lastly, if the previous methods don’t give enough control over validation or how the validation error responses are generated by Laravel, we can manually create a Validator instance:

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class UserController extends Controller
{
    public function update(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required|string|max:150',
            'email' => 'required|email|max:150'
        ]);

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

        // Update user
    }
}

官方 验证规则列表 可以是良好的面试问题饲料。

因此,我们已经介绍了Laravel验证器最重要的功能,并希望您能够深入了解候选代码样本中要查找的内容。

刀片模板

刀片是Laravel强大,易于使用的模板引擎。虽然我们可以写一篇关于刀片的整篇文章,但我们只能通过每个Laravel Web开发人员熟悉的基本功能。

也许刀片最使用的功能是它能够扩展布局,使用部分,包括子视图。让我们来看看一个例子:

<!-- Main Layout -->

<html>
    <head>
        <title>Page</title>
    </head>
    <body>

        @include('header')
        @yield('content')

    </body>
</html>

Here, we have a base layout which is located in /resources/views/layout.blade.php. It includes a header subview, /resources/views/header.blade.php, and it displays content from the content 部分 的 the view which extends the layout. Here’s how we would write the /resources/page.blade.php view containing that section:

@extends('layout')

@section('content')

    <p>Lorem ipsum dolor sit amet.</p>

@endsection

我们的标题Subview可以如下所示:

<header>
    <h1>Lorem Page</h1>
</header>

Now, we just need to return the page.blade.php view from our controller method:

public function show()
{
    return view('page');
}

......呈现的HTML看起来像这样:

<html>
    <head>
        <title>Page</title>
    </head>
    <body>

        <header>
            <h1>Lorem Page</h1>
        </header>

        <p>Lorem ipsum dolor sit amet.</p>

    </body>
</html>

然而,通常,通常需要显示静态内容,我们需要将数据从控制器方法发送到他们需要显示的刀片视图。这可以很容易完成:

public function show()
{
    return view('page')->with(['pageTitle' => 'Some Page']);
}

$pageTitle variable will now be accessible in our views. Let’s display it in the header:

<header>
    <h1>{{ $pageTitle }}</h1>
</header>

Sometimes, we’ll also have collections of data which we’ll need to iterate over and display in the view. For example, let’s pull Posts from the database:

public function show()
{
    $posts = Post::all();

    return view('postList')->with(['posts' => $posts]);
}

In resources/views/postList.blade.php, Blade’s @foreach and @if statements make it a breeze to display only the active ones:

@extends('layout')

@section('content')

    @foreach($posts as $post)

        @if ($post->is_active)

            <h2>{{ $post->title }}</h2>

            {{ $post->content }}

        @endif

    @endforeach

@endsection

虽然刀片模板引擎还有很多更多,但这些是写入清洁,可扩展的前端代码所需的基础。在少数情况下,如果有的话,刀片会要求任何解决方法解决问题,因此在评估候选人的代码时,这是需要考虑的。

验证

小旅行者 comes with a complete and powerful, yet simple, authentication system implementation. By default, it uses the App\User model—specifically its email and password properties—to authenticate users.

与身份验证系统进行交互以两种方式之一完成:

  1. Using the Illuminate\Support\Facades\Auth facade
  2. Using the auth() helper function

两者都支持相同的方法,所以使用一个或另一个是开发人员的偏好。

让我们来看看使用身份验证时最常用的方法:

// Attempt to log in a user using credentials supplied in the request
if (auth()->attempt(['email' => $request->input('email'), 'password' => $request->input('password')])) {
    // User is authenticated
}

// Log in an existing user instance
auth()->login($user);

// Log a user in using their ID
auth()->loginUsingId($id);

// Retrieve authenticated user
$user = auth()->user();

// Log the user out
auth()->logout();

// Determine if the current user is logged in...
if (auth()->check()) {
    // User is logged in
}

// ...or not
if (auth()->guest()) {
    // User is not logged in
}

这简要概述了Laravel的身份验证系统如何工作。但是,对于大多数应用程序,这是真正需要利用其功能所需的一切。反过来,当涉及到所有与身份验证相关的所有繁重时,通过所有繁重的提升来加速开发过程。掌握身份验证系统的良好掌握是制造伟大的LARAVE专家的东西之一。

授权

授权是一种允许或阻止用户执行某些操作的方式 - 例如,创建页面或更新其用户名。有两种不同的方法:盖茨和政策。门是基于闭合的,主要用于与任何特定模型无关的动作,而策略基于类别,每个策略都是针对单个模型的特定。

Let’s look at a couple of Gates, which will usually be defined in the AuthServiceProvider:

public function boot()
{
    $this->registerPolicies();

    Gate::define('update-username', function ($user) {
        return $user->role == 'admin';
    });

    Gate::define('delete-page', function ($user, $page) {
        return $user->role == 'admin' && $page->canBeDeleted();
    });
}

Gates always receive a user instance as the first argument, and can receive any number of additional arguments. To use Gates, we have two methods at our disposal—全部ows and denies:

if (Gate::allows('update-username')) {
    // Current user can update their username...
}

if (Gate::denies('delete-page', $page)) {
    // Current user cannot delete the page...
}

Unlike gates, each policy’s focus is a single model. For example, if you have an application which has categorized items, you’re likely going to have an Item model and an ItemPolicy that authorizes actions for that model.

Policies are registered in the policies property of the AuthServiceProvider, where all models are mapped to their corresponding policies. The easiest way to create a policy is via the artisan make:policy command:

php artisan make:policy ItemPolicy

这 policy should contain a corresponding method for each model action that needs to be authorized, like update or delete, and should return true if the action is authorized, or false if it’s not. Each method will receive the user instance as its first parameter, and optionally an instance of the model for which the action is being authorized:

namespace App\Policies;

use App\Item;
use App\User;

class ItemPolicy
{
    // Every user can create an Item
    public function create(User $user)
    {
        return true;
    }

    // Only item's owner can update the Item
    public function update(User $user, Item $item)
    {
        return $item->user_id == $user->id;
    }

    // Only administrator can delete an item
    public function delete(User $user, Item $item)
    {
        return $user->role == 'admin';
    }
}

这re are several ways we can use policies. The most common ones are calling the can and cant methods on the user instance:

if ($user->can('create', App\Item::class)) {
    // ...
}

if ($user->cant('update', $item)) {
    // ...
}

…and calling the authorize method within a controller method on the controller instance:

public function delete(Request $request, $itemId)
{
    $item = Item::find($itemId);

    $this->authorize('delete', $item);

    // User can delete the item
}

门和政策提供了一种清洁而简单的方法来提取和分组应用程序的授权逻辑。熟练的Laravel开发人员将使用这些方法来保持其代码清洁,可读和可扩展。

收藏品

Collection class is a powerful wrapper for PHP arrays. It provides 众多方便的方法 for working with arrays, such as map, filter, and contains.

Creating a collection is very simple. We just call the collect() helper function and pass an array as an argument:

 $collection = collect(['some', 'values', 'here']);

现在,让我们来看看集合如何使开发人员的生活更轻松和代码清洁器的一些示例:

collect([20, 13, 18, 22])->sort()->values()->toArray();
// [13, 18, 20, 22]

collect([
    ['name' => 'John', 'age' => 20],
    ['name' => 'Jane', 'age' => 30],
    ['name' => 'Mark', 'age' => 35],
    ['name' => 'Buzz', 'age' => 18]
])->filter(function($item) {
    return $item['age'] >= 30;
})->toArray();
// [['name' => 'Jane', 'age' => 30], ['name' => 'Mark', 'age' => 35]]

collect([
    ['page' => 'Home'],
    ['page' => 'About Us']
])->map(function($item) {
    $item['slug'] = Str::slug($item['page']);
    return $item;
})->toArray();
// [['page' => 'Home', 'slug' => 'home'], ['page' => 'About Us', 'slug' => 'about-us']]

This is just a tiny fraction of what the Collection class is capable of. In a proficient developer’s hands, collections will all but render PHP’s native functions for working with arrays obsolete—speeding up development and increasing code readability. Good Laravel developers will use collections wherever possible; anything less should be considered a red flag.

工匠

工匠 is a command-line interface (CLI) that ships with Laravel. It provides numerous convenient commands for automating tedious, everyday tasks while writing an application, like generating controllers, models, and jobs; caching config, routes, and views; clearing the cache; creating migrations; and many more. (Running the php artisan list command gives a full list of commands.)

While the built-in commands are sufficient in most cases, sometimes, a developer will want to be able to execute some arbitrary, custom code via an Artisan command. They can do so by creating a custom command, which will be placed in the /app/Console/Commands folder:

php artisan make:command PruneUsers

Custom commands consist of $signature and $description properties, and the handle() method. $signature is used to run the command—for example, php artisan prune:users—and it will be displayed alongside the $description when artisan list is called. When running the command, the handle() method is called. This is where developers place the code to be run, and where they type-hint any dependencies:

namespace App\Console\Commands;

use App\User;
use App\Repositories\UserRepository;
use Illuminate\Console\Command;

class PruneUsers extends Command
{
    protected $signature = 'prune:users';

    protected $description = 'Prune inactive users';

    public function __construct()
    {
        parent::__construct();
    }

    public function handle(UserRepository $userRepository)
    {
        $userRepository->inactiveUsers()->delete();
    }
}

正如我们所看到的,Artisan命令可以非常方便,以自动化某些任务,以及通过调度程序和CLI快速和清洁到功能。熟悉Artisan CLI可以提高生产力并帮助开发人员清理其代码。

队列

LARAVAL队列使应用程序能够将冗长的任务(将电子邮件,生成报告等)卸载到处理的后台,从而显着增加了应用响应性。虽然这一主题非常全面,但我们将简要概述排队如何工作以及如何使用它们。

小旅行者 supports several different queue drivers out of the box: database, Beanstalkd, SQS, and Redis. For local testing, there is also a sync driver, which executes tasks immediately. Usually, developers will opt for one of these built-in connection options and configure several different queues (“lanes” that tasks can be dispatched into) on it—for example, one might have an emails queue and a reportGeneration queue. All of this is configured within the /config/queue.php configuration file.

With the configuration all set, we can start sending jobs onto queues. A Job is a dispatchable class, which just means it implements the Illuminate\Contracts\Queue\ShouldQueue contract so it can be easily sent off to a queue by calling the dispatch() method on it. Once in a queue, a job’s handle() method will be called—this is where the task-processing logic is coded.

Jobs are created by running the make:job 工匠 command:

php artisan make:job GenerateReport

Let’s look at an example of a Job class:

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class GenerateReport implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $reportData;

    public function __construct($reportData)
    {
        $this->reportData = $reportData;
    }

    public function handle()
    {
        // Generate Report logic...
    }
}

现在,让我们发出:

class ReportController extends Controller
{
    public function generate(Request $request)
    {
        GenerateReport::dispatch($request->all())->onQueue('reportGeneration');

        return response()->json(204);
    }
}

一旦作业被派遣到队列上,它将被A拾取 队伍工人。队列工作人员是长期流程,可在内存中持有当前的Laravel应用程序状态,并在队列中处理作业。这意味着它们不会将任何代码更改恢复到您的应用程序,因此每次更新应用程序时都需要重新启动队列工作者。使用以下Artisan命令启动并重新启动队列工作者:

# start
php artisan queue:work

# restart
php artisan queue:restart

队列可以是Laravel开发人员的阿森纳中一个非常强大的工具。因此,候选人应该熟悉应该使用队列和何时使用队列,以及支持的队列驱动程序之间的基本差异。

任务调度

Instead of having to ssh into a server and define a separate cron job for every recurring task, Laravel’s task scheduler allows developers to do so within PHP code using a fluent API. To make this work, all that’s needed is to set up a single cron job on the server that runs the php artisan schedule:run command every minute. Laravel will leverage this cron job to assess the app’s defined tasks and run the ones that are due.

Scheduled tasks are defined in the schedule method of the App\Console\Kernel class. The scheduler can run Artisan commands, queued jobs, or any other arbitrary piece of code:

protected function schedule(Schedule $schedule)
{
    // Run an artisan command once a week
    $schedule->command('locations:update-images')->weekly();

    // Queue a GenerateReport job once a day
    $schedule->job(new GenerateReport)->daily();

    // Execute arbitrary code every 30 minutes
    $schedule->call(function () {

        // Code...

    })->everyThirtyMinutes();
}

小旅行者调度程序也支持 各种命令 for defining the frequency at which the tasks will execute, like daily() and weekly() used in our examples.

小旅行者’s task scheduler is a very convenient tool for “porting” cron job definitions from the server to the app codebase, and therefore allowing developers to keep them within a project’s version control system (VCS)—e.g., Git, as well as making them more readable and elegant. Developers who know Laravel’s ins and outs will also know how to use the features offered by the task scheduler to their advantage.

数据库

Interacting with a database in Laravel is very simple, using either the Illuminate\Support\Facades\DB facade, or the Eloquent ORM. We’ll talk about Eloquent in a bit; for now, let’s look at how we can run raw SQL queries using the DB facade:

// Select statement
DB::select('select * from posts where id > ?', [20]);

// Insert statement
DB::insert('insert into posts (title, slug, content) values (?, ?)', ['First Post', 'first-post', 'Lorem ipsum content']);

// Insert statement
DB::update('update posts set content = ? where slug = ?', ['Dolor sit amet content', 'first-post']);

// Delete statement
DB::delete('delete from posts where slug = ?', ['first-post']);

// General statement
DB::statement('ALTER TABLE posts CHANGE title post_title VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci');

运行原始的SQL语句有时需要,但大多数情况下,有一种更好,更可读,基于API的基于API的方式,可以生成SQL查询:查询构建器。 Laravel的查询Builder提供了一个方便的方式生成几乎任何查询应用程序需要的需求。让我们看看最常用的方法:

// get() method returns a Collection of results
$posts = DB::table('posts')->get();

// where() method appends the WHERE clause
$posts = DB::table('posts')->where('id', '>', 20)->get();

// first() method returns the first result as an
// stdClass object that matches the criteria
$posts = DB::table('posts')->where('slug', 'some-post')->first();

// orderBy() method sorts the results
$posts = DB::orderBy('created_at', 'desc')->get();

// insert() method inserts a row into the database
DB::table('posts')->insert(
    ['title' => 'Some Post Title', 'slug' => 'some-post',
     'content' => 'Lorem ipsum content']
);

// update() method updates a row in the database
DB::table('posts')->where('slug', 'some-post')
    ->update(['content' => 'Dolor sit amet content']);

// delete() method deletes rows from the database
DB::table('posts')->where('active', 0)->delete();

以下是使用查询构建器可以实现的更多示例:

// Select all posts which are either active, 
// or created by users with id 1, 2 or 3
$posts = DB::table('posts')->where('is_active', 1)
    ->orWhereIn('user_id', [1, 2, 3])->get();

// Skip 20 posts, then select the next 10
$posts = DB::table('posts')->skip(20)->take(10)->get();

// Join posts with users, and select all columns from 
// 'posts' table, and 'name' from 'users' table
$posts = DB::table('posts')
    ->join('users', 'posts.user_id', '=', 'users.id')
    ->select('posts.*', 'users.name')->get();

Another convenient feature provided by the DB facade are transactions. A transaction ensures that either 全部 执行内部的查询,或者没有。有两种方法可以使用交易:基于Closure和手动:

// Closure based
DB::transaction(function () {
    DB::table('users')->where('id', 5)->update(['active' => 1]);
    DB::table('users')->where('active', 0)->delete();
});

// Manual
try {
    DB::beginTransaction();

    DB::table('users')->where('id', 5)->update(['active' => 1]);
    DB::table('users')->where('active', 0)->delete();

    DB::commit();
} catch (\Exception $e) {
    DB::rollback();
}

基于关闭的方法通常更简单,因为它会自动处理其事务,或者在异常情况下滚动它。但是,手动方法可以在需要的情况下提供更多的控制。

One last, but definitely not least, feature to mention is database migrations. Migrations are classes which allow for version-controlling database changes—everything from creating tables and columns, deleting them, and updating them. They consist of up and down methods. The up method is run when first changing the database in some way (creating a table, column, etc.), and the down method is used for reverting those changes.

Migration classes are generated by running the make:migration 工匠 command:

php artisan make:migration create_posts_table 

工匠 places the migration files in the /database/migrations folder. A migration file will include various 列类型(String,Text ...)和修饰符(索引,空...):

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title')->index();
            $table->string('subtitle')->nullable();
            $table->string('slug')->index();
            $table->text('content');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::drop('posts');
    }
}

Migrating the database is done via the migrate 工匠 command:

php artisan migrate 

This will run the up method in the migration classes. Rolling back the migrations is done by running:

php artisan migrate:rollback 

This will run the down method in the migration classes.

虽然与数据库的互动选项在Laravel中充足,但API相当容易记住,这使得有效的开发人员体验。深入了解数据库API工作如何对LARAVE应用程序开发非常重要,因为它会影响生产力和代码质量。

Eloquent:Laravel的对象 - 关系映射器(ORM)

Eloquent is likely the most complex component of the Laravel framework, but its basic functionalities are the foundation for using Laravel proficiently. Each Eloquent model maps directly to a database table, and each Model object maps to a database row in that table. This, and the fact that it uses Laravel’s query builder underneath to generate SQL queries makes it an invaluable tool for interacting with the database in an object-oriented way.

All Eloquent models must extend the Illuminate\Database\Eloquent\Model class, and the easiest way to create them is by using the make:model 工匠 command:

php artisan make:model Post

This will generate the following class in the app folder:

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    //
}

By default, the table name the model corresponds to will be auto-guessed by Eloquent—for our particular example, a posts table. If developers wish to define a custom table name, they can use the protected $table property on the model.

现在我们拥有我们的模型并了解它将使用哪个数据库表,让我们看看我们可以执行的最常用操作,使用与查询构建器所做的相同流利的API:

// Return a collection of Post objects
$posts = Post::all();
$posts = Post::where('active', 1)->get();
$posts = Post::where('user_id', 5)->orderBy('created_at', 'desc')->get();

// Return a single Post object
$post = Post::find(5);
$post = Post::where('slug', 'some-post')->first();

// Create a Post object
$post = Post::create(['title' => 'Some Post', 'slug' => 'some-post', 'content' => 'Lorem ipsum content']);

// Update the Post object
Post::where('slug', 'some-post')->update(['content' => 'Dolor sit amet content']);

// Alternatively
$post = Post::where('slug', 'some-post')->first();
$post->content = 'Dolor sit amet content';
$post->save();

// Delete the matching Post objects
Post::where('active', 0)->delete();

// Alternatively, delete a Post object
$post = Post::where('slug', 'some-post')->first();
$post->delete();

Another powerful feature of the Eloquent ORM is managing table relationships. For example, a Category model may have many Posts, and a Post may belong to a User. Eloquent provides 流利的API 用于管理几种类型的关系:

  • 一对一
  • 一对一
  • 很多到很多人
  • 有一点
  • 有很多
  • 一到一个(多晶型)
  • 一对多(多态)
  • 许多人(多态)

我们将看看最常用的关系:

  • 一对一 (a Category has many Posts)
  • 它的反向, 属于 (each Post 属于 a single User)
  • 很多到很多人 (a Post has many Tags, and a Tag can belong to many Posts)

关系被定义为返回关系实例的方法。让我们定义 一对一 Posts relationship on our Category model:

class Category extends Model
{
    public function posts()
    {
        return $this->hasMany('App\Post');
    }
}

For this relationship to work, we must have a category_id column in our posts table, which is automatically assumed by Laravel by concatenating category (snake-cased name of the Category model) and adding _id to it. Now we can call the relationship:

$categoryPosts = $category->posts()->get();

This will return a collection of Posts that belong to the given Category. Alternatively, we can achieve the same result by calling posts as a dynamic property instead of the posts() method. Eloquent is smart enough to map the posts dynamic property to the relationship method and return the desired Posts collection:

$categoryPosts = $category->posts;

我们也可以应用过滤器,与我们之前相同的筛选器:

$activePosts = $category->posts()->where('active', 1)->orderBy('created_at', 'desc')->get();

If we want to find out which User owns a certain Post, we can define inverse of the hasMany relationship (belongsTo) on our Post model:

class Post extends Model
{
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

让我们称之为:

$user = $post->user;

Once again, notice we’re not calling the user() method, but rather the user dynamic property.

很多到很多人 relationship requires an additional, intermediary (pivot) table. If we want our Posts to have many Tags, and the Tags to belong to many Posts, then our intermediary table will need to be named post_tag (snake-cased models ordered alphabetically) and have post_id and tag_id columns.

现在我们可以定义模型上的关系:

class Post extends Model
{
    public function tags()
    {
        return $this->belongsToMany('App\Tag');
    }
}

class Tag extends Model
{
    public function posts()
    {
        return $this->belongsToMany('App\Post');
    }
}

This allows us to find all the Tags for a given Post:

$postTags = $post->tags()->get();

And all the Posts a given Tag belongs to:

$tagPosts = $tag->posts()->get();

Eloquent还提供了一种优化数据库查询的方法 渴望加载. Eager loading solves the “N + 1 problem” when iterating over a collection of Model objects and querying their relationships. For example, let’s iterate over a category’s posts and display the name of each post’s user:

$category = Category::find(1);

foreach ($category->posts as $post) {
    echo $post->user->name;
}

如果我们的类别有10个帖子,则此代码段将生成12个查询。让我们看看发生了什么:

Category::find(1);

This will query the database for a Category with an ID of 1.

foreach ($category->posts ...

This will load the category’s posts into the Category object. Now comes the problematic part:

$post->user...

我们有10个帖子,每个帖子都会查询数据库以获取拥有帖子的用户,以便我们可以显示他们的名称。要解决这个问题,我们可以 渴望加载 所有类别的所有用户的帖子:

$category = Category::with('posts.user')->where('id', 1)->first();

By calling the with('posts.user') method, we can tell Eloquent that we want it to find all the posts belonging to the category with ID 1, then find all of their users in a single database query. This will result in a total of 只有三个疑问,无论类别的帖子数量如何:

  • 用于获取类别的一个查询
  • 一个查询来获取所有帖子
  • 一个查询,用于获取这些帖子的所有用户

这总结了Eloquent Orm的基础知识。虽然Eloquent可以做到我们在这里讨论的那么多,但这应该足以评估开发人员的知识达到多远。了解雄辩是每个专家LARULAR DEMPLOWER的必要条件,所以在面试过程中包括雄辩的相关问题将走很长的路要走。

调试

小旅行者的简单性可以是双刃剑。它可以欺骗新手开发人员认为写作代码将永远是一个平滑的体验,而且没有什么会出错。但这并不是软件开发的作品:一旦他们以欺骗虫的形式击中墙壁,他们就会迷路,不会知道如何向前迈进。一个 错误500. 屏幕将被呈现给他们,并且他们不会知道下一步是解决方案的。

经验丰富的开发人员最有价值的特征之一就是精通调试。谈到Laravel时,有几种方法可以调试应用程序。

这 first thing the developer should be aware of is the debug option in the config/app.php config file: When set to true, after hitting an exception in code, the exception details screen will be shown in the browser, instead of a blank error 500 page. This will, in most cases, point us to the exact line of code where the exception happened and provide a lot of helpful information about the exception. All of this information will also be written to the storage/logs/laravel.log log file, regardless of the value of the debug option.

调试的另一种伟大的方法是使用Laravel Debugbar库。除了显示所有与异常相关的数据之外,Debugbar还将提供有关请求数据,会话数据和执行的数据库查询的信息,这些数据库查询可以加速调试。其他值得一提的调试库是Laravel望远镜和发条浏览器扩展。

如何聘请最好的小狗开发人员:最佳实践的经验是关键

寻找和雇用一位伟大的Laravel自由职业者肯定是一个高大的秩序。 LARAVEL框架的简单性及其优秀,易懂的文档使得几乎所有开发人员都可以轻松迅速拾取,无论他们的经验如何。这可以使杂草开发人员难以为您的团队找到合适的兴趣。

我们的小径招聘指南提供了足够的知识和了解Laravel Web开发如何帮助认可在美国或国外的技术开发商,并为其业务需求做出正确的选择。但是,不知道这导游中提到的一切都不一定意味着开发商不擅长他们所做的事情。反之亦然:记住所有Laravel的文档而没有任何实用的经验,不会让开发商很棒。

通过本指南,关于如何雇用专用的LARAVE开发商,采访者可以轻松制作所需的相关面试问题,评估其候选人的知识,并在正常招聘模型中进行最终呼叫。好运!

特色Toptal Laravel出版物

顶级小狗开发商需求量很高。

开始招聘