Inspirer

文章列表

laravel 学习笔记 —— 查询构造器(下)

来继续填坑(上个月没发,因此这个月至少两篇)。

上一篇 laravel 学习笔记 —— 查询构造器(下) 中我们正在开始分析查询构造器的 where 方法,作为出场率最高的方法,其中相关的玩意儿足以帮助我们去理解整个组件大致的设计思路和实现细节。由于整体分析实在是太过麻烦(我其实就是懒),因此我们在上一篇的末尾提了三个问题,本文也将顺着这三个问题来进行解析,当然其余的思路类似的,就不在赘述,毕竟精力有限。

上一篇提到的问题是:

  • where 方法中多余的参数是干什么的
  • 方法中的代码为什么要拆分(或者封装)的那么细 ?
  • Expression 这个类是干嘛的 ?

我们就从多余的参数是做什么的开始吧。

Laravel Pipeline 组件的实现

Laravel 框架中有一个非常有趣的功能,就是 HTTP 中间件,我们在定义路由的时候,通过中间件对访问进行过滤。来自外部的请求首先经过全局中间件,若通过,则会继续穿过层层路由组所设置的中间件,在到达目的路由,当然,目的路由也可能定义了个中间件,通过后,该路由的处理对象(如控制器),得到的就是一个经过过滤的请求了。

开始

本文当然不是讨论中间件如何使用,而是其实现的基础。Laravel 框架中有一个组件叫做 Illuminate\Pipeline,意味 “管道”,我们看看下面这个代码示例:

<?php
use Illuminate\Pipeline\Pipeline;

$pipe1 = function ($poster, Closure $next) {
    $poster += 1;
    echo "pipe1: $poster\n";
    return $next($poster);
};

$pipe2 = function ($poster, Closure $next) {
    if ($poster > 7) {
        return $poster;
    }

    $poster += 3;
    echo "pipe2: $poster\n";
    return $next($poster);
};

$pipe3 = function ($poster, Closure $next) {
    $result = $next($poster);
    echo "pipe3: $result\n";
    return $result * 2;
};

$pipe4 = function ($poster, Closure $next) {
    $poster += 2;
    echo "pipe4 : $poster\n";
    return $next($poster);
};

$pipes = [$pipe1, $pipe2, $pipe3, $pipe4];

function dispatcher($poster, $pipes)
{
    echo "result: " . (new Pipeline)->send($poster)->through($pipes)->then(function ($poster) {
            echo "received: $poster\n";
            return 3;
        }) . "\n";
}

echo "==> action 1:\n";
dispatcher(5, $pipes);
echo "==> action 2:\n";
dispatcher(7, $pipes);

上述代码执行结果如下:

==> action 1:
pipe1: 6
pipe2: 9
pipe4 : 11
received: 11
pipe3: 3
result: 6
==> action 2:
pipe1: 8
result: 8

laravel 学习笔记 —— 查询构造器(上)

当下所有包含数据库组件的框架,都提供了一套流畅的操作方式去生成查询语句,这一部分我们称作 查询构造器 。查询构造器的存在,使得在数据库操作这一层面彻底的和原生开发区分开来。原生开发中,查询语句都是人为地根据业务需求手工写的,没有对查询语句进行规范的封装(即使有也不是人人能够做得到且做得好),随着项目扩展,这种原生的写法会导致项目愈发难以维护,而且由于操作原始,更加容易引发很多不必要的 BUG 以及安全隐患。查询构造器针对每一类语句关键字进行封装,通过流畅的链式方法组合,形成一个树状的数据结构,最终由生成器生成目标查询语句。

我向来认为 Laravel 框架的组件永远不是最优秀的,但由于其他框架或多或少不优雅、实现差、功能残缺,才使得 Laravel 的每个组件无论是单个拿出来看还是组合起来看,都是那么的好用,这其中的典型就是 查询构造器

laravel 学习笔记 —— 数据和模型之数据连接层

所谓万丈高楼平地起,再强大的功能组件,也是建立在许多功能很基础的模块之上。而且越是强大、富有扩展性,则拆分越细,分层越明显。Laravel 的许多组件都是这样,数据库组件当然更能直观体现出来这种设计思路。关于分层,我在上文已经给出了一定的解释,不再赘述。本文是对数据库的连接层进行讲述,在此,希望各位确保对 PDO 已经有了一定的认识和理解。

laravel 学习笔记 —— 数据和模型起步篇

自上一篇 《laravel 学习笔记 —— 神奇的服务容器》 已经有一年了,很多人都问过关于数据库部分的文章什么时候出来。其实不是不想写,而是没法写,因为当时大部分特性都没用到,以至于我无法以笔记形式给出。经过一年时间,laravel 已被我运用在很多类型的项目里,或多或少也对数据库组件了解的比较完整了,是时候完善学习笔记序列重要的环节之一 —— 数据库 部分。

