搜索
首页后端开发php教程用Composer构建属于你的PHP框架

用Composer构建属于你的PHP框架

May 02, 2020 am 10:09 AM
php框架

为什么要构建自己的 PHP 框架?

现在的 PHP 框架很多,当然不止 PHP ,即使是其他编程语言也有很多框架,这篇文章讲 PHP 框架构建是因为我对 PHP 的生态最为熟悉,但这个方法同样也适用于其他编程语言框架的构建。

框架是为了提升我们的应用开发效率,市面上有很多开源免费的框架给我们使用,我们尽可以拿来用,为什么还要自己构建一个自己的框架呢?原因就在于市面上的开源框架,是给大部分人用的,给通用项目用的,作为框架的开发者是不知道自己的框架使用者的具体业务的,所以开源框架一定是满足大部分人的需求,而且力求能够为开发者提供所有可能用到的功能。

但是对于一个商业项目或者是一个你自己要做的项目也许只能用到框架的很少一部分功能,或者是框架给你提供的东西并不是最符合你自己的需求的,你使用了框架的一部分功能,另一部分根本没用,这样使用框架首先是性能上的损失,一些你根本用不到的功能却要降低你应用的性能显然不合适的。再就是也许框架提供的功能不是你想要的,或者这个功能这个框架提供的并不是符合你需求的,又或者要使用这部分功能必须按照框架开发者制定的规范来使用,这个规范并符合你的开发哲学。

从哪开始?

各种现代编程语言都有自己的包管理工具,PHP 就是 composer ,利用它我们就可以构建属于自己的框架了,并能很好的组织我们的框架。

怎么开始?

我们该怎么开始构建我们自己的框架呢?从零开始吗?这个问题没有标准答案,如果你要做的项目要求很严格,从底层开始就要保证项目架构的最稳定可控,那么建议你从零开始。如果要求不是非常严格那么我们就从那些开发一个应用最基本需要的功能开始,这样的功能谁提供呢?PHP 有很多微框架,这些框架提供开发一个应用最基础的功能,我们可以从这里开始。

首先我们通过 composer init 初始化一个项目:

{
    "name": "dongm2ez/m2ez-framework",
    "description": "a dongm2ez's framework",
    "keywords": ["framework", "m2ez-framework"],
    "license": "MIT",
    "authors": [
        {
            "name": "dongm2ez",
            "email": "dongm2ez@163.com"
        }
    ],
    "require": {}
}

复制代码这就是我得到的一个 composer.json 的描述文件,现在我们就从这里开始。我的目标是构建一个最符合我开发习惯的框架,让我的开发效率最高。

我选择 Slim 框架作为我的框架基础框架,这是一个微框架,我喜欢它,它足够简单,提供了 web 开发 和 API 开发最基础的功能,而且还有一个原因开发这个框架的作者写了一本名为《Modern PHP》的书,这本书颠覆了我对 PHP 这个语言的认知,开始喜欢并乐于使用它。

在引入这个框架之前我还要对 PHP 版本做个限制,从我使用 PHP 从 5.2 开始到现在,PHP 已经发展到 PHP 7.2 了,但是我不想再去使用低版本的 PHP,一个是 PHP 低版本马上将失去官方的支付,另一个是一些 PHP 的新特性我不能使用,而且低版本的性能也是不好的。所以我要将我的框架限制在 PHP 7.0 以上,同时我希望我的框架对中文有更好的支持。

那么我将更新我的框架 composer.json 文件:

{
    "name": "dongm2ez/m2ez-framework",
    "description": "a dongm2ez's framework",
    "keywords": ["framework", "m2ez-framework"],
    "license": "MIT",
    "authors": [
        {
            "name": "dongm2ez",
            "email": "dongm2ez@163.com"
        }
    ],
    "require": {
        "php": ">=7.0.0",
        "ext-mbstring": "*",
        "slim/slim": "^3.0"
    }
}

复制代码这样我就获得了一个最基础的我的框架版本,但是我还没完成,因为我们没有定义我的框架目录结构。我觉得 laravel 框架的目录划分是挺让我喜欢的,但我又不完全喜欢 laravel 的目录结构,我需要对它进行改造。

├── app

│   ├── Helpers.php

│   ├── Http

│   │   └── Controllers

│   └── Models

├── composer.json

└── tests复制代码我这样设置我的目录结构,并更新我的 composer.json:

