解决 PHP 8.1 隐式类型转换导致缩略图生成错误

  这几天解决了一个困扰已久的问题,我的博客系统在文章上传图片生成缩略图时,在本地测试环境没有任何问题,但在服务器环境中总是生成缩略图失败,报错:"Implicit conversion from float"。排查了 PHP 和环境扩展组件库、目录权限、图片格式大小等都没有问题。在百思不得其解时,我注意到了一个平时不太注意的细节,我在本地测试环境用的是 PHP 8.0,服务器上用的是 PHP 8.1,经过反复测试问题果然出在这里。

  由于生成缩略图时会对图片进行宽高尺寸和比例计算,然后对图片进行等比例缩放和裁切,生成相应尺寸的缩略图。在 PHP 8.1 中,报错 "Implicit conversion from float" 通常是因为在代码中将一个浮点数转换为了整数,而这个浮点数可能无法精确地表示为整数,从而导致了这个错误,而在 PHP 8.0 中没有这么严格的判定,则不会报错。

  要解决这个问题,可以采取以下几种方法:

  使用 (int) 强制转换:如果你确定要将浮点数转换为整数,可以使用 (int) 来强制转换。这将确保将浮点数舍入为最接近的整数。例如:

$floatValue = 10.5;  
$intValue = (int)$floatValue; // 将浮点数转换为整数

  使用 floatval() 函数:floatval() 函数可以将一个字符串或变量转换为浮点数。如果你不确定一个变量是否为浮点数,可以使用该函数来确保将其转换为浮点数。例如:

$value = "10.5";  
$floatValue = floatval($value); // 将字符串转换为浮点数

  避免隐式转换:在编写代码时,尽量明确地进行类型转换,而不是依赖于隐式转换。使用 (int) 或 (float) 来明确地指定你要进行的类型转换。例如:

$floatValue = 10.5;  
$intValue = (int)$floatValue; // 明确转换  
$floatValue2 = (float)$intValue; // 明确转换

  这是我用的缩略图生成类:

<?php
// 应用公共文件

/**
 * 居中裁剪图片
 * @param string $source [原图路径]
 * @param int $width [设置宽度]
 * @param int $height [设置高度]
 * @param string $target [目标路径]
 * @return bool [裁剪结果]
 */

function image_center_crop($source, $width, $height, $target)
{
	if (!file_exists($source)) return false;
	/* 根据类型载入图像 */
	switch (exif_imagetype($source)) {
		case IMAGETYPE_JPEG:
			$image = imagecreatefromjpeg($source);
			break;
		case IMAGETYPE_PNG:
			$image = imagecreatefrompng($source);
			break;
		case IMAGETYPE_GIF:
			$image = imagecreatefromgif($source);
			break;
	}
	if (!isset($image)) return false;
	/* 获取图像尺寸信息 */
	$target_w = $width;
	$target_h = $height;
	$source_w = imagesx($image);
	$source_h = imagesy($image);
	/* 计算裁剪宽度和高度 */
	$judge = (($source_w / $source_h) > ($target_w / $target_h));
	$resize_w = $judge ? ($source_w * $target_h) / $source_h : $target_w;
	$resize_h = !$judge ? ($source_h * $target_w) / $source_w : $target_h;
	$start_x = $judge ? ($resize_w - $target_w) / 2 : 0;
	$start_y = !$judge ? ($resize_h - $target_h) / 2 : 0;
	/* 绘制居中缩放图像 */
	$resize_img = imagecreatetruecolor($resize_w, $resize_h);
	imagecopyresampled($resize_img, $image, 0, 0, 0, 0, $resize_w, $resize_h, $source_w, $source_h);
	$target_img = imagecreatetruecolor($target_w, $target_h);
	imagecopy($target_img, $resize_img, 0, 0, $start_x, $start_y, $resize_w, $resize_h);
	/* 将图片保存至文件 */
	if (!file_exists(dirname($target))) mkdir(dirname($target), 0777, true);
	switch (exif_imagetype($source)) {
		case IMAGETYPE_JPEG:
			imagejpeg($target_img, $target);
			break;
		case IMAGETYPE_PNG:
			imagepng($target_img, $target);
			break;
		case IMAGETYPE_GIF:
			imagegif($target_img, $target);
			break;
	}
	return boolval(file_exists($target));
}

  知道问题的所在了,通过使用 (int) 进行显式转换,确保传递给图像处理函数的参数是整数类型,从而避免隐式类型转换错误。修改后的第 41 - 44 行代码:

