lorempixel.com さん再び使えなくなる
前回の 2019-06-11 時点では fzaninotto/Faker で image() を使ってて $faker->image() が false になるよ に続き、 2019-06-13 23:48 現在 lorempixel.com さんが落ちています。
前回は https://github.com/fzaninotto/Faker/issues/1710 にある通り、 SSL Certs の期限切れでのエラーでした。
で、ちょっとしたら Let's encrypt の証明証を更新されたようで、もとに戻っていました。(時刻は記録してなのですが、実際に手元で Seeder を走らせて問題なく動いていた。)
で、今は https://github.com/fzaninotto/Faker/issues/1712 にある通り、 2019-06-13 15:00 JST あたりですでに And it seems down now.
と。
とりあえずの対応方法:結論
/vendor/fzaninotto/faker/src/Faker/Provider/Image.php
public static function imageUrl($width = 640, $height = 480, $category = null, $randomize = true, $word = null, $gray = false)
{
- $baseUrl = "https://lorempixel.com/";
+ // $baseUrl = "https://lorempixel.com/";
+ $baseUrl = "https://picsum.photos/";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
- $success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
+ // $success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
+ $success = curl_exec($ch) && (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200 or curl_getinfo($ch, CURLINFO_HTTP_CODE) === 302 or curl_getinfo($ch, CURLINFO_HTTP_CODE) === 301);
なお、 vendor 以下を直接書き換えるのは望ましくないですね。
できれば Fork してから対応し、 Fork した方を composer から利用するようにするのが望ましいと思います。
どうしよう
lorempixel.com さんダウンで、どうしよう。
自前で imagemgak か gd で頑張るのも、まぁありといえばありなのですが、面倒です。
とう言うわけで、楽に終わる代替サービスを探してみました。
で、 https://picsum.photos/ これ。
やった!同じやん!これは URL 部分を差し替えれば良いだけだね!
URL を差し替えてみた
lorempixel
で検索したところ、 /vendor/fzaninotto/faker/src/Faker/Provider/Image.php
に $baseUrl = "https://lorempixel.com/";
といった具合に lorempixel.com がハードコーディングされてることが確認できました。
これを差し替えればおしまいですね!
というわけで早速以下のように変更。
- $baseUrl = "https://lorempixel.com/";
+ // $baseUrl = "https://lorempixel.com/";
+ $baseUrl = "https://picsum.photos/";
で、動かしてみるものの、 $fakeImage = $faker->image(...);
の結果は false 。
調査
xdebug を使えるように仕込んだ Docker Container なので、 # export XDEBUG_CONFIG="idekey=PHPSTORM"
として、環境変数を設定してから PhpStorm で以下のメソッドのそれっぽい箇所に BreakPoint を仕込んで再度 Seeder を走らせてみました。
public static function image($dir = null, $width = 640, $height = 480, $category = null, $fullPath = true, $randomize = true, $word = null)
{
$dir = is_null($dir) ? sys_get_temp_dir() : $dir; // GNU/Linux / OS X / Windows compatible
// Validate directory path
if (!is_dir($dir) || !is_writable($dir)) {
throw new \InvalidArgumentException(sprintf('Cannot write to directory "%s"', $dir));
}
// Generate a random filename. Use the server address so that a file
// generated at the same time on a different server won't have a collision.
$name = md5(uniqid(empty($_SERVER['SERVER_ADDR']) ? '' : $_SERVER['SERVER_ADDR'], true));
$filename = $name .'.jpg';
$filepath = $dir . DIRECTORY_SEPARATOR . $filename;
$url = static::imageUrl($width, $height, $category, $randomize, $word);
// save file
if (function_exists('curl_exec')) {
// use cURL
$fp = fopen($filepath, 'w');
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_FILE, $fp);
$success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
fclose($fp);
curl_close($ch);
if (!$success) {
unlink($filepath);
// could not contact the distant URL or HTTP error - fail silently.
return false;
}
} elseif (ini_get('allow_url_fopen')) {
// use remote fopen() via copy()
$success = copy($url, $filepath);
} else {
return new \RuntimeException('The image formatter downloads an image from a remote HTTP server. Therefore, it requires that PHP can request remote hosts, either via cURL or fopen()');
}
return $fullPath ? $filepath : $filename;
}
で、その結果、以下の if 節で false となっていることが判明しました。
if (!$success) {
unlink($filepath);
// could not contact the distant URL or HTTP error - fail silently.
return false;
}
つまり怪しいのは 、ここ。
$success = curl_exec($ch) && curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200;
とりあえず、どんな URL に実際にリクエストを出しているのか理解するため Debugger から Variables を確認したところ、 $url = https://picsum.photos/1200/300/?82828
となっていることを確認しました。
うん、正しいっぽい。
とりあえず、この URL にブラウザからアクセスしてみましょう。
https://picsum.photos/1200/300/?82828 → https://picsum.photos/id/430/1200/300
はい、 URL が書き換わっておりました。
これはおそらくリダイレクトレスポンスか何かを出してますね。
というわけで、 Chrome の dev tool の network タブあたりから確認してみましょう。
やっぱり、 301, 302 ですね!
このあたりをフォローしたら大丈夫そうです。
というわけで、前述の記述に至りました。
あくまで、暫定対応です。