Phalcon搭建多模块框架二:注册视图引擎及简单使用

phalcon提供的两种视图引擎,一种是php,还有一种是volt,另外还支持自定义和第三方视图引擎。
下面将按下图标注顺序逐渐完成该功能。
这里写图片描述
1、打开config下面的全局配置文件config.php
定义volt引擎服务配置和view视图服务配置,这是全局默认配置。
这里配置以volt为扩展名的模板使用viewEngineVolt引擎服务,以phtml为扩展名的模板使用viewEnginePhp引擎服务。这里的配置格式只是一种参考,你可以定义成任意你想要的格式,只要你能正确访问到就行了。

<?php
/**
 * @desc 全局配置文件
 * @author zhaoyang
 * @date 2018年5月3日 下午7:54:47
 */
return [
    // 服务配置
    'services' => [
        // volt引擎相关配置
        'view_engine_volt' => [
            // 编译模板目录
            'compiled_path' => BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/compiled/volt' . DS,
            // 是否实时编译
            'compile_always' => false,
            // 附加到已编译的PHP文件的扩展名
            'compiled_extension' => '.php',
            // 使用这个替换目录分隔符
            'compiled_separator' => '%%',
            // 是否要检查在模板文件和它的编译路径之间是否存在差异
            'stat' => true,
            // 模板前缀
            'prefix' => '',
            // 支持HTML的全局自动转义
            'autoescape' => false
        ],
        // 模板相关配置
        'view' => [
            // 模板后缀
            'view_suffix' => 'volt,phtml',
            // 模板路径
            'view_path' => APP_PATH . DEFAULT_MODULE . '/views' . DS,
            // 模板引擎,暂时支持viewEngineVolt or viewEnginePhp,与模板后缀一一对应
            'view_service' => 'viewEngineVolt,viewEnginePhp',
        ],
    ],
];

2、打开app/home/config下面的home模块配置文件,这里可以对模块进行针对性配置。

<?php
// 模块名称
defined('MODULE_NAME') || define('MODULE_NAME', 'home');
// 模块命名空间
defined('MODULE_NAMESPACE') || define('MODULE_NAMESPACE', APP_NAMESPACE . '\\Home');

return [
    // 模块名称
    'module_name' => MODULE_NAME,
    // 需要注册的模块命名空间
    'module_namespaces' => [
        MODULE_NAMESPACE . '\\Controllers' => APP_PATH . MODULE_NAME . '/controllers' . DS,
        MODULE_NAMESPACE . '\\Models' => APP_PATH . MODULE_NAME . '/models' . DS
    ],
    // 模块默认的命名空间
    'module_default_namespaces' => MODULE_NAMESPACE . '\\Controllers',
    // 服务配置
    'services' => [
        // volt引擎相关配置
        'view_engine_volt' => [
            // 编译模板目录
            'compiled_path' => BASE_PATH . 'runtime/' . MODULE_NAME . '/compiled/volt' . DS,
            // 是否实时编译
            'compile_always' => false,
            // 附加到已编译的PHP文件的扩展名
            'compiled_extension' => '.php',
            // 使用这个替换目录分隔符
            'compiled_separator' => '%%',
            // 是否要检查在模板文件和它的编译路径之间是否存在差异
            'stat' => true,
            // 模板前缀
            'prefix' => '',
            // 支持HTML的全局自动转义
            'autoescape' => false
        ],
        // 模板相关配置
        'view' => [
            // 模板后缀
            'view_suffix' => 'volt,phtml',
            // 模板路径
            'view_path' => APP_PATH . MODULE_NAME . '/views' . DS,
            // 模板引擎,暂时支持viewEngineVolt or viewEnginePhp,与模板后缀一一对应
            'view_service' => 'viewEngineVolt,viewEnginePhp',
        ],
    ]
];

3、在common目录下创建Common.php基础工具类,主要放些功能方法,例如目录格式化、创建目录等静态方法

<?php
/**
 * @desc 基础工具类
 * @author zhaoyang
 * @date 2018年5月4日 下午11:21:11
 */
namespace Common;

class Common {

    /**
     * @desc 格式化目录
     * @author zhaoyang
     * @date 2018年5月4日 下午11:21:27
     */
    public static function dirFormat(string $path) {
        $path = str_replace('\\', '/', $path);
        $path = preg_replace_callback('/(\{.+\})/U', function ($matches) {
            return date(rtrim(ltrim($matches[0], '{'), '}'));
        }, $path);
        return $path;
    }

