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'
),
};我们在代码中就可以使用 读文件 了