upmind / linode-api
Upmind 是 Webinarium Linode API 客户端库的分支
Requires
- php: ^8.1
- ext-json: *
- guzzlehttp/guzzle: ^7.8
- psr/http-message: ^2.0
- symfony/expression-language: ^6.4
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- phpunit/phpunit: ^9.6
This package is auto-updated.
Last update: 2024-09-25 17:15:45 UTC
README
此库是 Upmind 对 webinarium/linode-api 的分支
Linode API 客户端库
此包提供 PHP 客户端库以访问 Linode API。库与 API 4.171.0 版本保持一致,该版本于 2024-02-01 发布。
需求
PHP 需至少为 PHP 8.1 版本。
安装
推荐通过 Composer 安装
composer require upmind/linode-api
使用
基本使用
所有 API 端点通过 LinodeClient
类的实例访问,您必须首先创建它
use Linode\LinodeClient; $client = new LinodeClient(); $regions = $client->regions->findAll();
上面的示例创建了一个未经认证的客户端,这足以访问一些公共端点,如 regions 或 kernels。要访问您的私有数据,您需要向 LinodeClient
提供您的访问令牌
use Linode\LinodeClient; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); $linodes = $client->linodes->findAll();
访问令牌可以是手动生成的 Personal Access Token 或从 OAuth 工作流中检索到的令牌。您可以使用 oauth2-linode 库使用 OAuth 在 Linode 中进行认证。
错误
向 Linode 发送的任何 API 请求都可能失败。在这种情况下,Linode API 返回错误列表,每个错误都包含 reason
(一个可读的错误消息,始终包含)和 field
(提交的 JSON 中的特定字段,当不适用时为 null
)。
每次请求失败时,库都会抛出 LinodeException
。异常的消息始终是错误列表中的第一个错误的消息。您也可以使用其 getErrors
函数从异常中获取所有错误。
use Linode\Exception\LinodeException; use Linode\LinodeClient; use Linode\LinodeInstances\Linode; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); try { $linode = $client->linodes->create([ Linode::FIELD_TYPE => 'g6-standard-2', Linode::FIELD_REGION => 'us-east', ]); } catch (LinodeException $exception) { // This is the same as the reason of the very first error below. $message = $exception->getMessage(); foreach ($exception->getErrors() as $error) { echo $error->field; echo $error->reason; } }
实体和仓库
库为 Linode API 返回的每个对象提供 实体 类 - linodes、images、nodebalancers 等。所有实体都是只读的,数据可以通过属性访问。
此外,每个实体类型都有一个专门的仓库。大多数仓库都通过 LinodeClient
类可用
use Linode\LinodeClient; use Linode\LinodeInstances\Linode; use Linode\LinodeInstances\LinodeRepositoryInterface; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); /** @var LinodeRepositoryInterface $repository */ $repository = $client->linodes; /** @var Linode $linode */ $linode = $repository->find(123); echo $linode->label; echo $linode->hypervisor;
某些实体是嵌套的,例如 DomainRecord
对象始终属于某个 Domain
对象。此类嵌套实体的仓库应从相应的父实体获取。LinodeClient
类仅包含根实体的仓库。
use Linode\Domains\Domain; use Linode\Domains\DomainRecord; use Linode\LinodeClient; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); /** @var Domain $domain */ $domain = $client->domains->findOneBy([ Domain::FIELD_DOMAIN => 'example.com', ]); /** @var DomainRecord[] $records */ $records = $domain->records->findAll(); foreach ($records as $record) { echo $record->type; }
为了便于查找相应的实体和仓库,库源代码的结构与原始 API 文档相同。
仓库和集合
每个仓库实现 Linode\RepositoryInterface
并提供以下两个函数。
find
函数通过其 ID 搜索实体
use Linode\LinodeClient; use Linode\LinodeInstances\Linode; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); /** @var Linode $linode */ $linode = $client->linodes->find(123);
findAll
函数返回类型为 Linode\EntityCollection
的实体集合对象。此类对象实现了标准的 Countable
和 Iterator
接口
use Linode\LinodeClient; use Linode\LinodeInstances\Linode; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); /** @var Linode[] $linodes */ $linodes = $client->linodes->findAll(); printf('Found %d linode(s).', count($linodes)); foreach ($linodes as $linode) { // ... }
分页
当您从 Linode API 获取对象列表时,API 返回分页的列表。为了使您的生活更轻松,库在内部管理分页,因此您可以将实体列表视为简单的数组。
例如,假设您的账户中有 270 个 Linode,您需要枚举它们的标签
use Linode\LinodeClient; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); $linodes = $client->linodes->findAll(); foreach ($linodes as $linode) { echo $linode->label; }
当在这个示例中调用findAll
函数时,只会加载前100个实体(100是API中的默认页面大小)。一旦达到第101个实体,库会再次调用以获取下一个100个linode,以此类推。因此,库将为您270个linode发出三次API请求,但对于您来说这是完全透明的。当然,只有在需要时才会执行额外请求,所以如果您在中间中断枚举,剩余的实体将不会发出请求。
此外,检索到的实体按集合进行缓存,因此可以安全地多次枚举同一个集合
use Linode\LinodeClient; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); $linodes = $client->linodes->findAll(); // This will make three API requests. foreach ($linodes as $linode) { echo $linode->label; } // This will make no API requests at all. foreach ($linodes as $linode) { echo $linode->type; } $linodes2 = $client->linodes->findAll(); // This will make three API requests again, as this is another collection. foreach ($linodes2 as $linode) { echo $linode->type; }
排序
Linode API支持请求对象的排序,这可以在findAll
函数的两个可选参数中指定
use Linode\LinodeClient; use Linode\LinodeInstances\Linode; use Linode\RepositoryInterface; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); $linodes = $client->linodes->findAll(Linode::FIELD_LABEL, RepositoryInterface::SORT_DESC);
第一个参数是要按名称排序的实体字段。每个实体类都包含有用的常量,因此您不需要硬编码字段名称。
第二个参数是排序方向,如果省略则等于Linode\RepositoryInterface::SORT_ASC
。
过滤(简单查询)
Linode API支持请求对象的过滤,这通过Linode\RepositoryInterface
接口的findBy
、findOneBy
和query
函数实现。
findBy
函数接受数组作为第一个参数,其中包含一组标准。所有标准都通过逻辑AND
操作连接。
use Linode\LinodeClient; use Linode\LinodeInstances\Linode; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); $linodes = $client->linodes->findBy([ Linode::FIELD_REGION => 'us-west', Linode::FIELD_TAGS => 'app-server', ]);
函数的第二个和第三个参数用于排序,与findAll
函数的相应参数工作方式完全相同。
findBy
函数返回一个集合,如果未找到任何内容,则可能为空。当您需要使用过滤器检索单个对象时,可以使用findOneBy
函数,该函数只接受一个标准数组作为参数。
use Linode\LinodeClient; use Linode\LinodeInstances\Linode; $client = new LinodeClient('03d084436a6c91fbafd5c4b20c82e5056a2e9ce1635920c30dc8d81dc7a6665c'); $linode = $client->linodes->findOneBy([ Linode::FIELD_LABEL => 'mysql-server-02', ]);
如果没有找到任何内容,则函数返回null
。如果找到多个实体,则函数引发一个LinodeException
。
过滤(复杂查询)
上面提到的最后一个函数query
允许您使用Linode API的查询语言进行复杂请求。
API查询语言假设您将条件转换为JSON,这实际上使它们难以阅读、调试和维护。例如,当前的API文档建议以下JSON对象以获取所有既属于standard或highmem类,或者具有12到20个vcpus的Linode类型
{ "+or": [ { "+or": [ { "class": "standard" }, { "class": "highmem" } ] }, { "+and": [ { "vcpus": { "+gte": 12 } }, { "vcpus": { "+lte": 20 } } ] } ] }
query
函数允许您使用更易读的表达式编写条件,这些表达式作为字符串传递给第一个参数。上述示例可以如下实现
use Linode\LinodeClient; $client = new LinodeClient(); $types = $client->linodeTypes->query('(class == "standard" or class == "highmem") or (vcpus >= 12 and vcpus <= 20)'); foreach ($types as $type) { echo $type->class; echo $type->vcpus; }
库使用以下词法项支持所有Linode API运算符
如果在您的表达式中出现语法错误,库将引发一个包含所有找到错误的LinodeException
。
如果您需要使用一些变量来创建表达式,则可以使用参数化表达式,如下例所示
use Linode\LinodeClient; $client = new LinodeClient(); $parameters = [ 'class1' => 'standard', 'class2' => 'highmem', 'min' => 12, 'max' => 20, ]; $types = $client->linodeTypes->query('(class == :class1 or class == :class2) or (vcpus >= :min and vcpus <= :max)', $parameters);
每个参数以冒号开头,整个参数集作为数组一次性提供。
并且,就像findAll
和findBy
函数一样,query
函数有两个最后的可选参数用于排序
use Linode\LinodeClient; use Linode\LinodeTypes\LinodeType; use Linode\RepositoryInterface; $client = new LinodeClient(); $parameters = [ 'class1' => 'standard', 'class2' => 'highmem', 'min' => 12, 'max' => 20, ]; $types = $client->linodeTypes->query( '(class == :class1 or class == :class2) or (vcpus >= :min and vcpus <= :max)', $parameters, LinodeType::FIELD_MEMORY, RepositoryInterface::SORT_DESC);
开发
./bin/php-cs-fixer fix XDEBUG_MODE=coverage ./bin/phpunit --coverage-text
贡献
有关详细信息,请参阅CONTRIBUTING
致谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件