HYPHP框架前言

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框架 并不需要高大上的服务器环境. 框架文件并且轻量简洁.

PHP版本要求

  • PHP5.3以上版本 (包括5.3) 框架采用了OOP命名空间

WEB服务器与数据库类型要求

  • Windows/ Unix
  • 基础的Apache / IIS / Nginx 多种WEB环境
  • 数据库采用了PDO扩展, 目前仅支持: MySQL, MariaDB, MSSQL, Oracle, SQLite, PostgreSQL, Sybase

对于刚接触的PHP童鞋

建议你在本地搭建开发环境, 推荐几款: 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输出

Json & Jsonp 输出 我们通常会在前端用到JSON. 所以框架内置了两个简单的 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是什么意思. 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]); +++

URL缩短控制器方法

缩短控制器

我们通常定义的控制器 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生成

为什么需要这个函数? 有童鞋觉得是多余的, 太多余麻烦. 是的,作者本人也觉得麻烦, 开发时不如直接写固定连接好了 还要调用啥函数. 所以这个函数是提供给 需要经常使用 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 +++

{include 模板名}

可见我们的结果中. 控制器输出了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 ?>

循环标签

{for } {foreach}

与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 扩展列表


  • MySQL, MariaDB -> php_pdo_mysql
  • MSSQL (Windows) -> php_pdo_sqlsrv
  • MSSQL (Liunx/UNIX) -> php_pdo_dblib
  • Oracle -> php_pdo_oci
  • SQLite -> php_pdo_sqlite
  • PostgreSQL -> php_pdo_pgsql
  • Sybase -> php_pdo_dblib

如何开启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 //长连接
            ),
        )
    ),

S M函数使用

<?php
//连接 多个数据库配置中的 name 数据库. 并操作 他的user 表
$User = S('user','name');

where条件

基础 where演示

使用数据库无时无刻都需要条件去检索数据 . 框架内置的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)

        }

    }

AND OR

上面是基础的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'
            //  )
            // )

        }
    }

LINK 模糊查找条件

接下来我们看一下模糊匹配 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...
            ));


        }

    }

ORDER排序

<?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"
            // }

        }

    }

MATCH 多键搜索

<?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'
            ));

        }

    }

LIMIT

<?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

Select 选择器

数据库查询

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 插入数据

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 更新数据

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 删除数据

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

通过条件查询,将返回一条记录

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

通过条件搜素 判断数据是否存在

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

通过条件 检索数据的数量

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 Min

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 事务操作

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) 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 字符串转义

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 定义

什么是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 实例演示

/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 调试模式

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中内置了 查询缓存。

通常使用Select

<?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 自定义类库

Lib 可以在多种场景中使用, 包括Action,Model,View 中 默认Lib目录处于 /Lib . 新建文件 /Lib/User.php (注意大小写 首字母必须大写)

定义 Lib

<?php
namespace Lib;
class User{
    public function check_user($user){
        $len = strlen($user);
        if($len < 6 || $len > 18)
            return false; //'账号长度不符合标准,必须 大于6位 小于18位'
        return true;
    }
}

控制器中使用Lib

<?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 '反之';

        }
    }

框架内置函数

X 获取预定义变量

获取 PHP预定义变量 框架内置了一个函数 可以获取提交到服务器的参数数据.

X() 函数

函数声明 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 +++

S 与 M 函数

# S 与 M 函数

大家在之前的文档中 会经常看到 M("User") 的出现 M() 是框架一个内置的函数

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 函数差不多 S函数 是不加载你的自定义Model模型 跳过Model 的加载 直接加载系统底层操作对象类 所以使用S函数加载的对象 是操作不了Model的内容的

为什么增加一个S 函数? 既然与M 差不多

当我们的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 获取config配置

C 函数

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
        }
    }

A 调用另一个控制器方法

A 函数

我们开发时肯定会有很多个控制器 存放于 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

cookie 与 session 函数

Cookie 函数

该函数复制与 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

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());





        }
    }

E 函数

该函数较为少用 用于终止PHP运行 并抛出PHP错误进行提醒

该函数不是exit 以及 die 而是 throw new \Exception($str);

cache 数据缓存

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 使用实例

我们默认不需要配置以上的信息, 只是有额外需求时配置. 我们的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 文件数据缓存

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 函数 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配置

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源代码的情况下 去修改 你的代码内容.
该模式一般用于开源项目上使用, 可以更好的实现插件化程序.

目前框架提供了两种插件解析

  1. hook插入点
  2. re替换源代码

作者自评该模式 优缺各有展现, 优点可以更好的模块化, 缺点需要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 插件机制

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

中文PHP 简介

中文PHP可以在Action Model中使用 该引擎不会与原PHP函数出现冲突. 目前支持大部分常用的PHP内置函数 以及固定好的 HYPHP框架函数

开启 中文PHP引擎

在入口文件 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';

中文API

输出

中文名 原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

HYPHP Action

中文名 原PHP名称
输出模板 $this->display

HYPHP Model

中文名 原PHP名称
查找 find
插入 insert
插入更多 insertAll
选择 select
更新 update
删除 delete
是否存在 has
替换 replace
总数 count
最大值 max
最小值 min
平均值 avg
相加 sum
调试 debug

中文PHP 使用示例

常规Action定义

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'
    ),
};

我们在代码中就可以使用 读文件