Проблема загрузки файла PHP - PullRequest
1 голос
/ 25 февраля 2009

У меня действительно раздражающая проблема с загрузкой файлов.

Пользователи могут выбрать файл в поле html-файла. Когда они отправят форму, этот файл будет загружен.

На сервере я просто использую стандартный код PHP (move_uploaded_file). Я не делаю ничего странного.

Все отлично работает.

Я вижу файл на сервере, я могу загрузить его снова, ...

Однако иногда это не работает. Я загружаю файл, обрабатываю его и не получаю ошибок.

Но файл просто не существует на сервере.

Каждый раз, когда я загружаю этот конкретный файл, я не получаю ошибок, но он никогда не сохраняется.

Только если я переименую его (например, test.file в tst.file), я могу загрузить его, и он действительно будет сохранен.

Я получаю эту проблему очень редко. И переименование всегда работает. Но я не могу просить пользователей переименовать их файлы, очевидно ...

У меня нет доступа к каталогу файлов apache tmp, нет доступа к журналам или настройкам, поэтому это затрудняет отладку. У меня есть эта проблема только на этом конкретном сервере (которым я не управляю; у меня даже нет доступа к нему), и я использую один и тот же код на многих серверах, у которых нет этой проблемы.

Буду признателен, если кто-нибудь поможет мне здесь или укажет мне правильное направление.

Ответы [ 4 ]

2 голосов
/ 25 февраля 2009

Попытка добавить этот код отладки:

<code>echo '<pre>';
print_r($_FILES);
echo '
';

Вы должны увидеть номер ошибки. Вы можете посмотреть, что это значит на http://uk3.php.net/manual/en/features.file-upload.errors.php

Может также стоит проверить, чтобы убедиться, что целевой файл еще не существует.

2 голосов
/ 25 февраля 2009

Моей первой мыслью были проблемы с размером файла. В php.ini, если post_max_size или upload_max_filesize слишком малы, вы можете получить схожие результаты - файл кажется просто исчезнет. Вы получите сообщение об ошибке в журналах Apache (к которому, как вы упоминаете, у вас нет доступа).

В этих случаях массив $ _FILES будет просто пустым - как если бы файл никогда не поступал. Поскольку ваши ответы на Gumbo и Джеймса Холла показывают, что php сообщает о правильной загрузке, я удивляюсь, о какой обработке вы упоминаете.

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

memory_limit

max_execution_time

max_input_time

В противном случае, без журналов apache, я бы сказал, что было бы неплохо начать выводить собственный файл журнала на протяжении всего сценария обработки файлов. Попробуйте file_exists в файле tmp, посмотрите, какую информацию вы можете получить из файла (права доступа и т. Д.).

К сожалению, PHP не участвует, пока загрузка не будет завершена, что означает, что вы не получите много информации во время - только после факта. Лучшим вариантом может быть поговорить с хостинговой компанией и получить доступ к журналам - даже если на короткое время. По моему опыту, у меня редко возникали проблемы с получением журналов - или, по крайней мере, с поиском тех, кто проверяет журналы для меня во время выполнения тестов (в случае, когда общий сервер не разделяет их журналы), кажется смешным, но Я видел это раньше).

Редактировать: Я понимаю, что вы не можете изменить эти настройки php, но вы, возможно, захотите посмотреть, что они из себя представляют, чтобы выяснить, являются ли они потенциальными проблемами для вашего скрипта. Например, низкий предел памяти убьет ваш скрипт процессора, если он меньше размера загружаемого файла.

1 голос
/ 21 июля 2009

Это то, что вы сказали ...

"У меня нет доступа к каталогу файлов apache tmp, нет доступа к журналам или настройкам, поэтому это затрудняет отладку. У меня есть только эта проблема на этом конкретном сервере (которым я не управляю; даже доступ к нему), и я использую один и тот же код на многих серверах, у которых нет этой проблемы. "

В соответствии с тем, что вы сказали выше, я предполагаю, что вы используете сервер, который используется многими пользователями. Если Apache этого сервера настроен на что-то вроде «mod_suphp», то ваши PHP-скрипты будут выполняться с использованием привилегий вашей учетной записи пользователя UNIX (например, «jef1234»), что означает, что у создаваемых вами файлов будет (« jef1234 ") в качестве владельца (вместо" apache "или" www-data ").

Временный каталог системы (обычно «/ tmp») обычно настраивается с включенным «sticky bit». Это означает, что каждый может создавать файлы в этом каталоге, но созданные файлы доступны только владельцу (вы можете рассматривать это как тот, кто его создал).

В результате, если конфигурация сервера недостаточно тщательна, вы можете столкнуться с именами файлов с файлами других пользователей. Например, когда вы загружаете файл «test.file», если другой пользователь уже загрузил другой файл с тем же именем, система отказывается перезаписать созданный им файл, так как вам придется использовать другое имя.

Обычно проблема не существует, потому что PHP достаточно умен, чтобы генерировать временные имена для загруженного файла (т. Е. $ _FILES ["html_form_input_name"] ["tmp_name"]). Если каким-то образом вы можете подтвердить, что это действительно причина, сервер явно неправильно настроен. Сообщите системному администратору о проблеме, а затем попросите его решить. Если это не может быть решено, вы можете сделать некоторые трюки JavaScript с именем файла перед его загрузкой (не проверено, просто идея) ...

Когда пользователь отправляет форму, переименуйте файл, например, из «test.file» в «jef1234-test.file-jef1234». После загрузки файла переместите файл (например, move_uploaded_file () ) в другое место и переименуйте его в исходное имя файла, удалив добавленные строки.

Надеюсь, это поможет ...

Аска Кенджи

1 голос
/ 25 февраля 2009

Если загрузка не удалась, вы не получите такой же ошибки, как синтаксическая ошибка PHP или что-то подобное.

Но вы можете проверить статус загрузки файла и сообщить об ошибке самому пользователю.

...