diff --git a/README.md b/README.md index c32b66d..84a3d1c 100644 --- a/README.md +++ b/README.md @@ -494,6 +494,7 @@ $object = new 模型(); ``` ## 模板 +框架自带一款模板引擎,暂时命名为TOP模板引擎。此外支持扩展其他第三方模板引擎,后面会讲到,先来看看自带模板引擎的基础使用。 ### 模板继承 模板继承通过extend标签与block标签配合使用实现。 一个最简单的继承 @@ -657,6 +658,107 @@ public function _say($tag) ``` +### 模板缓存 +#### 关于模板缓存的实现 +在渲染模板后,可选择将渲染结果缓存下来。在框架调用控制器之前有面向控制器的前置操作,在此会判断是否存在模板缓存文件,如果存在并且有效,则会直接使用缓存文件。否则,将会重新渲染模板。 +#### 如何使用模板缓存 +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方法获取单例 diff --git a/framework/library/template/driver/tags/index.html b/framework/config/index.html similarity index 100% rename from framework/library/template/driver/tags/index.html rename to framework/config/index.html diff --git a/framework/create/tpl/controller/index.tpl b/framework/create/tpl/controller/index.tpl index 51356f6..216eb94 100644 --- a/framework/create/tpl/controller/index.tpl +++ b/framework/create/tpl/controller/index.tpl @@ -1,4 +1,5 @@ Document +

{$hello}

-
-

TOP-Framework

+ +

TOP-Framework