Laravel 有三宝,路由、容器和 Eloquent ORM,Eloquent ORM 实际上是 Laravel 框架数据库组件的一个部分,也是最为重要和常用的,所以我们在说 Laravel 数据库组件时,往往指的是 Eloquent ORM。当然,数据库篇的文章肯定要全面讲述,这样有助于理解,也能帮助一些在这一块遇到问题的朋友。

数据库组件是一个比较独立的组件,只依赖很少的东西,通过 composer 安装的话,可以在任意一个项目里使用该组件的全部功能,而不需要安装 laravel 框架。具体使用方法可到其 github 主页获取:https://github.com/illuminate/database

由于篇幅有限,且平时很忙,我将会将数据库部分文章拆成包括本篇在内的多篇文章,本文作为概览和文章预告,会对整个数据库组件的构成做一个大致的讲解。

扩展 Laravel 默认 Session 中间件导致的 Session 写入失效问题

最近由于项目开发需要,手机客户端和网页端统一使用一套接口,为保证 会话(Session) 能够正常且在各类情况下兼容,我希望能够改变 SessionID 的获取方式。默认情况下,所有网站都是通过 HTTP 请求的 Header 头部中的 Cookie 实现的,通过 Cookie 中指定的 SessionID 来关联到服务端对应数据,从而实现会话功能。

但对于手机客户端,可能并不会支持原始的 Cookie,亦或者根据平台需要而屏蔽,因此开发中要求通过增加一个请求头 X-Session-Token 来标识 SessionID。在 Laravel 框架中,实现 Session 初始化、读取和启动,都是通过 Illuminate\Session\Middleware\StartSession 这个中间件实现的,该中间件有一个关键方法 getSession,这个方法就是获取 SessionId 从而告知 Session 组件以什么凭据恢复 Session 数据。

该中间件注册于 app/Http/Kernel.php 文件下。

我新建了一个类继承该中间件,同时替换了在 app/Http/Kernel.php 下的注册的地方,原来的 getSession 方法源码如下:

public function getSession(Request $request)
{
    $session = $this->manager->driver();
    $session->setId($request->cookies->get($session->getName()));
    return $session;
}

在新的中间件中,我修改为:

public function getSession(Request $request)
{
    $session = $this->manager->driver();
    // 判断是否是接口访问并根据实际情况选择 SessionID 的获取方式
    if ($request->headers->has('x-session-token')) {
        $sessionId = $request->headers->has('x-session-token');
    } else {
        $sessionId = $request->cookies->get($session->getName());
    }
    $session->setId($sessionId);
    return $session;
}

但是麻烦也随之而来。。。

替换 laravel 分页组件默认生成的模板

在使用 Laravel 分页功能时,需要配合使用前端框架 Bootstrap 的分页组件,这两者结合甚为紧密。可是由于我的博客更换为 AmazeUI,而 AmazeUI 分页组件使用的 CSS 类选择器是 .am-pagination 而不是 Bootstrap 的 .pagination

那么如何在不修改框架代码的前提下替换默认的 Laravel Pagination 生成的 html 模板呢?本文将通过利用 Laravel Service Provider (服务提供者)实现该需求。通过了解本文的内容大家也可以实现更多的分页样式。

博客换装——“灵感”的新面孔

在一个多月中想法设法的挤出时间,调整了博客的模板,算是给自己一个满意的交代吧。

常关注我这个博客的朋友,应该发现我很喜欢 Dark Theme,包括我的代码编辑器在内,都趋向这种色调。但之前由于模板的设计很仓促,问题相当多,最大的问题就是对比度过高,看着及其费眼睛。于是经过这段时间慢慢调优,才有了现在的新面貌。

laravel 学习笔记 —— 神奇的服务容器

竟然有人认为我是抄 Laravel 学院的,心塞。世界观已崩塌。

容器,字面上理解就是装东西的东西。常见的变量、对象属性等都可以算是容器。一个容器能够装什么,全部取决于你对该容器的定义。当然,有这样一种容器,它存放的不是文本、数值,而是对象、对象的描述(类、接口)或者是提供对象的回调,通过这种容器,我们得以实现许多高级的功能,其中最常提到的,就是 “解耦” 、“依赖注入(DI)”。本文就从这里开始。

IoC 容器, laravel 的核心

Laravel 的核心就是一个 IoC 容器,根据文档,称其为“服务容器”,顾名思义,该容器提供了整个框架中需要的一系列服务。作为初学者,很多人会在这一个概念上犯难,因此,我打算从一些基础的内容开始讲解,通过理解面向对象开发中依赖的产生和解决方法,来逐渐揭开“依赖注入”的面纱,逐渐理解这一神奇的设计理念。

本文一大半内容都是通过举例来让读者去理解什么是 IoC(控制反转)DI(依赖注入),通过理解这些概念,来更加深入。更多关于 laravel 服务容器的用法建议阅读文档即可。

PHP开发

php,一个优秀的服务端脚本语言。灵活而又不失效率的php,在web领域风光无限,随着更为强劲的php引擎的不断演进,php在互联网领域前途依旧光明。

分类
标签