HYPHP是一款支持中文语法的PHP MVC开发框架. 它可以帮助你快速开发PHP应用. HYPHP基于Apache2开源协议发布 由 和悦网络科技团队进行维护
框架为了快速开发PHP应用而诞生的.
框架版本请跟随GIT GIT 地址 https://github.com/hyyyp/HYPHP2 https://github.com/hyyyp/HYPHP2.git
HYPHP 是OOP面向对象框架, 所以需要PHP 5.3+环境 (包括5.3) 同时也支持PHP7.0+ HYPHP 数据库操作采用了国外Medoo开源框架. 需要PDO支持! 仅支持PDO!
HYPHP框架 并不需要高大上的服务器环境. 框架文件并且轻量简洁.
建议你在本地搭建开发环境, 推荐几款: XAMPP , PHPStudy , 本地环境尽量采用Apache 作为WEB服务器 较为方便
第一次访问框架, 框架将自动生成应用目录
根目录 ├─Action 控制器目录 │ ├─Index.php 生成的Index控制器 ├─Conf 配置项目录 │ ├─config.php 默认配置文件 ├─Lib 自定义类库目录 ├─Model 数据库模型目录 ├─Plugin 插件目录 ├─Tmp 缓存文件目录 ├─View 模板目录
框架默认会生成一个Index控制器 (/Action/Index.php) 该文件内容为:
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ echo 'HY框架'; } }
+++ get:/ <<< success HY框架 +++
HYPHP控制器采用了OOP方式进行访问调用. 控制器就是一个类, 而操作方法则是一个类成员函数 下面是一个默认的 /Action/Index.php 内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ echo 'HY框架'; } }
当我们访问 (如果我们直接访问首页 不增加参数 则会自动指向 Index控制器的Index() 方法)
+++ get:/ <<< success HY框架 <<<
+++
访问了 /?index 既是访问了index控制器
+++ get:/?index <<< success HY框架 <<< +++
访问了 /?index/index 既是访问了index控制器里的index() 方法
+++ get:/?index/index <<< success HY框架 <<<
+++
访问了 /?index/test 既是访问了index控制器里的test() 方法
+++ get:/?index/test <<< Error 你的\Action\IndexAction没有存在Test操作方法 +++
当访问test就出错了 是因为Test() 并没有在Index中定义 Index中仅定义了 Index()
控制器的定义采用驼峰法. 首字母大写. 接下来新建一个 User 控制器 在/Action目录下新建文件 User.php (注意第一位大写字母) 在User.php文件写入内容
<?php namespace Action; use HY\Action; class User extends Action { public function Index(){ echo '这里是User模块的Index方法'; } }
而类的名称也是一样采用首字母大写的方式 User 继承了 Action
+++ get:/?User <<< success 这里是User模块的Index方法 +++
+++ get:/?User/Index <<< success 这里是User模块的Index方法 +++ 同理, 如果你仅仅访问了User控制器 却没有输入Index , 框架还是会自动指向Index()函数, 如果你的User控制器中 没有Index()函数 则会出错
有朋友不明白 为什么访问 /?User/Index 就能触发 Action/User.php文件中的Index函数 而根目录并没有/User目录呀
当访问了一个链接 /Test/Index 但你的控制器文件中 并没有Test.php 既是没有Test控制器 . 则框架会默认寻找Action下的No.php控制器
+++ get:/?Test/Index <<< Error Test控制器不存在! +++
新建一个空控制器 No.php 放入/Action目录 并写入内容
<?php namespace Action; use HY\Action; class No extends Action { public function index(){ echo '你访问的控制器不存在, 但被Empty接收了'; } }
我们在访问
+++ get:/?Test/Index <<< Success 你访问的控制器不存在, 但被Empty接收了 +++
但如果我们访问 /?Test/Home 呢
+++ get:/?Test/Home <<< Success 你的\Action\No没有存在Home操作方法 +++ 就会提示 你的Empty中没有Home函数了
我们在Empty中写入函数 _no _no函数 可以在任何控制中加入
<?php namespace Action; use HY\Action; class No extends Action { public function index(){ echo '你访问的控制器不存在, 但被Empty接收了'; } public function _no(){ echo '你访问的函数未定义'; } }
再次访问/Test/Home
+++ get:/?Test/Home <<< Success 你访问的函数未定义 +++ 可见 _no 已经接收了 空控制器下的空函数
有同学要问了 怎么获取访问进来的控制器名以及函数名呢 框架内置了一个变量 储存了访问了URL $_GET['HY_URL']
$_GET['HY_URL'][0] 则是 控制器名称 $_GET['HY_URL'][1] 则是 函数名称
单纯的Action输出内容是有限的, HYPHP内置了一个模板引擎. 默认模板目录位于 /View
/Action/Index.php # Index控制器编写一下内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $this->display("index"); } }
在 /View目录 新建文件 index.html 写入内容
Action调用了这个模板
访问首页
+++ get:/
<<< success Action调用了这个模板 +++
可见访问了首页触发了 Index 控制器的 Index函数 并在函数中调用了 display 显示 模板 index
display('index') 既是调用了 /View/index.html
有童鞋问了 模板后缀 .html 能不能更换呢 答: 可以的, 你可以在/Conf/config.php配置中 增加一项 'tpl_suffix' => '.tpl'
将成为 /View/index.tpl
显示模板();
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ 显示模板("index"); } }
当我们在Action中输出了模板. 但模板如何调用 Action中的变量呢? 看一下下面错误的示范 Index 控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $string = '这是一个字符串'; $this->display("index"); } }
模板 index.html 内容
我想调用刚才Action 的 $string 变量 输出变量: <?php echo $string; ?>
当我们访问时
+++ / <<< Error 调用了未定义的变量 $string +++ 可见 访问后 PHP提示出错 模板调用了一个 未定义的变量$string 但控制器中已经定义它了呀 在这里说明一下 Action 与 模板 是分离的 模板是不能直接使用 Action的值的 那该咋办咧
使用Action成员 v函数 将变量复制到模板中
再次编辑 Index 控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $string = '这是一个字符串'; $this->v("string",$string); $this->v("a",$string); $this->display("index"); } }
$this->v(复制后名称,传入变量)
index.html 模板内容 再次编辑
我想调用刚才Action 的 $string 变量 输出变量: <?php echo $string; ?> 在增加一个 <?php echo $a; ?>
再次访问首页
+++ get:/ <<< success 我想调用刚才Action 的 $string 变量 输出变量: 这是一个字符串 在增加一个 这是一个字符串 +++ 可见 输出内容中 $a 以及 $string 都变成了 这是一个字符串
额外的模板引擎标签 请在模板引擎目录查看
Json & Jsonp 输出 我们通常会在前端用到JSON. 所以框架内置了两个简单的 JSON格式化输出函数
该函数会更改 Content-Type 类型为 application/json; charset=utf-8
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $arr = array(1,2,3); $this->json($arr); } }
+++ get:/ <<< success [1,2,3] +++
可能新手不懂jsonp是什么意思. jsonp是提供给跨域访问使用的. 放A网站使用了ajax去获取 B网站的一个JSON数据 但两者是不同的域名 造成了 跨域危险. 所以AJax是不能直接通信的 所以只能采用JavaScript脚本的方法 使用函数去执行 格式化远程端的字符串JSON
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $arr = array(1,2,3); $this->jsonp($arr,'run'); } }
+++ get:/ <<< success run([1,2,3]); +++
我们通常定义的控制器 Index User Home ...等等 访问他们就需要 /index , /user /home 能不能不改变Index的情况下 改变URL中index名称呢? 就是 访问 /i 就能访问到 Index 控制器. HYPHP内置了一个小型控制器以及方法的绑定路由过程
打开/Conf/config.php 配置文件 增加配置项
<?php //这是 Conf/config.php 配置文件 return array( 'HY_URL'=>array( 'action'=>array( 'Index'=>'i', 'User'=>'u' ), 'method'=>array( 'Index'=>array( 'Index'=>'i' ) ) ), )
先看 Action 项 'Index' => 'i' 既是将URL中index方法改为了i 通常我们访问/?Index 现在可以通过 /?i 就可以访问了 而Method 则是控制器里函数方法. 将Index() 改为了 i() 通常我们访问 /?Index/Index 访问到 Index() 方法 我们现在可以用过 /?Index/i 的方法就访问到了 Index() 当然 你的控制器以及方法都该了 方法将成为 /?i/i 就能访问到了 /?Index/Index
为什么需要这个函数? 有童鞋觉得是多余的, 太多余麻烦. 是的,作者本人也觉得麻烦, 开发时不如直接写固定连接好了 还要调用啥函数. 所以这个函数是提供给 需要经常使用 URL缩短控制器方法的童鞋
他会通过你的缩短控制器更改去 生成合适的方法
具体使用方式详情 : http://bbs.hyphp.cn/t/740.html
获取用户请求类型 通常情况下 我们浏览器访问我们的网站时都是使用 GET 而提交表单大多都是使用POST 以及JS脚本AJAX访问 如果在控制器中获取访问者的请求类型呢 目前框架已经直接内置了常量
常量名 | 说明 |
---|---|
IS_GET | 直接访问的GET方式 |
IS_POST | 直接访问的POST方式 |
IS_AJAX | 直接访问的AJAX方式 |
目前就内置了3个常用的判断 他们的值将会是 bool类型
使用场景演示
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ if(IS_POST) echo '用户采用了POST访问'; elseif(IS_GET) echo '用户采用了GET访问'; elseif(IS_AJAX) echo '用户采用了AJAX访问'; } }
并不是3个类型 只有一个是 true
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ if(IS_POST && IS_AJAX) echo '用户采用了AJAX POST访问'; } }
我们开发时经常会输出大量的HTML内容, 但这些内容不可能堆积在控制器中. 所以我们最好使用文件区分开来. HYPHP内置了模板引擎, 提供一些常用的PHP标签以及 组合方式 默认模板路径在 /View ,常量定义为 VIEW_PATH . 建立方式: 模板名 + .后缀 例: (home.html) 控制器中调用该模板 $this->display("home") .从而输出 home.html的内容 .
可见定义模板时 使用了 (.html) 框架内置的默认值为 array(.html , .php) 意为模板可以使用 .html以及.php 如果你想修改该配置 可以从 Conf/config.php 加入 'tpl_suffix' => '.tpl' 或数组
Index控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $this->display("home"); } }
模板 home.html 内容
这是home模板 <br> 第二行文字
当我们访问时
+++ / <<< Success 这是home模板 第二行文字 +++
通常我们的模板文件都放于模板目录中. 而太多模板文件堆积在一起 却看起来很烦恼 所以有必要进行分组使用
通产我们使用的模板目录位于 /View , 我们可以在该目录下建立子目录. 例 : 建立目录 /View/home , 并新建模板文件在该目录下
在控制器方法中 调用display前 , 将分组名赋值给 : $this->view ,从而框架会通过该变量去增加路径 (注意大小写)
<?php //这是/Action/Index.php 文件 namespace Action; use HY\Action; class Index extends Action { public function index(){ //目前显示模板 /View/index_index.html $this->display('index_index'); } public function test(){ //将使用 /View/home/index_index.html 模板 $this->view = 'home'; $this->display('index_index'); } }
当我们在控制器输出模板时, 模板是无法直接调用方法函数中的变量的. 我们需要通过框架内置的输出方法, 将变量赋值到模板当中使用.
看一下下面错误的示范 Index 控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $string = '这是一个字符串'; $this->display("index"); } }
模板 index.html 内容
我想调用刚才Action 的 $string 变量 输出变量: <?php echo $string; ?>
当我们访问时
+++ / <<< 出错 调用了未定义的变量 $string +++ 可见结果, 模板是无法直接使用控制器内的变量的. 我们需要在控制器方法中 输出模板时将变量赋值到模板中 使用Action成员 v函数 将变量复制到模板中
再次编辑 Index 控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $string = '这是一个字符串'; $this->v("string",$string); $this->v("a",$string); $this->display("index"); } }
$this->v(复制后名称,传入变量)
index.html 模板内容 再次编辑
我想调用刚才Action 的 $string 变量 输出变量: <?php echo $string; ?> 在增加一个 <?php echo $a; ?> HYPHP 内置标签输出变量 : {$a}
再次访问首页
+++ get:/ <<< success 我想调用刚才Action 的 $string 变量 输出变量: 这是一个字符串 在增加一个 这是一个字符串 HYPHP 内置标签输出变量 : 这是一个字符串 +++ 可见 输出内容中 $a 以及 $string 都变成了 这是一个字符串
框架的模板引擎提供了一系列输出标签.
{$a} 等同于 <?php echo $a; ?>
Index 控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $arr =array( 'user'=>'admin', 'pass'=>'123456' ); $this->v('arr',$arr); $this->display("index"); } }
模板 index.html 内容
我想调用刚才Action 的 $arr 变量 输出变量: {$arr.user} {$arr.pass}
当我们访问时
+++ / <<< 出错 我想调用刚才Action 的 $arr 变量 输出变量: admin 123456 +++
我们之前的介绍都是在控制器中 单独输出了一个模板文件. 但我们的项目肯定是需要使用到 包含文件的 最常见的就是 HTML的 header 以及footer 或Menu
Index控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $this->display("index"); } }
模板 index.html 内容
{include header} 我是Index模板<br> {include footer}
模板 header.html 内容
我是头部文件 header <br>
模板 footer.html 内容
我是尾部文件 footer <br>
+++ / <<< Success 我是头部文件 header 我是Index模板 我是尾部文件 footer +++
可见我们的结果中. 控制器输出了index模板 而index中使用了include 包含了header 以及 footer 使用 {include} 是不需要加入模板后缀的.
PHP中我们使用的流程控制判断 大多都是使用 if elseif else
Index控制器内容
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $this->display("index"); } }
模板 index.html 内容
我是Index模板<br> {if '1' == '1'} 当然啦 {else} 你中毒不浅 {/if} 等同于 <?php if('1' == '1') echo '当然啦'; else echo '你中毒不浅'; ?>
在 {if} 允许使用变量 以及 PHP函数. 框架解析后 与 PHP原生是一样的
<!-- 注意 if 或者 elseif 后需要空格, 后面才是条件 --> {if $a > $b} {elseif $a > $b} <!-- elseif 可将它去除 --> {else} {/if} <!-- 这是原生的语句 --> <?php if (condition): ?> <?php else: ?> <?php endif ?> --------if elseif --------- <?php if (condition): ?> <?php elseif (condition): ?> <?php else: ?> <?php endif ?>
与php是一致的标签
模板文件内容
{for $i=0;$i<10;$i++} {/for} <!-- 第二种演示 --> {for $i=0,$ii=10;$i<$ii;$i++,$ii--} {/for} <!-- 原生for --> <?php for ($i=0;$i<10;$i++): ?> 输出$i : {$i} <?php endfor ?> --------------输出结果 输出$i : 0 输出$i : 1 输出$i : 2 输出$i : ...
{foreach $data as $K=>$v} {/foreach} {foreach $data as $v} {/foreach} <!-- 下面是原生foreach --> <?php $arr = array('1','2','3'); ?> <?php foreach ($arr as $key => $value): ?> 输出arr : {$value} <?php endforeach ?> ----输出结果 输出arr : 1 输出arr : 2 输出arr : 3
框架采用了国外Medoo作为支持. 它必须采用PHP PDO扩展支持, 否则将无法使用 目前框架支持的数据库引擎
PHP_PDO 扩展列表
打开 php.ini 找到你想要的相应扩展,去掉前面的;号即可
;extension=php_pdo_mysql.dll // 修改成 extension=php_pdo_mysql.dll // 保存,重启你的PHP或者服务器
如果你是Linux下的PHP环境 则.dll 为 .so
Config 配置 请打开 /Conf/config.php 文件 增加以下信息
<?php return array( //其他一些配置 .... //数据库类型 "SQL_TYPE" => "mysql", //数据库名称 "SQL_NAME" => "test", //数据库地址 "SQL_IP"=>"localhost", //数据库账号 'SQL_USER' => 'root', //数据密码 'SQL_PASS' => 'root', //数据库字符集 'SQL_CHARSET' => 'utf8', //数据库端口 'SQL_PORT' => 3306, //数据库前缀 'SQL_PREFIX' => 'hy_', //PDO配置 'SQL_OPTION' => array( PDO::ATTR_CASE => PDO::CASE_NATURAL, //PDO::ATTR_PERSISTENT => true //长连接 ) );
名称 | 说明 |
---|---|
SQL_TYPE | 数据库类型 |
SQL_NAME | 数据库名称 |
SQL_IP | 数据库地址 |
SQL_USER | 数据库 用户 |
SQL_PASS | 数据库 密码 |
SQL_CHARSET | 数据库编码 |
SQL_PORT | 数据库端口 |
SQL_PREFIX | 数据库前缀 |
SQL_OPTION | PDO 额外配置项 |
/Conf/config.php 增加内容
<?php return array( //单个数据库配置 //数据库类型 "SQL_TYPE" => "mysql", //数据库名称 "SQL_NAME" => "hybbs", //数据库地址 "SQL_IP"=>"localhost", //数据库账号 'SQL_USER' => 'root', //数据密码 'SQL_PASS' => '', //数据库字符集 'SQL_CHARSET' => 'utf8', //数据库端口 'SQL_PORT' => 3306, //数据库前缀 'SQL_PREFIX' => 'hy_', //PDO配置 'SQL_OPTION' => array( PDO::ATTR_CASE => PDO::CASE_NATURAL, //PDO::ATTR_PERSISTENT => true //长连接 ), //增加多数据库配置 'SQL_MORE'=>array( //这个数据库的名称 'caiji'=>array( //数据库类型 "SQL_TYPE" => "mysql", //数据库名称 "SQL_NAME" => "caiji", //数据库地址 "SQL_IP"=>"localhost", //数据库账号 'SQL_USER' => 'root', //数据密码 'SQL_PASS' => '', //数据库字符集 'SQL_CHARSET' => 'utf8', //数据库端口 'SQL_PORT' => 3306, //数据库前缀 'SQL_PREFIX' => '', //PDO配置 'SQL_OPTION' => array( PDO::ATTR_CASE => PDO::CASE_NATURAL, //PDO::ATTR_PERSISTENT => true //长连接 ), ), //再增加多个数据库 //'xxx'=>array('SQL_TYPE' .... .. . . .) //.. ... .. //..... ), );
和以往的数据库配置一样 不过他就是放入了 SQL_MORE 中
可见 SQL_MORE 中添加了一个 caiji 项 caiji 项的数据库信息 包含在caiji数组中 数据库信息 很直观 一看就懂
在使用多数据库前一定要配置 SQL_MORE 项 否则无法使用的! 接着上一个文章 的配置信息
'SQL_MORE'=>array( 'name1'=>array( //数据库类型 "SQL_TYPE" => "mysql", //数据库名称 "SQL_NAME" => "caiji", //数据库地址 "SQL_IP"=>"localhost", //数据库账号 'SQL_USER' => 'root', //数据密码 'SQL_PASS' => '', //数据库字符集 'SQL_CHARSET' => 'utf8', //数据库端口 'SQL_PORT' => 3306, //数据库前缀 'SQL_PREFIX' => '', //PDO配置 'SQL_OPTION' => array( PDO::ATTR_CASE => PDO::CASE_NATURAL, //PDO::ATTR_PERSISTENT => true //长连接 ), ) ),
<?php //连接 多个数据库配置中的 name 数据库. 并操作 他的user 表 $User = S('user','name');
使用数据库无时无刻都需要条件去检索数据 . 框架内置的where 采用数组方式传入解析. 并还原SQL语句进行执行
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); //满足email = a 的数据,并返回 user_name 字段数组 $User->select("user_name", array( "email" => "a" )); // WHERE email = 'a' $User->select(user_name", array( "user_id" => 200 )); // WHERE user_id = 200 $User->select("user_name", array( "user_id[>]" => 200 )); // WHERE user_id > 200 $User->select("user_name", array( "user_id[>=]" => 200 )); // WHERE user_id >= 200 $User->select(user_name", array( "user_id[!]" => 200 )); // WHERE user_id != 200 $User->select("user_name", array( "age[<>]" => [200, 500] )); // WHERE age BETWEEN 200 AND 500 $User->select("user_name", array( "age[><]" => [200, 500] )); // WHERE age NOT BETWEEN 200 AND 500 // [><] 和 [<>] 可以用于 datetime $User->select("user_name", array( "birthday[><]" => array( date("Y-m-d", mktime(0, 0, 0, 1, 1, 2015)), date("Y-m-d") ) )); //WHERE "create_date" BETWEEN '2015-01-01' AND '2015-05-01' (now) // 你不仅可以使用字符串和数字,还可以使用数组 $User->select("user_name", array( "OR" => array( "user_id" => [2, 123, 234, 54], "email" => array("foo@bar.com", "cat@dog.com", "admin@medoo.in") ) )); // WHERE // user_id IN (2,123,234,54) OR // email IN ('foo@bar.com','cat@dog.com','admin@medoo.in') // 多条件查询 $User->select("user_name", array( "AND" => array( "user_name[!]" => "foo", "user_id[!]" => 1024, "email[!]" => ["foo@bar.com", "cat@dog.com", "admin@medoo.in"], "city[!]" => null, "promoted[!]" => true ) )); // WHERE // `user_name` != 'foo' AND // `user_id` != 1024 AND // `email` NOT IN ('foo@bar.com','cat@dog.com','admin@medoo.in') AND // `city` IS NOT NULL // `promoted` != 1 // 或者嵌套 select() ak get() 方法 $User->select("user_name", array( "user_id" => $User->select("post", "user_id", ["comments[>]" => 40]) )); // WHERE user_id IN (2, 51, 321, 3431) } }
上面是基础的Where语句,下面看一下复杂一点的 你可以使用"AND" 或 "OR" 来拼接非常复杂的SQL语句
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); // 基础使用 $User->select("user_name", array( "AND" => array( "user_id[>]" => 200, "age[<>]" => array(18, 25), "gender" => "female" ) )); // WHERE user_id > 200 AND age BETWEEN 18 AND 25 AND gender = 'female' $User->select("user_name", array( "OR" => array( "user_id[>]" => 200, "age[<>]" => array(18, 25), "gender" => "female" ) )); // WHERE user_id > 200 OR age BETWEEN 18 AND 25 OR gender = 'female' // 复合条件 $User->has(array( "AND" => array( "OR" => array( "user_name" => "foo", "email" => "foo@bar.com" ), "password" => "12345" ) )); // WHERE (user_name = 'foo' OR email = 'foo@bar.com') AND password = '12345' // 注意 // 因为使用的是数组传参,所以下面这种用法是错误的。 // 可见 你有两个OR ,数组不可能存在两个相同索引. 所以你需要将另一个OR 加上一个注释 $User->select('*', array( "AND" => array( "OR" => array( "user_name" => "foo", "email" => "foo@bar.com" ), "OR" => array( "user_name" => "bar", "email" => "bar@foo.com" ) ) )); // [X] SELECT * FROM "account" WHERE ("user_name" = 'bar' OR "email" = 'bar@foo.com') 这是错误的示范 // 正确的方式是使用如下方式定义复合条件 $User->select('*', array( "AND #Actually, this comment feature can be used on every AND and OR relativity condition" => array( "OR #the first condition" => array( "user_name" => "foo", "email" => "foo@bar.com" ), "OR #the second condition" => array( "user_name" => "bar", "email" => "bar@foo.com" ) ) )); // SELECT * FROM "account" // WHERE ( // ( // "user_name" = 'foo' OR "email" = 'foo@bar.com' // ) // AND // ( // "user_name" = 'bar' OR "email" = 'bar@foo.com' // ) // ) } }
接下来我们看一下模糊匹配 Like语句 LIKE 使用语法 [~] .
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); // 默认情况下,使用%在前后包含关键词 $User->select("id", array( "city[~]" => "lon" )); WHERE "city" LIKE '%lon%' // 数组形式,查询多个关键词 $User->select("id", array( "city[~]" => array("lon", "foo", "bar") )); WHERE "city" LIKE '%lon%' OR "city" LIKE '%foo%' OR "city" LIKE '%bar%' // 不包含 [!~] $User->select("id", array( "city[!~]" => "lon" )); WHERE "city" NOT LIKE '%lon%' // 使用SQL自带的一些通配符 // 你可以使用sql自带的一些通配符来完成较复杂的查询 $User->select("id", array( "city[~]" => "stan%" // Kazakhstan, Uzbekistan, Türkmenistan )); $User->select("id", array( "city[~]" => "Londo_" // London, Londox, Londos... )); $User->select("id", array( "name[~]" => "[BCR]at" // Bat, Cat, Rat )); $User->select("id", array( "name[~]" => "[!BCR]at" // Eat, Fat, Hat... )); } }
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); $User->select("user_id", array( // "ORDER" => "age DESC" "ORDER" => ['age'=>'DESC'], )); // SELECT user_id FROM account // ORDER BY age // 多个排序 $User->select("user_id", array( "ORDER" => array('user_name DESC', 'user_id ASC') )); // SELECT user_id FROM account // ORDER BY "user_name" DESC, "user_id" ASC // 根据字段自定义排序顺序 // "ORDER" => array("column_name", [array #ordered array]) $User->select("user_id", array( "user_id" => array(1, 12, 43, 57, 98, 144), "ORDER" => array("user_id", array(43, 12, 57, 98, 144, 1)) )); // SELECT "user_id" // FROM "account" // WHERE "user_id" IN (1,12,43,57,98,144) // ORDER BY FIELD("user_id", 43,12,57,98,144,1) // array(6) { // [0]=> string(2) "43" // [1]=> string(2) "12" // [2]=> string(2) "57" // [3]=> string(2) "98" // [4]=> string(3) "144" // [5]=> string(1) "1" // } } }
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); //搜索一个用户 可能user 或者 email中存在关键字 $User->select("post_id", array( "MATCH" => array( "columns" => array("user", "email"), "keyword" => "foo" ) ); // WHERE MATCH (content, title) AGAINST ('foo') } }
在一些特殊的情况下,你可能需要使用SQL系统函数,只需要字段名前加上#号即可
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); $data = $User->select( array( 'user_id', 'user_name' ), array( '#datetime' => 'NOW()' )); // SELECT "user_id","user_name" // FROM "account" // WHERE "datetime" = NOW() // [重要]记住,价值也不会引用应符合xxx()大写。 //下面是一个错误的示例 $User->select(array( 'user_id', 'user_name' ), array( '#datetime2' => 'now()', 'datetime3' => 'NOW()', '#datetime4' => 'NOW' )); } }
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); $User->select("account", "user_id", array( "GROUP" => "type", // 必须有使用它与小组一起 "HAVING" => array( "user_id[>]" => 500 ), // LIMIT => 20 "LIMIT" => array(20, 100) )); // SELECT user_id FROM account // GROUP BY type // HAVING user_id > 500 // LIMIT 20,100 } }
数据库查询
select( $columns, $where) columns [string/array] 要查询的字段名. where (optional) [array] 查询的条件.
select($join, $columns, $where) join [array] 多表查询,不使用可以忽略. columns [string/array] 要查询的字段名. where (optional) [array] 查询的条件.
返回: [array] 你可以使用*来匹配所有字段, 但如果你指名字段名可以很好的提高性能.
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); $datas = $User->select(array( "user_name", "email" ), array( "user_id[>]" => 100 )); //返回数据 // $datas = array( // [0] => array( // "user_name" => "admin1", // "email" => "admin1" // ), // [1] => array( // "user_name" => "admin2", // "email" => "admin2" // ) // ) foreach($datas as $data) { echo "user_name:" . $data["user_name"] . " - email:" . $data["email"]; } // 查询所有字段 使用 * $datas = $database->select("*"); // 查询一个字段 输入他的字段名称 $datas = $database->select("user_name"); // $datas = array( // [0] => "admin1", // [1] => "admin2" // ) } }
多表查询
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); // [>] == LEFT JOIN // [<] == RIGH JOIN // [<>] == FULL JOIN // [><] == INNER JOIN $User->select("post", array( // Here is the table relativity argument that tells the relativity between the table you want to join. // The row author_id from table post is equal the row user_id from table account "[>]account" => array("author_id" => "user_id"), // The row user_id from table post is equal the row user_id from table album. // This is a shortcut to declare the relativity if the row name are the same in both table. "[>]album" => "user_id", // [post.user_id is equal photo.user_id and post.avatar_id is equal photo.avatar_id] // Like above, there are two row or more are the same in both table. "[>]photo" => array("user_id", "avatar_id"), // If you want to join the same table with different value, // you have to assign the table with alias. "[>]account (replyer)" => array("replyer_id" => "user_id"), // You can refer the previous joined table by adding the table name before the column. "[>]account" => array("author_id" => "user_id"), "[>]album" => array("account.user_id" => "user_id"), // Multiple condition "[>]account" => array( "author_id" => "user_id", "album.user_id" => "user_id" ) ), array( "post.post_id", "post.title", "account.user_id", "account.city", "replyer.user_id", "replyer.city" ), array( "post.user_id" => 100, "ORDER" => "post.post_id DESC", "LIMIT" => 50 )); // SELECT // `post`.`post_id`, // `post`.`title`, // `account`.`city` // FROM `post` // LEFT JOIN `account` ON `post`.`author_id` = `account`.`user_id` // LEFT JOIN `album` USING (`user_id`) // LEFT JOIN `photo` USING (`user_id`, `avatar_id`) // WHERE // `post`.`user_id` = 100 // ORDER BY `post`.`post_id` DESC // LIMIT 50 } }
举一个通俗易懂的例子 两个表 post 与 user
post表的数据
id | uid | title |
---|---|---|
1 | 1 | 文章标题 |
2 | 1 | 文章标题 |
3 | 1 | 文章标题 |
user表的数据 | uid | username | | --- | --- | | 1 | admin | | 2 | xxxx | | 3 | dddd |
问题: 如果获取 post表数据的时候 同时获取 用户名 (user.username) 答: 简单的都是先获取了 post的数据出来 再循环user表中的username
我们取出post表的数据时 还能取出uid 用户ID 却不能取出用户名, 这时就能用到多表查询
S('Post')->select(array( "[>]user" => [ "uid" => "uid"], //post.uid == user.uid ),array( 'post.title', 'user.username' ) ); 输出: arrary( 'title'=>'文章标题', 'username'=>'admin' )
多表查询 Count
S('Post')->count(array( "[>]user" => [ "uid" => "uid"], //post.uid == user.uid ), '*' );
复杂的多表查询 Count (HYBBS处的一段搜索代码)
$page_count = $Thread->count( array( "[>]post" => [ "pid" => "id"], //post.id == thread.pid ), '*', array('AND'=>array( 'isthread'=>1 ,'OR'=>array( 'thread.title[~]'=>$key, 'post.content[~]'=>$key ))) );
OBJ->count($join, "*" ,条件 );
insert($data) 中文 : 插入($data) data [array] 插入到表里的数据 Return: [number] 返回插入的id
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); $User->insert(array( "user" => "admin", "pass" => "admin", )); //返回插入的ID $User->id(); //中文语法 $User->插入(array( "user" => "admin", "pass" => "admin", )); } }
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = M("User"); $id = $User->insert(array( array( "user" => "admin", "pass" => "admin", ), array( "user" => "admin1", "pass" => "admin1", ) )); } }
update($data, $where) 中文 : 更新(数据,条件) data [array] 修改的数据. WHERE 条件.[可选] Return: [number] 受影响的行数.
$User = S("User"); $User->update(array( "type" => "user", // age字段的值 + 1 "age[+]" => 1, // 减 - 5 "level[-]" => 5, // 两倍 2 "score[*]" => 2, // SQL 函数 "#uid" => "UUID()" ), array( "user_id[<]" => 1000 ));
将 用户名user 等于 admin的用户密码修改为 123
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = M("User"); $User->update( array( "pass" => "123", ), array( 'user'=>'admin' ) ); //中文 $User->更新( array( "pass" => "123", ), array( 'user'=>'admin' ) ); } }
delete($where) 中文 : 删除(条件); where [array] WHERE 删除条件. Return: [number] 返回被删除的行数.
删除一个 user = admin 并 年龄<18的数据
$User = S("User"); $User->delete(array( "AND" => array( "user" => "admin" "age[<]" => 18 ) )); //中文语法 $User->删除(array( "AND" => array( "user" => "admin" "age[<]" => 18 ) ));
删除 user 等于 admin的数据
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例User表为对象 $User = S("User"); $User->delete( array( "user" => "admin", ) ); } }
通过条件查询,将返回一条记录
find($columns, $where) 中文 : 查找(返回字段, 条件); columns [string/array] 返回的字段列. where (optional) [array] WHERE 条件. Return: [string/array] 返回查询到的数据.
//查找 user 等于 admin的数据 并返回pass $User = S("User"); $pass = $User->find("pass", array( "user" => "admin" )); //查找条件与上一致 返回 更多字段的数据 $data = $User->find(array( "email", "user", "pass" ), array( "user" => "admin" )); // $data = array( // "email" => "admin@a.com", // "user" => "admin", // "pass" => "admin" // ) $pass = $User->find("*", array( "user" => "admin" )); //返回 所有字段 //中文语法 $User = S("User"); $pass = $User->查找("pass", array( "user" => "admin" ));
通过条件搜素 判断数据是否存在
has($where) 中文 : 是否存在(条件); where [array] WHERE 条件. Return: [boolean] 返回 TRUE 或者 FALSE.
has($join, $where) join [array] 多表查询. where [array] WHERE条件.
Return: [boolean] 返回 TRUE 或者 FALSE.
例:可以使用它来判断某用户是否存在 , 或者账号密码是否正确!
$User = S("User"); // 判断用户账号密码是否正确, 可见 user = admin && pass = admin if ($User->has(array( "AND" => array( "user" => "admin", "pass" => "admin" ) ))){ echo "正确"; } else{ echo "不正确"; } //判断账号是否存在 if ($User->has(array( "user" => "admin", ))) echo '存在'; else echo '不存在';
通过条件 检索数据的数量
count($where) 中文 : 总数(条件); where (optional) [array] WHERE 条件.
count( $join, $column, $where) join [array] 多表查询. column [string] 需要统计的字段. where (optional) [array] WHERE 条件.
Return: [number] 行的数量. 返回的是数字类型.
$User = S("User"); //查看 user = admin 有多少数目 $count = $User->count(array( "user" => "admin" )); //查找User表的数据总数 $All_count = $User->count();
max($column, $where) 中文语法 : 最大值() / 最小值() column [string] 查询的字段列. where (optional) [array] WHERE 条件.
max($join, $column, $where) join [array] 多表查询. column [string] 字段名. where (optional) [array] 条件.
Return: [number] 返回最大的值.
查询数据表中某整数字段的 最大值. 例如User表有一个年龄字段
$User = S("User"); //查看 age 字段最大值. $max = $User->max("age"); //增加条件检索 //user=admin的数据 age 最大值 $max = $User->max("age",array( 'user' = 'admin' ));
参数同Max 查询数据表中某整数字段的 最小值 用法与Max一致
action( $callback ) $callback [function] 事务内执行的方法.
$User = S("User"); $User->action(function($User) { $User->insert('User',array( "user" => "admin", "pass" => "admin" )); return true; //false 回滚 });
query($query) query [string] The SQL query. Return: [object] The PDOStatement object.
$User = S("User"); $User->query("CREATE TABLE table ( c1 INT STORAGE DISK, c2 INT STORAGE MEMORY ) ENGINE NDB;"); $data = $User->query("SELECT email FROM account")->fetchAll(); print_r($data);
PDO对象
//$Model -> pdo $User = S("User"); $User->pdo->query("CREATE TABLE table ( c1 INT STORAGE DISK, c2 INT STORAGE MEMORY ) ENGINE NDB;"); $data = $User->pdo->query("SELECT email FROM account")->fetchAll(); print_r($data);
quote($string) $string [string] 字符串. Return: [string]
可用于过滤字符串的SQL注入
$User = M("User"); $string = 'Nice'; print "Unquoted string: $string\n"; print "Quoted string: " . $User->quote($string) . "\n"; 以上例程会输出: Unquoted string: Nice Quoted string: 'Nice' /* Dangerous string */ $string = 'Naughty \' string'; print "Unquoted string: $string\n"; print "Quoted string:" . $User->quote($string) . "\n"; 以上例程会输出: Unquoted string: Naughty ' string Quoted string: 'Naughty '' string' /* Complex string */ $string = "Co'mpl''ex \"st'\"ring"; print "Unquoted string: $string\n"; print "Quoted string: " . $User->quote($string) . "\n"; 以上例程会输出: Unquoted string: Co'mpl''ex "st'"ring Quoted string: 'Co''mpl''''ex "st''"ring'
什么是Model , 当我们有大量的SQL需要重复执行, 不适合在控制器中大量的写入. 我们就需要将他们封装成函数.
比如我们有一段 添加用户账号密码进入用户表的代码 . 这代码可能会在多个控制器中使用. 此时我们就可以将这段代码封装到Model中.
Model的定义与控制器Action 是一样的操作 Model 默认存放目录在 /Model. 我们实例一个
写入内容 Model定义方式与Action一致 首字母大写.
新建文件 /Model/User.php
<?php namespace Model; use HY\Model; !defined('HY_PATH') && exit('HY_PATH not defined.'); class User extends Model{ public function test(){ echo '这是UserModel的test函数'; } }
上面就是一个简单的Model 类 与 方法函数 我们尝试在控制器中使用它
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例UserModel $User = M("User"); //调用UserModel 中的 test() ; $User->test(); //对User表插入数据 $User->insert(array( "user" => "admin", "pass" => "admin", )); } }
+++ get:/ <<< success 这是UserModel的test函数 +++
/Model/User.php 内容
<?php namespace Model; use HY\Model; !defined('HY_PATH') && exit('HY_PATH not defined.'); class User extends Model{ //一个添加用户的函数 public function add_info($user,$pass){ $this->insert(array( "user" => $user, "pass" => $pass, )); } //删除某用户函数 public function del_user($user){ $this->delete(array( 'user'=>$user )) } }
控制器中使用
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例UserModel $User = M("User"); //调用UserModel 中的 add_info() ; //添加一个用户 $User->add_info('admin','123456'); //删除 admin 用户 $User->del_user('admin'); } }
Model上的 debug()方法 可以对该条语句不执行 并输出该语句所生成的SQL语句
$id = $User->debug()->insert(array( "user" => "admin", "pass" => "admin", )); //输出 INSERT INTO "hy_user" ("user", "pass") VALUES ('admin', 'admin') //中文语法 $id = $User->调试()->插入(array( "user" => "admin", "pass" => "admin", ));
通常我们在使用select和find的时候,希望查询结果缓存下来,但是又需要调用cache(), 还要写判断语句,为了避免这种麻烦,HYPHP 直接在Model中内置了 查询缓存。
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $User = S("User"); $User->select('user',array( "uid" =>1, )); } }
上面的代码 select 获取user表 uid为1的用户 这是一个我们常用的查询方法。而且是固定的结果。 但是每次访问都必须执行这个SQL去获取。 所以会消耗服务器资源。 所以我们有必要将这个查询结果缓存下来。
S()->cache($key,$expire=NULL)->select() ->cache(缓存键名,缓存过期时间)->select()
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $User = S("User"); $User->cache('user',10)->select('user',array( "uid" =>1, )); } }
上面的代码 缓存10秒这个select查询得到的数据 缓存键名为user
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $User = S("User"); $User->cache(true,10)->select('user',array( "uid" =>1, )); } }
->cache(true,10) 缓存键名填写 true 则会按照这条sql做 自动补充键名。
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ $User = S("User"); $User->cache(true)->select('user',array( "uid" =>1, )); } }
看到上面代码,cache没有输入过期时间。则该缓存会永久缓存
Lib 可以在多种场景中使用, 包括Action,Model,View 中 默认Lib目录处于 /Lib . 新建文件 /Lib/User.php (注意大小写 首字母必须大写)
<?php namespace Lib; class User{ public function check_user($user){ $len = strlen($user); if($len < 6 || $len > 18) return false; //'账号长度不符合标准,必须 大于6位 小于18位' return true; } }
<?php namespace Action; use HY\Action; class Index extends Action { public function Index(){ //实例UserLib $UserLib = L("User"); $user = 'admin'; $bool = $UserLib->check_user($user); if($bool) echo '用户名格式正确'; else echo '反之'; } }
获取 PHP预定义变量 框架内置了一个函数 可以获取提交到服务器的参数数据.
函数声明 X(获取类型,默认值='');
X 函数可以获取 _GET _POST _SESSION _COOKIE _SERVER 数据. 并且你不需要再去使用isset 去判断索引是否存在 以及 empty 去判断是否为空 如果 X 函数返回假 说明不存在
类型 | 原方式 | 运用方式 |
---|---|---|
post | $_POST['参数名'] | X('post.参数名') |
get | $_GET['参数名'] | X('get.参数名') |
cookie | $_COOKIE['参数名'] | X('cookie.参数名') |
session | $_SESSION['参数名'] | X('session.参数名') |
server | $_SERVER['参数名'] | X('server.参数名') |
控制器中使用
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ echo X("get.id"); echo X('get.xxxx',0); //如果没设置get参数xxxx 则返回默认值0 } }
访问Index控制器 +++ get:/?id=1 <<< success 1 0 +++
大家在之前的文档中 会经常看到 M("User") 的出现 M() 是框架一个内置的函数
M 函数用于加载你的 Model 类 并且实例这个表作为对象操作.
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //使用 M 函数对 User 数据表 进行操作 $User = M("User"); //插入数据 $User->insert ... .. .... .. 关于 SQL操作 请在数据库模型中查看 } }
该函数在之前的文档中 没有提过 也没有进行过使用. 该函数与S 函数差不多 S函数 是不加载你的自定义Model模型 跳过Model 的加载 直接加载系统底层操作对象类 所以使用S函数加载的对象 是操作不了Model的内容的
当我们的Model封装了太多的 函数后 我们有时候操作简单的SQL 并不会使用到Model的内容是 我们就可以使用S函数 跳过Model的加载 提升效率
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //使用 S 函数对 User 数据表 进行操作 $User = S("User"); //插入数据 $User->insert ... .. } }
C 函数可以获取你在 /Conf/config.php 配置的值 你也可以临时将值储存 但他不会保存到你的config.php中哦! 你可以重复设置同一个值 进行覆盖
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //获取 echo C("url_explode"); //获取 URL分隔符 echo C("SQL_IP"); //获取 数据库地址 //设置 C('TEST','123'); C(array( 'TEST'=>'123', 'AAA'=>'zxc' )); //获取 echo C('TEST'); //输出 123 echo C('AAA'); //输出 zxc } }
我们开发时肯定会有很多个控制器 存放于 Action中 但如果我们想在 Index控制器 中调用 Home控制器 里的函数怎么办咧? 使用A函数
这是Index控制器内容
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ echo '我是Index控制器的Index()方法 <br>'; //我们调用一下 Home控制器的 test 方法 A('Home')->test(); //我们可以将 A 储存为对象 $HomeAction = A("Home"); $HomeAction->test(); } }
这是Home控制器内容
<?php namespace Action; use HY\Action; class HomeAction extends Action { public function test(){ echo '我是Home控制器的test()方法 <br>' ; } }
我们访问一下 Index 控制器 看一下结果 +++ get:/ <<< success 我是Index控制器的Index()方法 我是Home控制器的test()方法 我是Home控制器的test()方法 +++ End
该函数复制与 ThinkPHP .
Cookie 是我们最常用的操作 将数据存储在 用户浏览器上, 并且可以设置有效期.
cookie($name='', $value='',$expire=0) $name : cookie字段 [可选] $value : 设置cookie值 [可选] $expire : cookie有效期 [可选] 0 等于永远 如果3个参数都输入 直接调用cookie 会直接返回所有cookie .作为数组返回 相当于返回整个 $_COOKIE
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //获取cookie值 $user = cookie('user'); //储存在用户浏览器的user字段 //设置cookie值 cookie('user','admin'); //设置cookie值 并 设置有效期 //单位是秒 // 设置cookie user 只有60秒 cookie('user','admin',60); //删除cookie //将第二参数 设置为 null 即为删除 user字段 cookie('user',null); } }
session 与cookie不同. cookie 的数据是保存在 用户浏览器那边的, 所以懂点技术的用户是可以看到cookie 的内容的. 而session的数据是储存在 服务器的, 用户是无法直接看到 session储存的数据的
session 还是需要通过cookie储存一个索引在用户浏览器中 从而session从这个索引中找到 属于这个用户的数据
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //使用session 时一定要先启动session //启动session session('[start]'); //启动了这步 才能操作session 这个步骤请勿多次使用 每次执行只能使用一次 //获取session值 echo session('user'); //设置session值 session('user','admin'); //删除session值 session('user',null); //返回所有 session 等同于$_SESSION print_r(session()); } }
该函数较为少用 用于终止PHP运行 并抛出PHP错误进行提醒
该函数不是exit 以及 die 而是 throw new \Exception($str);
cache 数据缓存 HYPHP内置了 THINKPHP 的 数据缓存类 系统目前已经支持的缓存类型包括:Apachenote、Apc、Db、Eaccelerator、File、Memcache、Redis、Shmop、Sqlite、Wincache和Xcache。
默认会使用使用File缓存类型. 将你的数据储存到 /Tmp目录中 作为文件储存
配置你的数据缓存类型 配置信息请填写在 /Conf/config.php 中
以下是配置实例
<?php return array( 'DATA_CACHE_TYPE' => 'File', 'DATA_CACHE_TIME' => 0, 'DATA_CACHE_TABLE' => 'cache', 'DATA_CACHE_PREFIX' => '', 'DATA_CACHE_COMPRESS' => false, //开启缓存数据压缩 gzcompress 'DATA_CACHE_PATH' => TMP_PATH . 'cache', 'DATA_CACHE_KEY' => '', )
上面是File缓存方式的配置 关于配置项的更多信息
配置名 | 说明 |
---|---|
DATA_CACHE_TYPE | Apachenote、Apc、Db、Eaccelerator、File、Memcache、Redis、Shmop、Sqlite、Wincache和Xcache |
DATA_CACHE_TIME | 缓存过期时间 (秒) 0 = 永久缓存 |
DATA_CACHE_TABLE | 如果使用数据库DB缓存 请填写DB表 |
DATA_CACHE_PREFIX | 缓存前缀 默认为空 |
DATA_CACHE_PATH | 文件缓存保存路径 默认为 TMP_PATH/cache |
DATA_CACHE_KEY | 文件缓存名加密KEY |
DATA_CACHE_COMPRESS | 是否压缩数据 (需要gzcompress , gzuncompress函数支持) |
DATA_CACHE_TIMEOUT | 连接缓存服务器 超时时间 默认为空 使用系统默认值 |
REDIS_HOST | REDIS缓存服务器地址 |
REDIS_PORT | REDIS缓存服务器端口 |
MEMCACHE_HOST | Memcache 缓存服务器地址 |
MEMCACHE_PORT | Memcache 缓存服务器端口 |
MEMCACHED_SERVER | Memcached 缓存服务器地址 必须是array 多台服务器IP |
MEMCACHED_LIB | Memcached 配置参数 |
MemcacheD 配置
'MEMCACHED_SERVER' => array( array('mem1.domain.com', 11211, 33), array('mem2.domain.com', 11211, 67) );
DB表的建立
/** * 数据库方式缓存驱动 hy_ 是你配置的数据库前缀 * CREATE TABLE hy_cache ( * cachekey varchar(255) NOT NULL, * expire int(11) NOT NULL, * data blob, * datacrc int(32), * UNIQUE KEY `cachekey` (`cachekey`) * ); */
换网线
我们默认不需要配置以上的信息, 只是有额外需求时配置. 我们的cache函数是依然可用的
//设置缓存 设置字段user 储存为 admin 该数据就会默认储存为文件 可以下次使用 cache('user','admin'); //获取缓存 echo cache('user'); //获取之前设置的user字段 //输出 admin //删除缓存 cache('user',null) ; //将第二参数设置为null 则为删除缓存 //更多使用 //设置缓存 储存admin到user字段 有效期60秒 如果超过60秒 去获取 user 则返回false cache('user','admin',array( 'expire'=>60 )); //设置缓存 改为 db 缓存 cache('user','admin',array( 'type'=>'db' 'expire'=>60 )); //获取 后期db缓存 cache('user','',array( 'type'=>'db' 'expire'=>60 ));
F 函数是cache衍生的一个函数 他只采用File方式进行缓存 使用方式和cache 是一致的
//设置缓存 F('user','admin'); //输出缓存 echo F('user'); //删除缓存 F('user',null)
hy_is_mobile 函数 该函数来源于 Wordpress 中 返回(bool)
if(hy_is_mobile()) echo '移动短'; else echo '非移动端';
框架也直接内置了 判断移动端的常量 他的定义也是来源于 hy_is_mobile函数 内置了3个常量 IS_MOBILE , IS_SHOUJI , IS_WAP
if(IS_MOBILE) echo '移动端'; else echo '非移动端';
vendor 函数 vendor 函数是用于自动加载类库时使用的, 当我们在网络服务中获得 SDK 时, 就需要用到了. 现在大多SDK 都采用了namespace . 拿七牛云储存的SDK演示
在网站根目录新建目录 SDK , 在目录中放入七牛的SDK 路径成 wwwroot/SDK/Qiniu 当我们的 Action 需要使用Qiniu的SDK时
<?php namespace Action; use HY\Action; class Index extends Action { public function index(){ $auth = new \Qiniu\Auth('accessKey', 'secretKey'); //当访问时 就会出现 没有\Qiniu\Auth 类 //因为框架并没有找到 \Qiniu的目录进行自动加载 //所以我们需要用到 vendor函数 vendor('SDK'); //意为 将 SDK 加载到自动加载路径判断列表中 } }
部分常量 你可以在框架入口文件定义它.
常量名 | 说明 | 可否提前定义 |
---|---|---|
NOW_TIME | 当前服务器时间 返回时间戳 秒 | |
CLIENT_IP | 当前访问客户IP,非获取真实代理! | |
IS_GET | 当前访问是否为GET | |
IS_POST | 当前访问是否为POST | |
IS_AJAX | 当前访问是否为AJAX | |
ACTION_NAME | 当前访问Action | |
METHOD_NAME | 当前访问方法函数 | |
IS_WAP | 当前访问是否为移动端 | |
IS_SHOUJI | 当前访问是否为移动端 | |
IS_MOBILE | 当前访问是否为移动端 | |
PATH | 项目路劲 | Y |
ACTION_PATH | Action控制器目录路径 | Y |
VIEW_PATH | View模板目录路径 | Y |
CONF_PATH | Conf配置文件目录路径 | Y |
TMP_PATH | Tmp模板缓存目录路径 | Y |
TMPHTML_PATH | TmpThml静态缓存目录路径 | Y |
MYLIB_PATH | Lib自定义类库目录路径 | Y |
MODEL_PATH | 模型文件目录路径 | Y |
HY_PATH | 框架目录路径 | Y |
PLUGIN_PATH | HOOK 目录 | Y |
DEBUG | 调试模式 true or false | Y |
PLUGIN_ON HOOK | 插件机制开关 (bool) | Y |
PLUGIN_ON_FILE | 每个插件目录独立开关 (bool) | Y |
PLUGIN_MORE_LANG_ON | 中文PHP语法 (bool) | Y |
####额外说明 有的童鞋说 框架默认生成的目录路劲 能不能自己定义? 框架默认会将目录生成于根目录下 如果你要搬走它 请把入口文件index.php改为如下:
<?php define('INDEX_PATH' , str_replace('\\', '/', dirname(__FILE__)).'/'); define('PATH' , INDEX_PATH.'Apping/'); define('DEBUG' ,true); require INDEX_PATH . 'App/HY/HY.php';
框架生成的目录 就会在你的根目录下/App目录中生成
Config.php 参数 可能文档未来得及更新 部分配置参数
配置项 | 说明 | 可否修改 |
---|---|---|
var_left_tpl | { 模板变量输出标志符 | N |
var_right_tpl | } 模板变量输出标志符 | N |
tpl_suffix | 模板文件后缀 默认.html | Y |
url_suffix | URL为静态后缀 默认.html | Y |
url_explode | 路由控制分割符号 默认/ | Y |
tmphtml_del_time | 静态文件有效期 默认0 为永久 否则秒单位 | Y |
DEBUG_PAGE | DEBUG 页面显示 默认false | Y |
HOOK_SUFFIX | HOOK后缀 | Y |
error_404 | 404页面模板, 默认使用框架404页面 | Y |
MORE_LANG_LIB_FILE | 额外中文PHP函数配置 (数组) | Y |
配置项 | 说明 |
---|---|
DATA_CACHE_TYPE | Apachenote、Apc、Db、Eaccelerator、File、Memcache、Redis、Shmop、Sqlite、Wincache和Xcache |
DATA_CACHE_TIME | 缓存过期时间 (秒) 0 = 永久缓存 |
DATA_CACHE_TABLE | 如果使用数据库DB缓存 请填写DB表 |
DATA_CACHE_PREFIX | 缓存前缀 默认为空 |
DATA_CACHE_PATH | 文件缓存保存路径 默认为 TMP_PATH/cache |
DATA_CACHE_KEY | 文件缓存名加密KEY |
DATA_CACHE_COMPRESS | 是否压缩数据 (需要gzcompress , gzuncompress函数支持) |
DATA_CACHE_TIMEOUT | 连接缓存服务器 超时时间 默认为空 使用系统默认值 |
REDIS_HOST | REDIS缓存服务器地址 |
REDIS_PORT | REDIS缓存服务器端口 |
MEMCACHE_HOST | Memcache 缓存服务器地址 |
MEMCACHE_PORT | Memcache 缓存服务器端口 |
MEMCACHED_SERVER | Memcached 缓存服务器地址 必须是array 多台服务器IP |
MEMCACHED_LIB | Memcached 配置参数 |
配置项 | 说明 |
---|---|
SQL_TYPE | 数据库类型 : 数据库引擎用了PDO, 必须开启PDO扩展. 数据库支持根据你的PDO支持所支持 |
SQL_NAME | 数据库库名 |
SQL_IP | 数据库 IP |
SQL_USER | 数据库 用户名 |
SQL_PASS | 数据库 密码 |
SQL_CHARSET | 数据库字符集 |
SQL_PORT | 数据库 端口 |
SQL_PREFIX | 数据库 前缀 |
SQL_OPTION | PDO配置 |
什么是插件? 或者说是一种模块 他可以在不修改你Action Model View源代码的情况下 去修改 你的代码内容.
该模式一般用于开源项目上使用, 可以更好的实现插件化程序.
目前框架提供了两种插件解析
作者自评该模式 优缺各有展现, 优点可以更好的模块化, 缺点需要hook点以及关键字替换.
该模式一旦开启 你的Action Model 将会想View一样 采用缓存形式进行编译. 从而才能让插件模式进行解析.
在入口文件 index.php 开启插件模式 开发时 务必开启 DEBUG 模式.
<?php define('INDEX_PATH' , str_replace('\\', '/', dirname(__FILE__)).'/'); define('DEBUG' ,true); //开启DEBUG模式 define('PLUGIN_ON' ,true); //开启插件模式 require INDEX_PATH . 'HY/HY.php';
如果没有这个模式需求 请不要开启他
默认插件目录 /Plugin. 我们在该目录新建一个文件夹 test. 在 test 目录下新建文件 a.hook. 在a.hook文件中写入内容
echo '这是test插件的a hook内容 <br>';
那我们的控制器如何使用到这个a.hook呢 我们看一下控制器内容
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //{hook a} echo '这是Index控制器的index() 方法'; } }
访问控制器 +++ get:/
<<< success 这是test插件的a hook内容 这是Index控制器的index() 方法 +++ 在控制器中建立hook点 //{hook 名称} 框架引擎将查找你的插件目录 寻找到名称.hook 吧内容插入到控制器中执行
re 插件机制可以与hook同时使用, 但re机制的解析优先级要比hook的优先. re 插件机制 与 hook的不同之处是 hook需要在源代码插入hook点, 而re机制则不需要hook点 直接查找源代码进行替换修改 接着上面的做法 在test 插件目录新建文件re.php. 写入
<?php return array( 'Action/Index.php'=>array( 'a1'=>'a2' ) );
上面的意思是指: 修改Action/Index.php内容. 查找 /Plugin/test/a1 文件内容 替换为 /Plugin/test/a2 文件内容
Index控制器内容
<?php namespace Action; use HY\Action; class IndexAction extends Action { public function Index(){ //{hook a} echo '这是Index控制器的index() 方法'; } }
Plugin/test/a1 文件内容
echo '这是Index控制器的index() 方法';
Plugin/test/a2 文件内容
echo '这是Index控制器的index() 方法 <br>'; echo '我是re机制追加的内容'
访问控制器 +++ get:/
<<< success 这是test插件的a hook内容 这是Index控制器的index() 方法 我是re机制追加的内容 +++
控制每个插件的可用性
入口文件增加常量定义
<?php define('INDEX_PATH' , str_replace('\\', '/', dirname(__FILE__)).'/'); define('DEBUG' ,true); //开启DEBUG模式 define('PLUGIN_ON' ,true); //开启插件模式 define('PLUGIN_ON_FILE',true); //插件独立开关 require INDEX_PATH . 'HY/HY.php';
此时你的插件会全部失效. 只有你的插件目录存在 on 文件 才会启动它.
例: test插件 /Plugin/test. 你需要在 test 目录新建一个 on 文件 (不需要写入数据到该文件) test 插件才会生效
中文PHP可以在Action Model中使用 该引擎不会与原PHP函数出现冲突. 目前支持大部分常用的PHP内置函数 以及固定好的 HYPHP框架函数
在入口文件 index.php 中定义常量
define('PLUGIN_ON' ,true); define('PLUGIN_MORE_LANG_ON',true);
即可开启该机制
完整 index.php
<?php define('DEBUG' ,true); define('PLUGIN_ON' ,true); define('PLUGIN_MORE_LANG_ON',true); require 'HY/HY.php';
中文名 | 原PHP名称 |
---|---|
输出 | echo |
输出数组 | print_r |
中文名 | 原PHP名称 |
---|---|
如果 | if |
或者 | elseif |
反之 | else |
循环对象 | foreach |
循环 | for |
循环判断 | while |
跳出循环 | break |
跳到下次循环 | continue |
返回 | return |
结束 | exit |
包含文件 | include |
跳转运行 | goto |
延迟 | sleep |
微秒延迟 | usleep |
中文名 | 原PHP名称 |
---|---|
读取文件 | file_get_contents |
写入文件 | file_put_contents |
新建目录 | mkdir |
移动文件 | rename |
文件重命名 | rename |
文件是否存在 | is_file |
目录是否存在 | is_dir |
删除文件 | unlink |
删除目录 | rmdir |
复制文件 | copy |
打开文件 | fopen |
关闭文件 | fclose |
文件_指针是否结束 | feof |
文件_读取指针处字符 | fgetc |
文件_读取指针处一行 | fgets |
文件_读取指针处一行_过滤HTML | fgetss |
文件_读入数组 | file |
文件_上次访问时间 | fileatime |
文件_上次修改时间 | filemtime |
文件_所有者 | fileowner |
文件_获取权限 | fileperms |
文件_大小 | filesize |
文件_类型 | filetype |
文件_锁 | flock |
文件_读取指针处所有数据 | fpassthru |
文件_是否可读 | is_readable |
文件_是否可写 | is_writable |
中文名 | 原PHP名称 |
---|---|
打开目录句柄 | opendir |
关闭目录句柄 | closedir |
目录_句柄读取 | readdir |
删除目录 | rmdir |
中文名 | 原PHP名称 |
---|---|
执行程序 | exec |
执行程序并返回结果 | system |
中文名 | 原PHP名称 |
---|---|
数组_索引是否存在 | array_key_exists |
数组_获取所有索引名称 | array_key_exists |
数组_合并 | array_merge |
数组_排序 | array_multisort |
数组_删除结尾元素 | array_pop |
数组_删除开头元素 | array_shift |
数组_所有值相乘 | array_product |
数组_所有值相加 | array_sum |
数组_结尾追加元素 | array_push |
数组_开头追加元素 | array_unshift |
数组_随机取元素 | array_rand |
数组_搜索值 | array_search |
数组_删除重复值 | array_unique |
数组索引总数 | count |
数组_是否存在该值 | in_array |
定义数组 | array |
中文名 | 原PHP名称 |
---|---|
当前时间戳 | time |
格式化时间 | date |
中文名 | 原PHP名称 |
---|---|
分割字符串 | explode |
分割 | explode |
获取字符串长度 | strlen |
查找字符串位置 | strlen |
字符串_取部分 | strlen |
字符串_过滤HTML与PHP代码 | strlen |
转为小写 | strtolower |
转为大写 | strtoupper |
字符串_倒转 | strrev |
随机打乱字符串 | str_shuffle |
字符串_首字母转大写 | ucfirst |
字符串_买个段落首字母转大写 | ucwords |
字符串_截断数量 | wordwrap |
字符串_引号加斜杠 | addslashes |
两个字符串相似度 | similar_text |
中文名 | 原PHP名称 |
---|---|
DNS通信测试 | checkdnsrr |
获取域名指向IP | gethostbyname |
获取域名指向IP_数组 | gethostbynamel |
IP转数字 | ip2long |
数字转IP | long2ip |
打开套接字 | fsockopen |
打开套接字_持久 | pfsockopen |
关闭套接字 | fclose |
设置COOKIE | setcookie |
中文名 | 原PHP名称 |
---|---|
输出模板 | $this->display |
中文名 | 原PHP名称 |
---|---|
查找 | find |
插入 | insert |
插入更多 | insertAll |
选择 | select |
更新 | update |
删除 | delete |
是否存在 | has |
替换 | replace |
总数 | count |
最大值 | max |
最小值 | min |
平均值 | avg |
相加 | sum |
调试 | debug |
Index 控制器内容
<?php namespace Action; use HY\Action; class IndexAction 继承 Action{ 公开函数 index(){ 输出 '这里是IndexAction中的Index()方法'; } public function test(){ 输出 '这里是IndexAction中的test()方法'; } }
访问 / 则输出
这里是IndexAction中的Index()方法
访问 /index/test 则输出
这里是IndexAction中的test()方法
Index 控制器内容
<?php namespace Action; use HY\Action; class IndexAction 继承 Action{ 公开函数 index(){ $string = '这是一句话'; 写入文件(PATH . 'test.txt',$string); 输出 读取文件(PATH . 'test.txt'); 删除文件(PATH . 'test.txt'); } }
写入文件(路径,内容); 读取文件(路径); 删除文件(路径); 访问输出
这是一句话
更多的文件操作API 可以在文档中查看.
你可以在 config.php 中加入配置 MORE_LANG_LIB_FILE 加入更多的中文解析配置进来
config.php 内容
<?php return array( //....其他配置 'MORE_LANG_LIB_FILE'=>array( '配置文件路径' ), };
例如: 在Lib目录下新建文件 a.php; 写入内容
<?php return array( '/([{};,(\s.]+)读文件([\s\'\"\(]+)/i'=>'$1file_get_contents$2', };
config.php 内容
<?php return array( //....其他配置 'MORE_LANG_LIB_FILE'=>array( '/Lib/a.php' ), };
我们在代码中就可以使用 读文件 了