Операция, изменяющая сотни записей, может быть правильной согласно заданным правилам и при этом затронуть больше данных, чем ожидалось. Общее подтверждение — «Вы уверены?» — не позволяет оценить масштаб изменений или обнаружить непредвиденные ситуации. Предварительный просмотр изменений в PHP должен показывать, какие записи будут затронуты, какие значения изменятся и при каких условиях можно выполнить операцию.
Предварительный просмотр уменьшает вероятность сюрпризов, но не гарантирует, что последующее выполнение даст в точности тот же результат. Между этими этапами могут измениться данные, права доступа или область действия операции. Проектирование должно делать эту неопределённость очевидной и предусматривать повторную проверку всего необходимого перед записью данных.
Когда предварительный просмотр полезен

Предварительный просмотр стоит рассмотреть для массовых, чувствительных или труднообратимых операций: изменения цен, смены статусов, переназначения аккаунтов, удаления информации или пересчёта производных данных. Он также полезен, когда инициатору задачи нужно оценить её влияние или получить одобрение до выполнения.
Не для каждого действия нужен интерфейс предварительного просмотра. Если операция небольшая, обратимая и имеет однозначный результат, может быть достаточно контекстного подтверждения. Но если пользователь не понимает, что означает подтверждение, проблему нужно решать показом конкретных данных, а не добавлением ещё одного диалогового окна.
Предварительный просмотр также не заменяет резервную копию, механизм отката или политику согласования. Если ошибка может иметь серьёзные последствия, следует рассмотреть дополнительные меры контроля: например, одобрение другим человеком, постепенное выполнение или проверенный процесс восстановления.
Разделение расчёта и применения изменений
Бизнес-правило должно позволять рассчитать предполагаемые изменения без модификации базы данных. Практичный подход — использовать общий код выбора записей и расчёта в двух режимах: один описывает изменения, другой применяет их. Отказ от двух независимых реализаций снижает риск того, что предварительный просмотр и выполнение будут трактовать правила по-разному.
Для каждого затрагиваемого элемента можно включить в описание изменений:
- Идентификатор, позволяющий распознать запись.
- Текущие значимые и ожидаемые значения.
- Причину включения или исключения записи.
- Выполненные проверки и обнаруженные конфликты.
- Область действия операции, например фильтры, аккаунт или временной интервал.
Например, при смене статуса заказов можно показать текущий и предлагаемый статус, а также причину, по которой заказ подходит для изменения. Если элементов слишком много, чтобы вывести их все на экран, можно показать общее количество и выборку, обязательно пояснив, что именно отображается, и предоставив возможность при необходимости просмотреть или экспортировать подробные данные.
В PHP выбор записей и расчёт изменений рекомендуется инкапсулировать в компоненты с чётко определёнными обязанностями. Доменный сервис может формировать предлагаемые изменения, другой компонент — отображать их, а прикладной слой — выполнять проверку и сохранять результат. Предварительный просмотр не должен косвенно выполнять запись из-за побочных эффектов чтения.
Проверка данных, прав и области действия
Полезное описание изменений показывает не только, что изменится, но и почему это допустимо. Проверяйте условия на текущих данных и убеждайтесь, что у пользователя есть право просматривать и выполнять эту операцию. Право читать записи не обязательно означает право изменять их.
Область действия должна быть указана явно. Если действие зависит от фильтров, выбранных элементов или загруженного файла, зафиксируйте эти параметры в понятном виде и сообщите об ограничениях, исключениях и ошибках. Не допускайте, чтобы широкий поиск или пропущенный фильтр случайно превратили ограниченное действие в глобальное изменение.
Также следует обозначить, что невозможно предсказать с уверенностью. Предварительный просмотр автоматически не учитывает изменения, внесённые другими процессами, правила, выполняемые во внешних системах, и побочные эффекты, зависящие от будущего состояния. Если задействованы интеграции, очереди или последующие вычисления, описывайте такие эффекты отдельно и не представляйте их как подтверждённую часть результата.
Защита от применения устаревшего предварительного просмотра
Предварительный просмотр отражает данные на конкретный момент времени. До выполнения они могут измениться: заказ перестанет соответствовать условиям, пользователь потеряет права или запись будет обновлена другим процессом. Поэтому отображённый результат нельзя считать бессрочным разрешением на запись.
При выполнении повторно проверяйте условия, определяющие возможность изменения, и права доступа. В зависимости от ситуации можно сравнить версию записи, временную метку или значимые значения с теми, что были зафиксированы при расчёте предлагаемых изменений. Если обнаружены расхождения, не применяйте молча другое решение: сообщите о конфликте и запросите создание нового предварительного просмотра или явное разрешение конфликта.
В процессах, требующих строгого соответствия, сохраняйте ссылку на предложение и проверяйте, что при применении по-прежнему используются его область действия и правила. Транзакция может защитить набор операций записи от сбоев между отдельными операциями записи, но сама по себе не устраняет время, прошедшее между предварительным просмотром и выполнением. Стратегия конкурентного доступа должна соответствовать риску и объёму операции.
Пакетное выполнение и фиксация результатов
При больших объёмах применение всех изменений за одну операцию может увеличить время блокировок и усложнить восстановление. Определите размер пакетов с учётом базы данных и поведения приложения. При частичных сбоях пользователь должен иметь возможность различить применённые записи, пропущенные записи и записи, требующие проверки.
Фиксируйте достаточно информации для расследования результата: кто инициировал и одобрил операцию, когда она была подготовлена и выполнена, какая область действия была запрошена, сколько элементов обработано и какие ошибки возникли. Не сохраняйте персональные данные или чувствительные значения без необходимости; к журналам аудита также должны применяться соответствующие правила доступа и хранения.
Если операцию можно повторить, учитывайте идемпотентность: повторный запрос не должен приводить к неожиданному дублированию эффектов. Идентификатор операции и её статусы помогут распознавать повторные запросы и разделять подготовку, одобрение, выполнение и завершение. Не представляйте развёртывание кода как эквивалент выпуска или включения операции: это разные решения, и для каждого нужны собственные средства контроля.
Проверка того, что предварительный просмотр не меняет данные
Тесты должны проверять как расчёт, так и отсутствие записей в режиме предварительного просмотра. Используйте репрезентативные данные, чтобы проверить включение и исключение записей, текущие и предлагаемые значения, недостаточные права и ошибки валидации.
Кроме того, проверьте, что выполнение применяет ожидаемые изменения, а конкурентные изменения приводят к предусмотренному поведению. При необходимости тестируйте сбои внутри пакета, повторные попытки и ошибки интеграции. Интеграционные тесты с базой данных важны: модульный тест расчёта не доказывает, что в маршруте предварительного просмотра нет побочных эффектов.
Крайние случаи должны включать пустые фильтры, большие объёмы данных, удаление или изменение записей между этапами и пользователей с разными областями доступа. Также стоит убедиться, что интерфейс не обещает «будут обновлены именно эти записи», если при выполнении приложение заново рассчитает набор.
Контрольный список для выбора необходимых мер

- Затрагивает ли операция много записей, приводит ли к труднообратимым последствиям или требует одобрения?
- Показаны ли область действия, затрагиваемые элементы, текущие и ожидаемые значения?
- Отделён ли предварительный просмотр от записей и их побочных эффектов?
- Проверяются ли права, бизнес-правила и данные как при подготовке, так и при выполнении?
- Обнаруживаются ли существенные изменения, произошедшие между этими этапами?
- Заданы ли ограничения размера пакетов, порядок обработки частичных сбоев и предусмотрено ли уместное ведение журналов аудита?
- Подтверждают ли тесты, что предварительный просмотр не меняет данные, а выполнение соответствует проверенному результату?
Предварительный просмотр уместен, если он помогает принять информированное решение и его ограничения понятны. Если нельзя надёжно оценить влияние операции, лучше сузить её область действия, сначала выполнить операцию в контролируемой среде или потребовать дополнительной проверки, а не превращать число или неполный список в обещание результата.



