首先它应该是可以在SHELL中运行的,而不是单纯的浏览器中运行来应对大型,多图片网站 运行方式应该是如下:
screen -S updateimage
php update_product_images.php
我们来网站的根目录下,或是pub目录下来建立此文件update_product_images.php用如下代码
付费内容限时免费中...
<?php
use Magento\Framework\App\Bootstrap;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\Exception\LocalizedException;
// 开启错误报告以便调试
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 设置更大的内存限制和执行时间,以防产品过多
ini_set('memory_limit', '2048M');
set_time_limit(86400); // 24小时
try {
// 引导Magento应用
require __DIR__ . '/app/bootstrap.php';
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
// 设置区域代码为 'adminhtml' 以便有权访问所有数据
$state = $objectManager->get(\Magento\Framework\App\State::class);
$state->setAreaCode('adminhtml');
// 获取所需的服务
$filesystem = $objectManager->get(\Magento\Framework\Filesystem::class);
$mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$productCollectionFactory = $objectManager->get(\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory::class);
$productRepository = $objectManager->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
// 创建产品集合
$collection = $productCollectionFactory->create();
$collection->addAttributeToSelect(['name', 'sku']); // 只需要名称和SKU用于日志
echo "开始处理产品图片...\n";
$productCount = $collection->getSize();
echo "找到 " . $productCount . " 个产品。\n\n";
$processedCount = 0;
// 遍历所有产品
foreach ($collection as $product) {
$processedCount++;
echo "--------------------------------------------------\n";
echo "正在处理产品 " . $processedCount . "/" . $productCount . " - SKU: " . $product->getSku() . "\n";
try {
// 必须加载完整的产品对象才能获取和修改媒体库
$productToUpdate = $productRepository->getById($product->getId());
$productName = $productToUpdate->getName();
$mediaGalleryEntries = $productToUpdate->getMediaGalleryEntries();
if (empty($mediaGalleryEntries)) {
echo " - 产品没有图片,跳过。\n";
continue;
}
echo " - 产品名称: " . $productName . "\n";
$imageCounter = 1;
$hasChanges = false;
// 清理产品名称以用作安全的文件名
$cleanProductName = preg_replace('/[^a-z0-9_\\-\\.]/i', '-', strtolower($productName));
$cleanProductName = trim(preg_replace('/-+/', '-', $cleanProductName), '-');
// 遍历产品的媒体库条目
foreach ($mediaGalleryEntries as $entry) {
$originalPath = $entry->getFile();
// 跳过视频等非图片类型
if ($entry->getMediaType() !== 'image') {
echo " - 跳过非图片媒体: " . $originalPath . "\n";
continue;
}
$originalExtension = pathinfo($originalPath, PATHINFO_EXTENSION);
// 构建新的文件名
$newFileName = $cleanProductName . '-' . $imageCounter . '.' . $originalExtension;
$newPath = '/' . $newFileName[0] . '/' . $newFileName[1] . '/' . $newFileName; // Magento的路径结构 /a/b/abc.jpg
// 如果新旧路径相同,则无需处理
if ($originalPath === $newPath) {
echo " - 图片已经是新格式: " . $originalPath . ",跳过。\n";
$imageCounter++;
continue;
}
$absoluteOriginalPath = 'catalog/product' . $originalPath;
$absoluteNewPath = 'catalog/product' . $newPath;
if ($mediaDirectory->isExist($absoluteOriginalPath)) {
try {
// 重命名物理文件
$mediaDirectory->renameFile($absoluteOriginalPath, $absoluteNewPath);
// 更新媒体库条目中的文件路径
$entry->setFile($newPath);
$hasChanges = true;
echo " - 成功: " . $originalPath . " -> " . $newPath . "\n";
} catch (LocalizedException $e) {
echo " - 错误: 无法重命名文件 " . $absoluteOriginalPath . ". 原因: " . $e->getMessage() . "\n";
}
} else {
echo " - 警告: 找不到原始文件 " . $absoluteOriginalPath . ",跳过。\n";
}
$imageCounter++;
}
// 如果有更改,则更新产品并保存
if ($hasChanges) {
$productToUpdate->setMediaGalleryEntries($mediaGalleryEntries);
$productRepository->save($productToUpdate);
echo " - 产品 " . $productToUpdate->getSku() . " 的图片信息已更新。\n";
} else {
echo " - 产品 " . $productToUpdate->getSku() . " 无需更新。\n";
}
} catch (Exception $e) {
echo " - 处理产品 SKU: " . $product->getSku() . " 时出错: " . $e->getMessage() . "\n";
}
}
echo "\n所有产品处理完毕。\n";
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
echo "重要:请立即在Magento根目录运行以下命令以防止前台链接出错:\n";
echo "1. bin/magento indexer:reindex\n";
echo "2. bin/magento catalog:images:resize\n";
echo "3. bin/magento cache:flush\n";
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n";
} catch (Exception $e) {
echo "发生严重错误: " . $e->getMessage() . "\n";
exit(1);
}备份下载链接




