file
我为你们准备了一个富有挑战性的事情。接下来你们将以 无 框架的方式开启一个项目之旅。
首先声明, 这篇并非又臭又长的反框架裹脚布文章。也不是推销 非原创 思想 。毕竟, 我们还将在接下来的开发之旅中使用其他框架开发者编写的辅助包。我对这个领域的创新也是持无可非议的态度。
这无关他人,而是关乎己身。作为一名开发者,它将有机会让你成长。
也许无框架开发令你受益匪浅的地方就是,可以从底层运作的层面中汲取丰富的知识。抛却依赖神奇的,帮你处理无法调试和无法真正理解的东西的框架,你将清楚的看到这一切是如何发生的。
很有可能下一份工作中,你并不能随心所以地选择框架开拓新项目。现实就是,在很多高价值,关键业务的 PHP 工作中均使用现有应用。 并且该应用程序是否构建在当前令人舒爽的 Laravel 或 Symfony 等流行框架中,亦或是陈旧过时的 CodeIgniter 或者 FuelPHP 中,更有甚者它可能广泛出现在令人沮丧的 “面向包含体系结构” 的传统的 PHP 应用 之中,所以无框架开发会在将来你所面临的任何 PHP 项目中助你一臂之力。
上古时代, 因为 某些系统 不得不解释分发 HTTP 请求,发送 HTTP 响应,管理依赖关系,无框架开发就是痛苦的鏖战。缺乏行业标准必然意味着,框架中的这些组件高度耦合 。如果你从无框架开始,你终将难逃自建框架的命运。
时至今日,幸亏有 PHP-FIG 完成所有的自动加载和交互工作,无框架开发并非让你白手起家。各色供应商都有这么多优秀的可交互的软件包。把他们组合起来容易得超乎你的想象!
PHP 是如何工作的?
在做其他事之前,搞清楚 PHP 如何与外界沟通是非常重要的。
PHP 以请求 / 响应为周期运行服务端应用程序。与你的应用程序的每一次交互——无论是来自浏览器,命令行还是 REST API ——都是作为请求进入应用程序的。 当接收到请求以后:
程序开始启动;
开始处理请求;
产生响应;
接着,响应返回给产生请求的相应客户端;
最后程序关闭。
每一个 请求都在重复以上的交互。
前端控制器
用这些知识把自己武装起来以后,就可以先从我们的前端控制器开始编写程序了。前端控制器是一个 PHP 文件,它处理程序的每一个请求。控制器是请求进入程序后遇到的第一个 PHP 文件,并且(本质上)也是响应走出你应用程序所经过的最后一个文件。
我们使用经典的 Hello, world! 作为例子来确保所有东西都正确连接上,这个例子由 PHP 的内置服务器 驱动。在你开始这样做之前,请确保你已经安装了 PHP7.1 或者更高版本。
创建一个含有 public 目录的项目,然后在该目录里面创建一个index.php 文件,文件里面写入如下代码:
declare(strict_types=1);
echo 'Hello, world!';
注意,这里我们声明了使用严格模式 —— 作为最佳实践,你应该在应用程序的 每个 PHP 文件的开头 都这样做。因为对从你后面来的开发者来说类型提示对 调试和清晰的交流意图很重要 。
使用命令行(比如 macOS 的终端)切换到你的项目目录并启动 PHP 的内置服务器。
php -S localhost:8080 -t public/
现在,在浏览器中打开 http://localhost:8080/ 。是不是成功地看到了 "Hello, world!" 输出?
很好。接下来我们可以开始进入正题了!
自动加载与第三方包
当你第一次使用 PHP 时,你可能会在你的程序中使用 includes 或 requires 语句来从其他 PHP 文件导入功能和配置。 通常,我们会避免这么干,因为这会使得其他人更难以遵循你的代码路径和理解依赖在哪里。这让调试成为了一个 真正的 噩梦。
解决办法是使用自动加载(autoloading)。 自动加载的意思是:当你的程序需要使用一个类, PHP 在调用该类的时候知道去哪里找到并加载它。虽然从 PHP 5 开始就可以使用这个特性了, 但是得益于 PSR-0 ( 自动加载标准,后来被 PSR-4 取代),其使用率才开始有真正的提升。
我们可以编写自己的自动加载器来完成任务,但是由于我们将要使用的管理第三方依赖的 Composer 已经包含了一个完美的可用的自动加载器,那我们用它就行了。
确保你已经在你的系统上 安装 了 Composer。然后为此项目初始化 Composer:
composer init
这条命令通过交互式引导你创建 composer.json 配置文件。 一旦文件创建好了,我们就可以在编辑器中打开它然后向里面写入 autoload 字段,使他看起来像这个样子(这确保了自动加载器知道从哪里找到我们项目中的类):
{
"name": "kevinsmith/no-framework",
"description": "An example of a modern PHP application bootstrapped without a framework.",
"type": "project",
"require": {},
"autoload": {
"psr-4": {
"ExampleApp\\": "src/"
}
}
}