Добрый день. Описанные ошибки — классическая проблема «headers already sent»: где‑то до попытки вызвать session_start() или setcookie() уже что‑то было выведено в браузер (даже невидимый BOM или пробел/перенос строки). Ниже — причины и конкретные шаги решения для новичка (OS‑3, PHP 7.4).
Коротко — что происходит
- PHP не может отправить заголовки (cookie, старт сессии), если до этого в вывод (stdout) уже что‑то ушло.
- В вашем случае вывод начался в файле /catalog/controller/extension/module/prostore_categories_min.php на строке 1 — это почти всегда BOM (UTF‑8 BOM) или пробел/перенос перед <?php.
Шаги решения (рекомендую выполнять в указанном порядке)
1) Сделайте резервную копию файлов
- Скопируйте изменяемые файлы прежде чем править.
2) Удалите BOM / лишние символы в проблемном файле
- Откройте /home/.../catalog/controller/extension/module/prostore_categories_min.php в редакторе (Notepad++, VSCode, Sublime).
- Убедитесь, что файл сохранён как "UTF-8 без BOM" (UTF-8 without BOM).
- Убедитесь, что первый символ файла — сразу "<?php" без пробелов/пустых строк перед ним.
- Также проверьте, чтобы в конце файла не было закрывающего тега "?>" с пробелами/переносами после него — лучше вообще убрать закрывающий тег в чисто‑PHP файлах.
Как проверить BOM из консоли (если есть SSH):
- head -c 3 /path/to/prostore_categories_min.php | xxd -p
— если вывод efbbbf — это BOM.
3) Поиск других файлов с BOM/выводом
- Плагины, шаблоны или модификации (OCMod/vQMod) тоже могут содержать BOM. Проведите простой поиск по файлам, либо вручную проверьте недавно добавленные файлы.
- В админке OpenCart: Extensions → Modifications → Refresh (обновить модификации) и очистить кеш.
4) Временные/подходящие исправления в коде библиотеки (если сразу исправить все файлы не получается)
- В файле Trace.php заменить вызов session_start() на проверку headers_sent(), чтобы подавить предупреждение (это временное решение — сессия может не стартовать если заголовки уже ушли):
if (session_status() === PHP_SESSION_NONE && !headers_sent()) {
session_start();
}
- Для setcookie тоже можно добавить проверку:
if (!headers_sent()) {
setcookie(...);
}
Это лишь «мягкий» патч: устраняет предупреждения, но не решает причину — вывод до заголовков.
5) Альтернативный временный обход (не рекомендуется в продакшн)
- В index.php сайта добавить в самом верху ob_start(); — тогда PHP буферизует вывод и заголовки можно будет отправить позже. Это скрывает проблему, но лучше убрать источник вывода.
6) Проверка отладки / отключение display_errors в продакшн
- Иногда сам PHP выводит предупреждения/notice, которые мешают заголовкам. Убедитесь, что в PHP.ini на продакшне display_errors=Off. Но не используйте это вместо исправления кода.
7) После правок
- Очистите кеш OpenCart (modifications), перезагрузите сервер (если нужно) и протестируйте.
- Если ошибка осталась, найдите первый файл, где "output started" — он указывает точное место, где начался вывод.
Почему сначала посмотреть на prostore_categories_min.php
- Сообщение об ошибке указывает output started at ...prostore_categories_min.php:1 — значит вывод начался там, поэтому начать надо с этого файла (частая причина — UTF‑8 BOM).
Если хотите, могу:
- Присказать, как именно открыть и изменить файл (каким редактором).
- Посмотреть первые строки проблемного файла (вставьте первые ~10 строк сюда) — подскажу точно, есть ли BOM/лишние пробелы.
- Подготовить патч для Trace.php и UtmCookie.php, если нужно временно подавить ошибки.
Резюме:
- Корень: вывод (часто BOM или пробел) сделан до попытки отправки заголовков.
- Решение: убрать BOM/пробелы/echo/var_dump в файлах, начать с указанного файла; при необходимости временно проверять headers_sent() перед session_start()/setcookie() или включить ob_start() как обходной путь.