一、mvc程序中路由的映射
原理:路由解析,从url地址中获取控制器、操作方法
1、Route.php文件
文件路径:20230316\app\admin\controller\User.php
namespace app\admin\controller;
require '../app/admin/controller/User.php';
class Route
{
// 路由解析
public static function parse()
{
// array_key_exists 判断数组下标是否存在(键值 索引)
// 判断超全局函数$_SERVER是否存在'PATH_INFO'下标
if ( array_key_exists('PATH_INFO',$_SERVER ) && ['PATH_INFO'] !== '/')
{
$pathinfo = array_values(array_filter(explode('/', $_SERVER['PATH_INFO'])));
// explode 分割函数
// array_filter 返回过滤数组中为空的元素
// array_values 获取数组中所有元素的值(或者是说重新索引)
// print_r($pathinfo);
if(count($pathinfo)>=2){
// ucfirst 首字母大写
//$controller = array_shift($pathinfo);
$controller = __NAMESPACE__ . '\\' . ucfirst(array_shift($pathinfo));
$action = array_shift($pathinfo);
$params = $pathinfo; //输出 array(0=>peter, 1=>12345);
} else {
$controller = array_shift($pathinfo);
}
}
// 从url中解析出控制器 操作方法 参数列表
return [$controller, $action, $params];
}
}
$res = Route::parse();
// call_user_func_array 调用回调函数,并把一个数组参数作为回调函数的参数
// 两个参数:callback 被调用的函数,args 要被传入回调函数的数组,得是索引数组
echo call_user_func_array([(new $res[0]), $res[1]] , $res[2]);
2、USER.php文件
文件路径:20230316\app\admin\controller\User.php
<?php
namespace app\admin\controller;
class User
{
public function index($name, $id)
{
return "晚上好,{$name},您的编号为{$id}";
}
}
3、输出结果:
4、小结:
- 解析路由,从url( http://tpedu.io/20230316/core/Route.php/user/index/peter/12345 )地址获取控制器、操作方法、参数
- 映射到控制器
USER
下面的一个具体操作方法index
上 - 参数注入到
index
方法上; - 调用回调函数,作为数组参数作为回调函数的参数返回。
二、封装查询构造器
<?php
namespace core;
use PDO;
// 被委托的类:查询构造类
class Query
{
protected PDO $db;
protected string $table;
protected string $field;
protected string $limit;
// 查询规则 子查询
protected array $opts = [];
// 构造器
public function __construct(PDO $db)
{
$this->db = $db;
}
// 设置数据表
// 返回类型 self 本对象
public function table(string $table):self{
$this->table = $table;
return $this;
}
// 设置数据查询字段
public function field(string $field='*'):self{
$this->field = $field;
return $this;
}
// 设置分页,每页显示数据条数
public function limit(int $limit=10):self{
$this->limit = $limit;
$this->opts['limit'] = " LIMIT $limit";
return $this;
}
// 设置分页,计算偏移量
public function page(int $num=1):self{
$this->opts['offset'] = ' OFFSET ' . ($num-1) * $this->limit;
return $this;
}
// where 条件:数据表查询条件
public function where(string $where = ''):self{
$this->opts['where'] = " WHERE $where";
return $this;
}
// 排序规则
public function order($field, $order = 'DESC'): self
{
$this->opts['order'] = " ORDER BY $field $order ";
return $this;
}
// 设置查询语句
// 返回数组类型
public function select(): array
{
$sql = 'SELECT ' . $this->field . ' FROM ' . $this->table;
$sql .= $this->opts['where'] ?? null;
$sql .= $this->opts['order'] ?? null;
$sql .= $this->opts['limit'] ?? null;
$sql .= $this->opts['offset'] ?? null;
echo $sql;
$stmt = $this->db->prepare($sql);
$stmt->execute();
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// 更新语句
public function update(array $data): int
{
$str = '';
foreach ($data as $k => $v) {
$str .= $k . '="' . $v . '",';
}
// 去掉最后一个逗号
// rtrim 移除字符串右侧的空白字符或其他预定义字符
$sql = 'UPDATE ' . $this->table . ' SET ' . rtrim($str, ',');
$sql .= $this->opts['where'] ?? die('禁止无条件更新');
$stmt = $this->db->prepare($sql);
$stmt->execute();
// 大于0表示更新成功,需要有返回值才能进行下一步工作
return $stmt->rowCount();
}
}