eppo / php-sdk
Eppo PHP SDK
Requires
- php: ^8.1
- ext-json: *
- composer/semver: ^3.4
- php-http/discovery: ^1.17
- psr/simple-cache: 3.*
- shrikeh/teapot: ^2.3
- symfony/cache: ^6.4
- webclient/ext-redirect: ^2.0
Requires (Dev)
- ext-pcntl: *
- ext-posix: *
- ext-sockets: *
- google/cloud-storage: ^1.30
- phpunit/phpunit: ^9.6
- psr-mock/http: ^1.0
- squizlabs/php_codesniffer: ^3.10
- dev-main
- v3.2.1
- v3.2.0
- 3.1.0
- 3.0.0
- 1.2.3
- 1.2.2
- 1.2.1
- 1.2.0
- 1.1.0
- 1.0.1
- 1.0.0
- dev-tp/config/nulletag
- dev-tp/action/branch
- dev-tp/makefail
- dev-tp/bandits/readme
- dev-tp/bandits/e2e
- dev-tp/bandit/eveneval
- dev-leoromanovsky-patch-1
- dev-lr/ff-953/try
- dev-catchup-upstream-121
- dev-lr/ff-1018/one-request
- dev-lr/ff-888/no-guzzle
- dev-lr/ff-962/php-sdk-name
- dev-docs-link-fix
- dev-pavel/upgrade-composer-version
- dev-pavel/improve-request-timeout
- dev-pavel/ANA-182-php-sdk
This package is auto-updated.
Last update: 2024-09-03 18:21:11 UTC
README
Eppo 是一个模块化的标记和实验分析工具。Eppo 的 PHP SDK 用于在多用户服务器端环境中进行分配,兼容 PHP 7.3 及以上版本。在继续之前,您需要一个 Eppo 账户。
功能
- 功能门
- 开关
- 渐进式发布
- A/B/n 实验
- 互斥实验(层)
- 动态配置
- 多臂上下文随机游走
安装
composer require eppo/php-sdk
快速开始
首先初始化 Eppo 客户端的单例实例。初始化后,客户端可以在您的应用程序的任何位置使用。
初始化一次
<?php use Eppo\EppoClient; require __DIR__ . '/vendor/autoload.php'; $eppoClient = EppoClient::init( '<your_api_key>', '<base_url>', // optional, default https://fscdn.eppo.cloud/api $assignmentLogger, // optional, must be an instance of Eppo\Logger\LoggerInterface $cache // optional, must be an instance of PSR-16 SimpleCache\CacheInterface. If not passed, FileSystem cache will be used $httpClient // optional, must be an instance of PSR-18 ClientInterface. If not passed, Discovery will be used to find a suitable implementation $requestFactory // optional, must be an instance of PSR-17 Factory. If not passed, Discovery will be used to find a suitable implementation );
在任何地方分配
$subjectAttributes = [ 'tier' => 2 ]; $assignment = $eppoClient->getStringAssignment('experimentalBackground', 'user123', $subjectAttributes, 'defaultValue'); if ($assignment !== 'defaultValue') { // do something }
选择 Bandit 行动
此 SDK 支持 多臂上下文随机游走。
$subjectContext = [ 'age' => 30, // Gets interpreted as a Numeric Attribute 'country' => 'uk', // Categorical Attribute 'pricingTier' => '1' // NOTE: Deliberately setting to string causes this to be treated as a Categorical Attribute ]; $actionContexts = [ 'nike' => [ 'brandLoyalty' => 0.4, 'from' => 'usa' ], 'adidas' => [ 'brandLoyalty' => 2, 'from' => 'germany' ] ]; $result = $client->getBanditAction( 'flagKey', 'subjectKey', $subjectContext, $actionContexts, 'defaultValue' ); if ($result->action != null) { // Follow the Bandit action doAction($result->action); } else { doSomething($result->variation); }
分配函数
每个 Eppo 标记在仪表板上创建时都会设置一次返回类型。创建标记后,应使用相应的类型函数在代码中进行分配
getBooleanAssignment(...) getNumericAssignment(...) getIntegerAssignment(...) getStringAssignment(...) getJSONAssignment(...)
每个函数都有相同的签名,但函数名中返回类型不同。对于布尔值使用 getBooleanAssignment
,其签名如下
function getBooleanAssignment( string $flagKey, string $subjectKey, array $subjectAttributes, bool $defaultValue ): bool
初始化选项
该 init
函数接受以下可选配置参数。
分配记录器
要使用 Eppo SDK 进行需要分析的实验,请在 SDK 初始化时将 LoggerInterface
的实现传递给 init
函数。SDK 会调用回调以捕获分配数据。分配数据需要在仓库中进行分析。
下面的代码演示了使用 Segment 的日志回调示例实现,但您可以使用任何系统。唯一要求是 SDK 收到 logAssignment
回调函数。我们定义了一个 Eppo AssignmentLogger
接口的实现,其中包含一个名为 logAssignment
的单个函数
<?php use Eppo\Logger\LoggerInterface; use Eppo\Logger\AssignmentEvent; use Eppo\Logger\LoggerInterface; class SegmentLogger implements LoggerInterface { public function logAssignment(AssignmentEvent $assignmentEvent): void { Segment::track([ 'event' => 'Flag Assignment for ' . $assignmentEvent->featureFlag, 'userId' => $assignmentEvent->subject, 'properties' => $assignmentEvent->toArray() ]); } }
Bandit 行动日志记录
当使用 Bandits 时,会调用不同的日志记录方法。您的日志类必须实现 IBanditLogger
而不是 LoggerInterface
。
<?php use Eppo\Logger\AssignmentEvent; use Eppo\Logger\BanditActionEvent; use Eppo\Logger\IBanditLogger; class SegmentLogger implements IBanditLogger { public function logAssignment(AssignmentEvent $assignmentEvent): void { Segment::track([ 'event' => 'Flag Assignment for ' . $assignmentEvent->featureFlag, 'userId' => $assignmentEvent->subject, 'properties' => $assignmentEvent->toArray() ]); } public function logBanditAction(BanditActionEvent $banditActionEvent): void { Segment::track([ 'event' => 'Bandit Action Selected', 'userId' => $banditActionEvent->subjectKey, 'properties' => $banditActionEvent->toArray() ]); } }
后台轮询
为了使使用库的体验更快,有一个选项可以启动后台轮询以获取随机化参数。此后台作业将开始调用 Eppo API,更新缓存中的配置。
为此,创建一个文件,例如 eppo-poller.php
,其内容如下
$eppoClient = EppoClient::init( '<your_api_key>', '<base_url>', // optional, default https://fscdn.eppo.cloud/api $assignmentLogger, // optional, must be an instance of Eppo\LoggerInterface $cache // optional, must be an instance of PSR-16 SimpleInterface. If not passed, FileSystem cache will be used $httpClient // optional, must be an instance of PSR-18 ClientInterface. If not passed, Discovery will be used to find a suitable implementation $requestFactory // optional, must be an instance of PSR-17 Factory. If not passed, Discovery will be used to find a suitable implementation ); $eppoClient->startPolling();
然后,通过以下方式运行此脚本
php eppo-poller.php
这将开始无限期轮询 Eppo-api 的过程。
故障排除
HTTP
此软件包使用 php-http/discovery
软件包来自动定位各种 HTTP 相关 PSR 接口的实现(例如:ClientInterface
、RequstFactory
等)。如果您的项目不依赖于任何可以满足此需求的库,您可能会看到以下异常。
致命错误:未捕获的 Http\Discovery\Exception\DiscoveryFailedException:无法使用任何发现策略找到资源。
要解决这个问题,只需引入一个合适的包,例如 guzzle
composer require guzzlehttp/guzzle:^7.0
哲学
易博的SDKs是为了简洁、速度和可靠性而构建的。标志配置被压缩并分布在全球CDN(Fastly)上,通常在15毫秒内到达您的服务器。服务器SDKs继续以30秒间隔轮询易博的API。配置随后在本地缓存,确保每次分配都是瞬间的。每个SDK内的评估逻辑由几行简单的数值和字符串比较组成。上面列出的类型化函数是开发者需要理解的全部,它抽象掉了易博底层(并且不断扩展)的功能集的复杂性。