    /**
     * @desc 创建目录
     * @param string $pathname 路径
     * @param int $mode 文件夹权限默认情况下,模式是0777
     * @param bool $recursive 规定是否设置递归模式
     * @param resource $context 规定文件句柄的环境。Context 是可修改流的行为的一套选项。
     * @return bool
     * @author zhaoyang
     * @date 2018年5月4日 下午11:21:43
     */
    public static function mkdir(string $pathname, int $mode = 0777, bool $recursive = true, resource $context = null) {
        if (is_dir($pathname)) {
            return true;
        }
        return is_resource($context) ? mkdir($pathname, $mode, $recursive, $context) : mkdir($pathname, $mode, $recursive);
    }

    /**
     * @desc 将字符串中下划线转为驼峰
     * @param string $string
     * @return string
     * @author zhaoyang
     * @date 2018年5月4日 下午11:22:02
     */
    public static function convertStrUnderline(string $string) {
        if(strpos($string, '_') !== false){
            $string = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $string))));
        }
        return $string;
    }

    /**
     * @desc 将数组中键名下划线转换为驼峰
     * @param array|object $arr
     * @return mixed
     * @author zhaoyang
     * @date 2018年5月4日 下午11:22:21
     */
    public static function convertArrKeyUnderline($arr) {
        $type = is_array($arr) ? 1 : (is_object($arr) ? 2 : 0);
        if ($type) {
            foreach ($arr as $k => $v) {
                $key = $k;
                if (strpos($key, '_') !== false) {
                    $key = Common::convertStrUnderline($key);
                    if ($type == 1) {
                        unset($arr[$k]);
                    } else {
                        unset($arr->$k);
                    }
                }
                if (is_array($v) || is_object($v)) {
                    $v = static::convertArrKeyUnderline($v);
                }
                if ($type == 1) {
                    $arr[$key] = $v;
                } else {
                    $arr->$key = $v;
                }
            }
        }
        return $arr;
    }

}

4、打开config下的services.php文件,分别注册视图引擎volt服务、视图引擎php服务和视图服务。
phalcon的视图支持分层渲染,如果不需要Main Layout和Controller Layout渲染可以在这里设置关闭。分层渲染的具体使用方法请看官方文档。

<?php
/**
 * @desc 注册服务
 * @author zhaoyang
 * @date 2018年5月3日 下午8:01:34
 */

use Common\Common;
use Phalcon\Config;
use Phalcon\DI;
use Phalcon\DI\FactoryDefault;
use Phalcon\Mvc\Dispatcher;
use Phalcon\Mvc\Router;
use Phalcon\Mvc\View;
use Phalcon\Mvc\View\Engine\Volt as ViewEngineVolt;
use Phalcon\Mvc\View\Engine\Php as ViewEnginePhp;

$di = new FactoryDefault();

/**
 * @desc 注册调度器服务
 * @author zhaoyang
 * @date 2018年5月3日 下午8:38:34
 */
$di->setShared('dispatcher', function () {
    $config = $this->getConfig();
    $dispatcher = new Dispatcher();
    $defaultNamespace = $config->module_default_namespaces ?? DEFAULT_MODULE_NAMESPACE . '\\Controllers';
    $dispatcher->setDefaultNamespace($defaultNamespace);
    return $dispatcher;
});

/**
 * @desc 注册配置服务
 * @author zhaoyang
 * @date 2018年5月3日 下午8:38:53
 */
$di->setShared('config', function () use ($config) {
    return new Config($config);
});

/**
 * @desc 注册路由服务
 * @author zhaoyang
 * @date 2018年5月3日 下午8:39:06
 */
$di->setShared('router', function () use ($routerRules) {
    $router = new Router();
    // 自动删除末尾斜线
    $router->removeExtraSlashes(true);
    foreach ($routerRules as $k => $v) {
        $router->add($k, $v);
    }
    return $router;
});

/**
 * @desc 注册视图引擎volt服务
 * @author zhaoyang
 * @date 2018年5月4日 下午5:28:52
 */
