admin.php 入口文件
<?php
// 后台入口
namespace core;
// 1. 获取到当前模块/应用的名称 , "admin"
define("APP_NAME", basename(__FILE__, '.php'));
// echo APP_NAME;
// 2. 加载MVC框架的核心类库
require __DIR__ . '/core/App.php';
// 3. 启动框架
App::run();
// echo(B::$a);
App.php
<?php
// 框架应用的基础类,用于启动框架
namespace core;
class App
{
public static function run()
{
// 1. 启动会话
session_start();
// 2. 公共函数库
// DIRECTORY_SEPARATOR: 目录分隔符常量, 可以自适应当前操作系统
require __DIR__ . DIRECTORY_SEPARATOR. 'common.php';
// 3. 设置常量
self::setConst();
// 4. 注册类的自动加载器
spl_autoload_register([__CLASS__, 'autoloader']);
// 5. 路由解析
[$controller, $action, $params] = Router::parse();
// 6. 实例化控制器
// 框架中, 视图目录 与 控制器 对应 , 模板文件 与 方法 对应的
// IndexController ---> index 目录
// hello -> hello.php 模板文件对应
// 在实例化控制器类之前, 先要得到视图类的实例
// 定义默认的视图路径的入口
// $path = '/app/admin/view';
$path = ROOT_APP_PATH . DIRECTORY_SEPARATOR . APP_NAME . DIRECTORY_SEPARATOR . 'view'. DIRECTORY_SEPARATOR;
// echo $path;
// 视图实例化
$view = new View($path, $controller, $action);
// 首字母大写, 加上后缀: Controller
$controller = ucfirst($controller) . 'Controller';
$controller = 'app\\' . APP_NAME . '\\controller\\' . $controller;
// 控制器实例化
$controller = new $controller($view);
// dump($controller);
// 调用控制器中的方法,并传入指定的参数,完成页面的渲染
echo call_user_func_array([$controller, $action], $params);
}
// 设置常量
private static function setConst()
{
// 1. 框架核心类库的路径常量
define('CORE_PATH', __DIR__);
// 2.根路径/项目路径常量: C:\Users\Administrator\Desktop\fram
define('ROOT_PATH', dirname(__DIR__));
// 3. 所有应用的入口: app/
define('ROOT_APP_PATH', ROOT_PATH. DIRECTORY_SEPARATOR.'app');
// 4. 配置常量
// 二级配置: 项目/框架级(默认) < 应用级(自定义)
$defaultConfig = ROOT_PATH . DIRECTORY_SEPARATOR.'config.php';
$appConfig = ROOT_APP_PATH . DIRECTORY_SEPARATOR.'config.php';
define('CONFIG', require file_exists($appConfig) ? $appConfig : $defaultConfig);
// 5. 设置调试开关
// php.ini
ini_set('display_errors', CONFIG['app']['debug'] ? 'Off' : 'On');
}
// 自动加载器(类)
private static function autoloader($class)
{
// 类文件的命名空间,应该与类文件所在的路径存在一一对应关系
// core\Controller.php
$file = str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';
file_exists($file) ? require $file : die($class . ' 类文件找不到');
}
}
common.php
<?php
// 公共函数库
namespace core;
// 快捷打印
function dump(...$data)
{
foreach ($data as $item) {
// true: 只返回不打印
$result = var_export($item, true);
// 自定义变量显示样式
$style = 'border:1px solid #ccc;border-radius:5px;';
$style .= 'background: #efefef; padding: 8px;';
// 格化式打印
printf('<pre style="%s">%s</pre>', $style, $result);
}
}
// $a = 100;
// $a = 'hello';
// $a = ['hello', 'world', 'zhu'];
// dump($a);
Controller.php
<?php
// 控制器类的基类
namespace core;
class Controller
{
// 视图对象
protected View $view;
// 构造器
public function __construct(View $view)
{
$this->view = $view;
}
}
Db.php
<?php
// 数据库操作入口类
namespace core;
use PDO;
class Db
{
// 连接对象
protected static PDO $db;
// 连接数据库, 创建PDO对象
protected static function connect(string $dsn, string $username, string $password)
{
self::$db = new PDO($dsn, $username, $password);
}
public static function __callStatic(string $name, array $argc)
{
// 1. 连接数据库
$dsn = CONFIG['database']['type']. ':dbname='. CONFIG['database']['dbname'] . '; host=' . CONFIG['database']['host'];
dump($dsn);
$username = CONFIG['database']['username'];
$password = CONFIG['database']['password'];
static::connect($dsn, $username, $password);
// 2. 将数据库所有的操作, 全部重定义到别一个类: Query.php
$query = new Query(static::$db);
return call_user_func_array([$query, $name], $argc);
}
}
Query.php
<?php
//数据查询
namespace core;
use PDO;
class Query
{
protected PDO $db;
protected string $table;
protected string $field;
public function __construct(PDO $db)
{
$this->db = $db;
}
// 获取当前数据表名称
public function table(string $table) : self
{
$this->table = $table;
return $this;
}
// 设置字段
public function field(string $field = '*') : self
{
$this->field = $field;
return $this;
}
// 获取全部数据
public function select()
{
$sql = 'SELECT ' . $this->field . ' FROM ' . $this->table;
echo $sql;
$stmt = $this->db->prepare($sql);
if ($stmt->execute()) {
return $stmt->fetchAll(PDO::FETCH_ASSOC);
} else {
print_r($stmt->errorInfo());
}
}
}
Router.php
<?php
// 路由类
namespace core;
use function core\dump;
class Router
{
public static function parse() :array
{
// 从URL中,解析出:控制器, 方法, 参数
// 默认控制器,方法和参数
$controller = CONFIG['app']['default_controller'];
$action = CONFIG['app']['default_action'];
$params = [];
// 判断是否存在 pathinfo
if (array_key_exists('PATH_INFO', $_SERVER) && $_SERVER['PATH_INFO'] !== '/') {
// dump($_SERVER['PATH_INFO']);
// dump(array_filter(explode('/', $_SERVER['PATH_INFO'])));
$pathinfo = array_filter(explode('/', $_SERVER['PATH_INFO']));
// dump($pathinfo);
if (count($pathinfo) >= 2) {
$controller = array_shift($pathinfo);
$action = array_shift($pathinfo);
$params = $pathinfo;
} else {
$controller = array_shift($pathinfo);
}
}
// dump([$controller, $action, $params]);
return [$controller, $action, $params];
}
}
View.php
<?php
// 视图类的基类
namespace core;
class View
{
// 视图默认目录
protected string $defaultPath;
// 当前控制器: 视图目录
protected string $controller;
// 当前控制器中的方法: 模板文件
protected string $action;
// 模板变量容器
protected array $data = [];
public function __construct(string $path, string $controller, string $action)
{
$this->defaultPath = $path;
$this->controller = $controller;
$this->action = $action;
}
// 模板赋值
public function assign($key, $value)
{
if (is_array($value)) {
$this->data = array_merge($data, $this->data) ;
}
$this->data[$key] = $value;
}
// 模板渲染
public function render(string $path = null, array $data = null)
{
// 允许模板赋值与模板渲染同步完成
// 考虑到原有模板变量数组中可能已有值,所以不能清空,只能合并
$this->data = $data ? array_merge($data, $this->data) : $this->data;
// 如果没有传入自定义模板路径,就使用默认方法来生成: 控制器/视图.php
$file = $path ?? $this->controller . DIRECTORY_SEPARATOR . $this->action;
$file = $file . '.' . CONFIG['app']['default_view_suffix'];
$file = $this->defaultPath . $file;
// dump($file);
// 模板赋值
extract($this->data);
// 渲染模板
file_exists($file) ? include $file : die('模板不存在');
}
}