资讯专栏INFORMATION COLUMN

利用 Composer 完善自己的 PHP 框架(一)——视图装载

LinkedME2016 / 2029人阅读

摘要:我们先从目前用着最不爽的地方视图装载下手。实现装载器完成基础准备以后我们正式开始制造视图装载器。下一步利用完善自己的框架二发送邮件

原文发表在我的个人网站:利用 Composer 完善自己的 PHP 框架(一)——视图装载


本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer


回顾

经过了上一个 系列教程 《利用 Composer 一步一步构建自己的 PHP 框架》,我们组建了一个具有 路由MVC 架构ORM 功能的基础框架 MFFC。接下来我们继续完善这个项目。

我们先从目前用着 最不爽 的地方——视图装载下手。我们将封装一个视图装载类,让它来帮我们装载视图,并把变量传递进视图。这个类将只暴露出来几个简单的接口,让我们在控制器里面用的爽,让我们一边写代码一边笑。真的笑,笑出声。:-D


正文 构思

视图装载类要做的工作其实很简单:

根据视图名称找到视图文件,支持文件夹

更加方便,更加优雅地把变量的值传递进视图

本文中我们将不会不引入模板引擎,只做装载文件和传递变量的功能。

基础准备

我们要引入视图装载器,这就正式打开了组件化的大门,所以我们需要做一些准备工作。

1. 启动流程组件化

public/index.php 里面的代码分离一部分到启动器(bootstrap),新建 MFFC/bootstrap.php 文件:

addConnection(require BASE_PATH."/config/database.php");
$capsule->bootEloquent();

修改 public/index.php 为:



这时候我们就完成了 入口文件 和 启动器 的分离,并定义了两个全局常量 BASE_PATHPUBLIC_PATH


  

在这里我们需要特别注意一点:“引入路由配置文件” 这一步并不只是简单地引入了一个配置文件,路由文件的最后一行 Macaw::dispatch(); 才是 真正执行某个控制器中某个 function 的地方,所有准备条件都应该在载入路由文件之前完成,例如 Eloquent 的初始化,还有以后我们要使用的 Composer 包的初始化等等。


2. 引入错误页面提示组件

我们选择 filp/whoops 作为我们错误提示组件包。

修改 composer.json

"require": {
  "codingbean/macaw": "dev-master",
  "illuminate/database": "*",
  "filp/whoops": "*"
},

运行 composer update,然后在 bootstrap.php 的最后添加:

// whoops 错误提示
$whoops = new WhoopsRun;
$whoops->pushHandler(new WhoopsHandlerPrettyPageHandler);
$whoops->register();

刷新 http://127.0.0.1:81 ,你得到的应该还是这个页面:

下面我们将增加路由配置中 无匹配项 的错误页面,修改 config/routes.php



现在访问一个随意输入的 URL,例如 http://127.0.0.1:81/asd ,我们会看到以下画面:

是不是有一种很熟悉的感觉!

很不幸,这个错误提示包正是 Laravel 采用的那个,所以,我们可爱的 MFFC 框架在长大以后还是成了 Laravel 的样子。%>_<%

实现装载器

完成基础准备以后我们正式开始制造视图装载器。

视图装载器是一个可插拔组件,我们应该把所有可插拔组件全部归到一处,在 MFFC 中建议放在 MFFC/services 下。

CI 框架提供的基础组件库叫 helpers,Laravel 使用 illuminate/support 包提供一些可重用的系统函数。实际上 “illuminate/support” 这个包已经被我们的 ORM 包 “illuminate/database” 依赖了,现在 MFFC 框架里面已经可以直接使用。,这个包的中文文档见:http://laravel-china.org/docs/helpers

我们并没有像 CI 框架那样把视图装载器放到系统核心,有以下两个原因:

基于命名空间与自动加载的调用方式更加节省资源

在移动互联网和大前端愈演愈烈的时代,后端越来越 API 化、 json 化。很多时候都不到视图,没有必要再增加无畏的消耗。

下面开始着手实现视图装载器。

新建 MFFC/services 文件夹,并修改 composer.json 把这个文件夹下的所有类自动归入根命名空间:

"autoload": {
  "classmap": [
    "app/controllers",
    "app/models",
    "services"
  ]
}

新建 services/View.php 文件,内容如下:

