1. mvc/simple

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

public/index.php

<?php

$loader = new \Phalcon\Loader(); //反斜杠看着不习惯?请参见下面的[ 名字空间 ]

// 注册自动加载的类目录,为方便使用,在php解析程序启动时直接加载,参见[ 类的预加载 ]

$loader->registerDirs(array('../apps/controllers/', '../apps/models/'));

// Loader也要注册自身

$loader->register();

// 依赖注入器,参见[ 依赖注入 ],在深入到概念中之前,可以理解为构造类对象的地方

$di = new \Phalcon\DI();

// 下面是一些必需的对象

// 路由器: 将URI地址解析成Controller\Action\Params的模块

$di->set('router', 'Phalcon\Mvc\Router');

// 分发器: 利用Router解析得到的信息找到函数并执行

$di->set('dispatcher', 'Phalcon\Mvc\Dispatcher');

// 响应模块: 将执行结果封装成http协议,并发送给浏览器

$di->set('response', 'Phalcon\Http\Response');

// 请求模块: 将到来的http请求封装成对象,在dispatcher发给controller时也会把对象带过去便于访问

$di->set('request', 'Phalcon\Http\Request');

// 视图: 注入视图对象,当dispatcher调用时被访问

$di->set('view', function(){

  $view = new \Phalcon\Mvc\View();

  $view->setViewsDir('../apps/views/');

    return $view;

  });

// 数据库对象

$di->set('db', function(){

  return new \Phalcon\Db\Adapter\Pdo\Mysql(array(

    "host" => "localhost",

    "username" => "root",

    "password" => "",

    "dbname" => "invo"

  ));

});

// 数据表的元数据 : Memory表示该对象用于临时获取表结构,对象析构后表结构数据清除

$di->set('modelsMetadata', 'Phalcon\Mvc\Model\Metadata\Memory');

// 管理着Model的初始化、对应关系的类

$di->set('modelsManager', 'Phalcon\Mvc\Model\Manager');

try {

  //太简单了,一个Application类搞定主逻辑 [ 应用类 ]

  $application = new \Phalcon\Mvc\Application();

  $application->setDI($di);

  echo $application->handle()->getContent();

}

catch(Phalcon\Exception $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 \Phalcon\Mvc\Controller {

// 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 \Phalcon\Mvc\Model {

// 与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 \Phalcon\Mvc\Application {

  protected function _registerAutoloaders() {

    $loader = new \Phalcon\Loader();

    $loader->registerDirs(array(

      '../apps/controllers/',

      '../apps/models/'

    ));

    $loader->register();

  }

  protected function _registerServices() {

    $di = new \Phalcon\DI();

    $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(Phalcon\Exception $e){

  echo $e->getMessage();

}

上述代码注册controller和model的class,用的方式是registerDirs。

single-namespaces也同样自动加载自定义的controller和model,用的方式是registerNamespaces。

$loader->registerNamespaces(array(

  'Single\Controllers' => '../apps/controllers/',

  'Single\Models' => '../apps/models/'

));

上述代码注册controller和model的class,用的方式是registerDirs。

single-namespaces也同样自动加载自定义的controller和model,用的方式是registerNamespaces。

$loader->registerNamespaces(array(

'Single\Controllers' => '../apps/controllers/',

'Single\Models' => '../apps/models/'

));

因为引入了命名空间,使用时也需要显示声明

namespace Single\Controllers;

use Single\Models\Products as Products;

namespace Single\Models;

class Products extends \Phalcon\Mvc\Model {

...

}

4. mvc/single-factory-default

引入了配置项。这里用到了Include()的返回值,还用到了PHP 5.3以后才支持的闭包语法: function () use($config) {...}