1 Star 1 Fork 1

juheli / zhlphp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

ZHLPHP 使用说明

简介

ZHLPHP是一个开源、简单、快速、低耦合,高扩展,低门槛的PHP开发框架,遵循 Apache2.0 开源许可协议发布,可以免费使用。
小、精、简,无需学习沉重的框架语法,只需要了解框架目录结构以及了解php语法会写if判断和foreach数组遍历即可使用该框架。
本框架主要应用到web相关项目中,更多丰富内容支持自定义扩展,可以根据自己风格封装成属于自己的框架和应用项目。

一、安装

  • 下载并解压到服务根目录下即可。
  • 注意:app目录下的文件为示例,建议删除(app目录不要删除),实际开发根据业务而定功能模块。

二、目录结构

├── app  ------------------- 应用目录(如果想重新命名同时修改核心文件SYS_APP_PATH参数)
├── config  ---------------- 应用配置文件目录
│   └── config.php  -------- 自定义全局变量参数配置文件
│   └── database.php  ------ 数据库配置文件
├── extend  ---------------- 第三方扩展类库
│   └── Function.php  ------ 自定义函数扩展文件(非必须,可删除,应用时需要引入)
├── public  ---------------- 静态资源存放目录(比如css,js,image,uploads等)
├── runtime  --------------- 系统缓存日志等目录
│   ├── error  ------------- 系统日志存放目录
│   ├── db  ---------------- 自定义sql打印日志存放目录, 调用系统辅助函数SYS_DB_LOGER($s)
│   └── logs  -------------- 自定义打印日志存放目录, 调用系统辅助函数SYS_LOGER($s)
├── zhlphp  ---------------- 框架核心文件目录
└── .gitignore  ------------ Git忽略配置文件(可删除)
└── .htaccess  ------------- Apache,分布式配置文件(可放到public目录下)
└── 404.html  -------------- 404页面(可删除,建议保留,可放到public目录下)
└── index.php  ------------- 应用程序框架入口文件(可放到public目录下需要注意附件根目录设置)
└── LICENSE  --------------- 发布协议(可删除)
└── nginx.conf  ------------ Nginx配置文件(可放到public目录下)
└── README.md  ------------- 说明文档(可删除)
└── web.config  ------------ ISS配置文件(可放到public目录下)

app应用目录使用方式是app目录下创建一个文件夹(功能模块),里边分别controllersservesmodelsviews,比如创建web和admin:

├── web -------------------------------- [自定义]功能模块目录(比如当前为前台)
│   ├── controllers -------------------- [勿改名]控制器目录
│   │   └── Web_BaseController.php ----- 类不存在默认定向指定类(可自定义可配合404页面使用)
│   │   └── Web_IndexController.php ---- [自定义]控制器文件
│   ├── models ------------------------- [勿改名]模型目录
│   │   └── Web_CommModel.php ---------- [自定义]模型文件(主要数据交互)
│   ├── serves ------------------------- 服务层目录
│   │   └── Web_CommServe.php ---------- [自定义]服务文件(主要业务逻辑)
│   ├── views -------------------------- [勿改名]视图目录
│   │   ├── web_index ------------------ [自定义]视图目录(一般根据控制器命名,可自定义)
│   │   │   └── about.php -------------- [自定义]视图文件(控制器里的方法名)
│   │   │   └── common.php ------------- [自定义]w_index目录下公共父级模版视图,会覆盖上级目录common.php
│   │   │   └── index.php -------------- [自定义]视图文件(控制器里的方法名)
│   │   └── common.php ----------------- [自定义]当前模块下所有控制器父级模版视图(控制器displays方法才起作用)
├── admin ------------------------------ [自定义]功能模块目录(比如当前为后台,目录结构参考web)

三、运行

1、运行条件

(1)、环境

Apache / Nginx / ISS + PHP + MYSQL / ORACLE

  • php5.3以上版本(推荐php7)
  • mysql5以上版本(如果需要链接数据库时要求)
  • php运行环境(如Apache, Nginx, IIS)

(2)、扩展

扩展名 类型 说明
openssl 必须 框架内置加密函数必须开启
pdo 数据库需要 如果使用数据库pdo需要开启
mysqli 数据库需要 如果使用mysqli连接需要开启
oci8 数据库需要 如果使用oracle数据库需要开启
gd2 常用 如果用到文件上传需要开启
curl 常用 如果用到curl需要开启
mbstring 常用 如果用到mb_strlen()等需要开启
其他…… 常用 根据业务需要自行开启需要的扩展

(3)、配置

