FuelPHPの最新バージョンがPHP8に対応していないということで、ソースを手作業で修正しました。
最も手こずったのが、画像が真っ黒に表示されるという問題です。画像の枠自体は表示されますが中身が真っ黒になります。ブラウザにもログにもエラーが出ないためなかなか原因がわかりませんでした。
原因は画像の描画を行っているgd.phpのload()関数にありました。
fuel/core/classes/image/gd.php
public function load($filename, $return_data = false, $force_extension = false)
{
extract(parent::load($filename, $return_data, $force_extension));
$return = false;
$image_extension == 'jpg' and $image_extension = 'jpeg';
if ( ! $return_data)
{
$this->image_data !== null and imagedestroy($this->image_data);
$this->image_data = null;
}
// Check if the function exists
if (function_exists('imagecreatefrom'.$image_extension))
{
// Create a new transparent image.
$sizes = $this->sizes($image_fullpath);
$tmpImage = call_user_func('imagecreatefrom'.$image_extension, $image_fullpath); // ★
$image = $this->create_transparent_image($sizes->width, $sizes->height, $tmpImage);
if ( ! $return_data)
{
$this->image_data = $image;
$return = true;
}
else
{
$return = $image;
}
$this->debug('', "<strong>Loaded</strong> <code>".$image_fullpath."</code> with size of ".$sizes->width."x".$sizes->height);
}
else
{
throw new \RuntimeException("Function imagecreatefrom".$image_extension."() does not exist (Missing GD?)");
}
return $return_data ? $return : $this;
}
16行目で取得している$tmpImageが目的の画像イメージです。次の行でそれをcreate_transparent_image()関数の第3引数に渡しています。
create_transparent_image()の第3引数がnullだと下から4行目のimagecopy()を通らないので下地だけの画像のままになります。imagecopyを通れば画像は引数で渡したものになります。今回、第3引数ありますが、なぜかないと認識されてデフォルトのnullになるようになっていました。
確かにGDクラスのすべての関数の戻り値はPHP8でresource型からGDImage型に変更になったため$tmpImageもGDImage型になっていますが、引数がnullとなる直接的な原因はわかりませんでした。
protected function create_transparent_image($width, $height, $resource = null)
{
$image = imagecreatetruecolor($width, $height);
$bgcolor = $this->config['bgcolor'] == null ? '#000' : $this->config['bgcolor'];
$color = $this->create_color($image, $bgcolor, 0);
imagesavealpha($image, true);
if ($this->image_extension == 'gif' || $this->image_extension == 'png')
{
// Get the current transparent color if possible...
$transcolor = imagecolortransparent($image);
if ($transcolor > 0)
{
$color = $transcolor;
}
imagecolortransparent($image, $color);
}
// Set the blending mode to false, add the bgcolor, then switch it back.
imagealphablending($image, false);
imagefilledrectangle($image, 0, 0, $width, $height, $color);
imagealphablending($image, true);
if (is_resource($resource))
{
imagecopy($image, $resource, 0, 0, 0, 0, $width, $height);
}
return $image;
}
対応としては
①第3引数のデフォルトのnullを削除する。
protected function create_transparent_image($width, $height, $resource = null)
↓
protected function create_transparent_image($width, $height, $resource)
② GDImaigeを判定に加える
if (is_resource($resource))
↓
if (is_resource($resource) || $resource instanceof \GdImage)
としました。引数のデフォルト値を削除したためこの関数を呼び出してるすべての箇所において修正をしました。
これらの修正で正常に画像が表示されるようになりました。
gdクラスの変更点についてこちらの記事も参考になさって下さい。
`GdImage` class objects replace GD image resources – PHP 8.0 • PHP.Watch