8.1 插件汇总

优质
小牛编辑
124浏览
2023-12-01

结构

  1. public 文件夹用于存放入口文件 index.php

写个 demo:

<?php

echo "你好,FanlyPHP";

使用 php -S localhost:1234 命令执行看看效果:

  1. 创建 composer.json 文件用于添加我们的第三方插件

用命令行 composer init 根据提示初始化 composer.json 内容:

{
    "name": "coding01/fanlyphp",
    "description": "The Coding01 Framework for PHP.",
    "type": "project",
    "license": "MIT",
    "authors": [
        {
            "name": "coding01",
            "email": "yemeishu@126.com"
        }
    ],
    "require": {}
}

composer install 就会多一个 vendor 文件夹用于存放第三方插件。

  1. 创建 app 文件夹用于存放我们的代码,和 Laravel 的结构相似。并引入进 composer.json,按 psr-4 自动加载。记得要执行下命令:composer dump-autoload

安装插件

下面我们一个个来分析这几个插件的使用。

league/container

A simple but powerful dependency injection container.

http://container.thephpleague.com/

这个插件主要会引入 DI Container,也是本文推荐的,而且 nikic/fast-route 也是 Lumen 使用的。

写个 demo

先创建一个service demo 类

<?php
/**
 * User: yemeishu
 * Date: 2018/6/30
 * Time: 下午5:37
 */
namespace App;

class ServiceDemo
{
    public function hello()
    {
        return "叶梅树的 service demo";
    }
}

index.php 引入 autoload.php,这样就可以自动发现 composer 第三方包。

<?php

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

$container = new League\Container\Container;

// add a service to the container
$container->add('service', 'App\ServiceDemo');

// retrieve the service from the container
$service = $container->get('service');
echo $service->hello();

$demo = new App\ServiceDemo();
echo $demo->hello();

执行结果:

可以看出利用 Containernew App\ServiceDemo(),效果一致。

league/route

Route is a fast routing/dispatcher package enabling you to build well designed performant web apps. At its core is Nikita Popov’s FastRoute package allowing this package to concentrate on the dispatch of your controllers.

http://route.thephpleague.com/

composer require league/route

根据官网的提示,还需要安装一个插件:

composer require zendframework/zend-diactoros

写个 demo

在上文例子的基础上,增加 route 的代码,具体看代码,比较简单:

<?php

use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

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

$container = new League\Container\Container;

// add a service to the container
$container->add('service', 'App\ServiceDemo');

// retrieve the service from the container
$service = $container->get('service');

$container->share('response', Zend\Diactoros\Response::class);
$container->share('request', function () {
    return Zend\Diactoros\ServerRequestFactory::fromGlobals(
        $_SERVER,
        $_GET,
        $_POST,
        $_COOKIE,
        $_FILES
    );
});

$container->share('emitter', Zend\Diactoros\Response\SapiEmitter::class);

$route = new League\Route\RouteCollection($container);

$route->map(
    'GET',
    '/demo',
    function (ServerRequestInterface $request, ResponseInterface $response
    ) use ($service) {
        $hello = $service->hello();
        $response->getBody()->write("<h1>$hello</h1>");

        return $response;
    }
);

$response = $route->dispatch($container->get('request'), $container->get('response'));

$container->get('emitter')->emit($response);

看效果,路由指定到 http://localhost:1234/demo

League\Pipeline

This package provides a plug and play implementation of the Pipeline Pattern. It’s an architectural pattern which encapsulates sequential processes. When used, it allows you to mix and match operation, and pipelines, to create new execution chains. The pipeline pattern is often compared to a production line, where each stage performs a certain operation on a given payload/subject. Stages can act on, manipulate, decorate, or even replace the payload.

If you find yourself passing results from one function to another to complete a series of tasks on a given subject, you might want to convert it into a pipeline.

https://pipeline.thephpleague.com/

// 安装插件
composer require league/pipeline

