# ENPHP
**Repository Path**: wfdaj/ENPHP
## Basic Information
- **Project Name**: ENPHP
- **Description**: No description available
- **Primary Language**: PHP
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-10-24
- **Last Updated**: 2024-12-03
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
### ENPHP Framework是一个轻量级的,开包即用的PHP开源框架
ENPHP非常适合中小型web应用的开发设计,内置数据验证,多数据库分离,Redis,数据缓存,会话认证,中间件等支持及常用的库函数。
以优化80%重复功能为目标设计的全栈框架。
### 版本库依赖
> PHP7+
> mb_string扩展
### 文档目录索引
#### 常量配置
|||||
|---|---|---|---|
|[入口文件配置](#入口文件配置)| [常量设置](#常量设置) | [数据库配置](#数据库配置) | [全局变量数组](#全局变量数组)|
#### 框架基本使用
||||
|---|---|---|
|[Controller控制器](#Controller控制器) | [View视图](#View视图)| [Model数据模型](#Model数据模型)|
#### 框架核心组建
|||||
|---|---|---|---|
| [Input输入](#Input输入)| [Output输出](#Output输出) | [Session会话](#Session会话) | [Cookie管理](#Cookie管理)|
#### 数据库操作
||||
|---|---|---|
|[数据库基本操作](#数据库基本操作)| [Model数据对象](#Model数据对象)| [Model数据验证](#Model数据验证) |
#### 缓存
|||
|---|---|
|[Redis缓存](#Redis缓存) | [Cache缓存](#Cache缓存) |
#### 安全认证
||||
|---|---|---|
|[Authorize认证](#Authorize认证) | [Security安全](#Security安全) | [Captcha验证码生成](#Captcha验证码生成)|
||||||
#### 库函数
||||
|---|---|---|
|[Upload上传文件](#Upload上传文件) |[Html标签生成](#Html标签生成)|[Grid表格生成](#Grid表格生成) |
|[Image图片修饰](#Image图片修饰) |[Smtp发送邮件](#Smtp发送邮件) |[Captcha验证码生成](#Captcha验证码生成)|
文档内容
====
### 入口文件配置
> 入口文件一般是网站的根目录index.php文件,有几个重要的常量配置。
#### 运行环境设置
设置运行环境变量,三个值分别为测试环境,产品环境,开发环境。
```php
// test,production,development
define('ENVIRONMENT', 'development');
```
#### 应用目录设置
```php
define('APP_DIR', realpath('app_dir') . DIRECTORY_SEPARATOR);
```
#### 框架目录设置
```php
define('SYS_DIR', realpath('system_dir') . DIRECTORY_SEPARATOR);
```
#### 控制器模块目录设置
设置controller模块目录常量,模块必须是APP_DIR目录下module文件夹的子目录。
```php
define('MODULE', 'www');
```
#### 模板视图目录设置
设置模板目录常量,模板必须是APP_DIR目录下template文件夹的子目录。
```php
define('TEMPLATE', 'www');
```
### 全局常量设置
> 常量文件位置在APP_DIR/config/下面三个子目录test,production,development中的constans.php文件分别按环境设置。
#### 地址路由
地址路由配置,以/index.php?c=main&a=index为例子。
c代表控制器类名字,默认控制器为Main。
a代表action方法名称,默认action为index。
你可以自定义设置这些值。
```php
define('DEFAULT_CONTROLLER', 'main');
define('DEFAULT_ACTION', 'index');
define('CONTROLLER_KEY_NAME', 'c');
define('ACTION_KEY_NAME', 'a');
```
#### 字符编码
输出字符编码设置,以便Output::view()和Output::json()输出
```php
define('CHARSET', 'utf-8');
```
#### Cookie相关设置
```php
//有效域名
define('COOKIE_DOMAIN', 'test.com');
//是否https发送
define('COOKIE_SECURE', false);
//有效路径
define('COOKIE_PATH', '/');
//http只读
define('COOKIE_HTTPONLY', false);
//过期时间秒
define('COOKIE_EXPIRE', 0);
```
#### Session设置
```php
//自定义session cookie名
define('SESSION_COOKIE_NAME', 'SE');
//session保存时间,0为关闭浏览器即失效,秒为单位
define('SESSION_EXPIRE', 0);
```
#### 哈希验证配置
```php
//加密安全混淆值
define('ENCRYPTION_KEY', 'weryi9878sdfddtgtbsdfh');
//表单提交token session 名称
define('TOKEN_SESSION_NAME', '34efddddre');
//表单token字段名
define('TOKEN_INPUT_NAME', 'fh40dfk9dd8dkfje');
//token过期时间,秒为单位
define('TOKEN_EXPIRE', 3600);
```
#### 会话认证配置
```php
//认证方式,cookie,jwt,session
define('AUTH_TYPE', 'session');
//加密密钥
define('AUTH_SECRET', 'dsd#@4ddz!ds');
//认证名称
define('AUTH_NAME', 'auth');
//jwt存活时间,秒为单位
define('AUTH_JWT_EXPIRE', 600);
//jwt数据过载方式,header或url
define('AUTH_JWT_MODE', 'header');
//认证cookie存活时间
define('AUTH_COOKIE_EXPIRE', 0);
```
#### 多语言应用
```php
//默认语言环境
define('LANG', 'zh_cn');
```
#### URL转换
URL重写转换输出模版,和路由无关,以配合Helper::url()使用
```php
//url 重写
define('URL', ['mod_name'=>['controller_name/action_name'=>'/{controller_key}/{action_key}']]);
```
例子:
```php
//注意Helper::url()参数和数组key的顺序
define('URL', [
'www' => [
//www表示模块名称
'main/index' => '/',
//echo $this->helper->url(['c'=>'main','a'=>'index'])
//输出 /
'main/lists/type' => '/list/{type}.html',
//echo $this->helper->url(['c'=>'main','a'=>'lists','type'=>'2'])
//输出 /list/2.html
'main/lists/type/page' => '/list/{type}_{page}.html'
//echo $this->helper->url(['c'=>'main','a'=>'lists','type'=>'2','page'=>'34'])
//输出 /list/2_34.html
]
]);
```
#### 运行分析日志文件配置
```php
//分析器日志文件
define('PROFILER_LOG_FILE', APP_DIR . 'log/profiler.log');
```
#### 中间件配置
```php
define('MIDDLEWARE', [
//controller运行之前
'before' => [
'auth' => \middleware\Auth::class,
'authorize' => \middleware\Authorize::class
],
//controller运行之后
'after' => []
]);
```
### 数据库配置
> 数据库文件位置在APP_DIR/config/下面三个子目录test,production,development中的database.php文件分别按环境设置。
> 暂时只支持mysqli
default为默认数据库,可以直接Db::instance()访问默认数据库
Db::instance('read)访问read数据库
```php
//例子
return [
//默认数据库
'default' =>
[
'driver' => 'mysqli',
'host' => 'set.database.to.hosts.file',
'username' => 'root',
'password' => '123456',
'database' => 'dataname',
'port' => 3306,
'charset' => 'utf8'
],
//读数据库
'read'=>
[
'driver' => 'mysqli',
'host' => 'set.database.to.hosts.file',
'username' => 'root',
'password' => '123456',
'database' => 'dataname',
'port' => 3306,
'charset' => 'utf8'
]
];
```
### 全局变量数组
全局变量数组$var[]
```php
//默认已包含$vars['controller']当前控制器值
//默认已包含$vars['action']当前action值
global $vars;
```
### 数据库基本操作
> 暂时只支持mysqli
> default为默认数据库,可以直接Db::instance()访问默认数据库
> Db::instance('read)访问read数据库
#### query($sql) 方法
原始SQL语句执行,如是select返回数据集,delete,insert,update返回布尔值。
```php
use system/Database as Db;
$db=Db::instance();
//返回一个结果集对象句柄
$result=$db->query('select * from table1 where f=2;');
//返回数据的条数,int类型
$result->num_rows;
//返回结果集其中一条数据,默认第一条以对象形式返回字段
$result->row();
//以数组形式返回第3条数据
//$row['f'];
$row=$result->row(2,'array');
//以对象形式返回第4条数据
//$row->f;
$row=$result->row(3,'object')
//返回数据集,默认对象形式
$recordset=$result->result();
foreach($recordset as $rs){
echo $rs->f;
}
//数组形式返回数据集
$recordset=$result->result('array');
foreach($recordset as $rs){
echo $rs['f'];
}
```
#### select($table,$condition=[]) 方法
查询数据库表返回数据集对象。
> 参数说明
>> $table 数据表名称
>> $condition 查询条件数组,如果为空返回全部
```php
//查询条件
$condition= [
'where' => ['f1'=>'2','f3>'=>'3','f4!='=>'8'], //where条件,支持运算符>,<,<>,!=,=,in,like,>=,<=
'fields' => ['f1','f2','f3'],//返回字段
'orderby' => ['f1'=>'desc','f2'=>'asc'], //排序
'limit' => [0,20] //返回数据条数 ,也可以是一个int值,如:limit=>10
];
//返回数据句对象
$recordset=$db->select('table1',$condition);
foreach($recordset->result() as $rs){
echo $rs->f1;
}
```
#### insert($table,$data) 方法
插入数据到数据库表,返回布尔值。
>参数说明
>> $table 数据表名称
>> $data 插入表的数据数组
```php
//需要插入的数据
$data=['f1'=>'1','f2'=>'2'];
$rs=$db->insert('table1',$data);
if($rs){
//插入成功,返回最后一条插入语句产生的自增ID
$this->db->insert_id;
}
```
#### delete($table,$where=[]) 方法
删除数据集,返回布尔值
> 参数说明
>> $table 数据表名称
>> $where where条件数组,为空删除全部,谨慎使用!
```php
//删除条件
$data=['f1'=>'1','f2'=>'2'];
$rs=$db->delete('table1',$data);
if($rs){
//删除成功,返回影响数据行数
$this->db->affected_rows;
}
```
#### escape($str) 方法
SQL语句中的特殊字符进行转义,返回转义后字符串。
```php
//参见 http://php.net/manual/zh/mysqli.real-escape-string.php
$db->escape('str');
```
#### replace($table,$data) 方法
数据集主键如果存在就替换不然插入新数据,返回布尔值。
> 参数说明
>> $table 数据表名称
>> $data 需要操作的数据数组
```php
//需要插入或替换的数据,如果主键primary=1已存在,即替换本条数据,不然插入新数据。
$data=['primary'=>1,'f1'=>'1','f2'=>'2'];
$rs=$db->replace('table1',$data);
```
#### update($table,$data,$where=[]) 方法
更新数据,返回布尔值或影响行数。
>参数说明
>> $table 数据表名称
>> $data 需要更新的数据数组
>> $where where条件,为空更新全部
```php
$data=['f1'=>'3','f3'=>'1'];
$where=['id'=>2];
$rs=$db->update('table1',$data,$where);
if($rs){
//更新成功,返回影响数据行数
$this->db->affected_rows;
}
```
#### close() 方法
关闭数据库链接,返回布尔值。
正常情况下,框架在执行完到最后自动关闭链接,也可以提前手动关闭。
```php
//关闭默认数据链接
$db->close();
```
### Model数据模型
> 每个model必须于数据库某个表对应。
通过继承\system\Model,我们可以使用框架自带的功能便捷操作数据。
例如我们创建APP_DIR/model/Tablemodel.php。
```php
//Tablemodel.php
//命名空间
namespace model;
//类必须继承系统\system\Model类
class Tablemodel extends \system\Model
{
//构造函数必须有
public function __construct()
{
//必须设置一个数据表
$this->table = 'test';
//必须设置一个主键
$this->primary = 'id';
//设置一个表的结构,以便验证过滤
$this->schema = [
'id' => [
'rules' => 'num',
'label' => 'ID',
'default' => null,
'required' => false
],
'name' => [
'validate' => ''required|string|filter:html',
'label' => '名称',
'default' => '',
'required' => true
]];
}
}
```
```php
use model\Tablemodel;
//我们可以这样调用model
$model=new Tablemodel();
$model->one(1);
```
#### $this->RDB 属性
设置读数据库,默认为default数据库
```php
$this->RDB='read_database';
```
#### $this->WDB 属性
设置写数据库,默认为default数据库
```php
$this->WDB='write_database';
```
#### $this->table 属性
设置model对应数据表
```php
$this->table='table1';
```
#### $this->primary 属性
设置数据表主键字段
```php
$this->primary='id';
```
#### $this->schema 属性
设置数据表结构,以便验证过滤,数组key必须和字段名一致
> validate['regex'] 正则验证字段数据合法性
> validate['message'] 提示信息
> filter 过滤数据,blank|tag|entity 三个值组合使用,
>> blank把连续多个空白字符转换成一个,
>> tag过滤html标签,
>> entity把html标签转换成实体字符。
> literal 字段的字面名字
> default 字段默认值
> required 是否必须填写字段
```php
$this->schema = [
'id' => [
'validate' => ['regex' => '/^\d+$/', 'message' => 'ID 不能为空'],
'literal' => 'ID',
'default' => null,
'required' => false
],
'name' => [
'validate' => ['regex' => '/^\S+$/', 'message' => '名称不能为空'],
'filter'=>'blank|tag|entity'
'literal' => '名称',
'default' => '',
'required' => true
]
];
```
#### $this->all($fields) 方法
获取数据表全部数据集,大表谨慎使用。
```php
$recordset=$this->all(['fname1','fname2']);
//注意直接返回数据集,而不是result对象
foreach($recordset as $rs){
echo $rs->fname1;
}
```
#### $this->count($where=[]) 方法
获取数据表数据条数,适合myisam表。
```php
//带条件的计算
$this->count(['field'=>'val']);
//获取表总条数
$this->count();
```
#### $this->delete($where=[]) 方法
删除表数据,成功返回true不然返回false。
```php
$rs=$this->delete(['f1'=>'2']);
if($rs){
//删除成功返回true
echo $rs;
}
```
#### $this->insert($data=[]) 方法
插入数据,返回布尔值。
```php
$data=['f1'=>'1','f1'=>'2'];
$rs=$this->insert($data);
if($rs){
//插入成功
}
```
#### $this->lastid() 方法
获取最后插入的自增主键ID。
```php
$data=['f1'=>'1','f1'=>'2'];
$rs=$this->insert($data);
if($rs){
//获取最后插入自增主键
echo $this->lastid();
}
```
#### $this->one($id) 方法
通过主键数字ID或唯一字段获取一条记录。
```php
//如果是主键数字id
$this->one(12);
//如果是唯一字段
$this->one(['uniqname'=>'abc']);
```
#### $this->query($sql) 方法
执行通用SQL语句,
如果是select返回基础数据库result对象,
执行update,insert,delete返回布尔值。
```php
$result=$this->query('select * from table1');
```
#### $this->select($condition=[]) 方法
按条件获取表数据对象集,参数为空,返回全部数据。
```php
$condition=[
'where' => ['f1'=>'2'],
'fields' => ['f1','f2'],
'orderby' => ['f1'=>'desc','f2'=>'asc'],
'limit' => [0,20] //或 'limit'=>20
];
$this->select($condition);
```
#### $this->update($data,$where=[]) 方法
更新数据记录,成功返回true,失败返回false
```php
$data=['f1'=>2,'f2'=>3];
$where=['id'=>12];
$rs=$this->update($data,$where);
if($rs){
//修改成功,返回影响true
echo $rs;
}
```
#### $this->where($where,$fields=[]) 方法
按条件返回数据对象集,主要为了简化$this->select()
```php
$where=['f1'=>'2'];
$fields=['f1','f2'];
$this->where($where,$fields);
```
#### $this->safe 属性
验证过滤入库字段数据,返回system/Safe实例。
> 具体参见 文档Model数据验证部分
```php
//可以在控制器这样调用
$this->model('Tablemodel')->safe->clear($data);
```
### Model数据验证
> Model数据验证,为了用户输入数据的合法性,
> 提供了几个实用方法函数以配合Model的$this->schema属性使用。
#### $this->safe->illegalFields 属性
> 接受返回验证不通过非法字段名数组
#### $this->safe->notMemberFields 属性
> 接受返回不在表字段中的非法字段名数组
#### $this->safe->incompleteFields 属性
> 接受返回未完成及必须填写的字段名数组
#### $this->safe->clear($data) 方法
清理不存在于schema里面的字段,
不是成员的字段保存于$this->notMemberFields
返回清理后的数据
```php
//清理之前的数据
$beforedata=[
//假如nomember不存在于$this->schema中,将被清理掉
'notmember'=>'val',
//假如f1字段名存在于$this->schema
'f1'=>'val'
];
//清理之后
$afterdata=$this->safe->clear($data);
//输出['f1'=>'val']
var_dump($afterdata);
//输出不是成员字段名['notmember']
var_dump($this->notMemberFields);
```
#### $this->safe->complete($data) 方法
验证是否缺少必要字段,
缺少的必要字段保存于$this->incompleteFields
返回布尔值
```php
//假如$this->schema包含字段f1,f2必须填写不能为空
//注意$data没有包含字段f2
$data=['f1'=>'val'];
//验证完整性
$result=$this->safe->complete($data);
if($result){
//通过完整性验证
}else{
//没有通过验证
var_dump($this->incompleteFields);
//输出['f2']
}
```
#### $this->safe->merge($data) 方法
与schema默认数据覆盖合并,并且清理不存在于schema里面的字段,
不是成员的字段保存于$this->notMemberFields
返回合并及清理的数据
```php
//假如$this->schema中存在f1字段,默认值等于val1
//注意f1现在的值为val2
$data=['f1'=>'val2','notmember'=>'valxx'];
//合并覆盖数据并清理非成员字段
$result=$this->safe->merge($data);
//输出['f1'=>'val2']
var_dump($result);
//输出不是成员字段名['notmember']
var_dump($this->notMemberFields);
```
#### $this->safe->validate($data) 方法
验证数据合法性,非法字段保存于$this->illegalFields
返回布尔值
```php
//假如$this->schema中字段f1必须为int类型
//注意f1是字符串
$data=['f1'=>'val'];
//验证合法性
$result=$this->safe->validate($data);
if($result){
//通过合法性验证
}else{
//没有通过验证
var_dump($this->illegalFields);
//输出['f1']
}
```
### Controller控制器
#### 创建一个控制器
> 控制器文件必须放置在APP_DIR/module/module_name目录下,文件名必须和类名一致。
> 必须继承system/Controller。
创建一个控制器,以APP_DIR/module/www/Testcontroller.php为例。
```php
//命名空间
namespace module\www;
//Testcontroller继承自定的inherit/Controller或system/Controller
class Testcontroller extends \inherit\Controller
{
public function index()
{
$data['hello_world']='hello wolrd';
//调用一个model
$this->model('Testmodel')->select();
//获取表单全部字段数据
$postdata=$this->input->post();
//清理不是schema成员字段
$afterdata=$this->model('Testmodel')->safe->clear($data);
//插入表单提交的数据到数据库
$this->model('Testmodel')->insert($afterdata);
//视图输出
$this->output->view('main',$data);
}
}
```
### View视图
> 视图模板文件必须放置APP_DIR/template/module_name/目录下面
> 模板文件都是标准的原生php与htm混合代码,框架没有专门的模板功能
#### 创建视图模板
例如我们创建一个APP_DIR/template/www/test.php,www为module模块名。
```php
// //
// ``` ### Grid表格生成 待优化 #### $grid->fields #### $grid->setField() #### $grid->filters #### $grid->filters() #### $grid->setFilter() #### $this->tools #### $this->tools() #### $grid->setTool() #### $grid->table() ### Image图片修饰 对图片进行加水印和缩放操作 #### 简单代码例子 ```php //创建实例 $image= new \System\Library\Image(); //设置图片宽度 $image->width=300; //设置图片高度 $image->height=300; //源文件路径 $image->source='G:\fw.png'; //处理之后保存路径 $image->save='G:\fw300.png'; //水印字体大小 $image->fontsize=20; //字体文件路径 $image->font=APP_DIR.'font/1.ttf'; //图片质量 $image->quality=90; //文本水印 $image->text='text'; //是否开启水印功能,默认false $image->watermark=true; //水印文件地址,图片优先 $image->markimg='G:\water.png'; //处理图片,返回布尔值 if($image->resize()){ //处理结果状态码 $image->code; //处理结果返回信息 $image->message; } //具体状态码和状态信息请查看 $image::MAG 常量 ``` ### Smtp发送邮件 SMTP邮件发送, 支持发送纯文本邮件和HTML格式的邮件 #### 代码例子 ```php //设置smtp服务器 $mail = new \system\library\Smtp([ 'server'=>'smtp.qq.com', 'username' => "name", 'password' => "123456", 'port' => 25 ]); //设置发件人 $mail->from("XXXXX"); //设置发件人名字 $mail->fromname("XXXXX"); //设置收件人,多个收件人,调用多次 $mail->to("XXXXX"); //设置抄送,多个抄送,调用多次 $mail->cc("XXXX"); //设置秘密抄送,多个秘密抄送,调用多次 $mail->bcc("XXXXX"); //设置邮件主题 $mail->subject("test"); //设置邮件内容 $mail->body("test"); //发送邮件,返回布尔值 if($mail->send()){ //发送成功 }else{ //发送失败,返回错误信息 $mail->error(); } ``` ### Captcha验证码生成 #### $captcha->bgcolor 属性 设置验证码背景16进制颜色 ```php $captcha->bgcolor='#333333'; ``` #### $captcha->showBorder 属性 设置是否显示边框,布尔值 ```php $captcha->showBorder=true; ``` #### $captcha->borderColor 属性 设置验证码边框16进制颜色 ```php $captcha->borderColor='#cccccc'; ``` #### $captcha->charLen 属性 设置验证码的位数 ```php $captcha->charLen=4; ``` #### $captcha->fontPath 属性 设置字体放置目录,绝对路径,默认目录APP_DIR/font/ ```php $captcha->fontPath=APP_DIR.'/font/'; ``` #### $captcha->width 属性 设置图片宽度,单位像素 #### $captcha->height 属性 设置图片高度,单位像素 #### $captcha->getCode() 方法 获取生成的文字,以便保存到session #### $captcha->create() 方法 生成渲染图像 #### $captcha->show() 方法 发送显示到浏览器 #### 简单代码例子 ```php //假如地址 index.php?c=captcha&a=showimg $authcode = new \system\library\Captcha(); $authcode->create(); $this->session->set('authcode', $authcode->getCode()); $authcode->show(); //html img标签显示