$di->setShared('viewEngineVolt', function (View $view, DI $di) {
    // 获取config服务有多种方法,这是其一
    $voltConfig = $di->get('config')->services->view_engine_volt->toArray();
    $voltConfig = Common::convertArrKeyUnderline($voltConfig);
    $viewEngineVolt = new ViewEngineVolt($view, $di);
    $voltConfig['compiledPath'] = isset($voltConfig['compiledPath']) ? Common::dirFormat($voltConfig['compiledPath']) : BASE_PATH . 'runtime/' . DEFAULT_MODULE . '/compiled/volt' . DS;
    $mkdirRes = Common::mkdir($voltConfig['compiledPath']);
    if (!$mkdirRes) {
        throw new \Exception('创建目录 ' . $voltConfig['compiledPath'] . ' 失败');
    }
    $viewEngineVolt->setOptions($voltConfig);
    return $viewEngineVolt;
});

/**
 * @desc 注册视图引擎php服务
 * @author zhaoyang
 * @date 2018年5月4日 下午5:29:15
 */
$di->setShared('viewEnginePhp', function (View $view, DI $di) {
    $viewEnginePhp = new ViewEnginePhp($view, $di);
    return $viewEnginePhp;
});

/**
 * @desc 注册视图服务
 * @author zhaoyang
 * @date 2018年5月3日 下午10:52:37
 */
$di->set('view', function () {
    // 获取config服务有多种方法,这是其二
    $viewConfig = $this->getConfig()->services->view;
    $viewDir = $viewConfig->view_path ?? APP_PATH . DEFAULT_MODULE . '/views' . DS;
    if (isset($viewConfig->view_suffix)) {
        $viewSuffixs = explode(',', $viewConfig->view_suffix);
    } else {
        $viewSuffixs = [
            'volt'
        ];
    }
    if (isset($viewConfig->view_service)) {
        $viewServices = explode(',', $viewConfig->view_service);
    } else {
        $viewServices = [
            'viewEngineVolt'
        ];
    }
    $engines = [ ];
    foreach ($viewSuffixs as $k => $v) {
        $suffix = '.' . ltrim($v, '.');
        $engines[$suffix] = $viewServices[$k] ?? $viewServices[0];
    }
    $view = new View();
    // 设置视图路径
    $view->setViewsDir($viewDir);
    // 注册视图引擎
    $view->registerEngines($engines);
    // 如果不需要“生成显示到控制器布局”和“生成显示到主布局”,则关闭这两个渲染级别
    $view->disableLevel([
        View::LEVEL_LAYOUT      => true,
        View::LEVEL_MAIN_LAYOUT => true,
    ]);
    return $view;
});

5、在app/home/controllers目录下创建视图控制器ViewController.php来测试这两个视图引擎。

<?php
/**
 * @desc 测试视图
 * @author zhaoyang
 * @date 2018年5月4日 下午5:45:49
 */
namespace App\Home\Controllers;

use Phalcon\Mvc\Controller;

class ViewController extends Controller {

    public function voltAction() {
        $this->view->name = 'volt';
    }

    public function phpAction() {
        $this->view->name = 'php';
    }
}

6、在app/home/views目录下创建view目录(与控制器名对应),在view目录下创建两个模板。一个是volt.volt,这个使用的viewEngineVolt引擎,另一个是php.phtml模板,使用的是 viewEnginePhp引擎。
volt.volt模板

<!DOCTYPE html>
<html lang="zh-CN">
<head>
</head>
<body>
    volt引擎:{{name}}<br/>
</body>
</html>

php.phtml模板

<!DOCTYPE html>
<html lang="zh-CN">
<head>
</head>
<body>
    php引擎:<?= $name?><br/>
</body>
</html>

7、这时我们访问view控制器的php方法,可以看到如下结果
这里写图片描述
这时可以看到runtime目录下生成了目录,但没有文件,因为viewEnginePhp引擎使用php原生语法,不需要编译,再访问volt方法就可以看到编译文件了
这是访问volt方法的结果
这里写图片描述
这就是产生的编译文件
这里写图片描述

至此,视图引擎已经注册成功。这里注册了两个视图引擎,你也可以再添加或者减少视图引擎,比如home模块中只使用volt引擎,则只需要把位于app/home/config目录下的模块配置文件config.php中的’view_suffix’改成’volt’,’view_service’改成’viewEngineVolt’。如下图所示
这里写图片描述
不过这时如果再去访问php方法就会因为没有找到模板而没有任何输出。因为home模块配置文件会覆盖合并全局配置文件。所以home模块其实只注册了viewEngineVolt视图引擎。
至于volt视图引擎的具体语法,请查看官方文档。如果你觉得smarty模板引擎用的比较顺手,也可以尝试创建smarty模板引擎的适配器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值