#javascript #php
#javascript #php
Вопрос:
Я работаю над HTML-страницей, которая содержит форму, позволяющую пользователям вводить свои данные и загружать файлы. вся информация будет вставлена в базу данных Mysql.
в Javascript я использую XMLHttpRequest для отправки файлов на сервер и «upload.php » переименовать (чтобы избежать дублирования имен) и переместить их в каталог загрузки.
Для лучшего взаимодействия с пользователем это будет сделано перед отправкой всей формы.
Мой вопрос: как я могу сохранить новые имена файлов (определенные в upload.php ), чтобы использовать их при отправке формы «submit.php «?
причина этого в том, что в «submit.php «, я сначала вставляю информацию о пользователе в таблицу «user», а затем выбираю «user_id» (автоинкремент), который будет вставлен с именами файлов в таблицу «files».
Могут ли сеансы php быть подходом для этого? есть ли другой способ? Спасибо за вашу помощь
HTML:
<form action="submit.php" method="post" id="submitform">
<div>
<--!user info part1-->
</div>
<div id="filesContainer" class="eltContainer">
<input type="file" id="filesList" multiple>
</div>
<div>
<--!user info part2-->
</div>
javascript:
var fd = new FormData()
var xhr = new XMLHttpRequest()
for (var i=0,nb = fichiers.length; i<nb; i ) {
var fichier = fichiers[i]
fd.append(fichier.name,fichier)
}
xhr.open('POST', 'upload.php', true)
upload.php :
<?php
foreach($_FILES as $file){
$filename = date('Y') . date('m') . date('d') . date('H') . date('i') . basename($_FILES[$file]['name']);
move_uploaded_file( $file['tmp_name'],"../upload_dir/" .$filename);
}
exit;
Комментарии:
1. просто: запустите транзакцию db, вставьте базовую запись (минимум, необходимый для создания записи), получите ее идентификатор вставки, используйте этот идентификатор для создания вашего имени файла, затем обновите запись / зафиксируйте транзакцию, как только вы завершите манипуляции с файлом.
2. при вставке имени файла в БД мне не нужен идентификатор вставки файла, а идентификатор вставки пользователя (как внешний ключ). Проблема в том, что когда я выполняю манипуляции с файлами / вставку, я еще не достиг вставки пользователя, которая происходит после отправки всей формы .. я также хочу свести к минимуму транзакции с БД. В любом случае спасибо
3. то же самое верно. создайте запись пользователя-заполнителя, чтобы вы могли получить идентификатор пользователя, который затем можно прикрепить к записи файла-заполнителя, бла-бла-бла. все, что вам понадобится после этого, это скрипт-уборщик, чтобы уничтожить все заброшенные скелеты, чтобы вы не заполняли базу данных частичными.
4. в этом случае мне понадобится имя файла или идентификатор, чтобы прикрепить идентификатор пользователя к заполнителю. Остается вопрос, как я могу сохранить информацию о файле до этого момента?
5. @BenS. Будьте осторожны, ваш код позволяет пользователям загружать файлы с несколько произвольными именами. Если я хочу загрузить
something-evil.exe
, я могу, и вы просто добавите к нему дату. Это нехорошо. Кроме того, можно подняться в файловой системе, отправив../
имя файла. Это очень опасно. Используйте UUID для создания имени файла или имен файлов на основе их идентификаторов в вашей базе данных.
Ответ №1:
Я бы подумал об использовании чего-то вроде md5 для уникальных имен файлов.
Тем не менее, вы можете поместить имена файлов в некоторый массив, а затем вернуть эти имена файлов в результате post-запроса и поместить их обратно в некоторое поле ввода.
Чтобы получить ответ, просто добавьте эти строки в свой код ниже open
xhr.onreadystatechange = function {
// If the request completed and status is OK
if (req.readyState == 4 amp;amp; req.status == 200) {
// keep in mind that fileNames here are JSON string
// as you should call json_encode($arrayOfFilenames)
// in your php script (upload.php)
var fileNames = xhr.responseText;
}
}
Если вы хотите, рассмотрите возможность использования простой библиотеки для AJAX-запросов, такой как axios. Это HTTP-клиент на основе обещаний для браузера, очень простой в использовании и экономит ваше время и усилия, потому что вам не нужно запоминать все то, что мы с вами только что написали.
Это один из подходов, но я думаю, что вы тоже можете его использовать $_SESSION
, и он вполне допустим. Я предполагаю, что на данный момент у вас нет пользователя, вошедшего в систему, поэтому моя идея заключается в следующем:
-
поместите имена файлов в
$_SESSION
-
используйте транзакции БД — как предложил @Marc B — для соединения файлов с
пользователем -
если ошибок не было, просто удалите имена файлов из $ _SESSION, если они были, просто перенаправьте пользователя обратно в форму (возможно, с некоторой информацией о том, что пошло не так), и таким образом ему не нужно повторно загружать файлы, потому что у вас все еще есть имена файлов в
$_SESSION
Комментарии:
1. Спасибо за ответ. Но «upload.php » вызывается в API XMLHttpRequest в javascript, как я могу затем получить результат post-запроса?
2. Я изменил свой ответ, включая эту информацию.
3. «xhr.responseText» — это именно то, что мне было нужно. Я продолжу копать также в php-сессиях и посмотрю, какой из них использовать. Спасибо за вашу помощь.