kjschubert / php-gis-wrapper
PHP库,用于将您的项目与AIESEC的全球信息系统连接
Requires
- php: >=5.4.0
- lib-curl: *
README
我在AIESEC活跃期间开发了此项目,大约是EXPA v1和EXPA v2的开始。如问题报告所述,此代码与较新版本不兼容。我不再是活跃成员,因此此项目已被归档。我知道其他实体维护了此项目的分支或开发了类似的项目。此外,关于swagger / OpenAPI的工具正在增长,因此也可能有适当的代码生成器来生成您项目的客户端代码。
PHP GIS Wrapper
PHP GIS Wrapper是一个PHP库,用于将您的PHP项目与AIESEC的全球信息系统连接。
它允许您像使用原生对象一样访问GIS中的每个资源。您不需要担心任何请求、解析或令牌生成。只需使用用户名和密码创建一个身份验证提供者实例。然后创建GIS Wrapper实例,您就准备好了。
如果您已经使用了PHP GIS Wrapper v0.1,请注意v0.2是一个完全重写。有许多架构变化,因此您的项目更新可能不会那么简单。新版本肯定提供了性能提升并带来了许多新功能。请查看更改日志以获取更多信息。如果您需要帮助,请随时给我发消息。
- 作者:Karl Johann Schubert karljohann@familieschubi.de
- 版本:0.2
文档
请查看示例文件夹以快速入门。下面的解释更为通用。
安装
- 安装composer(https://composer.php.ac.cn/)
composer require kjschubert/php-gis-wrapper- 在您的脚本中要求composer自动加载器
AuthProviders
AuthProvider.php 文件提供了一个身份验证提供者的接口。身份验证提供者的目的是提供访问令牌以访问GIS API。
目前有三个主要的身份验证提供者
AuthProviderEXPA($username, $password)用于获取类似于登录EXPA的访问令牌。AuthProviderOP($username, $password)用于获取类似于登录OP的访问令牌。AuthProviderCombined($username, $password)此提供者尝试获取EXPA令牌,如果无效则返回OP令牌。
此外,还有两个特殊身份验证提供者
AuthProviderShadow($tokan, $authProvider)它接受一个有效的令牌作为第一个参数,并接受另一个AuthProvider作为第二个参数。当您缓存令牌时,您可以使用此AuthProvider。AuthProviderNationalIdentity($url)可以与AIESEC Identity项目的自定义TokenFlow一起使用。
提示:如果您想将国家或本地系统与GIS同步,只需在您的办公室创建一个新的账户和一个新的团队。然后,在新团队中将新账户匹配为团队领导。现在,您可以使用此账户的凭据为您同步生成访问令牌。
每个身份验证提供者都必须提供 getToken() 和 getNewToken() 函数。第二个函数在API响应错误并且访问令牌已过期时,由API包装器使用,以尝试使用新令牌。这对于身份验证提供者缓存访问令牌并且没有选项来确定其是否仍然有效时很有用。
如何选择正确的身份验证提供者
- 如果您有一个预定义并处于活动状态的用户:AuthProviderEXPA
- 如果您只想验证活动用户:AuthProviderEXPA(记住:如果您获得访问令牌,这并不意味着该用户是活动的,所以如果您需要验证,请使用current_person端点来验证令牌)
- 如果您需要验证活动和非活动用户:AuthProviderCombined
- 如果您只需要OP权限,或者只有非活动用户:AuthProviderOP
尽可能使用AuthProviderEXPA和AuthProviderOP。AuthProviderCombined直接提供当前人员对象,从而验证令牌是否为EXPA或OP令牌,但因此它需要更多的请求。
特别是如果您只想验证活动用户,请使用AuthProviderEXPA并在之后验证令牌。AuthProviderCombined将进行更多一次请求以生成OP令牌。
保持GIS身份会话
当用户访问GIS的前端之一时,他将被重定向到auth.aiesec.org的GIS身份服务。此服务为用户打开一个会话,因此当用户访问另一个前端时,他不需要再次登录。到目前为止,所有三个主要身份验证提供者都可以使用此会话。一方面,这可以提高您脚本的性能。另一方面,您也可以仅通过保持会话文件来生成访问令牌,而不保存用户凭据。
您可以通过函数 setSession($path) 设置会话的文件路径。函数 getSession() 返回当前的会话路径。会话文件事先必须不存在,但目录和文件必须对PHP可写。
如果您想在没有用户凭据的情况下从现有会话生成访问令牌,请使用文件路径作为第一个参数实例化标准AuthProvider之一,并保留第二个参数为空或设置为null。如果会话文件不存在,这将产生一个 E_USER_ERROR php 错误。如果会话无效,则生成令牌将抛出 InvalidCredentials 异常。
请确保在生成任何访问令牌之前调用函数 setSession($path)。其他一切都会正常工作,但可能导致不一致的行为。
辅助函数
- 所有三个主要身份验证提供者都支持将布尔值作为构造函数的第三个参数。将此参数设置为false将禁用SSL对等验证。如果使用会话实例化AuthProvider,请将第二个参数设置为
null - 所有三个主要身份验证提供者都提供函数
getExpiresAt(),该函数返回当前访问令牌有效的截止时间戳。 AuthProviderCombined还提供以下功能:- 函数
isOP()和isEXPA(),根据令牌的作用域返回一个布尔值 - 函数
getType(),根据令牌的作用域返回 'EXPA' 或 'OP'。 - 函数
getCurrentPerson()返回当前人员对象,因为它需要加载此对象以验证令牌
- 函数
AuthProviderShadow提供了函数getAuthProvider(),它返回底层 AuthProvider 或 null
类 GIS
类 GIS 是从您的项目中访问 AIESEC 全球信息系统 (GIS) 的入口点。第一个参数必须是 AuthProvider。第二个参数可以是空的,或 API 文档的 URL,或包含已解析的 API 文档的数组。
对于简单的项目,可以保留第二个参数为空。
$user = new \GISwrapper\AuthProviderEXPA($username, $password);
$gis = new \GISwrapper\GIS($user);
如果您想提高项目性能,请参阅缓存部分以获取更多信息。
缓存
GIS API 以 Swagger 格式进行文档记录。通常,GIS 包装器会下载这些文件并在每次实例化时解析它们。如果您的项目在更大的规模上使用 GIS,您可以检索解析结果并自行缓存。
\GISwrapper\GIS::generateSimpleCache()返回一个只包含已解析根 Swagger 文件的数组\GISwrapper\GIS::generateFullCache()返回一个包含所有已解析端点的数组
这两个函数都可以将 API 文档的替代链接作为第一个参数。
您可以使用返回的数组作为第二个参数来实例化 GIS 类。请检查示例文件夹以获取如何将完整缓存保存到文件的示例脚本。
数据访问和操作
请查看 http://apidocs.aies.ec/ 上的 API 文档以了解哪些端点存在。(注意:确保将文件从 v1 改为 v2 的 docs.json)
从您的 GIS 实例(例如 $gis)开始,路径中的每个静态部分在 /v2/ 之后都会转换为对象。每个动态部分将前一部分转换为数组,其中数组键代表动态部分的值。
// /v2/opportunities.json
$gis->opportunities;
// /v2/opportunities/{opportunity_id}.json
$gis->opportunities[opportunity_id]
// /v2/opportunities/{opportunity_id}/progress.json
$gis->opportunities[opportunity_id]->progress
获取数据
有两种不同类型的端点。那些只返回一个资源的(如 /v2/current_person.json),以及那些返回具有资源列表的不同页面的。
要从第一种端点获取数据,只需调用 get 方法。
// /v2/current_person.json
$res = $gis->current_person->get();
print_r($res);
第二种类型的端点可以通过迭代器访问,因此您可能希望使用 foreach 循环。
// /v2/opportunities.json
foreach($gis->opportunities as $o) {
print_r($o);
}
创建资源
请查看参数部分以了解如何访问端点的参数。在设置所有创建新对象所需的参数后,在该端点上调用 update() 函数。
请查看示例文件夹以获取如何创建、更新和删除新机会的脚本。
支持创建新对象的端点支持 HTTP 方法 POST。请查看相应端点的文档以了解所需的参数。
更新现有资源
在端点上设置所需的参数后,在该端点上调用 update() 方法。
请查看示例文件夹以获取如何创建、更新和删除新机会的脚本。
支持更新的端点支持 HTTP 方法 PATCH。请查看相应端点的文档以了解所需的参数。
删除资源
要删除资源,请在对应的端点上调用 delete() 方法。
支持删除方法的端点是那些支持 HTTP 方法 DELETE 的端点。请检查 API 文档以找到这些端点。
参数
GIS API 上的每个端点都有参数。一些参数已经包含在路径中。正如之前所述,这些参数会变成数组键。
GIS 包装器已经处理了 access_token、page 和 per_page 参数。因此,您无法访问或更改它们。
所有其他参数(查询和表单类型)都会变成端点的子对象。文档中的数组表示法在 PHP 中翻译为对象表示法。因此,通常文档中提到的每个键都成为子对象,其中 PHP 中的数组表示法用于具有数组数据类型的参数的不同元素。
让我们看一下端点 /v2/opportunities.json
$gis->opportunities->q = "some String"; // set parameter q
$gis->opportunities->filters->organisation = 10 // set parameter filters[organisation]
$gis->opportunities->filters->issues[0] = 10 // set element 0 of the array parameter filters[issues]
$gis->opportunities->filters->issues[1] = 20 // set element 1 of the array parameter filters[issues]
$gis->opportunities->filters->skills[0]->id = 10 // set the id of the first element of the array parameter filters[skills]
$gis->opportunities->filters->skills[1]->id = 20 // set the id of the second element of the array parameter filters[skills]
注意:请注意,这些参数将在您取消设置之前一直保留。即使是请求也不会取消设置。
您可以在层次结构中的每个元素上调用 php 函数 unset。这将删除特定实例,并因此删除以下所有参数。请记住,当您取消 GIS 类的实例时,您必须自己重新初始化 GIS 包装器。GIS 类下面的每个对象都会在您访问它时自动重新初始化。
在请求后取消设置您所操作的端点是最简单的方法。在上面的示例中,这意味着 unset($gis->opportunities)。
哈希和数组参数
当涉及到哈希和数组参数时,您应该仔细查看 API 文档中的列数据类型。
数据类型为哈希的参数没有可访问的值。相反,您可以将它看作值由子参数的值组成。
因此,哈希参数在 PHP 中也不是作为数组可访问的,每个子参数在 PHP 中都变成子对象。例如,上面示例中使用的 filter 参数。
另一方面,存在两种不同类型的数组参数。那些有子参数的和那些没有子参数且只取值的。在 PHP 中,这些参数变成数组。
在第一类数组参数中,您可以在每个数组键上访问子参数,就像上面示例中的 filter skills。
在第二类数组参数中,您可以在每个数组键上访问和设置值。在上述示例中,这将是对 filer issues 的访问和设置。
同时设置多个参数
如果您想一次性设置多个参数而不使用带有子对象的冗长表示法,可以将它们作为数组设置。请注意,这种方法可能难以调试。
当您将数组分配给端点或参数时,每个键的值将递归地分配给子端点和命名与键相同的参数。当您的数组中有路径的动态部分时,这不起作用,但一旦您将等效的数组分配给最后一个动态端点,它就会起作用。
上面的示例将如下所示
$gis->opportunities = [
"q" => "some String",
"filters" => [
"issues" => [10, 20],
"skills" => [
["id" => 10],
["id" => 20]
]
]
]
辅助函数
- 在具有子对象的每个对象上,您可以通过调用函数
exists($name)来检查是否存在子对象。这并不意味着已经存在该对象的实例,而是表示它可以访问。 - 在具有动态子端点的端点(可以通过数组表示法访问端点)上,
exists($name)函数会同时检查子对象和数组键。- 要仅检查子对象,请使用函数
existsSub($name)。子对象是静态路径端点和参数。 - 要仅检查动态子端点的元素,请使用函数
existsDynamicSub($key)。 - 在检查动态子端点时,GIS 包装器实际上会向 GIS 发送请求以检查资源是否可用。
- 建议在具有动态子端点的端点上使用函数
existsSub($name)和existsDynamicSub($key),以避免不必要的请求。 - 请注意,函数
existsSub($name)和existsDynamicSub($key)仅在具有动态子对象的对象上可用。在具有静态子对象和参数的对象上,您只能使用函数exists($name)。
- 要仅检查子对象,请使用函数
- 函数
isset($object)在相应的对象初始化后立即返回 true。如果对象未初始化,则返回 false。- 如果
isset($object)返回 false,这并不意味着对象不可访问。要检查对象是否可访问,请使用上述描述的函数exists($name)。 - 目前,
isset($object)也会在参数初始化但未设置值时返回 true。这可能在未来发生变化。目前,您可以使用下面描述的函数valid($operation)。 - 在数组键上调用
isset($object)将在存在实例时返回 true。这并不一定意味着为此键存在资源。
- 如果
- 函数
unset($object)将删除给定对象的实例。- 之后,
isset($object)将在您再次访问对象之前返回 false。 - 在父对象上调用
exists($name)仍将返回 true。
- 之后,
- 函数
count($object)可以用于分页端点和数组参数,两者也都是可迭代的(例如,在 foreach 循环中)。- 在分页端点上,这将与当前参数集相关的请求。
- 要获取上次请求中的元素数量,请在端点上调用
lastCount()。
测试
PHP GIS 包装器使用 PHP 单元进行测试。所有测试都可以在 tests 文件夹中找到。在那里您还可以找到代码覆盖率报告。
如果您发送拉取请求,请确保您的代码已覆盖,并在提交之前在根目录中运行 phpunit。通常,phpunit 会自动识别根目录中的 phpunit.xml 文件。
提供者
提供者的目的是在不同的上下文中包含 GIS 包装器的功能(例如,框架)。
目前,我们支持 PHP 框架 Lumen,因此也支持 Laravel。有关详细信息,请参阅 providers 文件夹中的 README。
变更日志
0.2.5
- 添加了 AuthProviderShadow 和 AuthProviderNationalIdentity
- 添加了 Lumen 的 ServiceProvider(也应与 Laravel 一起使用)
- 为分页端点添加了
currentPage()、setStartPage($page)和setPerPage($number)函数(测试尚缺失) - 更新了单元测试
0.2.4
- 修复了 API 端点的一些小错误
0.2.3
- 修复了在带有过期令牌的 GET 请求运行时令牌再生的问题
0.2.2
- 修复了参数验证中发生的问题,该问题发生在不同方法具有相同名称的参数时
0.2.1
- 提高了 swagger 解析的稳定性
0.2
在本版本中,PHP-GIS-Wrapper 完全重构。最重要的更改包括
- 新系统架构,特别是针对swagger解析器。这导致源代码更干净,性能大幅提升。
- 可以缓存swagger解析结果,提供更好的性能,特别是对于大型项目。
- 支持所有三个身份验证提供者中的GIS Identity会话,可以提高性能并提供更多机会。
- 动态路径部分使用ArrayAccess,使用起来更加直观。
- 对数组参数的支持更好。
- 参数类型验证。
- PHP GIS包装器已成为Composer包。
0.1
这是PHP-GIS-Wrapper的初始版本。它只支持GET请求。
- 最初只有一个名为AuthProviderUser的AuthProvider。
- 随着GIS v2的引入,该提供商更新为新的GIS Identity,但仅支持EXPA用户。
- 后来,AuthProviderUser被AuthProviderEXPA、AuthProviderOP和AuthProviderCombined取代。
常见问题解答(FAQ)
如果您有任何问题、功能请求、问题或发现了错误,请随时发送电子邮件至 karljohann@familieschubi.de
如果您发现了错误,也可以直接在github存储库中打开一个问题。
如果您将PHP GIS包装器集成到框架中作为提供者或服务,或在使用了它的一些项目中,请随时给我发消息以在此展示功能,或者写一个拉取请求以将您的代码包含在提供者文件夹中。
如果您编写了另一个示例,只需发送一个拉取请求。