utopia-php/framework

一个简单、轻量且高级的PHP HTTP框架

1.0.2 2024-09-10 09:04 UTC

This package is auto-updated.

Last update: 2024-09-10 10:44:36 UTC


README

Logo

Build Status Total Downloads Discord

Utopia HTTP是一个基于PHP MVC的框架,具有专业、简单、高级和安全的Web开发所必需的最小功能。此库由Appwrite团队维护。

Utopia HTTP几乎无依赖。任何额外的功能,如认证或缓存,都作为独立模型提供,以保持框架核心的清洁、轻量且易于学习。

入门指南

使用Composer安装

composer require utopia-php/http

src/server.php中初始化您的第一个应用程序

require_once __DIR__.'/../vendor/autoload.php';

use Utopia\DI\Container;
use Utopia\DI\Dependency;
use Utopia\Http\Http;
use Utopia\Http\Request;
use Utopia\Http\Response;
use Utopia\Http\Adapter\FPM\Server;

// Creating the dependency injection container
$container = new Container();

// Adding a user dependency to the container
$user = new Dependency();
$user
    ->setName('user')
    ->inject('request') // We can insert and use other injections as well
    ->setCallback(fn (Request $request) => $request->getHeader('x-user-id', 'John Doe'));

$container->add($user);
    
// Defining Route    
Http::get('/hello-world') 
    ->inject('request')  // Auto-injected each request
    ->inject('response') // Auto-injected each request
    ->inject('user')
    ->action(
        function(Request $request, Response $response, string $user) {
            $response
              ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
              ->addHeader('Expires', '0')
              ->addHeader('Pragma', 'no-cache')
              ->json(['message' => 'Hello World', 'user' => $user]);
        }
    );

Http::setMode(Http::MODE_TYPE_PRODUCTION);

$http = new Http(new Server(), $container, 'America/New_York');
$http->start();

运行HTTP服务器

php -S localhost:8000 src/server.php 

发送HTTP请求

curl http://localhost:8000/hello-world

服务器适配器

此库支持服务器适配器,以便在任意的PHP环境中运行。您可以使用FPM或Swoole服务器。

使用PHP FPM服务器

use Utopia\DI\Container;
use Utopia\Http\Http;
use Utopia\Http\Response;
use Utopia\Http\Adapter\FPM\Server;

Http::get('/')
    ->inject('response')
    ->action(
        function(Response $response) {
            $response->send('Hello from PHP FPM');
        }
    );

$http = new Http(new Server(), new Container() 'America/New_York');
$http->start();

当使用PHP FPM时,您可以使用命令php -S localhost:80 src/server.php在本地运行HTTP服务器

使用Swoole服务器

use Utopia\DI\Container;
use Utopia\Http\Http;
use Utopia\Http\Request;
use Utopia\Http\Response;
use Utopia\Http\Adapter\Swoole\Server;

Http::get('/')
    ->inject('request')
    ->inject('response')
    ->action(
        function(Request $request, Response $response) {
            $response->send('Hello from Swoole');
        }
    );

$http = new Http(new Server('0.0.0.0', '80' , ['open_http2_protocol' => true]), new Container(), 'America/New_York');
$http->start();

当使用Swoole时,您可以使用命令php src/server.php在本地运行HTTP服务器,但需要安装Swoole。对于使用Docker的设置,请查看我们的示例应用程序

参数

参数用于从HTTP请求接收输入到端点操作。参数可以定义为URL参数或在具有JSON等结构的正文中定义。

每个参数都必须定义一个验证器。验证器是简单的类,用于验证输入并确保输入的安全性。您可以定义自己的验证器或使用内置验证器

使用参数定义端点

Http::get('/')
    ->param('name', 'World', new Text(256), 'Name to greet. Optional, max length 256.', true)
    ->inject('response')
    ->action(function(string $name, Response $response) {
        $response->send('Hello ' . $name);
    });

发送HTTP请求以确保参数正常工作

curl http://localhost:8000/hello-world
curl http://localhost:8000/hello-world?name=Utopia
curl http://localhost:8000/hello-world?name=Appwrite

始终建议使用params,而不是直接从请求资源中获取params或body。如果您故意这样做,请确保在获取此类原始输入后立即运行验证。

钩子