1、index.php 入口文件(放到不同的目录下注意附件根目录参数配置) 2、Apache 服务需要配置.htaccess文件(直接配置项目跟目录下.htaccess)
3、Nginx 服务需要配置nginx.conf文件(配置Nginx的对应的nginx.conf文件)
4、IIS 服务需要配置web.config文件(直接配置项目跟目录下web.config)
当前已经初始配置,详细配置见文档后部分“伪静态配置”。

2、框架运行流程

  • index.php -> /zhlphp/Base.php -> /zhlphp/core/Core.php -> {控制器C} (往后非必须)-> {服务层S} -> {模型M} -> {视图V},或者控制器直接到视图。

3、URL结构组成和解析

  • {网站根域名}/web_about_index/cid/1/id/2.html

(1)、web:为功能模块名

框架配置默认模块为“web”时可以为空,详细查看系统“可配置常量”
如:{网站根域名}/about_index/cid/1/id/2.html

(2)、about:为控制器

(3)、index:为方法名(index时可以为空)

如:{网站根域名}/about/cid/1/id/2.html

(4)、cid/1/id/2 :为参数和对应的值

等于cid=1&id=2,比如创建了admin模块,admin模块下创建了Admin_NewsController.php,里边方法是list,访问url为:{网站域名}/admin_news_list{伪静态后缀}

4、配置文件 /config/

(1)、config.php

  • 可以配置系统全局变量,代码中获取变量方式,
    如:$GLOBALS['CONFIG']['sysname'] 获得的值为ZHLPHP
return array(
  'sysname' => 'ZHLPHP',  // 列如:系统自定名称(单个变量)
  'autoload'=>array(      // 自动加载类(第三方类库带文件路径的必须定义)
      '/Mailer/', // 示例1
      '/uploads/',  // 示例2
  ),
  'other'=>array(         // 其他自定义全局变量(多级变量)
      'custom_param1' => '可继续追加其他全局变量参数……',
  ),
  //可继续追加……
);

(2)、database.php

  • 配置数据库链接参数,支持多数据库配置(多个数据库继续增加配置数组即可)。
  • 参数名和值必须全部小写:
'mysql1'=>array(    ------------------------- 数据库昵称(自定义)
    'db_type' => 'mysql',    --------------- 数据库类型(mysql/oracle)可不设置默认为mysql
    'db_link' => 'mysqli',    -------------- 链接方式(mysqli/pdo)可不设置默认为mysqli
    'db_host' => '127.0.0.1',    ----------- 链接地址(建议设置,不设置默认为localhost)
    'db_port' => 3306,    ------------------ 链接端口号(可不设置默认为3306)
    'db_name' => 'zhl_cms2',    ------------ 数据库名(必须配置)
    'db_user' => 'root',    ---------------- 链接帐号(建议设置不设置时默认root)
    'db_pwd'  => '123456',    -------------- 链接密码(建议设置不设置时默认为空无密码)
    'db_fix'  => 'zhl_',    ---------------- 表前缀(建议设置不设置时默认为空无表前缀)
    'db_char' => 'utf8',    ---------------- 链接编码(可不设置默认为utf8)
),
//可继续追加……

5、功能模块

如果在app目录下创建多个功能模块,可以自定义目录,类似上文webadmin文件夹,新建功能目录下有一般有4个文件夹分别为:controllersservesmodelsviews,其中controllers必须,其他根据业务取舍。

6、控制器 Controller

(1)、新建控制器

在新建的功能模块下的“controllers”目录下新建个控制器,文件命名规则:{功能模块文件名(必须首字母大写)}+{下划线}+{自定义控制器名(首字母大写)}+{Controller.php},比如“Web_AboutController.php”。
注意:创建的控制器类必须继承Controller基类,如:

class Web_AboutController extends Controller {
  function index(){
      // 你的代码
  }
}

(2)、参数接收

Fun::input($name='', $val='', $type='s', $leng=0, $start=0);
列如:$id = Fun::input('id');
列如:$paramArr = Fun::input();

  • 参数说明:
参数名 参数说明 备注
$name 参数名 【选填】参数key
$val 默认值 【选填】没有接收到值定义的默认值
$type 参数类型 【选填】默认s(d:数字,b:布尔型,f:小数,h:html标签,s:字符串);
$leng 截取长度 【选填】$type为小数时代表小数点后几位;
$start 开始位置 【选填】截取字符串时开始位置;

(3)、实例化调取其他控制器类

  • 示例1(同模块下实例化其他控制):
// 实例化功能模块“web”下“Web_CommController”类  
$commC = new Web_CommController();  
// 调取方法  
$list = $commC->getClassLists();
  • 示例2(跨模块实例化其他控制器):
// 实例化功能模块“admin”下“Admin_CommController”类  
$commC = new Admin_CommController();  
// 调取方法  
$list = $commC->getClassLists();

