読者です 読者をやめる 読者になる 読者になる

Zend Framework 2 の ZendDeveloperTools で GitHub API の 403 エラーが表示される

Zend Framework 2.1.5 でデバッグツールバー(ZendDeveloperTools)を入れてみたところ、次のようなエラーが表示されました。

Warning: file_get_contents(https://api.github.com/repos/zendframework/zf2/git/refs/tags/release-):
  failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
    in /path/to/Zend/Version/Version.php on line 83

github から zf2 のリリースタグの一覧を取得しようとして失敗したようです。最新のバージョン番号をツールバーで表示するためでしょう。

エラーメッセージから察するに https://api.github.com/repos/zendframework/zf2/git/refs/tags/release- からの応答が 403 Forbidden になっているみたいですが、 ブラウザからアクセスすると何事も無く結果が返ってきます。

PHP からアクセスしたときだけ 403 になります・・・

$ php -a

php> readfile("https://api.github.com/repos/zendframework/zf2/git/refs/tags/release-");

Warning: readfile(https://api.github.com/repos/zendframework/zf2/git/refs/tags/release-): failed to open stream: HTTP request failed! HTTP/1.1 403 Forbidden
 in php shell code on line 1

レスポンスボディも表示するために http ストリームコンテキストの ignore_errorstrue にすると・・・

$ php -a

php> stream_context_set_default(array("http" => array("ignore_errors" => true)));
php> readfile("https://api.github.com/repos/zendframework/zf2/git/refs/tags/release-");

{"message":"Missing or invalid User Agent string. See http://developer.github.com/v3/#user-agent-required"}

ユーザーエージェントが設定されていないことが原因でした。 PHP の http ストリームラッパーってデフォルトではユーザーエージェントを設定しないんですね、知りませんでした。

コンテキストのオプションでユーザーエージェントを指定するとエラーは無くなりました。

$ php -a

php> stream_context_set_default(array("http" => array("user_agent" => "php")));
php> readfile("https://api.github.com/repos/zendframework/zf2/git/refs/tags/release-");

...

php.ini でデフォルトが設定できるので、適当な値を設定しておくといいでしょう。

user_agent = php

というか zf2 の最新のバージョン番号が見れても別にうれしくないので、無効にしておきました。

config/autoload/zenddevelopertools.local.php

<?php
return array(
    'zenddevelopertools' => array(
        
        :
        
        'toolbar' => array(
            
            /**
             * If enabled, the Toolbar will check if your current Zend Framework version
             * is up-to-date.
             *
             * Note: The check will only occur once every hour.
             *
             * Expects: bool
             * Default: false
             */
            'version_check' => false,
            
             :
        ),
    ),
);