загрузить несколько файлов PHP и MySQL - PullRequest
0 голосов
/ 12 ноября 2011

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

Итак, я работаю над этим уже несколько дней и зашел так далеко

if(isset($_POST['Submit']))
{  $ttitle = $_POST['ttitle'];

    $file_dir = './../img/treatments/';
    foreach( $_FILES as $file_name => $file_array ){
    $current_image=$_FILES['image']['name'][0];
    $extension = substr(strrchr($current_image, '.'), 1);
if (($extension!= "png") && ($extension != "jpg")) 
{
die('Unknown extension');
}
$time = date("fYhis");
$new_image = $time . "." . $extension;
$new_dir = mkdir("./../img/treatments/" . $ttitle, 0700);
$destination= $new_dir && $new_image;
$action = copy($_FILES['image']['tmp_name'], $destination);
    }

  $last_name = $_POST['last_name'];
  $username = $_POST['username'];
  $pass = $_POST['pass'];
  $text = $_POST['text'];
  $bio = $_POST['bio'];
  $tsub = $_POST['tsub'];
  $image = $ttitle; 
if (!$action) 
{
die('File copy failed');
}else{
echo "File copy successful";
}

, а затем HTML-форма

<form method='post' enctype='multipart/form-data' action='#'>
<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td width="40%" class="right">

Title: </td><td width="60%" class="left"><input type="text" autofocus autofocus="autofocus" required required="required" name="ttitle" maxlength="255"
  />
*</td></tr><tr><td class="right">
Subtitle:</td><td class="left"> <input type="text" required required="required" name="tsub" maxlength="255"
  />
*</td></tr><tr><td class="right">
Username: </td><td class="left"><input type="text" required required="required" name="username" maxlength="255"
  />
*</td></tr><tr><td class="right">
Password: </td><td class="left"><input type="password" required required="required" name="pass" maxlength="255"
  />
*</td></tr>
<tr><td class="right">
Confirm Password: </td><td class="left"><input type="password" required required="required" name="pass2" maxlength="255"
  />
*</td></tr><tr><td class="right">Proposed Director
</td><td class="left"><input type="text" name="dir" maxlength="255"
  />
  *</td></tr><tr><td class="right">Proposed Additional
</td><td class="left"><input type="text" name="add" maxlength="255"
  /></td></tr><tr><td class="right" valign="top">
Text: </td><td class="left" valign="top"><textarea required required="required" name="text"></textarea>
*</td></tr><tr><td class="right">
Bobblehead: </td><td class="left">
<input type="file" required required="required" name="image[]" multiple="">
*</td></tr> </table>

И теперь все работает, за исключением фактического копирования и записи файлов в новый каталог, я сижу здесь, возясь с этим, но я чувствую, что я очень близок, и у кого-то, вероятно, есть ключ, я просто не могу понять это с макушки моей головы. Любая помощь будет великолепна, спасибо.

Ответы [ 2 ]

3 голосов
/ 12 ноября 2011

Давайте посмотрим, сколько способов я могу перечислить, насколько безумно ужасен ваш код:

  1. Вы используете необработанный POST для создания каталога на вашем сервере. Вы не фильтруете это поле поста для путей к символам, поэтому фактически вы позволяете удаленному пользователю создать каталог ИХ, выбрав ЛЮБОЕ на вашем сервере
  2. Вы анализируете расширения имени файла, чтобы определить типы файлов. На мгновение игнорируя, что параметр name в массиве $ _FILES - это имя файла, предоставленное пользователю, вы используете операции с подстрокой, чтобы получить расширение файла, игнорируя функцию pathinfo(), которая делает это за вас. , Возвращаясь к имени файла, ничто не мешает злонамеренному пользователю переименовать «nastyvirus.exe» в «kittens.jpg» и загрузить его на ваш сервер.
  3. Вы никоим образом / форма / форма не проверяете успешность загрузки - вы просто предполагаете, что все работает отлично, и начинаете обрабатывать загруженный файл. Существует точно ОДИН способ для успешной загрузки, и несколько триллионов способов для его сбоя ... возможно, вам нужно выполнить некоторую проверку ошибок - вот почему существует параметр error в массиве _FILES.
  4. Я дам вам очень много: вы не используете исходное имя файла для хранения файла, но вы слепо генерируете новое имя файла, а затем не проверяете, перезаписываете ли вы ранее загруженный файл. Вполне возможно, что два разных пользователя выберут один и тот же заголовок и загрузят два разных файла одновременно - ваш скрипт затем перезапишет один из этих файлов другим.
  5. Вы используете copy() для перемещения файла после загрузки. Это плохая идея. Для этой цели есть move_uploaded_file(). Помимо очевидной операции MOVE, она также имеет некоторые дополнительные проверки безопасности, чтобы гарантировать, что файл не был подделан на сервере во время между загрузкой и вашим скриптом, обрабатывающим файл. copy буквально скопирует файл, в результате чего (на короткий период) будет удвоено количество данных на вашем сервере, что является пустой тратой пространства. А на больших файлах операция копирования займет довольно много времени. По сравнению с этим перемещения внутри файловой системы почти мгновенные.

  6. Вы говорите, что разрешаете загрузку нескольких файлов, но ваш скрипт проверяет только первый из них [0]. Если вы хотите обрабатывать несколько файлов, вам нужно сделать этот код в цикле, например, foreach(array_keys($_FILES['image']['name']) as $i) { ... }, а затем использовать [$i] вместо [0].

  7. Помимо этого, у вас есть required и required="required" в вашем HTML, что является просто пустой тратой пространства. Используйте один или другой, но не оба.
  8. У вас есть $new_dir && $new_file. && - это не оператор конкатенации в PHP, это логический оператор AND. Вы не присваиваете строку $destination, вы сохраняете результат этого логического значения и, например, правда или ложь.
1 голос
/ 12 ноября 2011

Вы должны выполнить итерацию и copy / move_uploaded_file для каждого из загруженных файлов, так вы получаете доступ к файлу $_FILES['image']['tmp_name'][0].move_uploaded_file лучше всего подходит для этого.

...