moorexa/fatapi

适用于小型和大型项目的强大REST API框架。

维护者

详细信息

github.com/moorexa/fatapi

源代码

问题

安装: 22

依赖: 0

建议: 0

安全: 0

星标: 2

关注者: 1

分支: 0

开放问题: 0

类型:项目

v1.0.1 2023-03-16 22:57 UTC

This package is auto-updated.

Last update: 2024-09-17 02:17:07 UTC


README

适用于小型和大型项目的强大REST API框架。

专为PHP开发者打造。非常适合个人、企业和商业后端应用。

为什么选择FatApi

多年来构建后端应用的经验,使我们找到了这个一站式解决方案。多年来,我们使用以下请求方法构建REST API:GET、POST、DELETE、PUT,并且我们还必须关注以下方面;

  1. 版本控制
  2. 构建轻量级应用,然后扩展到微服务
  3. 管理多个程序性端点
  4. 为我们的请求和响应创建标准,即使在将后端应用的部分外包给远程开发者的情况下也是如此
  5. 无需编写一行代码即可为每个服务生成文档。
  6. 从市场获得额外的东西,例如认证、中间件、实时文档、插件等,这样我们就不必重新发明轮子。

是的,创建这个需要花费很多时间,许多初创公司、开发人员或软件代理机构如果拥有这样一个基础系统,就会更加放心。

  1. 连接到外部服务
  2. 创建小型程序,当业务扩展时可以将其解耦为微服务
  3. 构建版本之间一致的严格实体
  4. 生成符合标准、易于理解和格式一致的响应
  5. 清晰的URL可以解释其功能,允许开发人员通过附加请求头 x-meta-doc 获得文档。
  6. 降低管理多个端点的成本,无需向端点添加请求ID,使其保持整洁且易于使用。
  7. 采用新的请求标准,取消了对 DELETEPUT 请求方法的支持,但开箱即用,只需使用 GETPOST 请求方法即可完成更多操作,这使得FATAPI非常独特且易于使用。
  8. 还允许您使用所有请求方法访问外部服务。是的,FATAPI还充当网关,连接您到可能位于多个服务器上的其他服务,并允许您轻松地进行版本控制。
  9. 通过从 FatApi 市场place 获得服务、中间件、插件、文档模板等来快速上手。

列表可以一直列下去。这是一个低代码运动,我们希望通过将后端快速部署、正确记录并使其变得有趣来帮助您提高生产力。

架构风格或模式

  1. 事件总线模式
  2. 微服务
  3. 单体或对等模式

需求

  1. PHP 7及以上版本
  2. 熟悉PHP和OOP
  3. 了解Moorexa ORM是一个加分项,但不是必需的,所有内容都是自动为您生成的。

安装

非常简单!!!确保您已安装composer,并运行以下创建项目命令

composer create-project moorexa/fatapi project-name

上述命令将创建一个“项目名称”文件夹。

如果您省略了“项目名称”参数,则命令将创建一个fatapi文件夹,可以根据需要重命名。

运行此命令将安装您所需的所有内容,包括本地composer和所有必需的依赖项。

入门

首先,我们必须授权每个请求。为此,我们只需使用以下命令从命令行生成一个令牌

php fatapi make:token {unqiue name}

{唯一名称} 中可以是您项目的名称或对您来说是独特的东西。接下来,我们更新位于 src/Middlewares/ 中的 MustBeAuthorized 中间件。您还可以查看 FatApi 市场place 以获取授权中间件,这些中间件允许您进行更多操作,例如速率限制、超时等。

默认情况下,我们已经添加了 MustBeAuthorized 中间件,这样您仍然可以在此时完成工作,而无需升级到付费版本。

生成此令牌后,您应该得到一个大小为 40 的令牌,复制它并更新如下的 MustBeAuthorized 中间件。

/**
 * @package MustBeAuthorized
 * @author Amadi Ifeanyi <amadiify.com>
 */
