myphps/myphp

一个简单的php框架

Maintainers

Package info

github.com/ncwsky/myphp

pkg:composer/myphps/myphp

Statistics

Installs: 446

Dependents: 2

Suggesters: 0

Stars: 2

Open Issues: 0

2.26.3 2026-04-17 10:40 UTC

This package is auto-updated.

Last update: 2026-04-17 10:43:10 UTC


README

一个轻量级的 PHP MVC 框架,注重简洁与实用。

特性

  • MVC 架构 — 控制器、模型、视图分层清晰
  • 模块化 — 支持多模块应用,灵活的模块路径映射
  • 模板引擎 — 内置轻量模板引擎,支持变量输出、循环、条件、文件包含
  • 数据库 — 基于 PDO,支持 MySQL、SQLite、PostgreSQL、MSSQL、Oracle、TDengine
  • ORM — 流式查询构建器,事务支持
  • 缓存 — 文件缓存、Redis 缓存
  • 中间件 — Pipeline 中间件管道
  • CLI 支持 — 命令行模式执行控制器方法
  • 认证授权 — 内置登录检测与权限校验
  • 会话管理 — 文件/Redis 会话存储
  • Hook 系统 — 事件驱动的钩子机制
  • 日志 — 分级日志,自动轮转

环境要求

  • PHP >= 7.2

安装

composer require myphps/myphp

快速开始

创建入口文件 index.php

<?php
define('APP_PATH', __DIR__ . '/app');

// require 'conf.php'; // 可载入全局配置 $cfg = []
require './vendor/myphps/myphp/base.php';
myphp::Run();

访问 http://localhost/index.php/index/index 即可运行,会自动创建app目录。

目录结构

project/
├── web/                       # Web 入口目录
│   ├── index.php              # 主入口文件
│   └── admin.php              # 模块入口文件(可选)
├── app/                       # 应用目录
│   ├── config.php             # 应用配置
│   ├── control/               # 控制器
│   ├── model/                 # 模型
│   ├── view/                  # 视图模板
│   └── lang/                  # 语言包
├── common/                    # 公共代码
│   ├── config.php             # 全局配置
│   └── common.php             # 公共函数
├── runtime/                   # 运行时文件(缓存等)
├── conf.php                   # 全局配置文件
├── vendor/                    # Composer 依赖
└── composer.json

路由

采用 m/c/a(Module/Controller/Action)路由模式:

含义 示例
m 模块(可选) admin
c 控制器 user
a 方法 list

URL 模式:

模式 格式 示例
1 Query String /index.php?c=user&a=list
2(默认) PATH_INFO /index.php/user/list

URL 中的控制器名会自动转换为 PascalCase 并加上 Act 后缀:

/user-profile/list → app\control\UserProfileAct::list()

默认控制器和方法均为 index,即访问 / 等同于 /index/index

控制器

控制器放在 app/control/ 目录下:

<?php
namespace app\control;

use myphp\Control;

class UserAct extends Control
{
    // 前置方法,每个 action 执行前调用
    protected function _before() {}

    public function index()
    {
        $this->assign('title', '用户列表');
        return $this->fetch(['msg'=>'你好']); // 渲染 app/view/user/index.html
    }

    public function info()
    {
        $user = UserModel::where(['id' => $_GET['id']])->one();
        return self::ok($user); // JSON 成功响应
    }
}

响应方法:

self::ok($data, $info)          // 成功 JSON 响应
self::fail($info, $code)        // 失败 JSON 响应
self::json($data)               // 原始 JSON
self::jsonp($data)              // JSONP
self::html($content)            // HTML
self::redirect($url)            // 重定向
$this->fetch($template)         // 渲染模板

模型

模型放在 app/model/ 目录下:

<?php
namespace app\model;

use myphp\Model;

class UserModel extends Model
{
    protected $tbName = 'user';    // 表名
    protected $prikey = 'id';      // 主键
}

查询方法:

