CakePHP4中什么替代了CakePHP2的Datasource?如何创建无数据表Model?
CakePHP 4 对接OVH API实现邮件服务管理 + 无数据库表Model实现方案
无数据库表Model创建方式
CakePHP4不需要像2.x版本那样自定义Datasource实现外部数据源对接,核心逻辑是继承框架内置的Table类,手动指定非数据库连接、定义虚拟表结构即可,能完整复用框架的实体、数据校验、事件等全部能力。
- 第一步:安装OVH官方PHP SDK,在项目根目录执行命令:
composer require ovh/ovh - 第二步:在
config/app.php的Datasources配置块中添加OVH API连接配置,不需要填写任何数据库相关参数:
'ovh_api' => [ 'app_key' => '你申请的OVH应用Key', 'app_secret' => '你申请的OVH应用Secret', 'endpoint' => 'ovh-eu', // 根据账号所属区域替换,比如北美区用ovh-us 'consumer_key' => '授权后拿到的Consumer Key', ],
- 第三步:创建对应Table类,路径为
src/Model/Table/OvhEmailsTable.php,基础代码如下:
<?php declare(strict_types=1); namespace App\Model\Table; use Cake\ORM\Table; use Cake\Datasource\ConnectionManager; use Ovh\Api as OvhClient; class OvhEmailsTable extends Table { public static function defaultConnectionName(): string { // 绑定刚才配置的ovh_api连接,框架不会主动建立数据库连接 return 'ovh_api'; } public function initialize(array $config): void { parent::initialize($config); // 手动定义虚拟表结构,对应邮件账号、别名的操作字段,用于数据校验 $this->setSchema([ 'id' => ['type' => 'integer', 'null' => false], 'domain' => ['type' => 'string', 'null' => false, 'length' => 255], 'email_address' => ['type' => 'string', 'null' => false, 'length' => 255], 'password' => ['type' => 'string', 'null' => true, 'length' => 255], 'alias_target' => ['type' => 'string', 'null' => true, 'length' => 255], ]); // 定义创建邮件账号的校验规则,和普通Model用法一致 $this->addValidator('createAccount', function ($validator) { $validator->notEmptyString('domain', '域名不能为空') ->notEmptyString('email_address', '邮箱地址不能为空') ->notEmptyString('password', '邮箱密码不能为空') ->email('email_address', '邮箱格式不正确'); return $validator; }); // 定义创建邮件别名的校验规则 $this->addValidator('createAlias', function ($validator) { $validator->notEmptyString('domain', '域名不能为空') ->notEmptyString('email_address', '别名地址不能为空') ->notEmptyString('alias_target', '目标投递邮箱不能为空') ->email('email_address', '别名邮箱格式不正确') ->email('alias_target', '目标邮箱格式不正确'); return $validator; }); } // 内部封装OVH客户端实例化逻辑 protected function getClient(): OvhClient { $config = ConnectionManager::getConfig('ovh_api'); return new OvhClient( $config['app_key'], $config['app_secret'], $config['endpoint'], $config['consumer_key'] ); } }
邮件账号、别名创建功能实现
直接在上述OvhEmailsTable类中添加对应业务方法即可,不需要额外实现Datasource接口:
- 邮件账号创建方法
public function createAccount(array $postData): bool { $entity = $this->newEntity($postData, ['validate' => 'createAccount']); if ($entity->getErrors()) { return false; } $client = $this->getClient(); $accountPrefix = explode('@', $entity->email_address)[0]; // 调用OVH邮件账号创建接口 $client->post( sprintf('/email/domain/%s/account', $entity->domain), [ 'accountName' => $accountPrefix, 'password' => $entity->password, ] ); return true; }
- 邮件别名创建方法
public function createAlias(array $postData): bool { $entity = $this->newEntity($postData, ['validate' => 'createAlias']); if ($entity->getErrors()) { return false; } $client = $this->getClient(); $aliasPrefix = explode('@', $entity->email_address)[0]; // 调用OVH邮件别名创建接口 $client->post( sprintf('/email/domain/%s/alias', $entity->domain), [ 'alias' => $aliasPrefix, 'destination' => $entity->alias_target, ] ); return true; }
注意:使用前需要先完成OVH API的授权流程,给上述两个POST接口路径开通操作权限,否则会返回403权限错误。
调用方式
控制器中使用方式和普通Model完全一致,不需要额外处理:
// 控制器中创建邮件账号示例 $ovhEmailsTable = $this->fetchTable('OvhEmails'); $result = $ovhEmailsTable->createAccount($this->request->getData());
- 和CakePHP2的实现差异:4.x版本移除了2.x中笨重的Datasource强制实现要求,只要是继承Table类的Model不管底层数据源是什么,都能复用框架ORM层的全部能力,对接外部API的逻辑直接写在Table自定义方法里即可,维护成本比2.x低很多。
内容的提问来源于stack exchange,提问作者Oliv
相关产品推荐
相关产品推荐