class MustBeAuthorized implements MiddlewareInterface
{
    /**
     * @var string $authorizationToken
     * 
     * You should generate a new token from the CLI and update authorizationToken with it
     * By default, the system would auto generate one and load the request with it which is not the best
     * use 'php fatapi make:token {unique name}' to generate and update $authorizationToken
     */
    public $authorizationToken = '388b77473d46a13724192ae7735219a2ecae7a1b';

    ...

令牌应该是您刚刚生成的令牌。接下来,您现在可以共享此令牌,将其添加到每个传入请求的授权头中,如下所示。

Authorization : Bearer <generated token>

查找请求方法的帮助

在 fatapi 上开始使用?您可以通过下表获取特定请求方法的快速帮助。

可用的 CLI 命令

以下是一些可以帮助您加快开发的命令。

如何创建新的服务

服务就像包含一个或多个路由的资源。它们包含提供者、模型以及一些有助于构建功能性和可扩展系统的类和方法。在这里,我们演示如何使用命令行生成一个。

php fatapi make {service}

其中 {服务} 可以是一个没有特殊字符(除了 _ 和 -)的字符串,例如 service-name、myservice、user、account 等。

默认情况下,如果您在命令中不包括版本号,它将生成默认版本 v1 的服务。但万一您需要一个新版本,只需指定它,如下所示

php fatapi make {service}:v2

例如,创建一个名为 User 的服务并在版本 v1 上创建后,您应该看到以下文件和文件夹

- v1/
    - Documentation/
        - GetUser.md
        - PostUser.md
    - Data/
        - GeneralQuery.php
        - SQL.php
        - UnpackStruct.php
        - Struct.php
    - Model/
    - Events/
        - Listener.php
    - Providers/
        - CreateProvider.php
        - UpdateProvider.php
        - DeleteProvider.php
    - PostUser.php
    - GetUser.php
- readme.md

文件夹和文件分解

让我们看看这些文件和文件夹可以帮助我们完成什么,以及它们的用途。

如何创建新的路由

创建路由要求您已经生成了一个服务,并且该路由对该服务不存在。路由将是完成交易的触发器,它们通常将接收到的请求数据,提供一些使数据有意义的内部操作,然后通过 json 或 xml 发送响应。每个服务都必须至少有一个或多个路由才能成功,下面我们会向您展示一个基本命令来生成一个;

php fatapi make:route {service}/{route} -{option}

其中 {选项} 可以是 (post 或 get)。那么为什么 {选项}?它们有助于直接将路由添加到您想要的位置。请记住,我们有两个主要请求文件,名为 PostUser.phpGetUser.php,使用 User 服务作为示例。

其中 {服务} 是位于您的 src/Resource/{version} 文件夹中的有效服务名称。

其中 {路由} 是一个有效的未存在于方法中的方法,例如 submit-profile 等。

带有版本号的创建路由

您只需在路由名称后添加版本号,如下所示;

php fatapi make:route {service}/{route}:{version} -{option}

其中 {版本} 可以是 v1、v2 等。

不带选项的创建路由

您还可以从我们设计的命名标准中受益,以便您在路由名称上保持一致。这意味着您在创建路由时不再需要添加 -post-get。下表显示了如何实现,我们将以名为 User 的服务为例进行演示;

如何发送简单的 POST 请求

为了演示这一点,我们将使用 nodejsaxios 库。请注意 /api,这是我们单点入口。

var axios = require('axios');
var FormData = require('form-data');
var data = new FormData();

var config = {
  method: 'post',
  url: 'http://someendpoint.com/api',
  headers: { 
    'x-meta-service': 'user', 
    'x-meta-method': 'login', 
    ...data.getHeaders()
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

要获取有关发送请求到服务器所需信息的更多信息,请发送此简单请求以获取帮助。

var axios = require('axios');

var config = {
  method: 'post',
  url: 'http://someendpoint.com/help',
};

axios(config)
.then(function (response) {
  console.log(response.data);
})
.catch(function (error) {
  console.log(error);
});

或者直接向该 URL 发送 POST 请求以了解更多信息。

如何发送简单的 GET 请求

为了演示这一点,我们将使用 nodejsaxios 库。请注意 /api,这是我们单点入口。

var axios = require('axios');

var config = {
  method: 'get',
  url: 'http://someendpoint.com/api',
  headers: { 
    'x-meta-service': 'account', 
  }
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

要获取有关发送请求到服务器所需信息的更多信息,请发送此简单请求以获取帮助。

var axios = require('axios');

var config = {
  method: 'get',
  url: 'http://someendpoint.com/help',
};

axios(config)
.then(function (response) {
  console.log(response.data);
})
.catch(function (error) {
  console.log(error);
});

或者直接从浏览器向该URL发送GET请求以获取更多信息。

资源配置样式

在这里,您可以选择生成一个config.json文件,并使用通用样式或不同请求方法的独立通道将请求传输到外部服务。

这里是一个通用的请求样式,它接收所有请求并将其推送到一个端点。

通用请求样式 1

{
    "default": true,
    "type" : "api",
    "url" : "http://google.com/account/v1",
    "response" : {
        "type" : "application/json"
    }
}

以下是发生情况的分解

使用Socket.io发送GET或POST请求

在任何时候,如果您想利用Socket编程来促进通信而不是HTTP请求,我们可能有一个简单的解决方案。在您继续之前,请确保您已经

composer require workerman/phpsocket.io

安装或只需运行

php fatapi install socket

从您的cmd或终端安装socket.io的所有依赖项。

接下来,我们通过运行以下命令启动我们的socket服务器

php fatapi socket

这将启动工作员socket服务器,地址为 ws://0.0.0.0:8082。您可以在 framework/src/environment.yaml 中更改此默认设置。

使用JavaScript发送socket.io请求

要完成此操作,您必须已获取socket.io cdn或安装了socket.io客户端。在这里,我们将展示一个完整的步骤来让您快速入门。

<html lang="en">
<body>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.0/socket.io.min.js"></script>
    <script>
        let socket = io.connect('ws://0.0.0.0:8082');
        socket.on('connect', function () {

            console.log('connected');

            // making a get request
            socket.emit('meta.api', JSON.stringify({
                meta : {
                    service : 'user',
                    method : 'all',
                },
                header : {},
                version: 'v1',
                signature: '67shdjddd',
                method: 'get',
                query: {
                    limit: 20
                }   
            }));

            // we can now listen for a response from the socket server 
            // using the unqiue signature.
            socket.on('67shdjddd', (data)=>{
                console.log(data);
            });

            socket.on('disconnect', function () {
                console.log('disconnected');
            });
        });
    </script>
</body>
</html>

使用PHP发送socket.io请求

要完成此操作,您不需要安装任何依赖项。在这里,我们将展示一个完整的步骤来让您快速入门。

use Lightroom\Socket\SocketClient;

// create connectionn
$socket = new SocketClient('0.0.0.0', '8082');

// you can queue more than one request
$socket->queue('meta.api', json_encode([
    'meta'     => [
        'service'   => 'user',
        'method'    => 'all'
    ],
    'header'    => [],
    'method'    => 'get',
    'version'   => 'v1',
    'signature' => '8337sijdfu',
    'query'      => [
        'limit' => 20,
    ]
]));

// send all queues now
$socket->send();

目前,如果您不需要像JavaScript中那样等待和监听响应,使用PHP实现是有意义的。当您需要在程序内部向其他服务发送数据时,它很有用。

以下是发送到 meta.api 的示例数据的完整分解

如何在服务中使用模型

假设您已创建了一个服务和模型。您的模型应该可以从命名空间中使用。

对于这个例子,我们假设一个位于 src/Resources/Student/v1/Model/ 的测试模型。看看它应该是什么样子;

namespace Resources\Student\v1\Model;

use Engine\RequestData;
use Engine\{Interfaces\ModelInterface, DBMS, Table, ModelHelper};
/**
 * @package Test Model
 * @author Amadi Ifeanyi <amadiify.com>
 */
class Test implements ModelInterface
{
    /**
     * This 'ModelHelper' trait contains the fillable method and DB method.
     */
    use ModelHelper;

    /**
     * @var int $id
     * This is significant to your model class. It gets its value when two things happens
     * 1. The system encounters x-meta-id in the request header
     * 2. The POST body sent contains a key 'id' along side a number as its value
     */
    public $id = 0;

    ....
}

现在,对于发送到服务的每个请求,都存在一个 RequestResponse 类参数。这个 Request 类持有经过验证和确认的请求数据,还有一个名为 useModel() 的方法,它接受一个模型类名作为字符串,并将所有请求数据加载到该类中,以进行数据库操作。为了演示这一点,我们假设向学生服务发送一个POST请求到默认的Init方法。

namespace Resources\Student\v1;

/**
 * @method PostStudent Init
 * @param Request $request
 * @param Response $response
 * @return void
 * 
 * @start.doc
 * 
 * .. Your documentation content goes in here.
 * 
 */
public function Init(Request $request, Response $response) : void
{
    // our post data may contain
    // username, password, etc
    // next we just push that data to our test model and then run any of the
    // crud operations
    $model = $request->useModel(Model\Test::class);
    // this reads (Resources\Student\v1\Model\Test)

    // next we can run any operation that's avaliable in this model class
    // eg
    $model->Update(); // update a record

    // sample response
    $response->success('It works!');
}

获取请求ID

您是否已将ID传递到请求参数中或使用 x-meta-id 方法将ID与请求一起发送?以下是您如何在服务方法中获取它的说明。

namespace Resources\Student\v1;

/**
 * @method PostStudent Init
 * @param Request $request
 * @param Response $response
 * @return void
 * 
 * @start.doc
 * 
 * .. Your documentation content goes in here.
 * 
 */
public function Init(Request $request, Response $response) : void
{
    // our id is part of the request

    // sample response
    $response->success('It works!', [
        'id' => $request->id
    ]);
}

如何将模型连接到数据库

首先,您需要创建一个模型文件,然后我们使用以下命令创建一个新的连接

php fatapi make:dbms sessionConnection

其中 sessionConnection 可以是任何有效的函数名称。

这将在 src/Engine/DBMS.php 中位于 Engine\DBMS 类的新方法 sessionConnection() 中创建一个新的方法。

此方法的内容应如下所示

/**
 * @method DBMS sessionConnection
 * @param string $table
 * @return DriverInterface|
 */
public static function sessionConnection(string $table = '') 
{
    // connection name
    $connectionName = '';

    // get connection
    $connection = self::CreateConnection($connectionName);

    // has table
    return $table != '' ? self::ConnectToTable($connection, $table) : $connection;
}

接下来,将 $connectionName 的值设置为与在Moorexa src/database/database.php 文件中创建的连接密钥匹配。这可以是默认的 'new-db' 连接密钥。因此,您的连接方法现在应该如下所示

/**
 * @method DBMS sessionConnection
 * @param string $table
 * @return DriverInterface|
 */
public static function sessionConnection(string $table = '') 
{
    // connection name
    $connectionName = 'new-db';

    // get connection
    $connection = self::CreateConnection($connectionName);

    // has table
    return $table != '' ? self::ConnectToTable($connection, $table) : $connection;
}

如果 connectionName 为空,Moorexa 将尝试使用 src/database/database.php 中的默认连接设置。这意味着您必须为 developmentlive 设置一个值。下面是示例

->default(['development' => 'new-db', 'live' => '']);

也许您想添加另一个连接设置,以便您可以使用多个连接设置,请使用以下命令

php assist database add connectionName

其中 connectionName 是您想要识别该连接的东西。

接下来,您打开模型文件,将 $DBMSConnection 的值设置为在 Engine\DBMS 类中创建的新方法 sessionConnection 或您自己的唯一方法名,该类位于 src/Engine/DBMS.php 中。下面是示例:

namespace Resources\Student\v1\Model;
...
/**
 * @package Test Model
 * @author Amadi Ifeanyi <amadiify.com>
 */
class Test implements ModelInterface
{
    ...
    /**
     * @var string $DBMSConnection
     * This is a connection method name from our Engine\DBMS class and
     * it defaults to this model, to be accessed via 
     * - $this->DB()
     * or
     * - $this->DB(TABLE NAME)
     * Where TABLE NAME is a constant value from Engine\Table class or just a regular name.
     * 
     * You can also make queries to other connections via accessing them through
     * - DBMS::ConnectionName()
     * Where 'ConnectionName' is a connection method from our Engine\DBMS class
     */
    private $DBMSConnection = 'sessionConnection';
}

现在,您的模型已通过该方法连接到数据库,通常通过在 src/database/database.php 中找到的连接键来执行每个查询。

如何将中间件应用于资源

中间件为您提供核心系统之外的资源服务。它可以被描述为“服务胶水”。创建一个中间件很简单,可以使用以下命令实现,其中 MIDDLEWARE_NAME 是您独有的。

php fatapi make:ware MIDDLEWARE_NAME

假设我们已将我们的中间件命名为 MustBeAuthorized,现在我们可以将其应用于资源服务类或方法。为此,打开 src/Resources/middleware.json。为了演示这一点,我们将对名为 Student 的服务中的每个 POST 请求应用此操作,我们甚至可以进一步扩展到数组中或直接应用于特定类方法 Profile

{
    "verbs" : {
        "POST" : ["Middlewares\\PostMustHaveData"]
    },
    "resources" : {
        "Resources\\Student\\v1\\PostStudent" : ["Middlewares\\MustBeAuthorized",],
        "Resources\\Student\\v1\\PostStudent::Profile" : ["Middlewares\\MustBeAuthorized or another middleware"]
    }
}

如何直接将中间件应用于方法

现在,您可以直接将中间件作为文档注释的一部分添加到方法中。我们将使用我们假设的中间件 MustBeAuthorized 来演示,该中间件可以在 src/Middlewares/ 中找到。

/**
 * @package GetAuthentication
 * @author Amadi Ifeanyi <amadiify.com>
 *
 * @start.doc
 * 
 * .. Your documentation content goes in here.
 */
class GetAuthentication implements ResourceInterface
{
    /**
     * @method GetAuthentication Init
     * @param Request $request
     * @param Response $response
     * @return void
     * @middleware Middlewares\MustBeAuthorized
     * 
     * @start.doc
     * 
     * .. Your documentation content goes in here.
     * 
     */
    public function Init(Request $request, Response $response) : void
    {
        $response->success('It works!');
    }

    ...

注意 @middleware 标签!现在,每个进入该路由的请求都必须通过该中间件处理请求体之前。您可以有多个中间件,如下所示

/**
 * @package GetAuthentication
 * @author Amadi Ifeanyi <amadiify.com>
 *
 * @start.doc
 * 
 * .. Your documentation content goes in here.
 */
class GetAuthentication implements ResourceInterface
{
    /**
     * @method GetAuthentication Init
     * @param Request $request
     * @param Response $response
     * @return void
     * @middleware Middlewares\MustBeAuthorized
     * @middleware Middlewares\ExampleMiddleWare2
     * 
     * @start.doc
     * 
     * .. Your documentation content goes in here.
     * 
     */
    public function Init(Request $request, Response $response) : void
    {
        $response->success('It works!');
    }

    ...

如何过滤请求的每个输入

您只需要向 src/Resources/input.json 文件中添加一个条目,然后系统确保向您呈现的内容已通过检查并传递。否则,它将停止处理请求并要求开发者提供正确/所需的数据。现在,让我们用一个例子来演示,我们调用此服务 student,方法名为 login。此请求方法将是 POST,并触发位于学生资源文件夹中的类文件 PostStudent。现在,为了锁定此请求以获取所需数据,我们只需将其添加到我们的 src/Resources/input.json 文件中

[
    ...

    {
        "service" : "student",
        "method" : "login",
        "version" : "*",
        "verb" : "post",
        "body" : {
            "username" : "required|string|notag",
            "password" : "required|string|min:2"
        }
    }
]

如果此操作成功,则通过 Engine\Request 类使数据(用户名和密码)可用。以下是如何演示:

namespace Resources\Student\v1;

/**
 * @method PostStudent Init
 * @param Request $request
 * @param Response $response
 * @return void
 * 
 * @start.doc
 * 
 * .. Your documentation content goes in here.
 * 
 */
public function Login(Request $request, Response $response) : void
{
    // get username
    echo $request->username;

    // get password
    echo $request->password;

    // sample response
    $response->success('It works!', [
        'id' => $request->id
    ]);
}

现在,使用此文档中所示的模型将自动填充请求数据到您的模型中,或者您可以像这样自定义模型:

namespace Resources\Student\v1\Model;

use Engine\RequestData;
use Engine\{Interfaces\ModelInterface, DBMS, Table, ModelHelper};
/**
 * @package Test Model
 * @author Amadi Ifeanyi <amadiify.com>
 */
class Test implements ModelInterface
{
    /**
     * This 'ModelHelper' trait contains the fillable method and DB method.
     */
    use ModelHelper;

    /**
     * @var int $id
     * This is significant to your model class. It gets its value when two things happens
     * 1. The system encounters x-meta-id in the request header
     * 2. The POST body sent contains a key 'id' along side a number as its value
     */
    public $id = 0;

    // username
    public $Username;

    // password
    private $Password;

    // then add the fillable method
    /**
     * @method ModelInterface Fillable
     * @param RequestData $data
     * @return void
     * 
     * Has data that can be populated to the class 
     */
    public function Fillable(RequestData $data) : void
    {
        // set the username
        $this->Username = $data->username;

        // set the password
        $this->Password = $data->password;
    }

    ....
}

如何切换版本

您可以通过 src/Resources/versioning.json 文件针对不同的请求方法执行此操作。让我们画一个场景,您已构建了您的服务,现在您希望您的消费者使用新版本而无需更新前端?这不仅适用于服务,也适用于特定方法。我们如何做到这一点?请看以下示例

{
    "POST" : {
        "ExampleService" : {
            "version" : "v1"
        },
    },
    
    "GET" : {
        "ExampleService" : {
            "version" : "v2"
        }
    }
}

ExampleService 只是一个占位符,可以是您的服务名称,例如(student,user,account 等)。要更新服务方法的默认版本,只需在服务方法名后添加一个点(.)即可。以下是一个示例:

{
    "POST" : {
        ...
        "ExampleService.method" : {
            "version" : "v2"
        },
    },
    ...
}

GET 请求的默认查询过滤器

一个优秀的 API 没有搜索和过滤器是不完整的,我们都知道这一点,并且我们已经构建了多个选项来管理接收的内容,而无需编写额外的代码。以下是一些您可以在 URL 中添加的 GET 查询。

  1. ?sort=asc 或 desc
  2. ?column=* 或 name,age 等
  3. ?limit=0,4 或更多
  4. ?sortby=column|asc 或 desc
  5. ?rowid={0-9 或字符串}
  6. ?search=column|data

模型特殊方法

以下是我们模型魔术方法的完整列表,可以在外部文件中使用 CRUD 操作:

发送事务性和业务电子邮件

开箱即用,现在您可以使用 symfony/mailer 包发送电子邮件。我们扩展了此库,以简化其使用场景,从配置到发送带有附件的邮件等。有关此包的更多信息,请访问 [https://symfony.com.cn/doc/current/mailer.html]

完成这些后,让我们开始配置。打开文件 src/Messaging/Emails/config.php 进行您的配置。

/**
 * Configuration for sending out emails
 */
return [
    'default' => 'Messaging\Emails\Handlers\SymfonyMailer',
    'dsn' => 'smtp://{user}:{pass}@{host}:{port}',
    'host' => 'smtp.mailtrap.io',
    'port' => 2525,
    'user' => '',
    'pass' => ''
];

我们对 SymfonyMailer 包的默认处理器是 Messaging\Emails\Handlers\SymfonyMailer::class,您可以根据需要更改它。

接下来,创建动态方法并将它们链接到模板文件

您已经具备了这些,从 src/Messaging/Emails/email-list.json 文件中,您可以添加代表一个或多个模板文件的动态方法。以下是一个示例:

{
    "sendWelcomeMessage" : {
        "category" : "LoadBusinessTemplate",
        "template" : "welcome",
        "subject" : "Welcome to my application",
        "from" : "",
        "entities" : {
            "name" : "required|string|notag"
        }
    }
}

模板 "welcome" 代表一个必须在 src/Messaging/Emails/Templates/Business/ 目录下创建为 welcome.html 的模板文件,并可能包含一个或多个占位符以表示实际数据。您还可以看到分类。到目前为止,我们有两个分类,我会带您了解它们的模板文件所在位置;

您可以根据需要创建更多分类,并为每个分类添加指向模板文件的方法,以便在调用 src/Messaging/Emails/EmailTemplate.php 中的分类名称时获取模板。

"entities" 告诉开发者期望什么。这些字段可以包含如下所示默认数据

    "entities" : {
        "name" : ["required|string|notag", "default name"]
    }

其余的都是自我解释的。现在,我们可以从应用程序的任何地方向任何电子邮件地址发送邮件。以下是一个示例:

use Messaging\Emails\EmailSender;

// send welcome message
EmailSender::sendWelcomeMessage(
    // data to replace placeholders with 
    [
        'name' => 'fatapi' // this would replace {name} with fatapi
    ],

    // extra option
    [
        'background' => true, // this would send the mail in the background
        'subject' => '', // (optional) but can help change the mail subject
        'from' => '', // (optional) but can help change the mail sender
        'to' => 'someone@example.com' // this is the receiver email address 
    ],

    // (optional callback)
    function($email)
    {
        // now you have the Symfony\Component\Mime\Email in $email to work with
        // let try attaching a file
        $email->attach(fopen('/path/to/documents/contract.doc', 'r'));
    }
);

发送后台电子邮件

开箱即用,您可以使用 rabbitmq 服务器和客户端进行此操作。Moorea 已经使这变得容易。请确保您已经运行了 rabbitmq-server,然后您可以在 CLI 中运行以下命令以启动客户端监听器;

php assist start-rabbitmq-worker

现在您现在可以发送后台进程,如电子邮件、图像处理等。有关 rabbitmq-server 的文档指南:[https://rabbitmq.cn/documentation.html]

发送电子邮件警报

我们创建了一个名为 Messaging\EmailAlerts::class 的类,用于存储完成交易后发送到服务器的所有警报。交易可以是;

  1. 新客户订单
  2. 新注册
  3. 失败的购买等。

这些警报可以添加到 src/Messaging/EmailAlerts.php 中的 Messaging\EmailAlerts 类中,并在需要时从该命名空间调用。以下是一个示例:

<?php
namespace Messaging;

use Messaging\Emails\EmailSender;
/**
 * @package EmailAlerts
 * @author Amadi Ifeanyi <amadiify.com>
 * 
 * This alert is meant for internal email notifications
 */
class EmailAlerts
{
    /**
     * @var string $sendTo
     */
    public static $sendTo = 'alerts@yourdomain.com'; // destination address

    /**
     * @var bool $sendInBackground
     * 
     * To get the email to send in the background, ensure rabbitmq is running and rabbitmq client is running
     */
    public static $sendInBackground = true;

    /**
     * @method EmailAlerts newSubscriberAlert
     * @param array $data
     * @return void
     */
    public static function newSubscriberAlert(array $data = [])
    {
        EmailSender::newSubscriberAlert($data, [
            'background'    => self::$sendInBackground,
            'to'            => self::$sendTo,
            'subject'       => 'You have a new email subscriber'
        ]);
    }
}

// now we can just call
EmailAlerts::newSubscriberAlert();

请记住,所有警报都必须在 src/Messaging/Emails/Templates/Business/ 中保存模板文件以供商业使用,以及在 src/Messaging/Emails/Templates/Transactional 中保存类似 "登录、确认密码" 等事务性邮件的模板文件。

好了,祝您在构建伟大事物时玩得开心。