(4)、实例化调取服务层、数据层(可跨模块调用其他类)

示例1(实例化服务层):

// 实例化功能模块“web”下服务器层“Web_CommServe”类  
$commSer = new Web_CommServe();  
// 调取方法  
$list = $commSer->getClassLists($id);

示例2(实例化模型):

// 实例化功能模块“web”下数据层“Web_CommModel”类  
$commM = new Web_CommModel();  
// 调取方法  
$list = $commM->getClassLists($id);

(5)、映射模版

  • $this->display();
    默认映射模版:{当前功能模块}/views/{当前控制器名}/{当前方法}.php;比如当前功能模块为“web”,控制为“Web_AboutController” ,方法为 "index()", 映射的模版位置为:app/web/views/web_about/index.php
  • $this->display('w_index/index');
    指定映射模版:{当前功能模块}/views/w_index/index.php;比如当前功能模块为“web”,映射的模版位置为:app/web/views/w_index/index.php;不允许跨功能模块;只允许夸控制器和方法。
  • $this->displays();
    默认映射模版,但是会以“/views/common.php”为父级模版(父级模版内容也会展示)。views和子级目录下也存在common.php时比如:web/views/web_about/common.php 会重置覆盖父级的web/views/common.php 的模版内容。
  • $this->displays('w_index/index');
    指定映射的模版,同时先加载父级公共模版:common.php。

(6)、控制器变量参数映射到模版

  • $this->set('titleName', $title);
    把变量$titletitleName命名映射到模版,模版里接收为:$titleName

(7)、转json数据

  • Fun::json($list, true); // $list转换成json并直接输出json到页面后终止;
  • Fun::json($list); // $list转换成json但不输出(可赋值给变量);

(8)、示例:

class Web_AboutController extends Controller {
  function index(){
      // 获取传过来的id值
      $aid = Fun::input('id'); 
      // 实例化服务层:Web_CommServe类
      $commSer = new Web_CommServe(); 
      // 调取Web_CommServe类下的getClassLists方法,同时传值$aid
      $list = $commSer->getClassLists($aid);
      // 映射值
      $this->set('list', $list);
      // (也可以使用自定义Serve或者Model基类操作数据库,详细阅读文档Model使用)
      $params['table'] = 'member';
      $params['field'] = '*';  // 可以指定字段如:“id,classname”等
      $params['where']['id'] = $id;
      $info = Model::conn('mysql1')->find($sql);
      $this->set('memberInfo', $info);
      // 映射模版
      $this->display(); // 也可以用:$this->displays(); 
      // display和displays区别在于display直接到模版,displays包含common
  }
}

7、服务层 Serve(业务逻辑层)

当前模块非必须,目的是为了缓解业务的复杂性和代码可维护性可以创建服务层,主要在这里写业务逻辑。

(1)、新建服务层

  • 在新建的功能模块下“serves”目录下新建业务服务,文件命名规则:{必须首字母大写功能模块文件名}+{下划线}+{首字母大写自定义服务业务名}+{Serve.php},比如“Web_AboutServe.php”。

(2)、业务逻辑

  • 实例化其他服务层类和数据层(可跨模块调用其他服务层/数据层),需要在当前类中操作数据库时当前类可继承Model基类也可以直接静态使用Model基类,应用实例:
// 继承Model类操作数据库
class W_CommServe extends Model {

  // 获取栏目列表(通过写业务逻辑再实例化自定义Model)
  function getClassLists($id){
      // 可以写其他业务逻辑
      $id = intval($id);
      if(!$id){
          return array();
      }
      //实例化自定义的Model获取数据
      $where['id'] = $id;
      $commM = new W_CommModel();
      return $commM->getClassLists($where);
  }

  // 获取栏目列表(如果当前类继承了Model基类可以直接操作数据)
  function getClassListsV2($id){
      $where['id'] = $id;
      $sql['field'] = '*';
      $sql['table'] = 'classify';
      $sql['order'] = 'viewseq desc,id asc';
      $sql['where'] = $where;
      $db = $this->conn('mysql1');
      return $db->select($sql);
  }

}
// 不继承Model基类操作数据库
class W_CommServe {

  // 获取栏目列表(不管当前类有没有继承Model基类可以直接使用Model基类来操作数据库)
  function getClassListsV2($id){
      $where['id'] = $id;
      $sql['field'] = '*';
      $sql['table'] = 'classify';
      $sql['order'] = 'viewseq desc,id asc';
      $sql['where'] = $where;
      $db = Model::conn('mysql1');
      return $db->select($sql);
  }
}

8、模型 Model(主要在这里操作数据库)

当前模块非必须,目的是为了缓解业务的复杂性和代码可维护性可以自定义model数据层,主要在这里操作数据库。

