首先它应该是可以在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); }
备份下载链接