{
    "name": "dongm2ez/m2ez-framework",
    "description": "a dongm2ez's framework",
    "keywords": ["framework", "m2ez-framework"],
    "license": "MIT",
    "type": "project",
    "authors": [
        {
            "name": "dongm2ez",
            "email": "dongm2ez@163.com"
        }
    ],
    "require": {
        "php": ">=7.0.0",
        "slim/slim": "^3.0"
    },
    "require-dev": {
        "phpunit/phpunit": "~6.0"
    },
    "autoload": {
        "classmap": [
            "app/Models"
        ],
        "psr-4": {
            "App\\": "app/"
        },
        "files": [
            "app/Helpers.php"
        ]
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
}

复制代码这样的框架可以访问吗,显然是不行的,我们还要加一些东西让我们的框架真正可以跑起来,然后在来迭代它。

├── app

│   ├── Helpers.php

│   ├── Http

│   │   └── Controllers

│   └── Models

├── bootstrap

│   ├── app.php

│   └── autoload.php

├── composer.json

├── config

├── public

│   └── index.php

├── routers

└── tests复制代码我们将目录结构改造成这样,并编写一些启动框架的代码到相应的文件

// public/index.php

<?php
require __DIR__.&#39;/../bootstrap/autoload.php&#39;;
$app = require_once __DIR__.&#39;/../bootstrap/app.php&#39;;
$app->run();
// bootstrap/app.php
<?php
$app = new \Slim\App;
return $app;
// bootstrap/autoload.php
<?php
define(&#39;M2EZ_START&#39;, microtime(true));
require __DIR__.&#39;/../vendor/autoload.php&#39;;

复制代码然后运行 composer install 安装框架的依赖包,安装完成后我们的目录中就会多出一个 vendor 的目录和 composer.lock 的文件,此时运行 php -S 0.0.0.0:8080 -t public public/index.php 利用 PHP 自带的 web 服务器进行测试,为了这个命令更简单使用,我们可以将这个命令加到 composer.json 的 script 中。

此时访问 127.0.0.1:8080 或 localhost:8080 就可以看到如下的页面:

file

这说明框架正确启动了,那么我们怎么确定框架工作正常呢,这里有个简单方法:

<?php
use Slim\Http\Request;
use Slim\Http\Response;
require __DIR__.&#39;/../bootstrap/autoload.php&#39;;
$app = require_once __DIR__.&#39;/../bootstrap/app.php&#39;;
$app->get(&#39;/hello/{name}&#39;, function (Request $request, Response $response) {
    $name = $request->getAttribute(&#39;name&#39;);
    $response->getBody()->write("Hello, $name");
    return $response;
});
$app->run();

复制代码对 public/index.php 的代码进行修改,此时访问 http://localhost:8080/hello/dongm2ez,那么我们就会看到:

file

测试是成功了,但是我们不能把路由和逻辑都写到 index.php 文件里,因此我们需要代码更好的组织。要让我们的目录规划发挥正在的作用。

为了单独管理路由,我将路由单独写在 routers 文件夹中,在文件夹中我们新建两个 PHP 脚本文件,然后在 public/index.php 中加入两行代码:

<?php
require __DIR__ . &#39;/../bootstrap/autoload.php&#39;;
$app = require_once __DIR__ . &#39;/../bootstrap/app.php&#39;;
require __DIR__ . &#39;/../routers/web.php&#39;;
require __DIR__ . &#39;/../routers/api.php&#39;;
$app->run();

复制代码变成这样,这样我就可以单独管理 API 和 WEB 项目的路由了,如果有其他路由就也可以 require 更多路由。

<?php
$app->get(&#39;/&#39;, &#39;\App\Http\Controllers\WelcomeController:index&#39;);复制代码而我们的控制器长什么样呢,是这个样子的:
<?php
namespace App\Http\Controllers;
use Slim\Http\Request;
use Slim\Http\Response;
class WelcomeController extends Controller
{
    public function index(Request $request, Response $response)
    {
        $response->getBody()->write("Hello, world");
        return $response;
    }
}

复制代码我们知道在现代化的框架中,容器会让我们很方便,我们的基础框架 Slim 提供一个容器的实现,当然你也可以使用其他的第三方的,那么这显然是我们想要的结果,不是只能使用框架提供的,我们可以随时换掉框架的功能,换成我们想要的同样功能组件。

使用也很简单,在 app.php 文件中初始化 Slim 框架时将容器实例传递给它就可以了。

<?php
$container = new \Slim\Container;
$app = new \Slim\App($container);
return $app;

复制代码还记得上面那个控制器继承的基类控制器吗,那也是我自己写的,里面可以做一些所有控制器都有可能用的的操作封装。比如我为了更方便的使用容器,我在基类里初始化了一个容器实例。

<?php
namespace App\Http\Controllers;
use Interop\Container\ContainerInterface;
abstract class Controller
{
    protected $ci;
    public function __construct(ContainerInterface $ci)
    {
        $this->ci = $ci;
    }
}

复制代码现在我已经有了 路由功能,有了控制器功能,还有请求响应的操作,那么作为一个完整的框架那么必须有访问数据库的方法。

我很喜欢 Laravel 提供的数据库 ORM 组件,那么我就决定使用它了,执行 composer require illuminate/database "~5.5",我选择了最新的 Laravel 长期支持版 ORM 。

我们需要此时在 config 文件夹中新添加一个文件 databases.php 文件:

<?php
return [
    &#39;settings&#39; => [
        &#39;db&#39; => [
            &#39;driver&#39; => &#39;mysql&#39;,
            &#39;host&#39; => &#39;localhost&#39;,
            &#39;database&#39; => &#39;database&#39;,
            &#39;username&#39; => &#39;user&#39;,
            &#39;password&#39; => &#39;password&#39;,
            &#39;charset&#39;   => &#39;utf8&#39;,
            &#39;collation&#39; => &#39;utf8_unicode_ci&#39;,
            &#39;prefix&#39;    => &#39;&#39;,
        ]
    ],
];

复制代码然后修改 public/index.php:

<?php
require __DIR__ . &#39;/../bootstrap/autoload.php&#39;;
$config = require __DIR__ . &#39;/../config/databases.php&#39;;
$app = require_once __DIR__ . &#39;/../bootstrap/app.php&#39;;
require __DIR__ . &#39;/../routers/web.php&#39;;
require __DIR__ . &#39;/../routers/api.php&#39;;
$app->run();

复制代码修改 bootstrap/app.php:

<?php
$container = new \Slim\Container($config);
$app = new \Slim\App($container);
// Service factory for the ORM
$container[&#39;db&#39;] = function ($container) {
    $capsule = new \Illuminate\Database\Capsule\Manager;
    $capsule->addConnection($container[&#39;settings&#39;][&#39;db&#39;]);
    $capsule->setAsGlobal();
    $capsule->bootEloquent();
    return $capsule;
};
return $app;

复制代码然后我们就可以在控制器中使用 ORM 功能了。

<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Database\DatabaseManager;
use Illuminate\Support\Facades\DB;
use Interop\Container\ContainerInterface;
use Slim\Http\Request;
use Slim\Http\Response;
class WelcomeController extends Controller
{
    public function index(Request $request, Response $response)
    {
        /** @var DatabaseManager $db */
        $db = $this->ci->get(&#39;db&#39;);
        $user = $db->table("user")->first();
        var_dump($user);
        $response->getBody()->write("Hello, world");
        return $response;
    }
}

复制代码那么此时这个框架已经是一个可以开发 API 功能的框架了,如果要开发 Web 站我可能还需要加入渲染模板组件,无论是 twig、Smarty、Haml 还是 Blade,全都看你的喜好了。当然我觉得我做到这里就可以了,够我用了,因为对于前端我更喜欢用 React 或者是 Vue 去实现它。

需要更简便的操作 session、cookie 那么我们也可以添加相应的组件,各种已经有的框架了都提供这样的组件,看看你更喜欢哪一个了,现在你的框架你做主,你想添加什么就可以添加什么组件,经过这样的定制的框架一定是最符合你开发需求的。

我这里只是对已有的组件进行了配置组装,一旦哪天你发现所有的开源组件都满足不了你的需求的时候,因为你对你的框架了解,你可以自己造个轮子给自己的框架用,如果你写的好那么你也会创造出一个极好用的框架,现在最流行的 PHP 框架,你可以看看它的 composer.json 文件,它就是在前人的基础上进行开发维护的,已经有的功能他拿来直接用,觉得别人做的不完善的地方自己造一个轮子给大家用。

而且我这里也没有用到太多的设计模式,你还可以改造你的框架,利用PHP的魔术方法,反射,SPL 等等让你的框架更好,更容易扩展,更容易配置。

总结

框架很神秘吗?看过这篇文章我相信你不会这样觉得了。

造一个框架很难吗,是的很难,因为从 0 到 1 任何事都难,但是我们现在还需要从 0 到 1 吗,基本不需要了!站在巨人身上做事更容易,而且要记住,任何事只有行动起来你就会发现尝试比踌躇不前更好,从小处开始,做小事,有一天这个小事就变成了大事。不积跬步无以至千里。

Laravel 为什么流行,因为作者本是一名 .net 开发者,在使用 CI 框架时萌生了想法要做一个更简洁、灵活的框架,他的思想真的很先进吗,不一定的,其他开发语言早就有了 Laravel 中的功能,它只是在 PHP 中实现了它们。

以上例子其实告诉我们,不要给自己贴标签,人生不设限,你不是 PHP 程序员,你就是开发者,任何开发相关的东西我们都该去了解和掌握,标签只能别人给你贴,不要自己给自己贴。

推荐教程:《PHP教程

以上是用Composer构建属于你的PHP框架的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:juejin。如有侵权,请联系admin@php.cn删除
PHP行动:现实世界中的示例和应用程序PHP行动:现实世界中的示例和应用程序Apr 14, 2025 am 12:19 AM

PHP在电子商务、内容管理系统和API开发中广泛应用。1)电子商务:用于购物车功能和支付处理。2)内容管理系统:用于动态内容生成和用户管理。3)API开发:用于RESTfulAPI开发和API安全性。通过性能优化和最佳实践,PHP应用的效率和可维护性得以提升。

PHP:轻松创建交互式Web内容PHP:轻松创建交互式Web内容Apr 14, 2025 am 12:15 AM

PHP可以轻松创建互动网页内容。1)通过嵌入HTML动态生成内容,根据用户输入或数据库数据实时展示。2)处理表单提交并生成动态输出,确保使用htmlspecialchars防XSS。3)结合MySQL创建用户注册系统,使用password_hash和预处理语句增强安全性。掌握这些技巧将提升Web开发效率。

