#Описание и признаки неисправности
После переноса сайта на нового системного пользователя веб-форма принимает файл, но сохранение завершается ошибкой «Permission denied», «Unable to move uploaded file» или объект не появляется в каталоге загрузок. Часто файлы приложения остались во владении прежней учётной записи. Нужно отдельно проверить PHP-папку временной загрузки, фактическую папку назначения и права процесса, а не выдавать 777 рекурсивно.
#Как отличить возможные причины
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Каталог принадлежит старому пользователюПроцесс PHP больше не имеет права записи в назначение. | stat показывает старого владельца, в журнале permission denied. | Согласовать точечную смену владельца нужного каталога. |
| Нет доступа к одному из родительских каталоговДаже writable каталог не поможет без права прохода по пути. | На родительском каталоге нет x, вывод namei -l это показывает. | Уточнить владельца и права прохода, не менять системные каталоги. |
Временная папка недоступнаPHP не может записать файл ещё до move_uploaded_file(). | В $_FILES код UPLOAD_ERR_CANT_WRITE или UPLOAD_ERR_NO_TMP_DIR. | Проверить temp_path, quota, open_basedir и свободное место. |
#Пошаговая диагностика и решение
- Сохраните текущие права и пример ошибкиОткройте в панели карточку сайта и узнайте имя нового системного пользователя. В приложении повторите загрузку небольшого безвредного файла с уникальным именем и запишите время и точный текст ошибки. По SSH от имени администратора узнайте назначенный каталог загрузок из настроек сайта. Не пытайтесь чинить права на всём
/var/www: у сайтов могут быть разные владельцы. - Убедитесь, что проблема именно в записиПроверьте в панели журнал ошибок PHP и веб-сервера: ищите
Permission denied,move_uploaded_file,open_basedirи код ошибки загрузки из$_FILES[...][error]. КодUPLOAD_ERR_INI_SIZEозначает превышение размера, а не права; в этом случае откройте настройки лимитов PHP. Если ошибка возникает только у одного формата файла, изучите проверки типа и расширения в CMS. - Определите пользователя выполняющегося обработчикаВ карточке сайта проверьте, какому системному пользователю назначен сайт/пул PHP-FPM или FastCGI. Не приравнивайте результат команды
whoamiв SSH к пользователю PHP: это разные процессы. Если владелец неясен, администратор может посмотреть настройки пула и процессы веб-обработчика; не включайте публичную страницу phpinfo() с раскрытием конфигурации. - Посмотрите права каталога без измененияОткройте SSH и выполните
stat -c "%U %G %a %n" /ПУТЬ/К/UPLOADSиnamei -l /ПУТЬ/К/UPLOADS, подставив путь из настроек сайта; команды только читают владельца, группу и разрешения. Если путь не существует, сначала подтвердите правильность каталога и создавайте его только через штатный файловый менеджер панели в разрешённом месте. - Проверьте диск и квотуВ панели посмотрите использование дискового пространства и ограничения учётной записи; при SSH выполните
df -hиdf -i. Вторая команда показывает свободные inode: при нуле новых файлов не создаст даже при наличии гигабайтов. Если квота исчерпана, удаляйте только проверенные собственные временные файлы после резервной копии; не очищайте чужие каталоги и журналы наугад. - Согласуйте точечное исправление владельцаЕсли каталог и весь его состав действительно принадлежат именно этому сайту, сохраните список текущих владельцев и сделайте резервную копию. В файловом менеджере панели измените владельца только каталога загрузок на пользователя данного сайта, если панель поддерживает функцию. При SSH администратор может выполнить адресную смену владельца только после проверки точного пути и дерева. Не используйте рекурсивный
chmod 777или смену владельца всего веб-каталога. - Отличите запрет в PHP от запрета файловой системыЕсли права корректны, посмотрите
open_basedir, значениеupload_tmp_dir, ограничения AppArmor/SELinux в журнале безопасности (если они включены).move_uploaded_file()зависит от разрешений на конечный путь. Для AppArmor/SELinux не отключайте защиту целиком: согласуйте правило только для разрешённого каталога. Верните изменённые настройки PHP, если тест не помог. - Проверьте сохранение и откат владельцаЗагрузите небольшой файл, найдите его в файловом менеджере и убедитесь, что он открывается только через предусмотренный CMS путь. Посмотрите владельца нового файла с помощью
stat. Если ошибка осталась, верните зафиксированные права и владельца при условии совместимости с процессом старой учётной записи, затем предоставьте администратору точный путь, код ошибки, имя пользователя и время. Не удаляйте тестовые пользовательские файлы без проверки. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Проверка результата и дальнейшие действия
Успех — новая загрузка сохраняется в ожидаемую папку, запись появилась под верным владельцем, ошибок Permission denied нет, чтение файла работает через интерфейс сайта. При неуспехе соберите код $_FILES, путь назначения, stat/namei, свободное место и передайте ответственному администратору, не продолжая произвольно менять права.