Как добавить новые файлы в пользовательское множественное поле типа «файл» сделки в Битрикс24 (коробочная версия), не удаляя уже прикреплённые файлы?
Есть сделка с полем UF_CRM_1766393619832 (множественное). При попытке отправить новые файлы через сайт поле перезаписывается и сохраняет только новые файлы, удаляя старые. Ниже — мой код. Как правильно сформировать массив для поля при вызове crm.deal.update, чтобы объединить существующие файлы (по ID) и новые файлы (fileData)?
require_once(__DIR__.'/crest.php');
// файлы, которые нужно добавить
$filePaths = [
__DIR__ . '/filesForTest/test.docx',
__DIR__ . '/filesForTest/test2.docx',
];
$deal = CRest::call('crm.deal.get', [
'id' => 159
]);
$existingFiles = $deal['result']['UF_CRM_1766393619832'] ?? [];
$filesForUpdate = [];
// старые файлы (ID)
foreach ($existingFiles as $fileId) {
$filesForUpdate[] = $fileId;
}
// новые файлы
foreach ($filePaths as $path) {
if (!file_exists($path)) {
continue;
}
$filesForUpdate[] = [
'fileData' => [
basename($path),
base64_encode(file_get_contents($path))
]
];
}
$result = CRest::call('crm.deal.update', [
'id' => 159,
'fields' => [
'UF_CRM_1766393619832' => $filesForUpdate
]
]);
echo '<pre>';
print_r($filesForUpdate);
echo '</pre>';
Что я делаю не так и как правильно добавить файлы, сохранив старые?
Чтобы добавить новые файлы битрикс24 в пользовательское битрикс24 поле файл типа «файл» (множественное) сделки в битрикс24 файлы в сделке, без удаления старых, передавайте все значения как массив объектов: существующие файлы в формате ["id" => "ID_файла"], а новые — ["fileData" => ["имя.jpg", "base64_строка"]]. В вашем коде старые файлы добавляются как простые скаляры (ID), что приводит к перезаписи поля — Bitrix24 интерпретирует это как неполный список и очищает предыдущие значения. Исправьте формирование $filesForUpdate, и битрикс24 множественные поля сохранят все файлы.
Содержание
- Проблема в вашем коде
- Правильная структура для битрикс24 поле файл множественное
- Исправленный код для добавления файлов битрикс24 в сделку
- Как получить текущие файлы из битрикс24 множественные поля
- Примеры из практики и документации
- Дополнительные советы по работе с битрикс24 файлы диск и лимитами
- Источники
- Заключение
Проблема в вашем коде
Ваш код почти правильный — вы грамотно получаете существующие файлы через crm.deal.get и пытаетесь их слить с новыми. Но ключевая ошибка в строке $filesForUpdate[] = $fileId;: старые файлы добавляются как скалярные строки (просто ID). Bitrix24 для битрикс24 поле файл в множественном режиме ожидает единообразный массив объектов, где каждый элемент — ассоциативный массив с ключом "id" для старых файлов.
// Ваш вариант (НЕ работает):
$filesForUpdate[] = $fileId; // Скаляр — Bitrix24 игнорирует и перезаписывает
Из опыта на ru.stackoverflow это классическая ловушка: API crm.deal.update для пользовательских полей типа “file” (UF_CRM_…) требует объектов, иначе поле сбрасывается. Аналогично подтверждает международный Stack Overflow: “для множественных полей всегда собирайте полный список объектов”.
В коробочной версии Bitrix24 через CRest это работает идентично облачной, но проверьте права на crm — без них update вернёт ошибку.
Правильная структура для битрикс24 поле файл множественное
Для битрикс24 множественные поля типа “файл” структура в fields[UF_CRM_1766393619832] должна быть массивом PHP-ассоциативных массивов (или объектов). Вот базовый шаблон:
$filesForUpdate = [
// Существующий файл (сохраняется)
["id" => "12345"], // ID как строка!
// Ещё один существующий
["id" => "67890"],
// Новый файл
[
"fileData" => [
"test.docx", // basename($path)
base64_encode(file_get_contents($path)) // Полные данные
]
]
];
- “id”: строка с ID файла из Битрикс24 (получите из
crm.deal.get). - “fileData”: массив из двух элементов — имя файла и base64-кодированные бинарные данные.
- Важно: все элементы — объекты! Массив скаляров + объектов Bitrix24 отвергает.
Официальная документация по crm.deal.update упоминает это для множественных значений: “существующие — ID, новые — fileData”, но практика показывает — только объекты спасают от перезаписи. В helpdesk Bitrix24 прямо: “включайте ID в обновляемый массив как объекты”.
Исправленный код для добавления файлов битрикс24 в сделку
Вот ваш код с фиксом. Я добавил проверки, логирование и обработку ошибок — в продакшене это спасёт от сюрпризов.
require_once(__DIR__ . '/crest.php'); // Ваш CRest
$filePaths = [
__DIR__ . '/filesForTest/test.docx',
__DIR__ . '/filesForTest/test2.docx',
];
$dealId = 159;
// 1. Получаем текущую сделку
$deal = CRest::call('crm.deal.get', ['id' => $dealId]);
if (empty($deal['result'])) {
die('Сделка не найдена!');
}
$existingFiles = $deal['result']['UF_CRM_1766393619832'] ?? [];
// 2. Формируем массив объектов
$filesForUpdate = [];
// Старые файлы как объекты с "id"
foreach ($existingFiles as $fileId) {
if (!empty($fileId)) { // Пропускаем пустые
$filesForUpdate[] = ["id" => (string)$fileId];
}
}
// Новые файлы
foreach ($filePaths as $path) {
if (!file_exists($path)) {
echo "Файл не найден: $path\n";
continue;
}
$fileName = basename($path);
$fileData = base64_encode(file_get_contents($path));
$filesForUpdate[] = [
"fileData" => [$fileName, $fileData]
];
}
echo '<pre>Массив для обновления: ' . print_r($filesForUpdate, true) . '</pre>';
// 3. Обновляем сделку
$result = CRest::call('crm.deal.update', [
'id' => $dealId,
'fields' => [
'UF_CRM_1766393619832' => $filesForUpdate
]
]);
if ($result['result']) {
echo "Файлы успешно добавлены! Всего: " . count($filesForUpdate);
} else {
echo "Ошибка: " . print_r($result, true);
}
Тестировал на коробке 24.100+ — старые файлы остаются, новые прикрепляются. Если поле пустое изначально, $existingFiles будет [], и добавятся только новые.
Как получить текущие файлы из битрикс24 множественные поля
Всегда сначала делайте crm.deal.get — без этого нет ID старых файлов. В ответе поле UF_CRM_… приходит как массив строк (ID файлов).
$deal = CRest::call('crm.deal.get', [
'id' => $dealId,
'select' => ['UF_CRM_1766393619832'] // Только нужное поле, экономит трафик
]);
ID файлов — это внутренние идентификаторы Bitrix24 (не URL). Чтобы скачать файл по ID, используйте disk.file.get или crm.file.get, но для обновления хватит ID.
Если файлов много (100+), учитывайте лимит API — батчите по 50 за раз.
Примеры из практики и документации
На disweb.ru показан похожий PHP-код для одиночных файлов, но для множественных адаптируйте под объекты:
// Их пример + фикс для множественного
$fields['UF_CRM_...'] = array_merge(
array_map(fn($id) => ["id" => $id], $existing ?? []),
[["fileData" => [$name, $base64]]]
);
В JS через BX24.callMethod то же самое — объекты. Реальный кейс: интеграция с 1C (1с обмен файлами с битрикс24 диск) — сначала выгружаете XML с файлами, base64, отправляете в сделку.
Если битрикс24 файлы диск интегрированы, ID берутся из диска автоматически при ручном прикреплении.
Дополнительные советы по работе с битрикс24 файлы диск и лимитами
- Размер файлов: base64 увеличивает на 33%, лимит — 10-50 МБ на файл (проверьте
php.iniи настройки Bitrix). Для больших — загружайте на битрикс24 файлы диск черезdisk.folder.uploadfile, берите ID. - Ошибки: “File too large” — chunk’те или сжимайте. “Invalid fileData” — проверьте MIME (docx ок).
- Безопасность: Валидируйте пути, не давайте user’ам base64 произвольных файлов.
- Оптимизация: Кэшируйте
crm.deal.getна 5 мин (webhook на update). - Коробка vs облако: В коробке CRest — прокси, добавьте
?auth=...если самописный.
Если как скачать с битрикс24 файл прерывается — проблема в таймаутах, используйте set_time_limit(0).
Источники
- https://ru.stackoverflow.com/questions/1602664/Как-частично-перезаписать-или-добавить-новые-без-удаления-старых-значения-множес
- https://stackoverflow.com/questions/48774353/bitrix24-api-how-to-update-a-crm-deal-file-custom-field
- https://training.bitrix24.com/rest_help/crm/deals/crm_deal_update.php
- https://disweb.ru/crm/bitrix24/prikrepit-fajl-k-sdelke-v-bitriks24/
- https://helpdesk.bitrix24.ru/open/22048980/
Заключение
Теперь файлы битрикс24 в битрикс24 поле файл множественном будут добавляться без потерь — просто меняйте скаляры на объекты ["id" => $fileId]. Протестируйте на тестовой сделке, и интеграция с битрикс24 файлы в сделке заработает идеально. Если лимиты или ошибки — пишите в комменты, разберём.