検索
ホームページバックエンド開発PHPチュートリアルComposer を使用して独自の 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 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事はjuejinで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
PHPの現在のステータス:Web開発動向を見てくださいPHPの現在のステータス:Web開発動向を見てくださいApr 13, 2025 am 12:20 AM

PHPは、現代のWeb開発、特にコンテンツ管理とeコマースプラットフォームで依然として重要です。 1)PHPには、LaravelやSymfonyなどの豊富なエコシステムと強力なフレームワークサポートがあります。 2)パフォーマンスの最適化は、Opcacheとnginxを通じて達成できます。 3)PHP8.0は、パフォーマンスを改善するためにJITコンパイラを導入します。 4)クラウドネイティブアプリケーションは、DockerおよびKubernetesを介して展開され、柔軟性とスケーラビリティを向上させます。

PHP対その他の言語:比較PHP対その他の言語:比較Apr 13, 2025 am 12:19 AM

PHPは、特に迅速な開発や動的なコンテンツの処理に適していますが、データサイエンスとエンタープライズレベルのアプリケーションには良くありません。 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サーバーとRich Functionライブラリを提供します。 2。Pythonは、簡潔な構文と強力な標準ライブラリを備えたデータサイエンスと機械学習に適しています。選択するときは、プロジェクトの要件に基づいて決定する必要があります。

PHP:Web開発の重要な言語PHP:Web開発の重要な言語Apr 13, 2025 am 12:08 AM

PHPは、サーバー側で広く使用されているスクリプト言語で、特にWeb開発に適しています。 1.PHPは、HTMLを埋め込み、HTTP要求と応答を処理し、さまざまなデータベースをサポートできます。 2.PHPは、ダイナミックWebコンテンツ、プロセスフォームデータ、アクセスデータベースなどを生成するために使用され、強力なコミュニティサポートとオープンソースリソースを備えています。 3。PHPは解釈された言語であり、実行プロセスには語彙分析、文法分析、編集、実行が含まれます。 4.PHPは、ユーザー登録システムなどの高度なアプリケーションについてMySQLと組み合わせることができます。 5。PHPをデバッグするときは、error_reporting()やvar_dump()などの関数を使用できます。 6. PHPコードを最適化して、キャッシュメカニズムを使用し、データベースクエリを最適化し、組み込み関数を使用します。 7

PHP:多くのウェブサイトの基礎PHP:多くのウェブサイトの基礎Apr 13, 2025 am 12:07 AM

PHPが多くのWebサイトよりも優先テクノロジースタックである理由には、その使いやすさ、強力なコミュニティサポート、広範な使用が含まれます。 1)初心者に適した学習と使用が簡単です。 2)巨大な開発者コミュニティと豊富なリソースを持っています。 3)WordPress、Drupal、その他のプラットフォームで広く使用されています。 4)Webサーバーとしっかりと統合して、開発の展開を簡素化します。

誇大広告を超えて:今日のPHPの役割の評価誇大広告を超えて:今日のPHPの役割の評価Apr 12, 2025 am 12:17 AM

PHPは、特にWeb開発の分野で、最新のプログラミングで強力で広く使用されているツールのままです。 1)PHPは使いやすく、データベースとシームレスに統合されており、多くの開発者にとって最初の選択肢です。 2)動的コンテンツ生成とオブジェクト指向プログラミングをサポートし、Webサイトを迅速に作成および保守するのに適しています。 3)PHPのパフォーマンスは、データベースクエリをキャッシュおよび最適化することで改善でき、その広範なコミュニティと豊富なエコシステムにより、今日のテクノロジースタックでは依然として重要になります。

PHPの弱い参照は何ですか、そしていつ有用ですか?PHPの弱い参照は何ですか、そしていつ有用ですか?Apr 12, 2025 am 12:13 AM

PHPでは、弱い参照クラスを通じて弱い参照が実装され、ガベージコレクターがオブジェクトの回収を妨げません。弱い参照は、キャッシュシステムやイベントリスナーなどのシナリオに適しています。オブジェクトの生存を保証することはできず、ごみ収集が遅れる可能性があることに注意する必要があります。

PHPで__invoke Magicメソッドを説明してください。PHPで__invoke Magicメソッドを説明してください。Apr 12, 2025 am 12:07 AM

\ _ \ _ Invokeメソッドを使用すると、オブジェクトを関数のように呼び出すことができます。 1。オブジェクトを呼び出すことができるように\ _ \ _呼び出しメソッドを定義します。 2。$ obj(...)構文を使用すると、PHPは\ _ \ _ Invokeメソッドを実行します。 3。ロギングや計算機、コードの柔軟性の向上、読みやすさなどのシナリオに適しています。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。