UserModel::where(['id' => 1])->one();                // 单条
UserModel::where(['id' => 1])->lock()->one();        // 单条加锁查询 FOR UPDATE
UserModel::fields('id,name,sex')->all();             // 全部
UserModel::where(['status'=>1])->all();              // 条件查询 all|select效果一样
UserModel::where('age > ?', [18])->order('id DESC')->limit(10)->select();
UserModel::insert($data);                            // 插入
UserModel::insert([$data,$data,...]);                // 批量插入
UserModel::where('id = ?', [1])->update($data);     // 更新
UserModel::updateAll($data, ['id'=>1]);              // 更新
UserModel::where('id = ?', [1])->del();              // 删除
UserModel::delAll(['id'=>1]);                        // 删除

// 事务
Model::beginTrans();
Model::commit();
Model::rollBack();

模板引擎

模板文件默认使用 .html 后缀,放在 app/view/ 目录下。

变量输出

{$name}              → <?php echo $name;?>
{$data.name}         → <?php echo $data['name'];?>

包含文件

{include:header.html}

循环

{list $users}
    <p>{$val.name}</p>
{/list}

等同于 foreach($users as $key=>$val)。自定义变量名:

{list $users $user}
    <p>{$user.name}</p>
{/list}

等同于 foreach($users as $k_user=>$user)

条件

{if $age > 18}
    成年
{elseif $age > 12}
    青少年
{else}
    儿童
{/if}

其他标签

标签 作用 示例 输出
~ 执行 PHP 语句 {~echo $name} <?php echo $name ?>
* 原样输出表达式 {*$obj->name()} <?php echo $obj->name(); ?>
@ 语言变量 {@name} <?php echo GetL('name');?>
# 配置值 {#name} <?php echo GetC('name');?>
? isset 检查 {?$name} 存在则输出,否则为空

$ 标签会对变量做解析(如点号转数组访问),而 * 标签将内容作为原始 PHP 表达式直接输出,适用于方法调用、多维数组、带判断的复杂表达式等:

{$data.name}                → <?php echo $data['name'];?>
{*$user->getName()}         → <?php echo $user->getName(); ?>
{*$list[$i]['child'][$j]}   → <?php echo $list[$i]['child'][$j]; ?>
{*isset($a) ? $a : $b}     → <?php echo isset($a) ? $a : $b; ?>

? 标签用法:

{?$name}              → isset($name) ? $name : ''
{?$name:'默认值'}      → isset($name) ? $name : '默认值'
{?$name=trim}         → isset($name) ? trim($name) : ''
{?$name=trim:'默认值'} → isset($name) ? trim($name) : '默认值'

模块

模块通过 module_maps 配置映射:

'module_maps' => [
    'admin' => '/admin',           // / 开头相对项目根目录
    'api'   => 'module/api',       // 无 / 开头相对应用目录(/app/)
    'user'  => '/app/module/user'  // 完整路径
]

通过配置映射后,访问 /admin/user/list 将直接请求到admin模块下的user控制器下的list方法。 而通过单独的入口文件访问,则需要参照以下场景:

场景一:模块目录在项目根目录下

入口文件:/web/admin.php
模块目录直接位于根目录(如 /admin),入口文件直接指向该目录:

<?php
define('APP_PATH', __DIR__ . '/../admin');
define('COMMON', __DIR__ . '/../common');
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../conf.php';
require __DIR__ . '/../vendor/myphps/myphp/base.php';
myphp::Run();

场景二:使用 DEF_MODULE 指定默认模块

入口文件:/web/admin.php
通过主应用入口加载指定模块,模块位于根目录下:

<?php
define('APP_PATH', __DIR__ . '/../app');
define('COMMON', __DIR__ . '/../common');
define('DEF_MODULE', 'admin');
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../conf.php';
require __DIR__ . '/../vendor/myphps/myphp/base.php';
myphp::Run();

场景三:模块在子目录下,需手动配置命名空间

入口文件:/web/admin.php 模块位于 app/module/admin,需指定命名空间映射:

