PHP导入Excel通信录图片需依赖单元格中存储的可访问绝对路径(本地或URL),读取后单独下载/读取/转存;图片应存文件系统而非数据库BLOB,数据库仅存相对路径,并重命名防乱码;远程URL下载须用cURL设超时与错误处理,失败记录日志并标记状态;上传前须校验MIME类型、跳过空行标题行、过滤XSS、确认数据规范。
Excel 本身不存图片二进制数据,只存图片链接或嵌入对象(Office 内部格式),所以直接用 PhpSpreadsheet 读取 Excel 时,getCell('A1')->getValue() 拿不到图片内容——它只会返回空、文字或 #N/A。真正能“导入图片”的路径只有一条:Excel 表格里那一列必须是**图片文件路径(本地或 URL)**,PHP 读到路径后,再单独下载/读取/转存。
/uploads/stu_001.jpg 或 https://example.com/img/2025/001.png
PhpSpreadsheet 读取时,对图片列字段做额外判断:if (filter_var($cellValue, FILTER_VALIDATE_URL) || is_file($cellValue)) { ... }
通信录中头像这类图片,99% 场景下不该存进数据库 BLOB 字段。MySQL 存图片会拖慢备份、增加主从同步压力、不方便 CDN 接入,而且 PHP 读取时还得 base64 编码/解码,徒增开销。
/public/uploads/avatar/ 这类 Web 可访问目录,数据库只存相对路径,如 avatar/2025/08/stu_1001_abc7d2.jpg
sha1(uniqid() . $originalName) 避免中文名、空格、
$_FILES['file']['error'] === UPLOAD_ERR_OK 和 getimagesize($_FILES['file']['tmp_name']) 防止上传伪造文件如果 Excel 里填的是远程 URL(比如微信头像链接),用 file_get_contents() 下载时容易因超时、403、证书问题失败。不能让整批导入卡住或静默丢图。
curl_init() 并设置 CURLOPT_TIMEOUT = 10、CURLOPT_SSL_VERIFYPEER = false(仅内网可信源)error_log("Failed to fetch avatar for stu_id=1001: {$url}");,但继续处理下一条avatar_status 字段(enum: 'pending','success','failed'),后续可人工补传用户上传 Excel 文件,PHP 要校验、读取、过滤、插入,每一步都有风险点。别直接 move_uploaded_file() 后就 new \PhpOffice\PhpSpreadsheet\Reader\Xlsx()。
finfo_file(finfo_open(FILEINFO_MIME_TYPE), $_FILES['excel']['tmp_name']) === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
foreach ($worksheet->getRowIterator(2) as $row)
trim($cell->getValue()) !== '' 判空,避免全空格干扰htmlspecialchars(strip_tags($value), ENT_QUOTES, 'UTF-8') 防 XSS(尤其备注栏可能含 HTML)