Перейти к содержимому

Выгрузка пользователей - отбор, поля, персональные данные

Собираем выгрузку пользователей для рассылки, сверки или переезда: с нужным отбором, без падения по памяти и без лишних персональных данных в файле.

Решение

Отбираем нужных пользователей:

$by = 'ID'; $order = 'ASC';
$res = CUser::GetList($by, $order,
['ACTIVE' => 'Y', 'GROUPS_ID' => [5], '>=DATE_REGISTER' => '01.01.2026'],
['SELECT' => ['UF_*'], 'FIELDS' => ['ID', 'LOGIN', 'EMAIL', 'NAME', 'LAST_NAME']]);
// FIELDS - штатные поля, SELECT - пользовательские: это два разных списка

Выгружают отобранных, а не всех подряд. Отбор по группе и дате регистрации отсекает служебные учётные записи и старые регистрации, которые в выгрузке только мешают.

Читаем список порциями:

$res = CUser::GetList($by, $order, $filter, ['NAV_PARAMS' => ['nTopCount' => 500]]);
while ($row = $res->Fetch()) {
fputcsv($fh, [$row['ID'], $row['EMAIL'], $row['NAME'], $row['LAST_NAME']], ';');
}
// пишем в файл сразу, а не копим массив: сто тысяч строк в память не влезут

Строки пишут в файл по мере чтения. Массив на сто тысяч пользователей съедает память процесса задолго до конца выгрузки, а поток в файл работает на любом объёме.

Готовим файл к открытию в Excel:

fwrite($fh, "\xEF\xBB\xBF"); // метка кодировки, иначе кириллица поедет
fputcsv($fh, ['ID', 'Почта', 'Имя', 'Фамилия'], ';');
// разделитель «точка с запятой» Excel в русской локали понимает сам

Кодировка и разделитель решают судьбу файла у получателя. Без метки кодировки менеджер видит вместо имён набор символов и возвращает файл обратно с вопросом, что это было.

Убираем из выгрузки лишнее:

- пароли и их отпечатки не выгружают никогда, даже «для переноса»
- телефоны и адреса - только если они действительно нужны получателю
- готовый файл кладут вне открытого каталога и отдают по ссылке со сроком

Выгрузка пользователей - это персональные данные в одном файле. Чем меньше в нём полей и чем короче он живёт, тем меньше шансов, что он окажется там, где его никто не ждал.

Выгрузку по расписанию стоит перезаписывать, а не накапливать. Каталог с полусотней ежедневных выгрузок за год - это готовая утечка, ждущая своего часа.

Число строк в файле полезно сверять с числом в выборке. Обрыв на середине из-за времени выполнения выглядит как обычный файл, и заметен он только по счёту.

Согласие на обработку данных проверяют до выгрузки для рассылки. Список пользователей и список согласившихся на письма - разные списки, и путать их дорого.

Отдельно стоит договориться, кто получает файл и что с ним делает дальше. Выгрузка, отправленная в мессенджер «на посмотреть», живёт там вечно, и через год никто уже не вспомнит, чьи данные в ней были.

Типичные проблемы

Скрипт выгрузки падает по памяти.

Все строки собираются в массив и только потом пишутся в файл. Строки пишут в файл по мере чтения, порциями и без промежуточного массива.

В Excel вместо имён непонятные символы.

В начале файла нет метки кодировки, и Excel читает его как однобайтовый. Метку кодировки пишут самой первой строкой готового к отправке файла выгрузки.

Все данные оказались в одной колонке.

Разделитель полей не тот, который ждёт Excel в этой локали. Для русской локали Excel таким разделителем полей служит точка с запятой.

Файл выгрузки нашли в поиске.

Он сохранён в каталоге, доступном снаружи по прямой ссылке. Такие файлы держат вне корня сайта, в закрытом от посторонних глаз каталоге.

В выгрузке меньше строк, чем пользователей.

Скрипт оборвался по времени выполнения на середине списка. Число строк в готовом файле сверяют с числом записей в самой выборке.

Частые вопросы

Как выгрузить пользовательские поля?

Запросить их отдельным списком при выборке. Штатные и пользовательские поля задаются разными параметрами.

Можно ли выгрузить пароли для переноса?

Нет: хранятся не пароли, а их отпечатки, и выгружать их не нужно. При переносе базы они едут вместе с ней.

Где хранить готовый файл?

Вне открытого каталога, с отдачей по ссылке со сроком жизни. Каталог загрузок для этого не годится.

Как выгрузить только подписчиков рассылки?

По списку согласившихся, а не по всем пользователям. Это разные списки, и они не совпадают.

Смежное

Первоисточник