(1)、新建自定义模型

  • 在新建的功能模块下“models”目录下新建个模型,文件命名规则:{必须首字母大写功能模块文件名}+{下划线}+{首字母大写自定义模型名}+{Model.php},比如“Web_AboutModel.php”。
  • 操作数据库时当前类可以继承Model基类也可以直接静态使用Model基类,自定义model层文件创建和数据库操作示例:
  • 不管当前类是否继承Model基类都可以直接静态使用Model基类操作数据库,是否继承区别在于:继承Model类可以$this->conn('mysql1')和Model::conn('mysql1'),不继承Model类不能用$this->conn('mysql1'),只能用Model::conn('mysql1')。
// 继承Model类时示例
class W_CommModel extends Model {
  // 获取栏目列表
  function getClassLists1($where){
      $sql['field'] = '*';
      $sql['table'] = 'classify';
      $sql['order'] = 'viewseq desc,id asc';
      $sql['where'] = $where;
      $db = $this->conn('mysql1');
      return $db->select($sql);
  }
  function getClassLists2($where){
      $sql['field'] = '*';
      $sql['table'] = 'classify';
      $sql['order'] = 'viewseq desc,id asc';
      $sql['where'] = $where;
      $db = Model::conn('mysql1');
      return $db->select($sql);
  }
}

// 不继承Model类时示例
class W_CommModel {
  // 获取栏目列表
  function getClassListsV2($where){
      $sql['field'] = '*';
      $sql['table'] = 'classify';
      $sql['order'] = 'viewseq desc,id asc';
      $sql['where'] = $where;
      $db = Model::conn('mysql1');
      return $db->select($sql);
  }
}

(2)、数据库配置(多数据库支持)

  • $db = $this->conn('mysql1');或者Model::conn('mysql1');操作时,参数mysql1为数据库昵称,根据数据库配置文件(自定义设置),可以自由操作不同的数据库,详细见数据库配置文件: /config/database.php
  • 如果多个数据库在同一服务器下,登录的帐号且有权访问该服务器多个数据库的权限可以跨库表连接查询,
    例如:$sql = "select * from world.city a left join sakila.city b on a.id=b.city_id";

(3)、mysqli链接方式

  • DbMySqli 类封装了操作数据库一系列方法。
    嫌学习过程繁琐可以直接使用query方法(支持执行原始sql):
    $db = $this->conn('mysql1');
    $db->query($sql, $type, $returnId);
    也可以这样写:Model::conn('mysql1')->query($sql, $type, $returnId);
  • 注意: 增删改语句$type值不传,或者‘false’、0、null,' '(空),查询语句$type值传true或者1,$returnId参数默认‘id’(主键ID值,可以指定字段名)
    或者也可以放弃mysqli链接,使用下文PDO的方式,当然也可以引入自己的数据库操作类库(需要在Model基类追加数据库类)。

内置mysqli链接方式快速使用示例:

// 比如要操作数据库表zhl_member
// 这里填写不带表前缀的表名(database.php已经配置了可以忽略表前缀)
$table = 'member'; 
// 比如数组$data是要更新的数据,
// $data数组key对应数据库字段,value对应字段的值
$data = array(
  'uname'=>'小明',
  'qq'=>'123456789'
);

插入-方式一(add方法)

  $sql['data'] = $data;
  $sql['table'] = $table;
  $db = Model::conn('mysql1');
  $db->add($sql); // sql执行并返回是否执行成功状态true/false
  $db->rowCount(); // 受影响的行数
  $db->returnId(); // 新插入数据的主键ID值(默认id)
  $db->returnId('cid'); // 新插入数据的主键值(可以指定主键字段)

插入-方式二(addData方法)

  $db = Model::conn('mysql1');
  $db->addData($table, $data);
  $db->addData($table, $data, 'id'); //可以指定返回新插入的主键值

修改-方式一(update)

  $sql['data'] = $data;
  $sql['table'] = $table;
  $sql['where'][id] = $id;
  $db = Model::conn('mysql1');
  $db->update($sql);  // 执行并返回是否执行成功状态true/false
  $db->rowCount();    // 返回受影响的行数

修改-方式二(updateData方法)

  $where['id'] = $id;
  $db = Model::conn('mysql1');
  $db->updateData($table, $data, $where);
  $db->updateData($table, $data, $where, true); //可以指定返回影响行数

删除-方式一(del)

  $sql['table'] = $table;
  $sql['where']['id'] = $id;
  $db = Model::conn('mysql1');
  $db->del($sql);     // sql执行并返回是否执行成功状态true/false
  $db->rowCount();    // 返回受影响的行数

