CUser::Update изменяет данные существующего пользователя из кода —
и в этом же методе кроется распространённая проблема: он способен молча
перезаписать поля, которые вы не собирались трогать, если структура
передаваемого массива задумана неверно.
Базовый вызов
<?php
$user = new CUser;
$result = $user->Update($userId, [
'NAME' => 'Иван',
'LAST_NAME' => 'Петров',
'UF_PHONE' => '+79001234567',
]);
if (!$result) {
echo 'Ошибка: ' . $user->LAST_ERROR;
}
В отличие от Add, метод Update изменяет только
переданные поля — остальные данные пользователя остаются прежними.
Это ключевое отличие от полной перезаписи и одновременно источник частой
путаницы: если случайно передать пустое значение там, где должно быть
сохранено старое, поле действительно обнулится.
Смена пароля
<?php
$user = new CUser;
$result = $user->Update($userId, [
'PASSWORD' => $newPassword,
'CONFIRM_PASSWORD' => $newPassword,
]);
Оба поля обязательны одновременно при смене пароля — как и при создании.
Если передать только PASSWORD без подтверждения, метод
вернёт ошибку несовпадения, даже если по факту сравнивать не с чем.
Нужна помощь с Битрикс?
Смена email с подтверждением
При смене адреса почты имеет смысл предусмотреть подтверждение — иначе пользователь может случайно или намеренно указать чужой адрес и получить доступ к письмам, предназначенным другому человеку. Штатный механизм подтверждения смены email включается настройками главного модуля, а из кода это выглядит как обычное обновление поля:
<?php
$user->Update($userId, ['EMAIL' => $newEmail]);
При включённой проверке система сама отправит письмо со ссылкой подтверждения, и адрес изменится только после перехода по ней.
Изменение групп пользователя
<?php
$user->Update($userId, [
'GROUP_ID' => [2, 5], // полностью заменяет список групп
]);
Здесь кроется главная ловушка метода: GROUP_ID при обновлении
полностью заменяет список групп пользователя, а не
добавляет к существующему. Если нужно добавить пользователя в новую
группу, не удаляя его из текущих, список групп сначала считывается,
а затем передаётся с добавленным значением:
<?php
$dbGroups = CUser::GetUserGroup($userId);
$dbGroups[] = 7; // добавляем новую группу к существующим
$user->Update($userId, ['GROUP_ID' => $dbGroups]);
Массовое обновление
При обновлении множества пользователей — например, после импорта или при массовой смене статуса — стоит обновлять только действительно изменившиеся записи, а не перезаписывать всех подряд без проверки. Это не только быстрее, но и безопаснее: меньше риска задеть поле, которое не должно было измениться.
<?php
foreach ($usersToUpdate as $userId => $newFields) {
$current = CUser::GetByID($userId)->Fetch();
$changed = array_diff_assoc($newFields, array_intersect_key($current, $newFields));
if (!empty($changed)) {
(new CUser)->Update($userId, $changed);
}
}
Частые ошибки
-
GROUP_IDзаменяет весь список групп. Пользователь неожиданно теряет права, которые не собирались отбирать. - Смена email без подтверждения включена там, где это нежелательно. Стоит явно решить, нужна ли проверка для конкретного сценария.
- Передан пустой пароль «на всякий случай». Некоторые реализации формы интерпретируют пустое поле как желание сменить пароль на пустой — стоит исключать поле из массива вовсе, если оно не менялось.
- Результат не проверяется. Ошибка обновления остаётся незамеченной.
Итог
CUser::Update изменяет только переданные поля, но у параметра
GROUP_ID особое поведение — он заменяет список групп целиком,
а не дополняет его. Перед добавлением пользователя в новую группу через
этот метод всегда считывайте текущий список и передавайте его вместе
с новым значением, иначе есть риск случайно лишить пользователя доступа,
который у него уже был.