写个 demo

use League\Pipeline\Pipeline;

// 创建两个闭包函数
$pipe1 = function ($payload) {
    return $payload + 1;
};

$pipe2 = function ($payload) {
    return $payload * 3;
};

$route->map(
    'GET',
    '/demo',
    function (ServerRequestInterface $request, ResponseInterface $response
    ) use ($service, $pipe1, $pipe2) {
        $params = $request->getQueryParams();

        // 引入闭包函数
        $pipeline = (new Pipeline)
            ->pipe($pipe1)
            ->pipe($pipe2);

        // 执行
        $callback = $pipeline->process($params['data']);

        $hello = $service->hello();
        $response->getBody()->write("<h1>$hello, $callback</h1>");

        return $response;
    }
);

ENV

与 Laravel 相似,我们借助 .env 来保存我们的配置信息。

安装插件

composer require vlucas/phpdotenv

写个 demo

$dotenv = new Dotenv\Dotenv(__DIR__."/../");
$dotenv->load();

$route->map(
    'GET',
    '/env_demo',
    function (ServerRequestInterface $request, ResponseInterface $response
    ) {
        $data = getenv('hello');
        $response->getBody()->write("<h1>使用 env</h1>");
        $response->getBody()->write("<p>$data</p>");
        return $response;
    }
);

看看 .env 定义的值

hello=Fanly

看执行结果:

tightenco/collect

我一直是 Laravel's Collections 的忠实粉丝,所以在框架中必然会引入 collect,所以本框架选用 tightenco/collect

A Collections-only split from Laravel's Illuminate Support

具体参考:https://github.com/tightenco/collect

webonyx/graphql-php

GraphQL 是一种现代化的 HTTP API 接口构建方式,是 Facebook 在 2012 年开发的,2015 年开源,2016 年下半年 Facebook 宣布可以在生产环境使用,而其内部早就已经广泛应用了。GraphQL 是作为一个 REST 和 SOAP API 的替代品来设计的,Facebook 应对复杂接口查询的方案非常简单:用一个 “聪明” 的节点来进行复杂查询,将数据按照客户端的要求传回去,后端根据 GraphQL 机制提供一个具有强大功能的接口,用以满足前端数据的个性化需求,既保证了多样性,又控制了接口数量。

参考:https://laravel-china.org/docs/graphql-php

安装插件

composer require webonyx/graphql-php

写个 demo

在上面的例子,我们结合 GraphQL:

首先定义一个 QueryType

$queryType = new ObjectType([
    'name' => 'HelloQuery',
    'fields' => [
        'hello' => [
            'type' => Type::string(),
            'args' => [
                'message' => ['type' => Type::string()],
            ],
            'resolve' => function ($root, $args) {
                return $root['prefix'] . $args['message'];
            }
        ],
    ],
]);

添加进 Schema

$schema = new Schema([
    'query' => $queryType
]);

增加 route:

$route->map(
    'POST',
    '/graphql_demo',
    function (
        ServerRequestInterface $request,
        ResponseInterface $response
    ) use (
        $queryType,
        $schema
    ) {
        $params = $request->getParsedBody();
        $collect = collect($params);
        $rootValue = ['prefix' => 'from: '];
        try {
            $result = GraphQL::executeQuery($schema, $collect->get('query'), $rootValue);
            $output = json_encode($result->toArray());
        } catch (\Exception $e) {
            $output = [
                'error' => [
                    'message' => $e->getMessage()
                ]
            ];
        }
        $response->getBody()->write("<h1>输出结果</h1>");
        $response->getBody()->write("<p>$output</p>");

        return $response;
    }
);

重点是该语句:$result = GraphQL::executeQuery($schema, $collect->get('query'), $rootValue);

运行结果如下:

如果传入的参数不对,看看显示效果:

其它插件

还有其它插件安装

// 时间处理插件
composer require nesbot/carbon

// Log 插件
composer require monolog/monolog