删除-方式二(delData方法)

  $where['id'] = $id;
  $db = Model::conn('mysql1');
  $db->delData('member', $where);  //只关注sql是否执行成功true/false
  $db->delData('member', $where, true); //可以指定返回影响行数

查询单条-方式一(find方法)

function getInfo($id){
  $params['table'] = 'member';
  $params['field'] = '*';  // 可以指定字段如:“id,classname”等
  $params['where']['id'] = $id;
  return Model::conn('mysql1')->find($params);
}

查询单条-方式二(findData方法)第一、二参数必填,第三、四个参数选填

  $info = Model::conn('mysql1')->findData($table, $where);
  $info = Model::conn('mysql1')->findData($table, $where, $field, $orderby);

查询多条-方式一(select)

function getList($status){
  $params['table'] = 'member';
  $params['field'] = '*';  // 可以指定字段如:“id,classname”等
  $params['where']['status'] = $status;
  return Model::conn('mysql1')->select($params);
}

查询多条-方式二(listData方法)第一、二参数必填,第三、四五参数选填

  $list = Model::conn('mysql1')->listData($table, $where, $field, $orderby, $limit);

查询多条方法三(findAll方法)

function getList($status){
  $params['table'] = 'member';
  $params['field'] = '*';  // 可以指定字段如:“id,classname”等
  $params['where']['status'] = $status;
  return Model::conn('mysql1')->findAll($params);
}

表连接查询(leftjoin、rightjoin、innerjoin 等)

function getList($status){
  $sql['field'] = 'm.id,m.code,m.nickname,c.classname';
  $sql['table'] = 'member';
  $sql['as'] = 'm';
  $sql['leftjoin']['classify'] = 'c on c.id=m.class_id';
  $sql['where']['m.status'] = $status;
  $result = Model::conn('mysql1')->select($sql);
  return $result;
}

执行手写sql语句方式( $db -> db_fix 可以获取表前缀,$db -> db_config可以获得数据库配置信息)

$db = Model::conn('mysql1');
$sql = "select * from '.$db->db_fix.'_member where id=1";

1、查询单条

// 返回的是二维数组
return Model::conn('mysql1')->query($sql, true); 
// 返回的是一维数组
return Model::conn('mysql1')->query($sql, true, 1); 

2、查询多条

return Model::conn('mysql1')->query($sql, 1);

3、添加/修改/删除

$sql = "insert into '.$db->db_fix.'_member (classname,status) values ('zhlphp','2')";
$sql = "update '.$db->db_fix.'_member set status='1' where id='1'";
$sql = "delete from '.$db->db_fix.'_member where id='1'";
return Model::conn('mysql1')->query($sql);

注:转译(过滤非法字符);

  • 可以用$db->sqlStr($id)进行转译/过滤非法字符

where条件

1、指定字段
$sql['where']['id'] = $id;
$sql['where']['level'] = 1;
$sql['where']['status'] = ['!=', 'no'];
>$sql['where']['num'] = ['>', 20];
// 或者(注意php版本低于5.4数组用array()不要用[]):
$where = ['id'=>$id, 'level'=>1, 'status'=>['!=','no'], 'num'=>['>',20]];
$sql['where'] = $where;
2、where字符串

(不推荐,必须使用时接收参数建议进行转译,比如:$id=$db->sqlStr($id);)

$where = " id='$id' and status='$statusCode'";
$sql['where'] = $where;
3、区间查询
// (1)大于
$sql['gt']['id'] = $id;
$sql['gt']['statusCode'] = $statusCode;
// (2)大于等于
$sql['gts']['id'] = $id;
$sql['gts']['statusCode'] = $statusCode;
// (3)小于
$sql['lt']['id'] = $id;
$sql['lt']['statusCode'] = $statusCode;
// (4)小于等于
$sql['lts']['id'] = $id;
$sql['lts']['statusCode'] = $statusCode;
4、模糊查询
// 默认是and连接符
$sql['locate']['classname'] = $className;
$sql['locate']['title'] = $title;
// 如果用or必须指定:
$sql['locate']['username'] = array($param,'or');
$sql['locate']['phone'] = array($param,'or');
// 注意:默认是and,如果用or必须指定,生成的sql相当于:
…… and locate ('是',classname) > 0 and locate ('是',title) > 0……
…… and (locate ('是',username) > 0 or locate ('131',phone) > 0)……
5、in查询(数组或者字符串)
// 方式一
$sql['in']['classname'] = array(1,2,3,4);
// 方式二
$sql['in']['classname'] = array('1','2','a');
// 方式三
$sql['in']['classname'] = '1,2,a';
// not in
$sql['notin']['classname'] = array(1,2,3,4);
6、or查询
// 方式一
$sql['or']['id'] = 1;
$sql['or']['status'] = 1;
// 方式二
$sql['or']['id'] = ['=', 1];
$sql['or']['status'] = ['=', 1];
$sql['or']['level'] = ['!=', 1];
7、null查询
// is null
$sql['null']['title'] = 'is';
// is not null
$sql['null']['title'] = 'not';