有三种类型的钩子

  • 初始化钩子在执行路由操作之前执行
  • 关闭钩子在路由操作完成后执行,但在应用程序关闭之前
  • 错误钩子在应用程序生命周期中的任何错误发生时执行

您可以为每个阶段提供多个钩子。如果您没有为钩子分配组,则默认情况下,钩子将适用于每个路由。如果为钩子定义了组,则它仅会在具有相同组名的动作的生命周期中运行。

Http::init()
    ->inject('request')
    ->action(function(Request $request) {
        \var_dump("Recieved: " . $request->getMethod() . ' ' . $request->getURI());
    });

Http::shutdown()
    ->inject('response')
    ->action(function(Response $response) {
        \var_dump('Responding with status code: ' . $response->getStatusCode());
    });

Http::error()
    ->inject('error')
    ->inject('response')
    ->action(function(\Throwable $error, Response $response) {
        $response
            ->setStatusCode(500)
            ->send('Error occurred ' . $error);
    });

钩子设计为在请求的生命周期中运行的行动。钩子应包含功能性逻辑。钩子不是设计来准备请求的依赖项或上下文的。对于此类用例,您应使用资源。

组允许您为多个端点定义共同的行为。

您可以从在端点上定义一个组开始。请注意,您还可以在单个端点上定义多个组。

Http::get('/v1/health')
    ->groups(['api', 'public'])
    ->inject('response')
    ->action(
        function(Response $response) {
            $response->send('OK');
        }
    );

现在,您可以定义仅适用于特定组的钩子。请记住,钩子也可以分配给多个组。

Http::init()
    ->groups(['api'])
    ->inject('request')
    ->inject('response')
    ->action(function(Request $request, Response $response) {
        $apiKey = $request->getHeader('x-api-key', '');

        if(empty($apiKey)) {
            $response
                ->setStatusCode(Response::STATUS_CODE_UNAUTHORIZED)
                ->send('API key missing.');
        }
    });

组设计为在请求的生命周期中运行的行动,这些请求到端点具有某些共同的逻辑。组允许您防止代码重复,并且设计为可以在您的源代码中的任何位置定义,以提供灵活性。

注入

注入允许您为数据库连接或发送请求的用户等请求准备依赖。对于每个请求都会创建一个新的资源实例。

我们使用容器来定义注入。

use Utopia\DI\Container;
use Utopia\DI\Dependency;

$container = new Container();

$timing = new Dependency();
$timing
    ->setName('timing')
    ->setCallback(fn () => \microtime(true));

$container->add($timing);

将资源注入到端点操作中。

Http::get('/')
    ->inject('timing')
    ->inject('response')
    ->action(function(float $timing, Response $response) {
        $response->send('Request Unix timestamp: ' . \strval($timing));
    });

将资源注入到钩子中。

Http::shutdown()
    ->inject('timing')
    ->action(function(float $timing) {
        $difference = \microtime(true) - $timing;
        \var_dump("Request took: " . $difference . " seconds");
    });

在高级场景中,资源也可以注入到其他资源或端点参数中。

资源旨在为请求准备依赖或上下文。资源不应用于执行功能逻辑或返回回调。对于此类用例,您应使用钩子。

要了解更多关于此库的架构和功能,请参阅更深入的入门指南

系统需求

Utopia HTTP 需要 PHP 8.1 或更高版本。我们建议尽可能使用最新版本的 PHP。

更多关于 Utopia

我们的生态系统支持其他旨在扩展 PHP Utopia HTTP 核心的轻量级 PHP 项目。

每个项目都专注于解决一个单一、非常简单的问题,您可以使用 composer 将它们中的任何一个包含到您的下一个项目中。

您可以在GitHub Utopia 组织中找到所有库。

贡献

所有代码贡献(包括具有提交访问权限的人的贡献)都必须通过拉取请求进行,并在合并之前由核心开发者批准。这是为了确保对所有代码进行适当审查。

分叉项目,创建功能分支,然后向我们发送拉取请求。

有关更多信息,请参阅贡献指南

对于安全问题,请通过电子邮件发送到[email protected],而不是在 GitHub 上发布公开问题。

版权和许可证

MIT 许可证 (MIT) http://www.opensource.org/licenses/mit-license.php