Сценарий загрузки PHP не работает должным образом с новым хостом

Я настроил php-скрипт, который создает каталог и загружает файл в этот каталог. Моя проблема в том, что когда я использую скрипт для создания каталога, файл не загружается полностью. Я запустил точно такой же скрипт на другом хосте, и процесс загрузки работает нормально. Кроме того, если я вручную создам каталог для загрузки и применю chmod 777 через ftp, то передача будет работать нормально. Может ли быть какая-то настройка хостинг-провайдера, которую необходимо изменить, чтобы функция работала правильно?

Вот форма загрузки:

<form action="/uploadFile.php" method="post"
enctype="multipart/form-data">
<label for="img_preview">Preview Image:</label>
<input type="file" name="img_preview" id="img_preview" />
<br />

<input type="hidden" name="id" value="newDirectory" />
<input type="submit" name="submit" value="Upload Flyer" />
</form>

Вот мой PHP-скрипт (uploadFile.php):

$thisdir = getcwd(); 
$new_dir = $_POST['id'];
$full_dir = $thisdir . "/upload/" . $new_dir;

function chk_dir($full_dir) {
if(is_dir($full_dir)) {
    echo 'welcome back';
} else {
    return mkdir($full_dir);
}

}
chk_dir($full_dir);
chmod($full_dir, 0777);
?>

<?php
//upload image

if ($_FILES["file"]["error"] > 0)
  {
  echo "Error: " . $_FILES["img_preview"]["error"] . "<br />";
  }
else
  {

  }
  //set image restrictions
?> 

<?php
if ((($_FILES["img_preview"]["type"] == "image/gif")
|| ($_FILES["img_preview"]["type"] == "image/jpeg")
|| ($_FILES["img_preview"]["type"] == "image/pjpeg"))
&& ($_FILES["img_preview"]["size"] < 80000))
  {
  if ($_FILES["img_preview"]["error"] > 0)
    {
echo "Please only upload an image for previewing (jpg or gif)...<br>
Also, check to         make     sure the filesize is less than 8MB" .          $_FILES["img_preview"]["error"] .     "<br />";
}
  else
{

//check the image into new directory
if (file_exists("upload/". $new_dir ."/". $_FILES["img_preview"]["name"]))
  {
  echo "It seems that " . $_FILES["img_preview"]["name"] . " already exists.";
  }
else
  {
  move_uploaded_file($_FILES["img_preview"]["tmp_name"],
  "upload/" . $_POST['id'] . "/" . $_FILES["img_preview"]["name"]);
  echo "image file has transferred successfully!";
      }
    }
  }
else
  {
  echo "Invalid file please contact for assistance.";
  }
?> 

Кроме того, когда я запускаю сценарий, ошибок не возникает, и файл повторяет: «Файл изображения успешно передан!» но затем, когда я проверяю файл в новом месте, он полностью пуст. Спасибо за ваше время в этом вопросе.


person codacopia    schedule 05.07.2011    source источник


Ответы (4)


Похоже, ваш вопрос уже содержит ответ (загрузка работает, когда вы создаете каталог через FTP).

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

Что происходит:

  1. ваш скрипт создает каталог, владельцем которого будет веб-сервер
  2. ваш скрипт (владельцем скрипта обычно является ftp-пользователь) пытается выполнить chmod каталога

сценарий (владелец: ftp) не может изменить каталог (владелец: веб-сервер), потому что идентификаторы пользователя разные.

решение: используйте ftp_mkdir() для создания каталогов.

person Dr.Molle    schedule 06.07.2011
comment
Спасибо, это похоже на ответ, который лучше всего представляет мою проблему. Я пытался использовать функцию ftp_mkdir(), но она тоже не работает (даже когда я пробую упрощенную версию функции). Я собираюсь связаться с хостом по поводу параметра safe_mode и посмотреть, позволит ли он правильно работать ftp_mkdir или mkdir. - person codacopia; 06.07.2011

Во-первых, в вашем скрипте есть дыра в безопасности. Никогда не используйте переданные данные $_POST для создания системных каталогов. И никогда ни для чего не используйте 0777.

move_uploaded_file() возвращает false в случае сбоя, и вы все равно получите сообщение об успехе, даже если оно не удалось (в вашем коде)

Включите display_errors и ведение журнала ошибок и повторите попытку.

person Aleksey Korzun    schedule 05.07.2011
comment
Никогда не используйте переданные данные $_POST для создания системных каталогов. Я использую данные $_POST, чтобы связать каталог с пользователем. Вы предлагаете мне сделать это на предыдущем шаге? Или, скорее, вы предлагаете мне идентифицировать данные $_POST как отдельное значение, то есть $newvalue = $_POST['id']; И никогда ни для чего не используйте 0777. Как я могу разрешить пользователям сайта загружать файлы в каталог, если каталог не 777? - person codacopia; 06.07.2011
comment
Я понимаю, что, но $_POST может быть изменен в любое время, вам нужно, чтобы пользователи регистрировались, подтверждали свое имя пользователя (буквенно-цифровое, символы под и т. д.), прежде чем сохранять их данные в базе данных, и после того, как они загружают изображение, вам нужно убедиться, что текущий сеанс действителен и использует данные из базы данных (которые вы уже отфильтровали на этапе регистрации). - person Aleksey Korzun; 06.07.2011

вы использовали move_uploaded_file() самостоятельно. Если он возвращает false, то также будет напечатано сообщение sucsess.

Пытаться

if ( move_uploaded_file($_FILES["img_preview"]["tmp_name"],
  "upload/" . $_POST['id'] . "/" . $_FILES["img_preview"]["name"])) {
echo "sucess";
}else{
echo "fail";
}

После этого вы получите то, что является основной проблемой. Также используйте точку отладки от print_r($_FILES) до move_uploaded_file().

person GitsD    schedule 05.07.2011
comment
Также используйте точку отладки с помощью print_r($_FILES) перед move_uploaded_file() Не могли бы вы уточнить этот шаг? Вы предлагаете мне распечатать информацию о файле на странице перед перемещением файлов, чтобы я мог визуально видеть их местоположение? - person codacopia; 06.07.2011

Возможно, это не ответ на ваш вопрос, но все же он стоит вашего внимания, надеюсь. Не полагайтесь на тип файла, отправляемого через $_FILES, это всего лишь mime-тип, отправляемый браузером, насколько я помню, его можно легко скомпрометировать. Используйте функцию getimagesize(), чтобы получить истинный тип изображения, а также высоту/ширину.

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

person ashein    schedule 05.07.2011