PHPackages                             dkkevincheng/vinc - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. dkkevincheng/vinc

ActiveProject

dkkevincheng/vinc
=================

自己动手搭建一个属于自己的MVC框架，实现极简主义设计。风格类似Sinatra。

1.2(6y ago)20MITPHPPHP &gt;=7.1.3

Since Aug 7Pushed 6y ago1 watchersCompare

[ Source](https://github.com/dkkevincheng/Vinc)[ Packagist](https://packagist.org/packages/dkkevincheng/vinc)[ RSS](/packages/dkkevincheng-vinc/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (1)Versions (4)Used By (0)

Vinc
====

[](#vinc)

自己动手搭建一个属于自己的MVC框架，实现极简主义设计。风格类似Sinatra。

一个优雅简单的框架 : Vinc
----------------

[](#一个优雅简单的框架--vinc)

- [composer一个PHP界神器](#composer%E4%B8%80%E4%B8%AAPHP%E7%95%8C%E7%A5%9E%E5%99%A8)
- [MVC框架路由的思考](#MVC%E6%A1%86%E6%9E%B6%E8%B7%AF%E7%94%B1%E7%9A%84%E6%80%9D%E8%80%83)
- [设计框架的骨骼](#%E8%AE%BE%E8%AE%A1%E6%A1%86%E6%9E%B6%E7%9A%84%E9%AA%A8%E9%AA%BC)
- [使用ORM提高框架的效率](#%E4%BD%BF%E7%94%A8ORM%E6%8F%90%E9%AB%98%E6%A1%86%E6%9E%B6%E7%9A%84%E6%95%88%E7%8E%87)
- [发送属于你自己的第一封邮件](#%E5%8F%91%E9%80%81%E5%B1%9E%E4%BA%8E%E4%BD%A0%E8%87%AA%E5%B7%B1%E7%9A%84%E7%AC%AC%E4%B8%80%E5%B0%81%E9%82%AE%E4%BB%B6)
- [缓存服务器Redis，怎么能少了你呢？](#%E7%BC%93%E5%AD%98%E6%9C%8D%E5%8A%A1%E5%99%A8Redis%EF%BC%8C%E6%80%8E%E4%B9%88%E8%83%BD%E5%B0%91%E4%BA%86%E4%BD%A0%E5%91%A2%EF%BC%9F)
- [把门面做出来，让变美更简单](#%E6%8A%8A%E9%97%A8%E9%9D%A2%E5%81%9A%E5%87%BA%E6%9D%A5%EF%BC%8C%E8%AE%A9%E5%8F%98%E7%BE%8E%E6%9B%B4%E7%AE%80%E5%8D%95)

*本仓库是一个示例代码，如果有兴趣，可以关注作者公众号或者加群讨论。*

### composer一个PHP界神器

[](#composer一个php界神器)

说起composer，就要讲PSR规范，也就是FIG。FIG 最初由几位知名 PHP 框架开发者发起，在吸纳了许多优秀的大脑和强健的体魄后，提出了 PSR-0 到 PSR-4 五套 PHP 非官方规范:

- PSR-0 (Autoloading Standard) 自动加载标准
- PSR-1 (Basic Coding Standard) 基础编码标准
- PSR-2 (Coding Style Guide) 编码风格向导
- PSR-3 (Logger Interface) 日志接口
- PSR-4 (Improved Autoloading) 自动加载优化标准

Composer 利用 PSR-0 和 PSR-4 以及 PHP5.3 的命名空间构造了一个繁荣的 PHP 生态系统。类似 npm 和 RubyGems，给海量 PHP 包提供了一个异常方便的协作通道。 后期基于composer演化出来的框架，有 Laravel 和 Symfony。 本文也是基于composer创建一个自己的MVC框架。

### MVC框架路由的思考

[](#mvc框架路由的思考)

使用composer初始化项目

```
    composer init
```

> 使用阿里云的composer仓库

```
# 在json文件最后添加
"repositories": {
        "packagist": {
            "type": "composer",
            "url": "https://mirrors.aliyun.com/composer/"
        }
    }
```

安装composer

```
composer install
```

开始构建我们自己的路由，路由的选择可以参考github的[搜索结果](https://github.com/search?l=PHP&o=desc&q=router&ref=searchresults&s=stars&type=Repositories&utf8=%E2%9C%93)

本教程我们选择简单易上手的[noahbuscher/macaw](https://github.com/noahbuscher/macaw),大家可以去官网上看看。

> 编辑composer.json文件

```
# 安装noahbuscher/macaw
require: {
    "noahbuscher/macaw": "dev-master"
}
# 更新composer
composer update
```

使用插件

```
# 项目目录下新建public/index.php
# 代码如下
 原理梗概 当php引入composer的自动加载文件后，composer会在内存维护一个全量命名空间，类名到文件名的数组。这样我们在使用某个插件功能的时候，会在数组中找到它。 当Macaw::get，使用get的时候，会由Macaw的一个\_\_callstatic() 接收，这个函数接受两个参数，$method 和 $params，前者是具体的 function 名称，在这里就是 get，后者是这次调用传递的参数，即 Macaw::get('/',function(){...}) 中的两个参数，一个是路径，一个是函数处理。 \_\_callstatic() 做的事情就是分别将目标URL（即 ‘/’）、HTTP方法（即 GET）和回调代码压入 $routes、$methods 和 $callbacks 三个 Macaw 类的静态成员变量（数组）中。 最后由Macaw::dispatch()的方法处理。不能直接匹配到的将利用正则进行匹配。

### 设计框架的骨骼

[](#设计框架的骨骼)

终于我们的框架实现了第一步，已经能通过路由访问不同的页面了。 下面我们要实现的是搭建起来自己的MVC结构。 这就说到了PHP框架另外的价值：

1. 确立开发规范以便于多人协作
2. 使用 ORM、模板引擎 等工具以提高开发效率。

开始编码了～～

```
# 新建app文件夹在项目目录，添加controllers、models、views三个文件夹。
# controllers增加两个文件BaseController.php HomeController.php
# BaseController.php设置一些继承的属性
 配置数据库，实现model文件

```
# 新建文件 Data.php,这就是操作数据库的model文件。以后介绍使用ORM操作数据库
# 编辑文件，请查看GitHub内容。
# 修改HomeController.php
getAll($sql);
        $db->p($list);

    }
}
#重新加载类
composer dump-autoload
```

```
# 数据库的代码
# 创建你自己的数据库。修改你的配置，Data.php文件
CREATE TABLE `articles` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(255) DEFAULT NULL,
  `content` longtext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `articles` (`id`, `title`, `content`)
VALUES
(1,'标题1','内容111呀~~参与用户调研，有机会获得200元无门槛代金券！~ O(∩_∩)O'),
(2,'标题2','内容222呀~~联系我有优惠!~ O(∩_∩)O');
# 打开浏览器，输入网址 127.0.0.1:5000
# 看到打印内容，加载成功。现在已经和数据库连通了。
```

现在MVC的M和C都已经实现了。我们现在实现view

```
# 添加view目录下的home.php
 $value) {
    echo "". $value['title'].'';
    echo "". $value['content'].'';
}
# 引入文件到控制器
getAll($sql);
        require_once VINC_PATH . '/../app/views/home.php';
    }
}
# 刷新浏览器
```

MVC框架本质是一种管理代码的格式。现在几乎所有人都是通过学习某个框架来了解 MVC 的。但是一旦脱离了框架，一个页面也写不出。我认为，框架再成熟，也离不开PHP的基本原理和哲学。不管哪种语言都是为了让人脑这样的超低 RAM 的计算机能够制造出远超人脑 RAM 的大型软件。一个框架驱动程序做的时区是这样的，入口文件通过路由调用控制器，控制器调用模型，模型和数据库交互，返回数据给控制器，控制器在调用视图，视图把数据装载进视图显示给用户，流程结束。

### 使用ORM提高框架的效率

[](#使用orm提高框架的效率)

本篇集成一个 ORM Composer包 ORM 就是'Object Relational Mapping'=对象关系映射。ORM的出现是为了帮我们把对数据库的操作变得更加地方便。

```
# 编辑composer.json
    "require": {
        "php": ">=7.1.3",
        "noahbuscher/macaw": "dev-master",
        "illuminate/database": "*",
        "filp/whoops": "*"
    }
    # illuminate/database这个是Laravel的ORM 包。我试用了几个著名的ORM，发现还是 Laravel 的 Eloquent 好用！filp/whoops 是我们的错误提示组件包。也是laravel正在使用的。
# 编辑view/home.php

        欢迎使用!

```

```
# 编辑BaseController.php
view;
        if ($view instanceof View) {
            extract($view->data);
            require $view->view;
        }
    }
}

# 编辑HomeController.php
view = View::make('home')->with('article', Article::first())->withTitle('一个优雅简单的PHP框架--vinc')->withContent('vinc框架');
    }
}

# 编辑models/View.php
view = $view;
    }
    public static function make($viewName = null)
    {
        if (!$viewName) {
            throw new InvalidArgumentException("视图名称不能为空！");
        } else {
            $viewFilePath = self::getFilePath($viewName);
            if (is_file($viewFilePath)) {
                return new View($viewFilePath);
            } else {
                throw new UnexpectedValueException("视图文件不存在！");
            }
        }
    }
    public function with($key, $value = null)
    {
        $this->data[$key] = $value;
        return $this;
    }
    private static function getFilePath($viewName)
    {
        $filePath = str_replace('.', '/', $viewName);
        return VINC_PATH . '/../app/views/' . $filePath . '.php';
    }
    public function __call($method, $parameters)
    {
        if (starts_with($method, 'with')) {
            return $this->with(snake_case(substr($method, 4)), $parameters[0]);
        }
        throw new BadMethodCallException("方法 [$method] 不存在！.");
    }
}

# 编辑Article.php
mail;
        if ($mail instanceof Mail) {
            $mailer = new Nette\Mail\SmtpMailer($mail->config);
            $mailer->send($mail);
        }
# 调用发送邮件,发送邮件需要邮箱开通smtp
$this->mail = Mail::to(['yourname@gmail.com', 'yourname@qq.com'])->from('yourname ')->title('this is your good news!')->content('Hello~~');
```

### 缓存服务器Redis，怎么能少了你呢

[](#缓存服务器redis怎么能少了你呢)

Redis是一个高性能的 'key-value' 数据库，其'value'支持 'String'、'Map(Hash)'、'list'、'set' 和 'sorted sets'，中文翻译为 字符串、字典（哈希，在'世界上最好的语言PHP' 中属于 '数组' 的一部分）、列表、集合和有序集合。我们可以用 Redis 作为高速缓存，存放系统经常需要访问的数据。相比使用文件作为缓存，Redis 拥有更高的性能、更好地可维护性和更强大的操作 API。

> 我们来扩展redis功能

```
# 修改composer.json 添加
    "require": {
        "php": ">=7.1.3",
        "noahbuscher/macaw": "dev-master",
        "illuminate/database": "*",
        "filp/whoops": "*",
        "nette/mail": "*",
        "predis/predis": "*"
    }
# 装载插件
composer update

# 引入插件，增加app/models/Redis.php
# 修改HomeController.php
        Redis::set('key', 'value', 5, 's');
        echo Redis::get('key');
# 运行一次后将上面一行注释掉,不断刷新看'value'是否会在设定的时间结束后从页面上消失。
```

*我们的MVC框架搭建到此基本完善，后续还有很多好的插件，我会在这里进行更新，相关的模块如何使用，我会开设专门的板块讲解，谢谢您的耐心查看和陪伴！*

### 把门面做出来，让变美更简单

[](#把门面做出来让变美更简单)

使用我们的框架做一个程序 ...待续

### 参考文档列表

[](#参考文档列表)

> 1.[Pinatra/Pinatra](https://github.com/Pinatra/Pinatra)2.[noahbuscher/macaw](https://github.com/noahbuscher/macaw)3.[Illuminate/Database](https://github.com/Illuminate/Database/)4.[filp/whoops](https://github.com/filp/whoops)5.[nrk/predis](https://github.com/nrk/predis)6.[nette/mail](https://packagist.org/packages/nette/mail)

### 如果本文对你有帮助，谢谢您的支持

[](#如果本文对你有帮助谢谢您的支持)

###  Health Score

24

—

LowBetter than 32% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

2467d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/55afa6795f6a896ffef67bb988f930229a882a6e50a57d92181af8b16c28c2c2?d=identicon)[dkkevincheng](/maintainers/dkkevincheng)

---

Top Contributors

[![dkkevincheng](https://avatars.githubusercontent.com/u/30012525?v=4)](https://github.com/dkkevincheng "dkkevincheng (6 commits)")

### Embed Badge

![Health badge](/badges/dkkevincheng-vinc/health.svg)

```
[![Health](https://phpackages.com/badges/dkkevincheng-vinc/health.svg)](https://phpackages.com/packages/dkkevincheng-vinc)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
