• Phalcon的MVC框架解析


    1. mvc/simple
    从最简单的入手吧. 把一些能及时说明白的东西写在注释里了,需要扩展的知识列在下面。

    public/index.php

    <?php
    $loader = new PhalconLoader(); //反斜杠看着不习惯?请参见下面的[ 名字空间 ]
    // 注册自动加载的类目录,为方便使用,在php解析程序启动时直接加载,参见[ 类的预加载 ]
    $loader->registerDirs(array('../apps/controllers/', '../apps/models/'));
    // Loader也要注册自身
    $loader->register();
    // 依赖注入器,参见[ 依赖注入 ],在深入到概念中之前,可以理解为构造类对象的地方
    $di = new PhalconDI();
    // 下面是一些必需的对象
    // 路由器: 将URI地址解析成ControllerActionParams的模块
    $di->set('router', 'PhalconMvcRouter');
    // 分发器: 利用Router解析得到的信息找到函数并执行
    $di->set('dispatcher', 'PhalconMvcDispatcher');
    // 响应模块: 将执行结果封装成http协议,并发送给浏览器
    $di->set('response', 'PhalconHttpResponse');
    // 请求模块: 将到来的http请求封装成对象,在dispatcher发给controller时也会把对象带过去便于访问
    $di->set('request', 'PhalconHttpRequest');
    // 视图: 注入视图对象,当dispatcher调用时被访问
    $di->set('view', function(){
      $view = new PhalconMvcView();
      $view->setViewsDir('../apps/views/');
        return $view;
      });
    // 数据库对象
    $di->set('db', function(){
      return new PhalconDbAdapterPdoMysql(array(
        "host" => "localhost",
        "username" => "root",
        "password" => "",
        "dbname" => "invo"
      ));
    });
    // 数据表的元数据 : Memory表示该对象用于临时获取表结构,对象析构后表结构数据清除
    $di->set('modelsMetadata', 'PhalconMvcModelMetadataMemory');
    // 管理着Model的初始化、对应关系的类
    $di->set('modelsManager', 'PhalconMvcModelManager');
    try {
      //太简单了,一个Application类搞定主逻辑 [ 应用类 ]
      $application = new PhalconMvcApplication();
      $application->setDI($di);
      echo $application->handle()->getContent();
    }
    catch(PhalconException $e){
      echo $e->getMessage();
    }

    注解:

    名字空间:
    php在5.3.0版本以后开始支持的特性,用于解决两类问题 —— 命名冲突和给类重命名. 使用命名空间:别名/导入

    类的预加载:
    为了在使用一些类时不用写require或include,可以在php启动时就把一些目录下的类加载进来

    依赖注入:
    依赖注入是控制反转模式的一种实现。完全得解释依赖注入很难做到,因为这个模式被不同语言,不同框架用到,实现也各不相同。针对于Phalcon,可以看得出依赖注入(DI)模块是个容器,将类的生成方法写到DI容器中, 当有用到依赖时去DI中取出即可。具体DI的作用官方文档写得太好了官方文档

    应用类:
    封装了一些常用注入的类。当有它在时你可能不知道它做了些什么,除非看一下不用它我们需要做什么。见下面的例子simple-without-application

    controllers/ProductsController.php

    <?php
    // 控制器是用来执行业务逻辑的模块,每个方法叫做一个动作
    // URL美化后一般是这样路由的:www.demo.com/controllername/actionname/params
    class ProductsController extends PhalconMvcController {
    // action执行的结果使用view渲染,传递变量给对应的view,对应规则靠路径
      public function indexAction(){
        $this->view->setVar('product', Products::findFirst());
      }
    }

    官方文档-使用controller

    models/Products.php

    <?php
    // Phalcon的Model类是用来与数据库打交道的,大多数情况下,一个model对应一张表
    // source表示表名,setSource设置,getSource获取
    // 默认表名是to_lower(ModelClassName)
    class Products extends PhalconMvcModel {
    // 与controller一样,不建议用__construct,而是initialize
      public function initialize(){
        $this->setSource('products');
      }
    }

    2. mvc/simple-without-application
    只看public/index.php就可以了,其他文件雷同

    // 路由器执行handle()
    $router = $di->getShared('router');
    $router->handle();

    // 调度器传入路由器解析得到的controller和action以及参数
    $dispatcher = $di->getShared('dispatcher');
    $dispatcher->setControllerName($router->getControllerName());
    $dispatcher->setActionName($router->getActionName());
    $dispatcher->setParams($router->getParams());

    // 调度:调用对应的controller::action函数
    $dispatcher->dispatch();

    // 渲染视图
    $view = $di->getShared('view');
    $view->start();
    $view->render($dispatcher->getControllerName(), $dispatcher->getActionName(), $dispatcher->getParams());
    $view->finish();

    // 封装返回报文并发送给客户端
    $response = $di->getShared('response');
    $response->setContent($view->getContent());
    $response->sendHeaders();
    echo $response->getContent();

    这些就是Application的工作,还是有Application省事啊!

    3. mvc/single与mvc/single-namespaces
    这是两个对比case,意在阐明自定义namespace的用法。从例2中我们看到application负责路由调度和渲染,但是不负责DI注入。在single的例子中,自定义了application,把依赖注入的代码封装进去了,使得主逻辑只剩下非常少的代码

    class Application extends PhalconMvcApplication {
      protected function _registerAutoloaders() {
        $loader = new PhalconLoader();
        $loader->registerDirs(array(
          '../apps/controllers/',
          '../apps/models/'
        ));
        $loader->register();
      }
      protected function _registerServices() {
        $di = new PhalconDI();
        $di->set('router',...);
        $di->set('dispatcher',...);
        $di->set('response',...);
        $di->set('request',...);
        $di->set('view',...);
        $di->set('db',...);
        $di->set('modelsMetadata',..);
        $di->set('modelsManager',...);
        $this->setDI($di);
      }
      public function main() {
        $this->_registerServices();
        $this->_registerAutoloaders();
        echo $this->handle()->getContent();
      }
    }

    // 主逻辑
    try {
      $application = new Application();
      $application->main();
    }
    catch(PhalconException $e){
      echo $e->getMessage();
    }

    上述代码注册controller和model的class,用的方式是registerDirs。
    single-namespaces也同样自动加载自定义的controller和model,用的方式是registerNamespaces。

    $loader->registerNamespaces(array(
      'SingleControllers' => '../apps/controllers/',
      'SingleModels' => '../apps/models/'
    ));

    上述代码注册controller和model的class,用的方式是registerDirs。
    single-namespaces也同样自动加载自定义的controller和model,用的方式是registerNamespaces。

    $loader->registerNamespaces(array(
    'SingleControllers' => '../apps/controllers/',
    'SingleModels' => '../apps/models/'
    ));
    因为引入了命名空间,使用时也需要显示声明

    namespace SingleControllers;
    use SingleModelsProducts as Products;

    namespace SingleModels;
    class Products extends PhalconMvcModel {
    ...
    }
    4. mvc/single-factory-default
    引入了配置项。这里用到了Include()的返回值,还用到了PHP 5.3以后才支持的闭包语法: function () use($config) {...}
    参见 :闭包语法详解

  • 相关阅读:
    持续集成环境搭建(一)
    The POSIX API/nss/nscd
    [postfix]转发邮件设置
    [python]python安装包错误
    栈及栈帧讲解
    kernel-init-bash
    nginx no input file specified
    Lumen/Laravel调试API接口利器laravel-debugbar
    homestead实现外部局域网络其他主机的访问
    PHP rabbitmq扩展安装
  • 原文地址:https://www.cnblogs.com/xiaoleiel/p/8295233.html
Copyright © 2020-2023  润新知