league-php / leaguewrap
《英雄联盟》API 的包装器。
Requires
- php: >=5.5
- guzzlehttp/guzzle: ~6.1.0
Requires (Dev)
- mockery/mockery: ~0.9.0
- phpunit/phpunit: ~4.8.0
README
版本 0.7.2
这是对 leaguewrap 的分支。我们决定在 LeaguePHP 组织下创建仓库,以便我们能够继续发布新版本并将它们推送到 Packagist,因为 leaguewrap 的上一个版本是在 2015 年 9 月。
LeagueWrap 是一个《英雄联盟》API包装器。目标是帮助快速、简单地开发依赖于《英雄联盟》API的应用程序。此项目将帮助维护API的查询限制和缓存系统,这两者都在进行中。这个包装器的座右铭是“懒惰”。我们只在你需要的时候加载你需要的信息,并将尽一切可能减少对API的请求次数。你将在本README的后面注意到,因为这种座右铭而做出的选择。
安装
此软件包可在 Packagist 上找到,并建议使用 Composer 进行加载。我们支持 php 5.5、5.6 和 7.0。
简单示例
您可以在测试目录中找到如何使用包装器及其任何部分的许多示例(您可能永远不会接触到的),这些测试使用PHPUnit进行,非常小,每个只有几行,是开始的好地方。鉴于这一点,我仍将展示如何使用此包的示例。以下示例是该包非常简单的使用方法,是一个很好的开始。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $summoner = $api->summoner(); // Load up the summoner request object. $bakasan = $summoner->info('bakasan'); // Get the information about this user. $bakasan = $summoner->info(74602); // same thing as above, just to show that an id will work echo $bakasan->summonerLevel; // 30 echo $bakasan->id; // 74602 echo $bakasan->name; // "bakasan" echo $bakasan->profileIconId; // 24 echo $bakasan->revisionDate; // 1387391523000 echo $bakasan->revisionDateStr; // "12/18/2013 06:32 PM UTC"
上面的代码获取了用户 'bakasan' 的基本信息。上面的例子说明了事物工作的一般思路。您用给定的密钥加载API,这个API对象可以尽可能多地使用,并鼓励只有一个实例。从API中,您可以选择要查询的API(在这种情况下是召唤师API)。最后,您使用一个方法,取决于您查询的API,对该API执行请求。
区域
您可以设置您想要查询的区域。默认为 'na',但可以更改为任何字符串。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $api->setRegion('euw'); // Set the region to 'euw'
上面的代码很简单,适用于此API将生成的所有API请求对象。还有一个内置的支持用于限制区域访问的API调用。继续上面的代码片段。
$api->setRegion('br'); // Set the region to 'br' $champions = $api->champion()->free(); // will throw a LeagueWrap\Api\RegionException
上面的例子中 LeagueWrap\Api\RegionException
将包含字符串 'The region "br" is not permited to query this API.'
。
需要注意的是,一些区域,如 kr,需要使用特定的 URL,并且不能在 prod.api.pvp.net
上工作。这会自动处理,并且只要您有最新的包装器版本,您就无需担心这一点。
缓存
缓存非常重要,我们都知道这一点,考虑到每个应用程序都有限制查询数量的限制,因此本软件包的这一部分对每个开发人员来说都非常重要。鉴于此,默认情况下,缓存需要安装并运行在默认端口和本地主机上的memcached
。这可以通过实现自己的LeagueWrap\CacheInterface
版本来轻松更改。让我们从如何使用缓存的示例开始。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $api->remember(60); // Set the cache to remember every request for 60 seconds // or $api->remember(); // Enable cache with the default value for each API call. $api->remember(null); // Same as above, null is the default value
上述内容适用于通过$api
方法进行的每个未来请求。如果您希望为任何单个请求设置缓存时间,考虑到事物变化的速度不同,这是合理的。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $summoner = $api->summoner() // Get the summoner API request object ->remember(3600); // Remember all request done by this single request object $bakasan = $summoner->info('bakasan'); // This request is cached for 1 hour (3600 seconds)
现在,我们只会将info()方法的响应缓存1小时(3600秒)。所有其他API对象,如League,都不会受到影响,并且默认情况下不会缓存响应。如果您希望只有在请求命中缓存时才获取响应,可以启用cacheOnly
标志。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $api->remember() // Enable cache with the default values. ->setCacheOnly() // Only check the cache, don't do any http requests.
如果请求未在缓存中找到,将抛出LeagueWrap\Exception\CacheNotFoundException
异常。类似于remember()
方法,这也可以在API端点对象上调用,以仅影响某些请求或端点,而不会影响其他端点。
现在,假设您不想使用memcached,或者希望使用框架提供的缓存服务?我完全理解,这就是为什么您可以实现LeagueWrap\CacheInterface
以实现自己的缓存。这种依赖注入(DI)在快速参考部分中也被API客户端使用。要使用自己的缓存实现,您只需做以下操作。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $api->remember(60, $myCache); // Set the cache to use your own cache implementation // or $api->remember(null, $myCache); // Set the cache implementation but keep the default cache times
使用StaticProxys做起来甚至更容易,您将在速率限制部分之后看到。
速率限制
即使在缓存的情况下,您还必须考虑施加在API密钥上的速率限制。考虑到这一点,我们添加了对限制API请求速率的支持,类似于对缓存的支持。速率限制方法需要安装并运行在默认端口和本地主机上的memcached
。与缓存实现一样,您始终可以使用自己的LeagueWrap\LimitInterface
版本。让我们从一个基本的示例开始。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $api->limit(10, 10); // Set a limit of 10 requests per 10 seconds $api->limit(500, 600); // Set a limit of 500 requests per 600 (10 minutes) seconds
上述内容将为当时为平均开发人员密钥设置的2个限制。您可以向集合中添加尽可能多的限制,每个限制都将跟踪在memcached内存中。如果您超过限制,应用程序将抛出LeagueWrap\Limit\LimitReachedException
异常。与缓存一样,使用适当的DI实现此功能也很简单,您甚至可以使用多个限制接口……尽管我不认为这有什么意义。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API $api->limit(10, 10, $myLimiter); // Set a limit using your own limit implementation $api->limit(500, 600, $myLimiter);
请注意,限制功能完全支持以下部分中描述的静态API。
附加静态数据
某些请求包含静态ID,这些ID引用静态API中的数据。为此,您需要获取原始数据,提取ID,然后对静态API进行调用。我们使整个过程更加简单,并优化我们为所有数据进行的API请求数量,以减少带宽和请求数量。额外的静态请求不计入您的请求限制,因此,从这个意义上说,这不会影响您在特定时间内可以进行的请求数量,它只是消耗时间。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the Api $api->attachStaticData(); // Tell the api to attach all static data $champion = $api->champion()->championById(10); // Get the champion by id 10 echo $champion->championStaticData->name; // Outputs "Kayle"
它还将优化静态调用,使以下示例仅尝试3次静态API调用,即使它需要20多个不同的静态ID以支持多个DTO。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the Api $api->attachStaticData(); // Tell the API to attach all static data $match = $api->match()->match(1399898747); echo $match->team(0)->ban(0)->championStaticData->name; // outputs LeBlanc
静态代理
您可以通过静态客户端使用LeagueWrap来简化发送API请求的过程。
LeagueWrap\StaticApi::mount(); // Mount all the static static proxys Api::setKey('my-key'); // set the key for the API $summoner = Api::summoner(); // get a LeagueWrap\Api\Summoner instance $summoner->info('bakasan'); // get info about summoner echo $summoner->bakasan->id; // 74602 // or Summoner::info('bakasan'); // get info about the summoner 'bakasan' echo Summoner::get('bakasan')->id // 74602 Game::recent(Summoner::get('bakasan')); // get the recent games for bakasan $game = Summoner::get('bakasan')->recentGame(0); // get the most recent game
所有正常的API方法和API请求都可以使用静态代理进行,您不再需要LeagueWrap\Api
的实例。在调用任何API请求之前,您必须至少设置一次密钥,一旦设置,它将到处使用。同样的规则也适用于缓存提醒。
LeagueWrap\StaticApi::mount(); // Mount all the static static proxys Api::setKey('my-key'); // set the key for the API Api::remember(60); // cache all request for 60 seconds $bakasan = Summoner::info('bakasan'); // cached for 60 seconds // or Api::remember(60, $myCache); // cache all request using my own $bakasan = Summoner::info('bakasan'); // cached for 60 seconds using $myCache
并且有限制。
LeagueWrap\StaticApi::mount(); // Mount all the static static proxys Api::setKey('my-key'); // set the key for the API Api::remember(); // cache all request for the default number of seconds Api::limit(10, 10); // Limit of 10 request per 10 seconds Api::limit(500, 600); // Limit of 500 request per 10 minutes $bakasan = Summoner::info('bakasan'); // cached for 60 seconds
Http错误异常
当您尝试使用此API进行任何请求,并且由于某种原因,从API收到http错误时,我们将抛出异常。所有Http异常都可以在LeagueWrap\Response
命名空间中找到。异常分为3级,具体取决于您希望如何捕获异常。
use LeagueWrap\Api; $api = new Api($myKey); // Load up the API try { $summoner = $api->summoner(); // Load up the summoner request object. } catch (LeagueWrap\Response\Http404 $e) { // Only thrown when a 404 http error is found } catch (LeagueWrap\Response\HttpClientError $e) { // All Http4XX extend this abstract class. // Which is a catch all for client errors } catch (LeagueWrap\Response\ResponseException $e) { // All http error codes extends from this abstract class. // This is a catch all (both 4xx and 5xx http errors) // To get more detailed information about the response, the following methods are available $e->hasResponse(); // Checks if response was attached $response = $e->getResponse(); // Instance of LeagueWrap\Response // In some cases like resolving 429 status codes, information from headers could be useful // see: https://developer.riotgames.com/docs/rate-limiting $headers = $response->getHeaders(); // ['Retry-After' => ..., ...] $response->hasHeader('Retry-After'); $response->getHeader('that does not exist'); // null } catch (LeagueWrap\Response\UnderlyingServiceRateLimitReached $e) { // See https://github.com/paquettg/leaguewrap/issues/119 // Extends Http429 for backwards compatibility }
我们尝试实现API应该向您抛出的所有已记录的错误代码。响应消息也可以在Riot API文档中找到。
快速参考
LeagueWrap为API实现了一个非常严格的接口,其中所有内容都在您的控制之下,并且易于测试。以下是一些可能的启动方法的示例。
使用密钥创建一个新的Api实例。密钥是必需的,如果未提供,将抛出LeagueWrap\NoKeyException
。此实例将用于组织对API的后续调用,而无需重新输入密钥。
$api = new \LeagueWrap\Api($myKey);
使用DI原则,我们允许您注入自己的客户端对象,该对象实现了LeagueWrap\ClientInterface
。如果您愿意,可以使用自己的REST客户端而不是Guzzle(这是随包提供的)。
$api = new \LeagueWrap\Api($myKey, $myClient);
数组访问
许多DTO响应将扩展LeagueWrap\Dto\AbstractListDto
而不是LeagueWrap\Dto\AbstractDto
。扩展抽象列表的DTO将获得用作数组进行访问、遍历(使用foreach()
)和计数(使用count()
)的能力。
$game = $api->game(); $games = $game->recent(74602); $mostRecent = $games->game(0); // instead to access $mostRecent = $games[0]; // traversing foreach ($games as $game) { // do some stuff to each recent game } // counting $recentGameCount = count($games);
设置超时
值得注意的是,LeagueWrap\ClientInterface
接口有一个名为setTimeout($seconds)
的方法。您可以通过在请求对象上调用此方法来调用此功能。
$game = $api->game() ->setTimeout(3.14); // wait a maximum of 3.14 seconds for a response.
或者,您可以直接在API对象上调用它,这将适用于创建的任何未来的请求对象。
$api->setTimeout(3.14); $game = $api->game(); $mostRecent = $game->recent(74602); // this reques will wait a maximum of 3.14 seconds for a response.
召唤师
要获取LeagueWrap\Api\Summoner
对象的实例,该对象用于请求召唤师API的信息。这是获取此对象的主要方式。
$summoner = $api->summoner();
选择召唤师API要使用的有效版本。这些版本可以在对象类文件中找到,我们的目标是支持任何主要版本的最多两个次要版本。因此,如果v1.2已经发布超过一个月,您不应期望能够使用v1.1。
$summoner->selectVersion('v1.2')
通过召唤师名称'bakasan'进行召唤师信息请求将返回一个包含此召唤师信息的LeagueWrap\Dto\Summoner
DTO。
$bakasan = $summoner->info('bakasan');
您也可以通过召唤师ID 76204进行信息请求。它与上面的方法相同。
$info = $summoner->info(76204);
要执行单个请求并获取多个召唤师ID的信息,您可以传递一个数组。然后,它将返回有关这些召唤师的所有信息的数组。您真的应该使用此方法获取多个召唤师的信息,因为它只消耗您1次请求。
$summoners = $summoner->info([ 76204, 1234, 111111, 1337, ]);
您还可以混合使用ID和名称,并返回一个数组。但这将需要2次请求,所以请小心使用。另一个限制是每个请求的ID和名称限制为40个,这是API强加的,如果尝试这样做,我们将抛出LeagueWrap\Api\ListMaxException
。
$summoners = $summoner->info([ 76204, 'C9 Hai', 'riot', 1234, ]);
如果您想知道使用单个API对象已经执行了多少请求,您可以始终请求请求计数。它将简单地返回到目前为止对API执行的请求次数。
$summoner->getRequestCount()
要获取召唤师名称而不获取其他信息(节省数据传输和速度),可以使用召唤师对象中的name()方法。
$names = $summoner->name(76204);
它还接受一个id数组而不是单个id,并将返回一个关联数组,其中 id => summonername
。
$names = $summoner->name([ 76204, 1234, 1337, 123456789 ]);
要获取召唤师的符文页,有多种选择。首先使用召唤师请求对象和召唤师id。这将返回一个LeagueWrap\Dto\RunePage
对象数组。runePages()方法还接受一个id数组而不是单个id。
$runePages = $summoner->runePages(76204);
最后,您可以使用从info()接收的召唤师dto对象或此类对象的数组。
$summoner->runePages($bakasan);
当使用上述方法并传入召唤师dto对象以获取召唤师的第一符文页时,您可以调用对象的runePage()
方法。runepage的索引是方法调用中预期的第一个参数。
$runePage = $bakasan->runePage(0);
同样适用于精通页,但使用的是召唤师请求对象上的masteryPages()
方法而不是runePages()
方法。我们还有一个快捷方法allInfo
,它将获取每个传入召唤师的所有信息。它的工作方式与info
相同,但会额外进行两次请求以获取符文页和精通页信息
$bakasan = $summoner->allInfo(76204); // 3 requests // or $summoners = $summoner->allInfo([ 76204, 'C9 Hai', 'riot', 1234, ]); // this will take 4 requests
英雄
英雄API非常简单,因为API中的大部分信息都是静态信息,所以您最好从静态API获取这些信息。要获取英雄请求对象,您可以调用API实例上的champion()
方法。
$champion = $api->champion();
要一次性获取所有英雄信息,只需调用all()
方法即可。它将返回一个LeagueWrap\Dto\ChampionList
对象。
$champions = $champion->all(); $kayle = $champions->getChampion(10); // or $kayle = $champions->champions[10];
您也可以通过id获取单个英雄的信息。
$aatrox = $champion->championById(266);
最后,您可以获取给定区域的全部免费英雄列表。这将返回一个包含给定区域和周每个免费英雄的LeagueWrap\Dto\ChampionList
对象。
$freeChampions = $champion->free();
游戏
游戏API非常简单,但返回了大量关于给定召唤师的信息。要获取此请求对象,您只需调用API对象上的game()
即可。
$game = $api->game();
我们有两种获取召唤师最近游戏信息的方法。您可以传入召唤师id或之前调用info时加载的召唤师对象LeagueWrap\Dto\Summoner
。
$games = $game->recent(74602); $game = $games->recentGame(0); // or $game = $games->games[0]; // or $game->recent($bakasan); $game = $bakasan->recentGame(0);
比赛
注意:MatchHistory API端点已被Riot弃用,并于2015年9月22日删除。请使用Matchlist端点代替!
Match API可以用来获取比游戏API提供的更详细的比赛历史记录。这仅包括排名靠前的游戏。您可以传入召唤师id或召唤师对象LeagueWrap\Dto\Summoner
。
$matchHistory = $api->matchHistory(); $matches = $matchHistory->history(74602); $match = $matches[0];
Matchlist API为您提供自Match API上线以来所有已玩排名靠前比赛的压缩列表。它将返回一个LeagueWrap\Dto\MatchList
对象,您可以通过传入召唤师id或召唤师对象LeagueWrap\Dto\Summoner
来获取。
$matchlistapi = $api->matchlist(); $matchlist = $matchlist->matchlist(30447079); $numberOfplayedGames = $matchlist->totalGames; $roleInGame = $matchlist->match(0)->role;
您可以添加过滤器参数,包括队列、赛季、已玩英雄、起始和结束索引以及时间。
$matchlistapi = $api->matchlist(); $matchlist = $matchlist->matchlist(30447079, "RANKED_SOLO_5x5", "SEASON2015", [1,2,3], 5, 7, 12346586, 35483434);
对于更具体的比赛信息,可以使用match API获取每个召唤师的详细统计数据以及可选的事件时间线。作为参数,您需要传递从LeagueWrap\Dto\Match->matchId
、LeagueWrap\Dto\MatchReference->matchId
或LeagueWrap\Dto\Game->gameId
获取的比赛id。
$matchapi = $api->match(); $match = $matchapi->match(1399898747);
要包含时间线
$matchapi = $api->match(); $match = $matchapi->match(1399898747, true); $timeline = $match->timeline
联赛
League API的文档尚未完成,但它是完全功能的。
$league = $api->league();
统计
Stat API的文档尚未完成,但它是完全功能的。
$stat = $api->stat();
英雄精通
Champion mastery API的文档尚未完成,但它是完全功能的。
$championMastery = $api->championMastery(); $masteryList = $championMastery->champions($summonerId); $championPointsAnnie = $masteryList->getChampion(1)->championPoints
团队
Team API的文档尚未完成,但它是完全功能的。
$team = $api->team();
当前游戏
当前游戏API提供了有关正在进行的游戏的信息。
// receive a current game $currentGame = $api->currentGame(); $game = $currentGame->currentGame($summonerId); $game->ban(1) // first ban of the ban phase $game->observers->encriptionKey // observer key for spectating // participant of a game $participant = $game->participant($summonerId) $participant->masteries $participant->runes $participant->championId
静态数据
静态数据API的文档尚未完整,但功能完全正常。
$staticData = $api->staticData();
状态
状态API的文档尚未完整,但功能完全正常。
$status = $api->status(); $shardStatus = $status->shardStatus('euw'); $service = $shardStatus->getService('Game'); if(sizeof($service->incidents) > 0) echo "There are incidents";
免责声明
用户有责任评估内容,我不会对因使用本开源软件造成的任何损害或损失承担责任。我们不保证软件会按预期运行,用户有责任确保与软件的交互是正确的。
本产品未经Riot Games,Inc.及其任何关联公司的任何形式的认可、认证或批准。