order by排序

(1)、直接字符串

$sql['order'] = 'a.viewseq desc,a.id desc';

(2)、可以数组

// 单个字段排序
$order = array('createdate'=>'desc');
// 或者这样写
$order['createdate'] = 'desc';
// 多个字段排序 
$order = array(array('createdate'=>'desc'), array('id'=>'desc'));
// 或者这样写
$order[0]['createdate'] = 'desc';
$order[1]['id'] = 'desc';
// 如果php版本5.4以上也可以这样写
$order = [['createdate'=>'desc'], ['id'=>'desc']];
$sql['order'] = $order;

limit指定条数

// 数字方式:
$limit = 10;    // 取前10条
// 字符串方式
$limit = '2,10'; // 第二条往后取10条
// 数组方式
$limit = array(2,10);  // 第二条往后取10条
$sql['limit'] = $limit;

group by分组

// 单个字段
$sql['group'] = 'code';
// 多个字段
$sql['group'] = 'code,type';

事务

示例:

$db = $this->conn('mysql1'); // 链接数据库
$db->startTrans();  // 开启事务
try{
   $sql['field'] = '*';
   $sql['table'] = 'essay';
   $sql['where']['ver'] = $param['version'];
   $r = $db->find($sql); // 查询数据
   if($r){
       throw new Exception("已存在"); // 存在抛出异常
   }
   $sql2['data']['ver'] = $param['version'];
   $sql2['data']['title'] = $param['title'];
   $sql2['table'] = 'essay';
   $db->add($sql2);    // 新增数据
   $db->commit();      // 提交事务
   return array('code'=>'200','msg'=>'success');
}catch (Exception $e){  // 捕获异常
   $db->rollback();    // 事务回滚
   return array('code'=>'500','msg'=>$e->getMessage());
}

打印sql

在find()、select()、findAll()、update()、del() 之前$db->db_log = true;控制是否打印sql日志(日志文件目录:runtime/logs/db)日志文件格式如'DB2022_10_10.log'。

(4)、pdo链接方式

  • 详细参考PHP:PDO官方文档(target="_blank"),以下列举常用到的:
  • 注:$db->db_fix可以获取表前缀。

- 单条:

$db = $this->conn('mysql2'); // mysql2:config/database.php 配置的自定义数据库昵称
$sql = 'select id,fid,classname,status from zhl_classify where id=:id';
$stmt = $db->prepare($sql);
$stmt->bindValue('id', $id);
$stmt->execute();
return $stmt->fetch(PDO::FETCH_ASSOC);

- 多条fetch改成fetchAll即可:

return $stmt->fetchAll(PDO::FETCH_ASSOC);

- 添加/修改/删除:

  • (只执行到$stmt->execute();后再获取响应行数):
$sql = "update ……";
$stmt = $db->prepare($sql);
$stmt->execute();
return $stmt->rowCount() > 0;

- 获取刚插入的行数据主键ID

$stmt->lastInsertId();

- 事务

$db = $this->conn('mysql2');
$db->beginTransaction(); // 开启一个事务
$db->commit(); // 提交事务
$db->rollback(); // 回滚事务

示例:

try {
  $pdo->beginTransaction(); // 开启一个事务
  $row = null;
  $row = $pdo->exec("xxx"); // 执行第一个 SQL
  if (!$row){
    throw new PDOException('提示信息或执行动作'); // 如出现异常提示信息或执行动作
  }
  $row = $pdo->exec("xxx"); // 执行第二个 SQL
  if (!$row){
    throw new PDOException('提示信息或执行动作');
  }
  $pdo->commit();
} catch (PDOException $e) {
  $pdo->rollback(); // 执行失败,事务回滚
  exit($e->getMessage());
}

9、视图 View(页面模版文件)

(1)、新建视图

  • 在新建的功能模块下“views”目录下新建个视图文件目录,目录命名规则:一般根据控制器名称一致(全部小写且不加Controller)例如:“web_about”。
  • 视图文件规则一般根据对应控制器下的方法名+.php,也可以自定义名称(自定义时控制器映射需要填写指定模版名称)。例如:index.phpabout.php
  • 公共父级模版:common.php(非必须)控制器调用displays方法才生效,支持自定义名称需要修改核心配置文件常量配置参数:SYS_TMPL_PARENT
  • 控制器内公共父级模版,列如:views/web_index/common.php会覆盖父级views/common.php模版。
  • /core/View.class.php文件下render方法可以引人模版引擎(如果使用可以自行扩展)。