<?php
define('APP_PATH', __DIR__ . '/../app/module/admin');
define('COMMON', __DIR__ . '/../common');
define('DEF_MODULE', 'admin');
require __DIR__ . '/../vendor/autoload.php';
require __DIR__ . '/../conf.php';
require __DIR__ . '/../vendor/myphps/myphp/base.php';
myphp::$cfg['app_namespace'] = 'app\\module\\admin';
myphp::$namespaceMap['app\\'] = __DIR__ . '/../app';
myphp::Run();

CLI 模式

命令行下执行控制器方法,参数格式同 URL:

php index.php m/c/a "b=1&d=1"
php index.php m/c/a b=1 d=1
php index.php m/c/a?b=1
php index.php "m/c/a?b=1&d=1"

使用 my 命令行工具:

php my --init                    # 初始化项目 默认app
php my --init --run=admin        # 初始化模块(应用目录)
php my user/list                 # 执行 controller/action
php my admin/user/list           # 执行 module/controller/action
php my --run=admin dashboard/stats "id=5"  # 指定模块执行

配置

配置加载顺序(后者覆盖前者):

  1. 框架默认配置(def_config.php
  2. 全局配置(conf.php)— 项目部署环境配置,如数据库连接、调试开关等
  3. 共用配置(common/config.php)— 跨模块共用的业务配置
  4. 应用配置(app/config.php)— 当前应用的专属配置
  5. 模块配置(模块 config.php)— 模块级别的独立配置

常用配置项:

$cfg = [
    'debug'       => true,              // 调试模式
    'charset'     => 'utf-8',           // 字符编码
    'timezone'    => 'Asia/Shanghai',   // 时区
    'lang'        => 'zh-cn',           // 默认语言

    // 路由
    'url_mode'    => 2,                 // 1:Query String  2:PATH_INFO
    'url_rewrite' => true,              // 伪静态
    'def_control' => 'index',           // 默认控制器
    'def_action'  => 'index',           // 默认方法

    // 数据库
    'db' => [
        'type'   => 'pdo',
        'dbms'   => 'mysql',
        'server' => 'localhost',
        'name'   => 'database',
        'user'   => 'root',
        'pwd'    => '',
        'port'   => 3306,
        'char'   => 'utf8mb4',
        'prefix' => '',
    ],

    // 缓存
    'cache' => 'file',                  // 'file' 或 Redis 配置数组

    // 会话
    'session' => [
        'type'   => 'file',             // 'file' 或 'redis'
        'expire' => 1440,
    ],

    // 中间件
    'middleware' => [
        \myphp\middleware\Cors::class,
    ],

    // 日志
    'log_level' => 0,                   // 0:全部 1:debug 2:info 3:notice 4:warn 5:error
];

完整配置项参见 def_config.php

中间件

class AuthMiddleware
{
    public function __invoke(\myphp\Request $request, \Closure $next)
    {
        // 前置处理
        if (!check_login()) {
            return myphp::res()->withStatus(401, 'Unauthorized');
        }
        $response = $next($request);
        // 后置处理
        return $response;
    }
}

在配置中注册:

'middleware' => [
    AuthMiddleware::class,
]

日志

use myphp\Log;

// 按级别记录
Log::DEBUG('调试信息');
Log::INFO('一般信息');
Log::WARN('警告');
Log::ERROR('错误');
Log::SQL($sql);

// 自定义写入
Log::trace('自定义日志', 'trace');   // 追踪日志
Log::write('自定义日志', 'info');    // 写入指定级别
Log::echo('日志1', '日志2');         // 多内容输出

// 请求与异常
Log::miniREQ();                      // 简要请求信息
Log::REQ();                          // 完整请求信息
Log::Exception($e);                  // 记录异常

日志自动按大小轮转(默认 4MB),存放在 log/ 目录。

开发工具

# 安装
composer require --dev phpstan/phpstan friendsofphp/php-cs-fixer

# 静态分析
phpstan analyse -c ./phpstan.neon.dist --memory-limit 1G

# 代码格式化
php-cs-fixer fix --config=./.php-cs-fixer.dist.php

协议

MIT License