registerResource 资源注册
在开发中,我们可能不止使用文件作为模板资源,可能有些模板会来自数据库,或者来自远端的url 请求,使用 registerResource 可以定制自己的资源模板解析。
编写模板资源
插件在 Sdopx 模板引擎中是一个类,应该实现 sdopx\interfaces\Resource ,但是并不要强制要求以代码接口实现的形式书写代码。
以下我演示一个数据库资源的例子:
dbtpl 资源:
define('ROOT_DIR', __DIR__);
date_default_timezone_set('PRC');
require(ROOT_DIR . '/vendor/autoload.php');
use sdopx\Sdopx;
Sdopx::$defaultTemplateDirs = './view';
Sdopx::$defaultCompileDir = './runtime';
//定义一个资源
class DbtplResource implements \sdopx\interfaces\Resource
{
/**
* 获取内容
* @param string $tplname
* @param Sdopx $sdopx
* @return string
*/
public function getContent(string $tplname, Sdopx $sdopx): string
{
$db = $sdopx->_cache['sdopx_db'];
if ($db == null) {
$sdopx->rethrow('需要传入 sdopx_db 的存储变量');
}
$row = $db->query('select content from mytpl where `name`="' . addslashes($tplname) . '"')->fetch_array(MYSQLI_ASSOC);
if ($row) {
return $row['content'];
}
$sdopx->rethrow($tplname . '模板没有找到');
}
/**
* 获取最后修改时间戳
* @param string $tplname
* @param Sdopx $sdopx
* @return string
*/
public function getTimestamp(string $tplname, Sdopx $sdopx): int
{
$db = $sdopx->_cache['sdopx_db'];
if ($db == null) {
$sdopx->rethrow('需要传入 sdopx_db 的存储变量');
}
$row = $db->query('select lasttime from mytpl where `name`="' . addslashes($tplname) . '"')->fetch_array(MYSQLI_ASSOC);
if ($row) {
return $row['lasttime'];
}
$sdopx->rethrow($tplname . '模板没有找到');
}
}
//注册资源 资源类型名称为 dbtpl
Sdopx::registerResource('dbtpl', new DbtplResource());
$sdopx = new Sdopx();
//将数据库链接存入
$sdopx->_cache['sdopx_db'] = new mysqli('127.0.0.1', 'root', '123456', 'mytest1');
$sdopx->assign('name', 'wj008');
//显示dbtpl 的模板数据
$sdopx->display('dbtpl:mytpl');
// 在模板中 include extends 一样可以使用资源 资源类型:名称
/**
* CREATE TABLE `mytpl` (
* `id` int(11) NOT NULL AUTO_INCREMENT,
* `name` varchar(255) DEFAULT NULL,
* `content` text,
* `lasttime` int(11) DEFAULT NULL,
* PRIMARY KEY (`id`)
* ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
* INSERT INTO `mytpl` VALUES ('1', 'mytpl', 'hello {$name}', '1532724940');
*/
自动装载资源
资源是可以被自动加载的
1 需要被自动载入的资源命名要求。
需要自动载入的插件命名必须为大驼峰形式的类名 其类名后缀必须是 Resource 结尾,文件名与类名必须保持一致。
如:
class Hello //无效,没有以Resource 结尾,找不到。
class helloResource //无效,类名不是大驼峰,找不到。
class My_nameResource //无效,类名不可出现下划线。
class MyNameResource //有效,但是 插件使用时是 {include file='my_name:xxxx'}
而不是 myMame:xxxx 或者 myname:xxxx
class HelloResource // 有效 资源使用是 $this->display('hello:xxx')
文件名 如 HelloResource.php
2 需要被自动载入的插件 命名空间必须是 namespace sdopx\resource;
Sdopx 是有命名空间要求的,所以需要被自动载入插件的类,必须是在 sdopx\resource 下的。
如:
DbtplResource.php
namespace sdopx\resource;
use sdopx\Sdopx;
class DbtplResource
{
/**
* 获取内容
* @param string $tplname
* @param Sdopx $sdopx
* @return string
*/
public function getContent(string $tplname, Sdopx $sdopx): string
{
$db = $sdopx->_cache['sdopx_db'];
if ($db == null) {
$sdopx->rethrow('需要传入 sdopx_db 的存储变量');
}
$row = $db->query('select content from mytpl where `name`="' . addslashes($tplname) . '"')->fetch_array(MYSQLI_ASSOC);
if ($row) {
return $row['content'];
}
$sdopx->rethrow($tplname . '模板没有找到');
}
/**
* 获取最后修改时间戳
* @param string $tplname
* @param Sdopx $sdopx
* @return string
*/
public function getTimestamp(string $tplname, Sdopx $sdopx): int
{
$db = $sdopx->_cache['sdopx_db'];
if ($db == null) {
$sdopx->rethrow('需要传入 sdopx_db 的存储变量');
}
$row = $db->query('select lasttime from mytpl where `name`="' . addslashes($tplname) . '"')->fetch_array(MYSQLI_ASSOC);
if ($row) {
return $row['lasttime'];
}
$sdopx->rethrow($tplname . '模板没有找到');
}
}
3 需要被自动载入的插件 存放位置要求。
如果 你使用的是 composer 自动加载路径,那么 你只要在你的 composer.json 文件中指定 sdopx/resource 命名空间的对应目录即可。
如:
composer.json
{
.... 你的其他配置信息
"autoload": {
"psr-4": {
"sdopx\\resource\\": "myresource",
}
},
.... 你的其他配置信息
}
这个时候 你可以把你的插件放入跟目录下的 myresource 文件夹中,并且运行 composer update
如果上例子 存放路径为 /myresource/DbtplResource.php
如果你不使用 composer 那么 你需要用 Sdopx::setResourceDir(); 来设置你插件的存放路径
使用代码如下:
define('ROOT_DIR', __DIR__);
date_default_timezone_set('PRC');
require(ROOT_DIR . '/sdopx/Sdopx.php');
use sdopx\Sdopx;
Sdopx::$defaultTemplateDirs = './view';
Sdopx::$defaultCompileDir = './runtime';
//设置自定义资源存放路径
Sdopx::setResourceDir('./myresource');
$sdopx = new Sdopx();
//将数据库链接存入
$sdopx->_cache['sdopx_db'] = new mysqli('127.0.0.1', 'root', '123456', 'mytest1');
$sdopx->assign('name', 'wj008');
$sdopx->display('dbtpl:mytpl');
在这里 我们依然建议您使用 composer 的方式自动载入命名空间。