PHP和Python:比较两种流行的编程语言PHP和Python:比较两种流行的编程语言Apr 14, 2025 am 12:13 AM

PHP和Python各有优势,选择依据项目需求。1.PHP适合web开发,尤其快速开发和维护网站。2.Python适用于数据科学、机器学习和人工智能,语法简洁,适合初学者。

PHP的持久相关性:它还活着吗?PHP的持久相关性:它还活着吗?Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在现代编程领域中依然占据重要地位。1)PHP的简单易学和强大社区支持使其在Web开发中广泛应用;2)其灵活性和稳定性使其在处理Web表单、数据库操作和文件处理等方面表现出色;3)PHP不断进化和优化,适用于初学者和经验丰富的开发者。

PHP的当前状态:查看网络开发趋势PHP的当前状态:查看网络开发趋势Apr 13, 2025 am 12:20 AM

PHP在现代Web开发中仍然重要,尤其在内容管理和电子商务平台。1)PHP拥有丰富的生态系统和强大框架支持,如Laravel和Symfony。2)性能优化可通过OPcache和Nginx实现。3)PHP8.0引入JIT编译器,提升性能。4)云原生应用通过Docker和Kubernetes部署,提高灵活性和可扩展性。

PHP与其他语言:比较PHP与其他语言:比较Apr 13, 2025 am 12:19 AM