\ No newline at end of file diff --git a/framework/extend/wechat/index.html b/framework/extend/wechat/index.html new file mode 100644 index 0000000..e69de29 diff --git a/framework/extend/wechat/token/index.html b/framework/extend/wechat/token/index.html new file mode 100644 index 0000000..e69de29 diff --git a/framework/library/Controller.php b/framework/library/Controller.php index c2e1055..58a4789 100644 --- a/framework/library/Controller.php +++ b/framework/library/Controller.php @@ -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', [ diff --git a/framework/library/Database.php b/framework/library/Database.php index ab0bd39..6b3b8ad 100644 --- a/framework/library/Database.php +++ b/framework/library/Database.php @@ -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); diff --git a/framework/library/Router.php b/framework/library/Router.php index 603c7df..4d50df2 100644 --- a/framework/library/Router.php +++ b/framework/library/Router.php @@ -95,10 +95,6 @@ class Router $this->check(); - Register::set('Config', function () { - return Config::instance(); - }); - return $this; } } diff --git a/framework/library/Template.php b/framework/library/Template.php index a2de458..a127375 100644 --- a/framework/library/Template.php +++ b/framework/library/Template.php @@ -14,9 +14,16 @@ class Template use Instance; - // 操作的具体实现 + /** + * 模板操作的具体实现 + * @var + */ private $template; + /** + * 参数 + * @var array + */ private $param = []; /** diff --git a/framework/library/View.php b/framework/library/View.php index 87382a4..eedb2db 100644 --- a/framework/library/View.php +++ b/framework/library/View.php @@ -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); } diff --git a/framework/library/cache/File.php b/framework/library/cache/File.php deleted file mode 100644 index 1f8e28e..0000000 --- a/framework/library/cache/File.php +++ /dev/null @@ -1,71 +0,0 @@ - $time) { - return false; - } else { - return true; - } - } else { - return false; - } - } -} diff --git a/framework/library/cache/Redis.php b/framework/library/cache/Redis.php deleted file mode 100644 index 7f4c06b..0000000 --- a/framework/library/cache/Redis.php +++ /dev/null @@ -1,77 +0,0 @@ -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); - } -} diff --git a/framework/library/cache/driver/File.php b/framework/library/cache/driver/File.php new file mode 100644 index 0000000..4352a5a --- /dev/null +++ b/framework/library/cache/driver/File.php @@ -0,0 +1,183 @@ +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_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); + } + } + +} diff --git a/framework/library/cache/driver/Redis.php b/framework/library/cache/driver/Redis.php new file mode 100644 index 0000000..e4094ee --- /dev/null +++ b/framework/library/cache/driver/Redis.php @@ -0,0 +1,99 @@ +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); + } +} diff --git a/framework/library/cache/driver/index.html b/framework/library/cache/driver/index.html new file mode 100644 index 0000000..e69de29 diff --git a/framework/library/cache/ifs/CacheIfs.php b/framework/library/cache/ifs/CacheIfs.php index da2460a..f4f0269 100644 --- a/framework/library/cache/ifs/CacheIfs.php +++ b/framework/library/cache/ifs/CacheIfs.php @@ -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 = ''); diff --git a/framework/library/database/driver/ObjectForMySQL.php b/framework/library/database/driver/ObjectForMySQL.php new file mode 100644 index 0000000..0b8a15d --- /dev/null +++ b/framework/library/database/driver/ObjectForMySQL.php @@ -0,0 +1,462 @@ +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(); + } +} diff --git a/framework/library/functions/functions.php b/framework/library/functions/functions.php index f2703f0..49c0f31 100644 --- a/framework/library/functions/functions.php +++ b/framework/library/functions/functions.php @@ -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; +} + // 模型自动验证函数 /** diff --git a/framework/library/http/Request.php b/framework/library/http/Request.php index 201bc91..96ecbfe 100644 --- a/framework/library/http/Request.php +++ b/framework/library/http/Request.php @@ -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); diff --git a/framework/library/http/response/ResponseData.php b/framework/library/http/response/ResponseData.php index 6dbba94..87b75c7 100644 --- a/framework/library/http/response/ResponseData.php +++ b/framework/library/http/response/ResponseData.php @@ -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); diff --git a/framework/library/http/response/index.html b/framework/library/http/response/index.html new file mode 100644 index 0000000..e69de29 diff --git a/framework/library/route/driver/Command.php b/framework/library/route/driver/Command.php index 71bcc67..763314c 100644 --- a/framework/library/route/driver/Command.php +++ b/framework/library/route/driver/Command.php @@ -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(); } /** diff --git a/framework/library/template/driver/Smarty.php b/framework/library/template/driver/Smarty.php index e23526c..7e7fe4f 100644 --- a/framework/library/template/driver/Smarty.php +++ b/framework/library/template/driver/Smarty.php @@ -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 . '/'; diff --git a/framework/library/template/driver/Top.php b/framework/library/template/driver/Top.php index 0fdb0ae..bae44eb 100644 --- a/framework/library/template/driver/Top.php +++ b/framework/library/template/driver/Top.php @@ -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(); diff --git a/framework/library/template/driver/Twig.php b/framework/library/template/driver/Twig.php index 5d51f5c..04721a4 100644 --- a/framework/library/template/driver/Twig.php +++ b/framework/library/template/driver/Twig.php @@ -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 . '/'; diff --git a/framework/library/template/driver/tags/Engine.php b/framework/library/template/driver/engine/Engine.php similarity index 99% rename from framework/library/template/driver/tags/Engine.php rename to framework/library/template/driver/engine/Engine.php index f7f1256..dc0736e 100644 --- a/framework/library/template/driver/tags/Engine.php +++ b/framework/library/template/driver/engine/Engine.php @@ -1,8 +1,7 @@ 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; } diff --git a/framework/middleware/View.php b/framework/middleware/View.php index eef094c..5eda809 100644 --- a/framework/middleware/View.php +++ b/framework/middleware/View.php @@ -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; diff --git a/framework/traits/index.html b/framework/traits/index.html new file mode 100644 index 0000000..e69de29 diff --git a/public/index.php b/public/index.php index dfe64e9..ad1bbd7 100644 --- a/public/index.php +++ b/public/index.php @@ -7,7 +7,7 @@ require '../framework/Framework.php'; // 可能你会使用到下面这些配置 // 调试模式,缺省值:false -Framework::debug(true); +// Framework::debug(true); // 可使用常量DEBUG取得该值 // 项目目录,缺省值:./application/