view = $view;
  }

  public static function make($viewName = null)
  {
    if ( ! $viewName ) {
      throw new InvalidArgumentException("视图名称不能为空!");
    } else {

      $viewFilePath = self::getFilePath($viewName);
      if ( is_file($viewFilePath) ) {
        return new View($viewFilePath);
      } else {
        throw new UnexpectedValueException("视图文件不存在!");
      }
    }
  }

  public function with($key, $value = null)
  {
    $this->data[$key] = $value;
    return $this;
  }

  private static function getFilePath($viewName)
  {
    $filePath = str_replace(".", "/", $viewName);
    return BASE_PATH.self::VIEW_BASE_PATH.$filePath.".php";
  }

  public function __call($method, $parameters)
  {
    if (starts_with($method, "with"))
    {
      return $this->with(snake_case(substr($method, 4)), $parameters[0]);
    }

    throw new BadMethodCallException("方法 [$method] 不存在!.");
  }
}

运行 composer dump-autoload,完成以后,我们就可以在控制器中直接调用这个类了。

修改 controllers/HomeController.php

view = View::make("home")->with("article",Article::first())
                                    ->withTitle("MFFC :-D")
                                    ->withFuckMe("OK!");
  }
}

修改 controllers/BaseController.php

view;
    if ( $view instanceof View ) {
      extract($view->data);
      require $view->view;
    }
  }
}

修改 app/views/home.php




  
  <?php echo $title ?>


  

  • Fuck Me !

刷新,你将看到以下页面:

至此,视图装载器实现完成。


下面我大致说一下设计视图装载器的基本思路:

这个视图装载器类模仿了 Laravel 的 View 类,它实现了一个静态方法 make,接受视图名称作为参数,以 . 作为目录的间隔符。

make 静态方法会检查视图名称是否为空,检查视图文件是否存在,并给出相应的异常。这就是我们引入异常处理包的原因。

视图名称合法且文件存在时,实例化一个 View 类的对象,返回。

使用 with("key", $value) 或者优雅的 withKey($value) 来给这个 View 对象插入要在视图里调用的变量。withFuckMe($value) 将采用蛇形命名法被转化成 $fuck_me 供视图使用。

最终组装好的 View 对象会被赋给 HomeController 的成员变量 $view,这个变量是从 BaseController 中继承得来。

父类 BaseController 中的析构函数 __destruct() 将在 function home() 执行完成后处理这个成员变量:extract 出视图要用到的变量,require 视图文件,将最终运算结果发送给浏览器,流程结束。


下一步:利用 Composer 完善自己的 PHP 框架(二)——发送邮件

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/20853.html

相关文章

  • 【完结】利用 Composer 完善自己 PHP 框架(三)——Redis 缓存

    摘要:原文发表在我的个人网站利用完善自己的框架三缓存本教程示例代码见回顾上两篇文章中我们完成了视图加载类和邮件发送类的设计,完成了两个可插拔组件。相比使用文件作为缓存,拥有更高的性能更好地可维护性和更强大的操作。 原文发表在我的个人网站:利用 Composer 完善自己的 PHP 框架(三)——Redis 缓存 本教程示例代码见 https://github.com/johnlui/My...

    icattlecoder 评论0 收藏0
  • 【完结】利用 Composer 完善自己 PHP 框架(三)——Redis 缓存

    摘要:原文发表在我的个人网站利用完善自己的框架三缓存本教程示例代码见回顾上两篇文章中我们完成了视图加载类和邮件发送类的设计,完成了两个可插拔组件。相比使用文件作为缓存,拥有更高的性能更好地可维护性和更强大的操作。 原文发表在我的个人网站:利用 Composer 完善自己的 PHP 框架(三)——Redis 缓存 本教程示例代码见 https://github.com/johnlui/My...

    Charlie_Jade 评论0 收藏0
  • 利用 Composer 完善自己 PHP 框架(二)——发送邮件

    说明 原文发表在我的个人网站:利用 Composer 完善自己的 PHP 框架(二)——发送邮件 本教程示例代码见 https://github.com/johnlui/My-First-Framework-based-on-Composer 回顾 上一篇文章中,我们手工建造了一个简易的视图加载器,顺便引入了错误处理包,让我们的 MFFC 框架在 M、V、C 三个方面都达到了好用的水平。V...

    crossea 评论0 收藏0
  • laravel开发扩展记录

    摘要:自动代码扩展开发时遵守的代码风格是项目开发规范。遵照此规范,在实际操作中,有许多重复,接下来推荐一款专为此规范量身定制的代码生成器。可以利用此扩展来快速构建项目原型。后续还会为大家带来一些最新的技术扩展。 whoops 错误提示扩展 whoops 是一个非常优秀的 PHP Debug 扩展,它能够使你在开发中快速定位出错的位置。laravel默认安装。showImg(https://s...

    fancyLuo 评论0 收藏0

发表评论

0条评论

LinkedME2016

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<