Call to undefined function imagecreatefromstring()

Markup (JSON-LD) structured in schema.orgプラグインのサポートページにエラー報告が。

[10-Feb-2017 16:22:13 UTC] PHP Fatal error: Uncaught Error: Call to undefined function imagecreatefromstring() in /…/wp-content/plugins/wp-structuring-markup/includes/wp-structuring-display.php:220

あら?!imagecreatefromstring()関数でエラーが出ているらしい。何でも、「GDはWordPressのインストール要件にありません。私達のサイトはImageMagickを採用しています。あなたのプラグインの要件にもGDのインストールする旨の注釈はありません。WordPressの規格に合わせてサムネイルジェネレータのコードを書き換えてください。とりあえずWebサイトのクラッシュを避けるために、GDの検出ルーチン(function_exists)を追加しました。」と書いてある。
そうか、ImageMagickの考慮が足りなかった…。ていうか、imagecreatefromstring()関数ってGDしか対応していないんだ。

サポートの内容にこれを使え的なURLが貼ってあった。WP_Image_Editorクラスだと!?こんなのあるんだ。無知とは恐ろしい。このクラスの内容を見ていって実装し直そうと思います。

wp_get_image_editor()関数

WP_Image_Editorクラスの例を見ると、wp_get_image_editorという関数でWP_Image_Editorクラスをreturnしている模様。ちょっとダンプして中身を確認。

$image = wp_get_image_editor( ABSPATH . 'wp-content/uploads/2017/02/kinoko.jpg' );

if ( ! is_wp_error( $image ) ) {
	var_dump( $image );
} else {
	echo "ERROR";
	var_dump( $image );
}

エラーなしでreturnされる値は「WP_Image_Editor_GD」が返ってきました。WP_Image_Editor_GDは、WP_Image_Editorを継承しています。

object(WP_Image_Editor_GD)[10681]
  protected 'image' => resource(396, gd)
  protected 'file' => string '/var/www/wordpress/wp-content/uploads/2017/02/kinoko.jpg' (length=56)
  protected 'size' => 
    array (size=2)
      'width' => int 3008
      'height' => int 2000
  protected 'mime_type' => string 'image/jpeg' (length=10)
  protected 'default_mime_type' => string 'image/jpeg' (length=10)
  protected 'quality' => int 82
  protected 'default_quality' => int 82

なるほど、ちゃんとWordPressにはGD用とImageMagick用の処理がわけてある。wp-includesディレクトリのmedia.phpの中に_wp_image_editor_choose()関数があってその中に処理が書いてあった。ImageMagickだと「WP_Image_Editor_Imagick」というクラスが返ってくる模様。

画像のサイズを取得

WP_Image_Editorクラスのget_size()メソッドで取得するようです。戻り値はarray型。

public function list_page_render () {
	$image = wp_get_image_editor( ABSPATH . 'wp-content/uploads/2017/02/kinoko.jpg' );


	if ( ! is_wp_error( $image ) ) {
		$size_array = $image->get_size();
		var_dump( $size_array['width'] );
		var_dump( $size_array['height'] );
	}
}

ものすごく簡単だ…。curlとか駆使して必死に画像サイズ取ってた処理って一体…。画像キャッシュ処理やcurlでの画像処理を書いていたソースコードが激的にスリムになった。62行あったソースコードが9行に軽量化。

/**
 * Return image dimensions
 *
 * @version 3.2.1
 * @since   2.3.3
 * @author  Justin Frydman
 * @author  Kazuya Takami
 * @param   string $url
 * @return  array | boolean $dimensions
 */
private function get_image_dimensions ( $url ) {
	$image = wp_get_image_editor( $url );

	if ( ! is_wp_error( $image ) ) {
		return $image->get_size();
	} else {
		return __return_false();
	}
}

バグ修正したバージョン3.2.1をリリースしました。リリースはいつもどきどきする。
Markup (JSON-LD) structured in schema.org
GitHub(今回対応した差分)