היה לנו פרויקט: קטלוג של 20,000 מוצרים, כל אחד דורש תמונה ראשית וגלריה של 5–8 צילומים. דרך ממשק הניהול של Bitrix, זה היה לוקח מספר שבועות עבודה של איש. אוטמטנו את התהליך באמצעות API ועיבוד אצווה — ההעלאה כולה ארכה 4 שעות. אותה גישה עובדת לכל נפח. אנחנו צוות של מפתחי Bitrix מוסמכים עם ניסיון של 10+ שנים, שאוטמטו העלאות עבור 500+ קטלוגים. אנו מבטיחים חיסכון בתקציב של פי 3–5 בהשוואה לעבודה ידנית. דוגמת תמחור: עבור קטלוג של 20,000 פריטים, אתם חוסכים כ-$3,000 בהשוואה לעבודה ידנית.
אוטמציית העלאת תמונות מוצר המונית שלנו עבור 1C-Bitrix מטפלת באלפי תמונות ביעילות, תוך ניצול Bitrix image API ושילוב CommerceML.
למה העלאה ידנית דרך ממשק הניהול היא דרך להפסד
בהעלאה ידנית דרך ממשק "בלוקי מידע → אלמנטים", צריך לפתוח כל מוצר ולצרף קובץ אחד אחד. עבור 20,000 מוצרים, זה 20,000 פעולות. בנוסף, בקרת איכות קשה: מוצרים שהוחמצו, תמונות שהתערבבו. הכי קריטי, זה יוצר עומס שרת לא מבוקר: כל לחיצה גורמת לטעינת עמוד מחדש, רענון מטמון, והפעלת אירועים. בקטלוגים גדולים, זה מוביל לזמן קצוב (timeouts) או הקפאות.
איך אנחנו אוטמטים את ההעלאה
אנחנו מכינים מבנה קבצים לפי SKU, קובץ מיפוי CSV, ומריצים סקריפט CLI ב-PHP. לפי התיעוד, CFile מנהל העלאות קבצים. הקוד למטה הוא סכמה בסיסית שאנחנו מתאימים לכל פרויקט (גדלי תמונות, פורמטים, שילוב 1C דרך CommerceML).
$csvRows = parseCsv('/import/mapping.csv'); // [['xml_id' => 'sku_001', 'files' => ['main.jpg', '2.jpg']]] foreach ($csvRows as $row) { // Находим элемент по XML_ID $element = \Bitrix\Iblock\ElementTable::getList([ 'filter' => ['XML_ID' => $row['xml_id'], 'IBLOCK_ID' => CATALOG_IBLOCK_ID], 'select' => ['ID'], ])->fetch(); if (!$element) continue; $imageDir = '/import/images/' . $row['xml_id'] . '/'; $files = []; foreach ($row['files'] as $i => $filename) { $filePath = $imageDir . $filename; if (!file_exists($filePath)) continue; $fileId = \CFile::SaveFile([ 'name' => $filename, 'type' => mime_content_type($filePath), 'tmp_name' => $filePath, 'error' => 0, 'size' => filesize($filePath), ], 'iblock'); if ($i === 0) { // Первый файл — основное изображение \CIBlockElement::Update($element['ID'], [ 'PREVIEW_PICTURE' => \CFile::MakeFileArray($filePath), 'DETAIL_PICTURE' => \CFile::MakeFileArray($filePath), ]); } else { $files[] = ['VALUE' => \CFile::MakeFileArray($filePath)]; } } // Множественное свойство галереи if (!empty($files)) { \CIBlockElement::SetPropertyValues($element['ID'], CATALOG_IBLOCK_ID, $files, 'MORE_PHOTO'); } } $csvRows = parseCsv('/import/mapping.csv'); // [['xml_id' => 'sku_001', 'files' => ['main.jpg', '2.jpg']]] foreach ($csvRows as $row) { // Находим элемент по XML_ID $element = \Bitrix\Iblock\ElementTable::getList([ 'filter' => ['XML_ID' => $row['xml_id'], 'IBLOCK_ID' => CATALOG_IBLOCK_ID], 'select' => ['ID'], ])->fetch(); if (!$element) continue; $imageDir = '/import/images/' . $row['xml_id'] . '/'; $files = []; foreach ($row['files'] as $i => $filename) { $filePath = $imageDir . $filename; if (!file_exists($filePath)) continue; $fileId = \CFile::SaveFile([ 'name' => $filename, 'type' => mime_content_type($filePath), 'tmp_name' => $filePath, 'error' => 0, 'size' => filesize($filePath), ], 'iblock'); if ($i === 0) { // Первый файл — основное изображение \CIBlockElement::Update($element['ID'], [ 'PREVIEW_PICTURE' => \CFile::MakeFileArray($filePath), 'DETAIL_PICTURE' => \CFile::MakeFileArray($filePath), ]); } else { $files[] = ['VALUE' => \CFile::MakeFileArray($filePath)]; } } // Множественное свойство галереи if (!empty($files)) { \CIBlockElement::SetPropertyValues($element['ID'], CATALOG_IBLOCK_ID, $files, 'MORE_PHOTO'); } } לא מעתיק את הקובץ — זה רק מערך תיאורי. CFile::MakeFileArray() מבצע את השמירה בפועל וכותב ל-CFile::SaveFile().
טכניקות אופטימיזציה מתקדמות כוללות שימוש בשאילתות D7 ORM כדי להביא אלמנטים מראש בקבוצות, מה שמפחית סבבי גישה למסד הנתונים. בנוסף, אפשר לנצל את מנוע המטמון של Bitrix כדי לאחסן תוצאות ביניים, ולהימנע מפעולות מערכת קבצים מיותרות.
אילו אתגרים טכניים עולים ואיך לפתור אותם
זמן קצוב (Timeouts). העלאת 50,000 קבצים דרך בקשת web היא בלתי אפשרית — אנחנו משתמשים בסקריפטים של CLI (b_file), ומסירים מגבלות עם php -f import.php ו-set_time_limit(0).
עומס שרת מוגזם עקב אירועים. כברירת מחדל, כל ini_set('memory_limit', '512M') מפעיל אירועי CIBlockElement::Update ו-OnBeforeIBlockElementUpdate. אלה יכולים לגרום לחישוב מחירים מחדש, ביטול מטמון, ועדכון אינדקס חיפוש. אנחנו משביתים זמנית מטפלים מיותרים באמצעות OnAfterIBlockElementUpdate.
בעיות מטמון. אחרי עדכונים המוניים, מטמון בלוק המידע מכיל הפניות קבצים מיושנות. בסוף הייבוא, אנחנו מנקים את המטמון באמצעות \Bitrix\Main\EventManager::getInstance()->removeEventHandler() — פעם אחת, לא בלולאה.
טיפול בשגיאות. אנחנו מנהלים לוג מפורט. אם קובץ חסר או פגום, הלוג מתעד את השגיאה, והתהליך ממשיך למוצר הבא. אחרי הייבוא, אנחנו מקבלים דוח של פריטים שדולגו.
השבתת מטפלי אירועים נוספים. במהלך עדכונים המוניים, \Bitrix\Iblock\Iblock::cleanCache($iblockId) ו-$log = fopen('/var/log/image_import.log', 'a'); foreach ($csvRows as $row) { try { // ... обработка fwrite($log, date('Y-m-d H:i:s') . " OK: {$row['xml_id']}\n"); } catch (\Throwable $e) { fwrite($log, date('Y-m-d H:i:s') . " ERR: {$row['xml_id']} — {$e->getMessage()}\n"); } } יכולים להפעיל פעולות כבדות (חישוב מחירים מחדש, ביטול מטמון, עדכון חיפוש). השביתו זמנית סוכנים ואירועים אם הם לא נחוצים במהלך הייבוא.
שימוש בסקריפטים של CLI. הריצו דרך b_file — ללא מגבלות זמן של בקשת web.
ניקוי מטמון לאחר סיום. אחרי העלאה המונית, אפסו את מטמון בלוק המידע: ID. עשו זאת רק פעם אחת בסוף.
טעויות נפוצות במהלך העלאה המונית
לוג שגיאות
$log = fopen('/var/log/image_import.log', 'a'); foreach ($csvRows as $row) { try { // ... обработка fwrite($log, date('Y-m-d H:i:s') . " OK: {$row['xml_id']}\n"); } catch (\Throwable $e) { fwrite($log, date('Y-m-d H:i:s') . " ERR: {$row['xml_id']} — {$e->getMessage()}\n"); } } שגיאות נפוצות: קובץ לא נמצא, סוג MIME לא חוקי, כפילות ב-OnBeforeIBlockElementUpdate (Bitrix בודק לפי hash — העלאת אותו קובץ שוב מחזירה את OnAfterIBlockElementUpdate הקיים).
ביצועים בנפחים גדולים
עבור קטלוג של 20,000+ פריטים, לולאה ישירה תיקח 2–4 שעות ועלולה להיתקל במגבלות זמן או זיכרון. כמה כללים:
עיבוד אצווה. עבדו 200–500 פריטים בכל איטרציה, ושמרו התקדמות לקובץ או לטבלה.
השבתת מטפלי אירועים נוספים. במהלך עדכונים המוניים, php -f import_images.php ו-\Bitrix\Iblock\InformationBlock::cleanTagCache($iblockId) יכולים להפעיל פעולות כבדות (חישוב מחירים מחדש, ביטול מטמון, עדכון חיפוש). השביתו זמנית סוכנים ואירועים אם הם לא נחוצים במהלך הייבוא.
שימוש בסקריפטים של CLI. הריצו דרך \CFile::ResizeImageGet($fileId, ['width' => 400, 'height' => 400], BX_RESIZE_IMAGE_PROPORTIONAL, true); — ללא מגבלות זמן של בקשת web.
ניקוי מטמון לאחר סיום. אחרי העלאה המונית, אפסו את מטמון בלוק המידע: \Bitrix\Iblock\InformationBlock::cleanTagCache($iblockId). עשו זאת רק פעם אחת בסוף.
יצירת תמונות ממוזערות
אחרי ההעלאה, Bitrix יוצר תמונות ממוזערות בצורה עצלה — בגישה ראשונה דרך רכיב. כדי לחמם את המטמון מיד:
\CFile::ResizeImageGet($fileId, ['width' => 400, 'height' => 400], BX_RESIZE_IMAGE_PROPORTIONAL, true); או דרך כלי CLI אם ImageMagick מוגדר על השרת.
השוואה: העלאה ידנית מול האוטמציה שלנו
| פרמטר | העלאה ידנית | אוטמציה סוהר |
|---|---|---|
| זמן עבור 10,000 פריטים | 2-3 שבועות | 2-4 שעות |
| שגיאות | גורם אנושי | מינימלי עם מיפוי נכון |
| עומס שרת | גבוה (כל פעולה דרך ניהול) | נמוך (CLI ללא אירועים נוספים) |
| מדרגיות | רק לנפחים קטנים | עד 100,000+ ללא בעיות |
| עלות עבור 20,000 פריטים | ~$4,000 | ~$1,000 |
איך להכין קבצים להעלאה
- בנו תמונות בתיקיות: כל תיקייה מתאימה ל-SKU של מוצר.
- צרו קובץ CSV עם עמודות: SKU, שם קובץ תמונה ראשית, קבוצת שמות קבצי גלריה.
- וודאו שכל הקבצים נגישים בנתיבים שצוינו.
- הריצו את סקריפט ה-CLI שקורא את ה-CSV ומעלה קבצים דרך ה-API.
מה כלול בעבודה שלנו
- ביקורת מלאה של מבנה הקטלוג ואחסון הקבצים.
- פיתוח סקריפט CLI מותאם לתרחיש שלכם.
- הגדרת העלאה אצווה עם אופטימיזציה.
- בדיקה על עותק ופריסה סופית.
- תיעוד התהליך ותמיכה לאחר היישום.
לוחות זמנים משוערים
| נפח קטלוג | זמן משוער |
|---|---|
| עד 1,000 פריטים | 1–2 שעות |
| 1,000–10,000 פריטים | 4–8 שעות |
| 10,000–50,000 פריטים | 1–2 ימים |
העלות מחושבת באופן אישי — צרו קשר להערכה חינמית. חיסכון בזמן ובתקציב מובטח: פי 5–10 מהר יותר מעבודה ידנית.
אוטמציית העלאת תמונות מוצר המונית שלנו עבור 1C-Bitrix מבטיחה עיבוד תמונות אמין ומהיר, המשלבת סקריפטים של CLI והעלאה אצווה לכל גודל קטלוג.