(2)、获取控制器映射的值

  • 比如控制器中:
    $this->set('titleName', $title);
    $this->set('list', $list);
    映射过来的值,在模版中输出:
<!DOCTYPE html>
<html>
<head>
   <meta content="text/html; charset=UTF-8">
   <title>zhlphp-测试页面</title>
</head>
<body>
<!-- 直接输出变量 -->
<h1><?php echo $titleName?></h1>
<?php
//如果是数组根据业务逻辑进行foreach遍历
foreach($list as $v){
  echo '<p>'.$v.'</p>';
}
// 变量插入html时可以使用定界符如(EOF可以自定义):
foreach($list as $v){
  $title = $v['title'];
  echo <<<EOF
  <div>$title</div>
EOF;
}
?>
</body>
</html>

(3)、模版文件中加载其他模版文件

  • 除了控制器映射模版外,在已经映射的模版文件里再引入其他模版文件时可以参考以下操作:

方法一

  • 加载views文件夹下视图(注意文件后缀和系统配置保持一致)
 <!--同级模版文件引用-->
 <?php include 'test.php';?>
 <!--使用常量自动获得文件绝对路径-->
 <?php include SYS_VIEW_PATH.'test.php';?>
 <!--当前模块下/w_index/test.php模版-->
 <?php include SYS_VIEW_PATH.'/w_index/test.php';?>
 <!--使用常量自动获得文件后缀-->
 <?php include SYS_VIEW_PATH.'/w_index/test'.SYS_TMPL_FIX;?>

方法二【推荐】

  • 使用辅助函数,不用关注常量,绝对路径加载更快
 <?php include SYS_TMPL('w_index/test');?>

注意:

  • 模版加载不能加载其他功能模块下的模版(不能跨功能模块),列如web/views下的模版不能加载admin/views下的模版。

四、扩展

1、自定义方法

  • /extend/Function.php 可以自定义方法(在哪个文件使用必需引入该文件例如:include SYS_PATH.'extend/Function.php';)。
  • 【推荐】为了方便使用自定义方法可以在系统入口处统一引入Function.php即可,也可以在系统扩展文件service.php里统一引入Function.php,当然不仅仅是Function.php,也可以自定义其他文件用同样的方式引入即可。

2、扩展第三方类库

  • 第三方类库直接放入 /extend/ 文件夹下,类库名和文件名必须要一致(使用时直接实例化类无需引入,系统会自动引入加载实例化对应的类)。
  • 注意:如果第三方类是在extend文件下的子文件夹里或者多层子文件夹里边时,需要配置/config/config.php自动加载类数组参数,例如:
return array(
   'autoload'=>array(     // 自动加载类
       '/Mailer/mail/',   // 示例1
       '/uploads/',       // 示例2
   ),
);

3、部署安全

为了项目核心目录文件安全,可以根目录指向到public目录下其他目录禁止权限,但index.php,.htaccess,web.config 需要放到public目录下(index.php附件根目录SYS_PATH_FILE参数需要为空)。
注意:这样部署的时候必须用域名访问且uploads、css、js等文件需要放到public目录下(根目录指定public目录时,本地可以虚拟域名部署)。

4、全局常量

(1)、固定常量

常量名称 备注说明
SYS_VERSION 系统版本
SYS_INIT_MEMORY 系统初始内存
SYS_INIT_TIME 系统运行初始时间
SYS_PATH 项目根目录
SYS_ROOT 核心文件目录
SYS_HOST 项目域名路径
SYS_URL 当前访问的url
SYS_APP_PRO 当前功能模块
SYS_VIEW_PATH 模版绝对路径常量

(2)、可配置常量

  • 核心目录下/helper/config.php (常量名字固定不可修改,值可根据需求配置):
常量名称 默认值 备注说明
SYS_APP_PATH 'app' 应用路径
SYS_APP_DEFAULT 'web' 指向默认模块
SYS_DEBUG false 调试开关(系统错误是否输出到页面,生产环境请关闭)
SYS_DEBUG_LOG true 系统日志开关(系统错误是否记录日志到文件)
SYS_DEBUG_LOG_PATH 'runtime/error/' 系统错误日志目录
SYS_RUN_LOG true 自定义日志开关
SYS_RUN_LOG_PATH 'runtime/logs/log/' 自定义日志目录
SYS_DB_LOG true sql日志开关
SYS_DB_LOG_PATH 'runtime/logs/db/' sql日志目录
SYS_URL_BOGUS true 伪静态开关
SYS_URL_FIX '.html' 伪静态后缀初始值(必须.开头)
SYS_TMPL_FIX '.php' 视图模版文件后缀(最好不要修改)
SYS_TMPL_PARENT 'common' 视图父级模版名称(可自定义默认common)
SYS_PAGE404 false 404页面开关(SYS_DEFAULT_CLASS定义值后该参数失效)
SYS_DEFAULT_CLASS '' 类不存在默认定向指定类(设置时可覆盖404)