PHP适合web开发,特别是在快速开发和处理动态内容方面表现出色,但不擅长数据科学和企业级应用。与Python相比,PHP在web开发中更具优势,但在数据科学领域不如Python;与Java相比,PHP在企业级应用中表现较差,但在web开发中更灵活;与JavaScript相比,PHP在后端开发中更简洁,但在前端开发中不如JavaScript。

PHP与Python:核心功能PHP与Python:核心功能Apr 13, 2025 am 12:16 AM

PHP和Python各有优势,适合不同场景。1.PHP适用于web开发,提供内置web服务器和丰富函数库。2.Python适合数据科学和机器学习,语法简洁且有强大标准库。选择时应根据项目需求决定。

PHP:网络开发的关键语言PHP:网络开发的关键语言Apr 13, 2025 am 12:08 AM

PHP是一种广泛应用于服务器端的脚本语言,特别适合web开发。1.PHP可以嵌入HTML,处理HTTP请求和响应,支持多种数据库。2.PHP用于生成动态网页内容,处理表单数据,访问数据库等,具有强大的社区支持和开源资源。3.PHP是解释型语言,执行过程包括词法分析、语法分析、编译和执行。4.PHP可以与MySQL结合用于用户注册系统等高级应用。5.调试PHP时,可使用error_reporting()和var_dump()等函数。6.优化PHP代码可通过缓存机制、优化数据库查询和使用内置函数。7

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中