重写File缓存类、优化视图缓存

This commit is contained in:
TOP糯米 2019-08-31 02:45:24 +08:00
parent e752358bf6
commit a056c9a27c
33 changed files with 996 additions and 225 deletions

153
README.md
View File

@ -494,6 +494,7 @@ $object = new 模型();
```
## 模板
框架自带一款模板引擎暂时命名为TOP模板引擎。此外支持扩展其他第三方模板引擎后面会讲到先来看看自带模板引擎的基础使用。
### 模板继承
模板继承通过extend标签与block标签配合使用实现。
一个最简单的继承
@ -657,6 +658,107 @@ public function _say($tag)
<say what="Hello world!" />
```
### 模板缓存
#### 关于模板缓存的实现
在渲染模板后,可选择将渲染结果缓存下来。在框架调用控制器之前有面向控制器的前置操作,在此会判断是否存在模板缓存文件,如果存在并且有效,则会直接使用缓存文件。否则,将会重新渲染模板。
#### 如何使用模板缓存
1. 在view方法中使用。第三个参数为缓存控制传入的参数为true时使用配置文件中设置的全局缓存时间传入数字则表示当前模板的缓存时间
```
return $this->view('Index/index', [
'data' => $data
], 30);
```
2. 直接在控制器中调用cache方法。参数作用参照view方法。
```
$this->cache(30);
```
### 第三方模板引擎
文件存放位置 'framework/library/template/driver' 。必须实现TemplateIfs接口。存在以下方法
1. run
返回当前类实例,做模板引擎初始化操作。
2. cache
设置缓存状态。
3. fetch
返回模板渲染后的内容。
驱动类编写完成后需要以下两个步骤方可使用以TOP模板引擎为例
1. 配置文件中注册
```
'register' => [
'Top' => \top\library\template\driver\Top::class,
],
```
2. 模板配置中配置使用
```
'view' => [
'engine' => 'Top',
]
```
## 缓存
缓存类实现了CacheIfs接口所以至少存在以下四个方法
1. set
设置缓存。三个参数前两个为必须第三个默认为10第一个参数为准备缓存数据的key第二个参数为缓存的具体数据字符串、数组、对象第三个为当前缓存的有效时间。
```
$cache->set('lists', [0, 1, 2, 3, 4, 5], 30);
```
2. get
根据key获取缓存内容
```
$cache->get('lists');
```
3. remove
根据key删除缓存
```
$cache->remove('lists');
```
4. exists
根据key判断缓存是否存在/有效
```
$cache->exists('lists');
```
### 文件缓存
```
use top\library\cache\driver\File;
$cache = File::instance();
if (!$cache->exists('data')) {
$data = '测试';
$cache->set('data', $data);
}
$data = $cache->get('data');
```
### Redis
```
use top\library\cache\driver\Redis;
$cache = Redis::instance();
if (!$cache->exists('data')) {
$data = '测试';
$cache->set('data', $data);
}
$data = $cache->get('data');
```
### 自定义缓存类
文件存放位置 'framework/library/cache/driver' 。必须实现CacheIfs接口具体方法看缓存介绍。
## 自定义路由
路由配置文件位于 application 下文件名route.php
现有News控制器中的detail方法
@ -668,7 +770,7 @@ public function detail($id)
];
}
```
假设访问地址为: http://127.0.0.3/home/news/detail/id/1.html 。
假设访问地址为: http://127.0.0.1/home/news/detail/id/1.html 。
### 必须参数
添加如下规则
```
@ -677,7 +779,7 @@ public function detail($id)
'home/news/detail'
]
```
完成后,可使用 http://127.0.0.3/detail/1.html 访问到对应位置。
完成后,可使用 http://127.0.0.1/detail/1.html 访问到对应位置。
### 可选参数
修改detail方法
```
@ -695,7 +797,7 @@ public function detail($id = 0)
'home/news/detail'
]
```
完成后,可使用 http://127.0.0.3/detail.html 访问到对应位置如果没传递id则使用默认值。
完成后,可使用 http://127.0.0.1/detail.html 访问到对应位置如果没传递id则使用默认值。
### 多个参数
```
'detail' => [
@ -705,6 +807,51 @@ public function detail($id = 0)
```
## 其他
### Database类
模型中的数据库操作实际也是调用Database类中的方法模型类是在此基础上新增了更多高级操作Database类方法的使用请参照模型中的2至22个方法的使用。在此需要特别指出获取Database类实例使用table方法table方法中传入表名以指定即将操作的数据表
```
$db = Database::table('users');
$data = $db->find(1);
```
框架默认使用MySQL数据库。此外支持自定义数据库操作驱动类文件位置 'framework/library/database/driver' 参数需要自行解析换言之也就是SQL语句需要自行组合。自定义数据库驱动类必须实现DatabaseIfs接口包括以下方法
1. connect
连接数据库。方法参数为数据库连接配置。
2. insert
插入记录。参数列表:
$table、$join、$on、$where、$order、$limit、$data
3. update
更新记录。参数列表
$table、$distinct、$field、$join、$on、$where、$order
4. find
查询一条记录。参数列表
$table、$distinct、$field、$join、$on、$where、$order
5. select
查询所有记录。参数列表
$table、$distinct、$field、$join、$on、$where、$order、$limit
6. delete
删除记录。参数列表
$effect、$table、$join、$on、$where、$order、$limit
7. query
执行SQL语句。参数列表
$query
8. close
关闭数据库连接。
### Request类
获取实例
1. instance方法获取单例

View File

@ -1,4 +1,5 @@
<?php
namespace app\{name}\controller;
use top\library\Controller;

View File

@ -1,4 +1,5 @@
<?php
namespace app\{name}\model;
use top\library\Model;

View File

@ -8,8 +8,24 @@
<title>Document</title>
</head>
<body>
<style>
h3 {
color: #666666;
font-weight: 300;
}
.version {
width: 100%;
height: 22px;
color: #b9b9b9;
font-size: 12px;
text-align: center;
line-height: 22px;
margin: 0 auto;
padding-bottom: 20px;
}
</style>
<h3>{$hello}</h3>
<hr>
<p style="color: #666666; text-align: center; font-size: 13px;">TOP-Framework</p>
<p class="version">TOP-Framework</p>
</body>
</html>

View File

View File

View File

@ -34,12 +34,12 @@ abstract class Controller
/**
* 缓存页面(具体视图驱动完成此功能)
* @param bool $status
* @param bool $param
* @return $this
*/
protected function cache($status = true)
protected function cache($param = true)
{
Register::get('View')->cache($status);
View::instance()->cache($param);
return $this;
}
@ -50,7 +50,7 @@ abstract class Controller
*/
protected function param($name, $value)
{
Register::get('View')->param($name, $value);
View::instance()->param($name, $value);
}
/**
@ -62,7 +62,7 @@ abstract class Controller
*/
protected function view($file = '', $param = [], $cache = false)
{
return Register::get('View')->fetch($file, $param, $cache);
return View::instance()->fetch($file, $param, $cache);
}
/**
@ -86,7 +86,7 @@ abstract class Controller
if (request()->isAjax()) {
return $this->json($message, '', 'tips', ['url' => $url, 'sec' => $sec]);
} else {
$viewConfig = Register::get('Config')->get('view');
$viewConfig = Config::instance()->get('view');
$tipsTemplate = $viewConfig['dir'] . 'tips.' . $viewConfig['ext'];
(!file_exists($tipsTemplate)) && file_put_contents($tipsTemplate, '');
return $this->view('tips', [

View File

@ -60,7 +60,7 @@ class Database
private function __construct($table, $pk)
{
$driver = Register::get('DBDriver');
$this->config = $config = Register::get('Config')->get('db');
$this->config = $config = Config::instance()->get('db');
$this->table = $config['prefix'] . $table;
$this->pk = $pk;
$this->setDriver($driver, $this->config);

View File

@ -95,10 +95,6 @@ class Router
$this->check();
Register::set('Config', function () {
return Config::instance();
});
return $this;
}
}

View File

@ -14,9 +14,16 @@ class Template
use Instance;
// 操作的具体实现
/**
* 模板操作的具体实现
* @var
*/
private $template;
/**
* 参数
* @var array
*/
private $param = [];
/**

View File

@ -25,7 +25,7 @@ class View
*/
private function __construct()
{
$this->config = Register::get('Config')->get('view');
$this->config = Config::instance()->get('view');
$driver = Register::get($this->config['engine']);
$this->template = Template::instance($driver);
}

View File

@ -1,71 +0,0 @@
<?php
namespace top\library\cache;
use top\library\cache\ifs\CacheIfs;
use top\traits\Instance;
class File implements CacheIfs
{
use Instance;
/**
* 设置缓存
* @param string $name
* @param string $value
* @param bool $timeout
* @return bool
*/
public function set($name = '', $value = '', $timeout = 0)
{
// TODO Auto-generated method stub
$dirArray = explode('/', $name);
unset($dirArray[count($dirArray) - 1]);
$dir = implode('/', $dirArray);
if (!is_dir($dir)) {
mkdir($dir, 775, true);
}
if (file_put_contents($name, $value) !== false) {
return true;
}
return false;
}
/**
* 获取缓存
* @param string $name
*/
public function get($name = '')
{
}
/**
* 删除缓存
* @param string $name
*/
public function remove($name = '')
{
}
/**
* 检测缓存
* @param string $name
* @param int $time
* @return bool
*/
public function check($name = '', $time = 0)
{
if (file_exists($name)) {
$modifyTime = filemtime($name);
$nowTime = time();
if ($nowTime - $modifyTime > $time) {
return false;
} else {
return true;
}
} else {
return false;
}
}
}

View File

@ -1,77 +0,0 @@
<?php
namespace top\library\cache;
use top\library\cache\ifs\CacheIfs;
use top\library\Config;
use top\traits\Instance;
class Redis implements CacheIfs
{
use Instance;
private $config = [];
private $redis = null;
private function __construct()
{
$config = Config::instance()->get('redis');
$this->redis = new \Redis();
$this->redis->connect($config['host'], $config['port']);
if ($config['auth']) {
$this->redis->auth($config['auth']);
}
}
/**
* 设置缓存
* @param string $name
* @param string $value
* @return bool
*/
public function set($name = '', $value = '', $timeout = 0)
{
if (is_array($value) || is_object($value)) {
$value = json_encode($value);
}
return $this->redis->set($name, $value, $timeout);
}
/**
* 获取缓存的值
* @param string $name
* @return bool|mixed|string
*/
public function get($name = '')
{
$value = $this->redis->get($name);
$jsonDecode = json_decode($value);
if (is_null($jsonDecode)) {
return $value;
} else {
return $jsonDecode;
}
}
/**
* 删除缓存
* @param string $name
* @return int
*/
public function remove($name = '')
{
return $this->redis->del($name);
}
/**
* 判断缓存是否设置
* @param $name
* @return bool
*/
public function exists($name)
{
return $this->redis->exists($name);
}
}

183
framework/library/cache/driver/File.php vendored Normal file
View File

@ -0,0 +1,183 @@
<?php
namespace top\library\cache\driver;
use top\library\cache\ifs\CacheIfs;
use top\traits\Instance;
/**
* 文件缓存
* Class File
* @package top\library\cache
*/
class File implements CacheIfs
{
use Instance;
/**
* 当前实例
* @var
*/
private static $instance;
/**
* 默认缓存位置
* @var null|string
*/
private $dir = './runtime/data/';
/**
* 复写获取单一实例方法
* @param null $dir
* @return mixed
*/
public static function instance($dir = null)
{
$ident = md5($dir);
if (!isset(self::$instance[$ident])) {
self::$instance[$ident] = new self($dir);
}
return self::$instance[$ident];
}
/**
* 进行一些初始化操作
* File constructor.
* @param null $dir
*/
private function __construct($dir = null)
{
if ($dir) {
$this->dir = $dir;
}
}
/**
* 设置缓存
* @param string $key
* @param string $value
* @param int $timeout
* @return bool
*/
public function set($key = '', $value = '', $timeout = 10)
{
$this->createCacheDir();
$filename = $this->getFileName($key);
if (is_array($value) || is_object($value)) {
$value = json_encode($value);
}
$value = '<?php $timeout = ' . $timeout . '; ?>' . PHP_EOL . $value;
if (file_put_contents($filename, $value)) {
return true;
}
return false;
}
/**
* 获取缓存
* @param string $key
* @return bool|false|string
*/
public function get($key = '')
{
$filename = $this->getFileName($key);
if (file_exists($filename)) {
if ($this->isTimeOut($key)) {
return $this->getCacheContent($key);
}
return false;
}
return false;
}
/**
* 删除缓存
* @param string $key
* @return bool
*/
public function remove($key = '')
{
$filename = $this->getFileName($key);
if (file_exists($filename)) {
@unlink($filename);
}
return true;
}
/**
* 判断缓存是否存在/有效
* @param $key
* @return bool
*/
public function exists($key)
{
return $this->isTimeOut($key);
}
/**
* 获取文件缓存内容
* @param $key
* @return false|string
*/
private function getCacheContent($key)
{
$filename = $this->getFileName($key);
ob_start();
require $filename;
$content = ob_get_contents();
ob_clean();
$jsonDecode = json_decode($content, true);
if (is_null($jsonDecode)) {
return $content;
}
return $jsonDecode;
}
/**
* 判断缓存是否超时
* @param $key
* @return bool
*/
private function isTimeOut($key)
{
$filename = $this->getFileName($key);
if (file_exists($filename)) {
ob_start();
require $filename;
ob_clean();
$mtime = filemtime($filename);
if ($timeout == 0) {
return true;
} elseif ((time() - $mtime > $timeout)) {
// 已超时,删除缓存
$this->remove($key);
return false;
} else {
return true;
}
}
return false;
}
/**
* 获取缓存文件名称
* @param $key
* @return string
*/
public function getFileName($key)
{
return $this->dir . $key . '.php';
}
/**
* 创建缓存目录
*/
private function createCacheDir()
{
if (!is_dir($this->dir)) {
mkdir($this->dir, 0777, true);
}
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace top\library\cache\driver;
use top\library\cache\ifs\CacheIfs;
use top\library\Config;
use top\traits\Instance;
/**
* Redis缓存
* Class Redis
* @package top\library\cache
*/
class Redis implements CacheIfs
{
use Instance;
/**
* redis配置
* @var array
*/
private $config = [];
/**
* redis实例
* @var null|\Redis
*/
private $redis = null;
/**
* 复写构造方法,初始化操作
* Redis constructor.
*/
private function __construct()
{
$config = Config::instance()->get('redis');
$this->redis = new \Redis();
try {
$this->redis->connect($config['host'], $config['port']);
} catch (\Exception $e) {
throw new \Exception(mb_convert_encoding($e->getMessage(), 'utf8', 'gbk'));
}
if ($config['auth']) {
$this->redis->auth($config['auth']);
}
}
/**
* 设置缓存
* @param string $key
* @param string $value
* @param int $timeout
* @return bool
*/
public function set($key = '', $value = '', $timeout = 0)
{
if (is_array($value) || is_object($value)) {
$value = json_encode($value);
}
$timeout = $timeout == 0 ? null : $timeout;
return $this->redis->set($key, $value, $timeout);
}
/**
* 获取缓存的值
* @param string $key
* @return bool|mixed|string
*/
public function get($key = '')
{
$value = $this->redis->get($key);
$jsonDecode = json_decode($value, true);
if (is_null($jsonDecode)) {
return $value;
}
return $jsonDecode;
}
/**
* 删除缓存
* @param string $key
* @return int
*/
public function remove($key = '')
{
return $this->redis->del($key);
}
/**
* 判断缓存是否设置
* @param $key
* @return bool
*/
public function exists($key)
{
return $this->redis->exists($key);
}
}

View File

View File

@ -5,7 +5,7 @@ namespace top\library\cache\ifs;
interface CacheIfs
{
public function set($name = '', $value = '', $timeout = 0);
public function set($name = '', $value = '', $timeout = null);
public function get($name = '');

View File

@ -0,0 +1,462 @@
<?php
namespace top\library\database\driver;
use top\library\database\ifs\DatabaseIfs;
use top\library\exception\DatabaseException;
use top\traits\Instance;
/**
* MySQL数据库驱动
* @author topnuomi 2018年11月20日
*/
class ObjectForMySQL implements DatabaseIfs
{
use Instance;
private $link;
private $mysqli = null;
private $sql;
/**
* 连接数据库
* @param array $config
* @return $this|DatabaseIfs
*/
public function connect($config)
{
$this->mysqli = new \mysqli($config['host'], $config['user'], $config['passwd'], $config['dbname']);
$this->mysqli->query('set names ' . $config['charset']);
return $this;
}
/**
* 插入记录
* @param string $table
* @param array $data
* @return mixed
* @throws DatabaseException
*/
public function insert($table, $data)
{
// TODO Auto-generated method stub
if (count($data) == count($data, 1)) { // 一维数组
$query = 'insert into ' . $table;
$field = ' (' . implode(',', array_keys($data)) . ')';
$value = array_values($data);
$value = '(' . implode(',', $this->checkNull($value)) . ')';
$this->sql = $query .= $field . ' values ' . $value . ';';
$this->query($query);
} else { // 二维数组
foreach ($data as $key => $value) {
$query = 'insert into ' . $table;
$allField = ' (' . implode(',', array_keys($value)) . ')';
$allValue = '(' . implode(',', $this->checkNull($value)) . ')';
$this->sql = $query .= $allField . ' values ' . $allValue . ';';
$this->query($query);
}
}
return $this->mysqli->insert_id;
}
/**
* 更新记录
* @param string $table
* @param array $join
* @param array|string $on
* @param array|string $where
* @param string $order
* @param string $limit
* @param array $data
* @return int|mixed
* @throws DatabaseException
*/
public function update($table, $join, $on, $where, $order, $limit, $data)
{
// TODO Auto-generated method stub
$join = $this->parseJoin($join, $on);
$where = $this->parseWhere($where);
$order = $this->parseOrder($order);
$limit = $this->parseLimit($limit);
$query = 'update ' . $table . "{$join} set ";
$updateData = [];
foreach ($data as $key => $value) {
if (!is_numeric($value) && !$value) {
$value = 'NULL';
} else {
$value = '\'' . $this->mysqli->real_escape_string($value) . '\'';
}
$updateData[] = $key . '=' . $value;
}
$this->sql = $query .= implode(',', $updateData) . "{$where}{$order}{$limit}";
$this->query($query);
return $this->mysqli->affected_rows;
}
/**
* 查询一条记录
* @param string $table
* @param $distinct
* @param array|string $field
* @param array $join
* @param array|string $on
* @param array|string $where
* @param string $order
* @return array|mixed|null
* @throws DatabaseException
*/
public function find($table, $distinct, $field, $join, $on, $where, $order)
{
// TODO Auto-generated method stub
$join = $this->parseJoin($join, $on);
$distinct = $this->parseDistinct($distinct);
if ($distinct) {
$field = $distinct;
} else {
$field = $this->parseField($field);
}
$where = $this->parseWhere($where);
$order = $this->parseOrder($order);
$this->sql = "select {$field} from $table{$join}{$where}{$order} limit 1";
$result = $this->query($this->sql);
return $result->fetch_assoc();
}
/**
* 查询所有记录
* @param string $table
* @param $distinct
* @param array|string $field
* @param array $join
* @param array|string $on
* @param array|string $where
* @param string $order
* @param string $limit
* @return array|mixed|null
* @throws DatabaseException
*/
public function select($table, $distinct, $field, $join, $on, $where, $order, $limit)
{
// TODO Auto-generated method stub
$join = $this->parseJoin($join, $on);
$distinct = $this->parseDistinct($distinct);
if ($distinct) {
$field = $distinct;
} else {
$field = $this->parseField($field);
}
$where = $this->parseWhere($where);
$order = $this->parseOrder($order);
$limit = $this->parseLimit($limit);
$this->sql = "select {$field} from {$table}{$join}{$where}{$order}{$limit}";
$result = $this->query($this->sql);
return $result->fetch_all(MYSQLI_ASSOC);
}
/**
* 删除记录
* @param array|string $effect
* @param string $table
* @param array $join
* @param array|string $on
* @param array|string $where
* @param string $order
* @param string $limit
* @return int|mixed
* @throws DatabaseException
*/
public function delete($effect, $table, $join, $on, $where, $order, $limit)
{
// TODO Auto-generated method stub
$effect = $this->parseEffect($effect);
$join = $this->parseJoin($join, $on);
$where = $this->parseWhere($where);
$order = $this->parseOrder($order);
$limit = $this->parseLimit($limit);
$this->sql = "delete{$effect} from $table{$join}{$where}{$order}{$limit}";
$this->query($this->sql);
return $this->mysqli->affected_rows;
}
/**
* 获取表结构
* @param $table
* @return bool|mixed
* @throws DatabaseException
*/
public function tableDesc($table)
{
$sql = 'desc ' . $table;
if (!$result = $this->query($sql)) {
return false;
}
$data = $result->fetch_all(MYSQLI_ASSOC);
return $data;
}
/**
* 计数
* @param $table
* @param $field
* @param $join
* @param $on
* @param $where
* @return mixed
* @throws DatabaseException
*/
public function count($table, $field, $join, $on, $where)
{
$field = $this->parseField($field);
$join = $this->parseJoin($join, $on);
$where = $this->parseWhere($where);
$this->sql = "select count({$field}) from $table{$join}{$where}";
$result = $this->query($this->sql);
$count = $result->fetch_array();
return $count[0];
}
/**
* 公共方法
* @param $table
* @param $distinct
* @param $field
* @param $join
* @param $on
* @param $where
* @param $type
* @return bool
* @throws DatabaseException
*/
public function common($table, $distinct, $field, $join, $on, $where, $type)
{
$distinct = $this->parseDistinct($distinct);
if ($distinct) {
$field = $distinct;
} else {
$field = $this->parseField($field);
}
$join = $this->parseJoin($join, $on);
$where = $this->parseWhere($where);
$this->sql = "select {$type}({$field}) from {$table}{$join}{$where}";
$result = $this->query($this->sql);
$data = $result->fetch_array();
if (isset($data[0])) {
return $data[0];
} else {
return false;
}
}
/**
* 执行SQL
* @param string $query
* @return mixed
* @throws DatabaseException
*/
public function query($query)
{
$result = $this->mysqli->query($query);
if (!$result) {
throw new DatabaseException($this->mysqli->error);
}
return $result;
}
/**
* 获取执行的最后一条SQL
*
* @return string
*/
public function sql()
{
return trim($this->sql, ' ');
}
public function parseEffect($effect)
{
if ($effect) {
if (is_array($effect)) {
$effect = implode(',', $effect);
}
return ' ' . $effect;
}
return '';
}
/**
*
* @param $distinct
* @return string
*/
private function parseDistinct($distinct)
{
if ($distinct) {
if (is_array($distinct)) {
$distinct = implode(',', $distinct);
}
return 'distinct ' . $distinct;
}
return '';
}
/**
* 组合字段
* @param string|array $field
* @return string
*/
private function parseField($field)
{
if (!$field) {
$field = '*';
} else if (is_array($field)) {
$field = implode(',', $field);
}
return $field;
}
/**
* 组合where条件
* @param array $array
* @param string $glue
* @return string
*/
private function parseWhere(array $array, $glue = 'and')
{
$where = [];
foreach ($array as $value) {
if (empty($value)) continue;
if (is_array($value)) {
foreach ($value as $key => $val) {
if (is_array($val)) {
switch (strtolower($val[0])) {
case 'in':
$arr_ = (is_array($val[1])) ? $val[1] : explode(',', $val[1]);
$str = '';
for ($i = 0; $i < count($arr_); $i++) {
$str .= (($i != 0) ? ',' : '') . $this->checkNull(trim($arr_[$i]));
}
$where[] = $key . ' ' . $val[0] . ' (' . $str . ')';
break;
case 'like':
$where[] = $key . ' ' . $val[0] . ' \'%' . $val[1] . '%\'';
break;
default:
$where[] = $key . ' ' . $val[0] . ' ' . $this->checkNull($val[1]);
}
} else {
$val = $this->checkNull($val);
$where[] = $key . '=' . $val;
}
}
} else {
$where[] = $value;
}
}
if (empty($where)) {
return '';
} else {
return ' where ' . implode(' ' . $glue . ' ', $where);
}
}
/**
* 组合order
* @param string $order
* @return string
*/
private function parseOrder($order = '')
{
if ($order) {
$order = ' order by ' . $order;
}
return $order;
}
/**
* 组合limit
* @param string $limit
* @return string
*/
private function parseLimit($limit = '')
{
if ($limit) {
if (is_array($limit)) {
$limit = ' limit ' . implode(',', $limit);
} else {
$limit = ' limit ' . $limit;
}
}
return $limit;
}
/**
* 链接多表join on
* @param array $data
* @param string|array $on
* @return string
*/
private function parseJoin($data, $on)
{
$join = [];
for ($i = 0; $i < count($data); $i++) {
if (is_array($on[$i])) {
$pieces = [];
foreach ($on[$i] as $key => $value) {
$pieces[] = $key . ' = ' . $value;
}
$onString = implode(' and ', $pieces);
} else {
$onString = $on[$i];
}
$join[] = $data[$i][0] . ' join ' . $data[$i][1] . ($data[$i][2] ? ' as ' . $data[$i][2] : '') . ' on ' . $onString;
}
if (!empty($join)) {
return ' ' . implode(' ', $join);
}
return '';
}
/**
* 检查并处理空值
* @param $value
* @return array|string
*/
private function checkNull($value)
{
if (is_array($value)) {
foreach ($value as $k => $v) {
if (!is_numeric($v) && !$v) {
$value[$k] = 'NULL';
} else {
$value[$k] = '\'' . $this->mysqli->real_escape_string($v) . '\'';
}
}
} else {
if (!is_numeric($value) && !$value) {
$value = 'NULL';
} else {
$value = '\'' . $this->mysqli->real_escape_string($value) . '\'';
}
}
return $value;
}
/**
* 关闭数据库连接
*/
public function close()
{
if ($this->mysqli->close()) {
return true;
}
return false;
}
public function __destruct()
{
$this->close();
}
}

View File

@ -227,10 +227,9 @@ function filter($str)
*/
function session($name, $value = '')
{
$config = \top\library\Register::get('Config')->get('session');
$config = \top\library\Config::instance()->get('session');
if (empty($config) || !$config['prefix']) {
$route = \top\library\Register::get('Route');
$prefix = $route->module;
$prefix = request()->module();
} else {
$prefix = $config['prefix'];
}
@ -400,6 +399,20 @@ function is_mobile()
return false;
}
/**
* 获取当前视图文件的缓存标识
* @return string
*/
function viewCacheIdent()
{
if (isset($_SERVER['REQUEST_URI'])) {
$ident = md5($_SERVER['REQUEST_URI']);
} else {
$ident = request()->module() . request()->controller() . request()->method();
}
return $ident;
}
// 模型自动验证函数
/**

View File

@ -2,9 +2,9 @@
namespace top\library\http;
use top\library\Config;
use top\middleware\ifs\MiddlewareIfs;
use top\middleware\Init;
use top\library\Register;
use top\library\route\driver\Command;
use top\library\route\driver\Pathinfo;
use top\library\Router;
@ -375,7 +375,7 @@ class Request
$routeDriver = $this->routeDriver($type);
$this->router = (new Router($routeDriver, $defaultModule))->handler();
$userMiddleware = Register::get('Config')->get('middleware');
$userMiddleware = Config::instance()->get('middleware');
$systemMiddleware = [Init::class, View::class];
$middleware = array_merge($systemMiddleware, $userMiddleware);

View File

@ -2,7 +2,7 @@
namespace top\library\http\response;
use top\library\Register;
use top\library\View;
use top\traits\Json;
/**
@ -40,7 +40,7 @@ class ResponseData
if (request()->isAjax()) {
$responseData = $this->returnJson($data);
} else {
$view = Register::get('View');
$view = View::instance();
$filename = request()->controller() . '/' . request()->method();
$responseData = $view->fetch($filename, $data);
unset($filename);

View File

@ -20,7 +20,7 @@ class Command implements RouteIfs
public $method = '';
// 参数
public $param = [];
public $params = [];
/**
* 暂时就这样吧(逃...
@ -32,7 +32,7 @@ class Command implements RouteIfs
$this->ctrl = $this->ctrl();
$this->class = '\\' . APP_NS . '\\' . $this->module . '\\controller\\' . $this->ctrl;
$this->method = $this->method();
$this->param = $this->param();
$this->params = $this->params();
}
/**

View File

@ -2,7 +2,7 @@
namespace top\library\template\driver;
use top\library\Register;
use top\library\Config;
use top\library\template\ifs\TemplateIfs;
use top\traits\Instance;
@ -17,7 +17,7 @@ class Smarty implements TemplateIfs
public function run()
{
$this->config = Register::get('Config')->get('view');
$this->config = Config::instance()->get('view');
$module = request()->module();
(!$this->config['dir']) && $this->config['dir'] = APP_PATH . 'home/view/';
(!$this->config['cacheDir']) && $this->config['cacheDir'] = './runtime/cache/application/' . $module . '/';

View File

@ -2,8 +2,9 @@
namespace top\library\template\driver;
use top\library\Register;
use top\library\template\driver\tags\Engine;
use top\library\cache\driver\File;
use top\library\Config;
use top\library\template\driver\engine\Engine;
use top\library\template\ifs\TemplateIfs;
use top\traits\Instance;
@ -29,7 +30,7 @@ class Top implements TemplateIfs
public function run()
{
$this->config = Register::get('Config')->get('view');
$this->config = Config::instance()->get('view');
$module = request()->module();
(!$this->config['dir']) && $this->config['dir'] = APP_PATH . $module . '/view/';
(!$this->config['cacheDir']) && $this->config['cacheDir'] = './runtime/cache/application/' . $module . '/';
@ -64,6 +65,7 @@ class Top implements TemplateIfs
}
/**
* 是否开启缓存或设置缓存时间
* @param $status
*/
public function cache($status)
@ -78,22 +80,19 @@ class Top implements TemplateIfs
* @return string
* @throws \Exception
*/
private function cacheFile($filename, $params)
private function cacheFile($filename, $params, $cacheTime)
{
if (isset($_SERVER['REQUEST_URI'])) {
$fileIdent = md5($_SERVER['REQUEST_URI']);
} else {
$fileIdent = request()->module() . request()->controller() . request()->method();
}
$filePath = $this->config['cacheDir'] . $fileIdent;
$cache = Register::get('FileCache');
$cache = File::instance($this->config['cacheDir']);
extract($params);
// 获取文件内容
ob_start();
require $filename;
$content = ob_get_clean();
$content = ob_get_contents();
ob_clean();
if ($cache->set($filePath, $content)) {
return $filePath;
// 写入文件缓存
$ident = viewCacheIdent();
if ($cache->set($ident, $content, $cacheTime)) {
return $cache->get($ident);
} else {
throw new \Exception('无法创建缓存文件');
}
@ -113,8 +112,15 @@ class Top implements TemplateIfs
if (file_exists($filename)) {
$filename = $this->compile($filename);
if ($this->cache || $cache) {
$filename = $this->cacheFile($filename, $params);
return file_get_contents($filename);
$cacheTime = $this->config['cacheTime'];
if (!is_bool($cache) || !is_bool($this->cache)) {
if ($cache > 0) {
$cacheTime = $cache;
} elseif ($this->cache > 0) {
$cacheTime = $this->cache;
}
}
return $this->cacheFile($filename, $params, $cacheTime);
} else {
extract($params);
ob_start();

View File

@ -2,7 +2,7 @@
namespace top\library\template\driver;
use top\library\Register;
use top\library\Config;
use top\library\template\ifs\TemplateIfs;
use top\traits\Instance;
use Twig\Environment;
@ -17,7 +17,7 @@ class Twig implements TemplateIfs
public function run()
{
$this->config = Register::get('Config')->get('view');
$this->config = Config::instance()->get('view');
$module = request()->module();
(!$this->config['dir']) && $this->config['dir'] = APP_PATH . 'home/view/';
(!$this->config['cacheDir']) && $this->config['cacheDir'] = './runtime/cache/application/' . $module . '/';

View File

@ -1,8 +1,7 @@
<?php
namespace top\library\template\driver\tags;
namespace top\library\template\driver\engine;
use top\library\Register;
use top\traits\Instance;
/**

View File

@ -2,10 +2,10 @@
namespace top\middleware;
use top\library\Config;
use top\middleware\ifs\MiddlewareIfs;
use top\library\Register;
use top\library\View;
use top\library\cache\File;
/**
* 初始化
@ -30,27 +30,24 @@ class Init implements MiddlewareIfs
require $funcFile;
}
$sessionConfig = Register::get('Config')->get('session');
$configInstance = Config::instance();
$sessionConfig = $configInstance->get('session');
if (!empty($sessionConfig) && $sessionConfig['open'] === true) {
session_save_path(SESSION_PATH);
session_start();
}
// 数据库驱动
$config = Register::get('Config')->get('db');
$config = $configInstance->get('db');
$driver = $config['driver'] ? $config['driver'] : 'MySQLi';
Register::set('DBDriver', function () use ($driver) {
$class = '\\top\\library\\database\\driver\\' . $driver;
return $class::instance();
});
// 视图文件缓存
Register::set('FileCache', function () {
return File::instance();
});
// 配置文件中配置的注册
$initRegister = Register::get('Config')->get('register');
$initRegister = $configInstance->get('register');
if (!empty($initRegister)) {
foreach ($initRegister as $key => $value) {
Register::set($key, function () use ($value) {
@ -59,11 +56,6 @@ class Init implements MiddlewareIfs
}
}
// 注册视图
Register::set('View', function () {
return View::instance();
});
return true;
}

View File

@ -2,8 +2,9 @@
namespace top\middleware;
use top\library\cache\driver\File;
use top\library\Config;
use top\library\http\Response;
use top\library\Register;
use top\middleware\ifs\MiddlewareIfs;
class View implements MiddlewareIfs
@ -11,18 +12,14 @@ class View implements MiddlewareIfs
public function before()
{
// TODO: Implement before() method.
if (!DEBUG) {
if (isset($_SERVER['REQUEST_URI'])) {
$fileIdent = md5($_SERVER['REQUEST_URI']);
} else {
$fileIdent = request()->module() . request()->controller() . request()->method();
}
$config = Register::get('Config')->get('view');
$filename = $config['cacheDir'] . $fileIdent;
$cache = Register::get('FileCache');
if ($cache->check($filename, $config['cacheTime'])) {
return Response::instance()->dispatch(file_get_contents($filename));
$ident = viewCacheIdent();
$config = Config::instance()->get('view');
(!$config['cacheDir']) && $config['cacheDir'] = './runtime/cache/application/' . request()->module() . '/';
$cache = File::instance($config['cacheDir']);
if ($cache->exists($ident)) {
$content = $cache->get($ident);
return Response::instance()->dispatch($content);
}
}
return true;

View File

View File

@ -7,7 +7,7 @@ require '../framework/Framework.php';
// 可能你会使用到下面这些配置
// 调试模式缺省值false
Framework::debug(true);
// Framework::debug(true);
// 可使用常量DEBUG取得该值
// 项目目录,缺省值:./application/