5、系统辅助函数

核心目录下/helper/helper.php (自定义函数可以扩展):

函数 说明
SYS_SESSIONS_SET($name, $val) 设置sessions
SYS_SESSIONS_GET($name) 获取sessions
SYS_SESSIONS_DEL($name) 删除sessions
SYS_SESSIONS_CLEAR() 清空所有session
SYS_COOKIES_SET($name,$val,$expire=604800) 设置cookie (默认7天)
SYS_COOKIES_GET($name) 获取cookie
SYS_COOKIES_DEL($name) 删除cookie
SYS_ERR_LOGER($str, $file='', $line='0') 系统错误日志打印记录(runtime/error/)
SYS_LOGER($str) 程序打印日志文件(runtime/logs/)
SYS_LOGERr($str) 程序日志输出到页面(美化print_r)
SYS_LOGERd($str) 程序日志输出到页面(美化var_dump)
sys_costs() 运行开销统计
SYS_REDIRECT($url) 重定向
SYS_JUMP($txt='提示', $url='') js提示跳转
SYS_URL_PATH($url) 路由自动拼接,站内跳转(如:SYS_URL_PATH('web_about_item/id/2'))
SYS_TMPL($tmpl) 模版路径自动生成辅助(如:SYS_TMPL('w_index/test');)
SYS_COOKIES_COUNT($kname, $kcount) 客户端操作次数限制
SYS_ENCRYPT($string, $key) 字符串-加密
SYS_DECRYPT($string, $key) 字符串-解密
SYS_ADD_PATH($path) 目录/路径不存在时循环创建目录
SYS_ADD_FILE($path, $data = '') 目录/路径不存在时循环创建目录

6、伪静态配置

(1)、Apache

  • 网站根目录下配置“.htaccess”文件,编写内容:
<IfModule mod_rewrite.c>
   RewriteEngine On
  
   #指定目录和文件不受影响
   RewriteCond %{REQUEST_URI} !(public|uploads|job)
   RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpeg|\.jpg|\.gif|\.txt|\.zip|\.rar|\.ico)$ [NC]

   # 确保请求路径不是一个文件名或目录
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d

   # 重定向所有请求到 index.php?zhlphpurl=PATHNAME
   RewriteRule ^(.*)$ index.php?zhlphpurl=$1 [PT,L]
</IfModule>
  • 还可以设置301重定向:
   #(设置301重定向)  
   RewriteCond %{HTTP_HOST} !^www\..+$ [NC]
   RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
   #或者这样:  
   RewriteCond %{http_host} ^yj521.com$
   RewriteRule ^(.*)$https://www.yj521.com/$1 [R=301,L]

(2)、Nginx

  • 配置“nginx.conf”文件,在server { 里边配置以下代码:
location / {
   if (!-e $request_filename) {
       rewrite ^(.*)$  /index.php?zhlphpurl=$1 last;
   }
}

location ~ /\.ht {
   deny all;
}

使用phpstudy(小皮)时在网站根目录下配置“nginx.htaccess”文件,内容直接复制上边规则。
注意:配置上边规则后需要重启Nginx。

(3)、IIS

  • 配置“web.config”文件,编写内容:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 <system.webServer>
   <rewrite>
     <rules>
       <rule name="OrgPage" stopProcessing="true">
         <match url="^(.*)$" />
           <conditions logicalGrouping="MatchAll">
             <add input="{HTTP_HOST}" pattern="^(.*)$" />
             <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
             <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
           </conditions>
      	 <action type="Rewrite" url="index.php?zhlphpurl={R:1}" appendQueryString="false" />
       </rule>
     </rules>
   </rewrite>
 </system.webServer>
</configuration>

7、扩展核心架构、类库、插件

/zhlphp/plug/ 目录下可扩展核心插件(不影响目前核心架构)。
/zhlphp/library/ 目录下可扩展框架核心类库(根据情况调整核心架构)。
/zhlphp/core/ 目录下扩展核心架构其他功能(可能会改变核心架构)。

五、版权信息

Version 2.3.5
Copyright ©遵循Apache2.0协议发布


--------- END ---------


Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

ZHLPHP是一个开源、简单、快速、低耦合,高扩展,低门槛的PHP开发框架。 展开 收起
PHP 等 4 种语言
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
PHP
1
https://gitee.com/juheli/zhlphp.git
git@gitee.com:juheli/zhlphp.git
juheli
zhlphp
zhlphp
master

搜索帮助