$resize_img = imagecreatetruecolor((int)$resize_w, (int)$resize_h);  
imagecopyresampled($resize_img, $image, 0, 0, 0, 0, (int)$resize_w, (int)$resize_h, (int)$source_w, (int)$source_h);  
$target_img = imagecreatetruecolor((int)$target_w, (int)$target_h);  
imagecopy($target_img, $resize_img, 0, 0, (int)$start_x, (int)$start_y, (int)$resize_w, (int)$resize_h);

本站原创内容,转载请注明来源:https://www.liutonghui.com/231

华为Mate60手机开售,麒麟5G芯片回归,遥遥领先
上一篇 2023-08-31
虚拟主机部署ThinkPHP项目设置public目录方法
下一篇 2023-09-09

评论列表(0条)

  • 暂无评论

发表评论

captcha

相关推荐

  • PHP隐藏文件真实下载地址防盗链功能

      这个方案核心是隐藏文件真实地址,文件存放在网站根目录外(无法直接HTTP访问),或用权限锁定,只允许PHP。读取用动态临时下载链接替代,定时随机变更链接,随机密钥不可预测,过期自动失效。   校验来源域名、IP地址、链接有效期、签名,彻底防止盗链、批量下载、服务器过载。单IP限速、单文件并发下载限制、错误次数锁定,防止服务器过载。PHP代理输出文件,支持大文件断点续传   1.配置文件(config.php)统一管理密钥、有效期、限......

    2013-12-06
    21440
  • PHP生成HTML静态页原理

      在PHP中生成HTML文件静态页,在后续的访问可以直接加载静态文件而无需再次执行PHP脚本。这可以提高网站性能,减轻服务器负担,并改善页面加载速度。   用一个简单的小项目来说明PHP生成HTML静态页原理,包含:模板分离、自动创建目录、生成静态页、更新静态页、删除静态页、生成列表页+详情页、防重复生成、错误提示等功能。   项目结构 / ├── template/ # 模板文件夹 │ ├── index.h......

    2014-02-17
    15990
  • jQuery实现文件列表和缩略图模式切换

      做一个简单的仿网盘前端页面,实现文件以列表模式和缩略图模式切换功能。 &lt;!DOCTYPE html&gt; &lt;html lang="zh-CN"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;列表/缩略图模式切换&lt;/title&gt; &lt;script src="https://code.jquery.com/jquery-1......

    2015-03-09
    17250
  • Dedecms文章内容页和图片集内容页调用缩略图的方法

      织梦DedeCMS的缩略图一般显示在列表页,但有时我们需要在文章内容页缩略图的调用,图片集内容页缩略图的调用,使用方法如下:   文章内容页和图片集内容页,缩略图的调用。适合内页中调用。 &lt;img src="{dede:field.picname runphp='var_dmp(@me)' /}"/&gt;   文章频道页、列表页调用缩略图: {dede:list pagesize='20'} [field:array ru......

    2015-04-29
    28090
  • PHP文字水印,缩略图,图片水印实现类与用法示例

      本文实例讲述了PHP开发的文字水印,缩略图,图片水印实现类与用法。分享给大家供大家参考,具体如下:   1.实现类ImageToTest.class.php参考代码 class ImageToTest { /** * 图片的基本信息 */ private $info; private $image; public function __construct($src){ $info = getima......

    2020-08-22
    19930
  • PHP生成任意尺寸并居中裁剪缩略图的函数

      在项目中经常需要对图片进行各种处理,比如生成缩略图,并且生成的缩略图还要保持原有图片的宽高比例不变形,下面就分享一个非常好用的PHP生成缩略图函数,可以手动输入自定义尺寸并居中裁剪保持图片比例不变形,代码如下: &lt;?php // 应用公共文件 /** * 居中裁剪图片 * @param string $source [原图路径] * @param int $width [设置宽度] * @param int $heig......

    2020-10-03
    19922
  • ThinkPHP文件上传类FileSystem自定义生成年月日目录

      FileSystem 是一个非常好用的文件上传扩展类,结合 Thinkphp 使用可以轻松的完成文件上传功能的开发。但是默认情况下 FileSystem 是按照&ldquo;年月日&rdquo;来生成上传日期目录的,长期使用下来就会有大量的&ldquo;Ymd&rdquo;目录,不方便管理,像我平时更新内容不多,如果以&ldquo;Ym&rdquo;的格式生成目录,按同一年同一月上传的文件放在一个日期目录中就方便管理多了。   需要......

    2023-04-23
    10342
  • ThinkPHP获取数据库类型和版本的方法

      在开发后台功能时,可能会需要自动获取当前使用的数据库类型和版本的情况,下面就举个简单的例子实现自动获取当前项目使用的是MySQL还是SQLite数据库及使用的相应数据库版本的方法: // 数据库类型 $default = config('database.default'); $config = config('database.connections.' . $default); $db_type = strtolower(tri......

    2024-11-02
    8890