#php #mysql
#php #mysql
Вопрос:
Здесь полный новичок, пожалуйста, потерпите меня.
Создание очень маленького персонального приложения, которое загружает некоторые изображения и информацию. Я не могу понять, почему следующий PHP / MySQL не добавляет последнюю вставку в запросе ( $file_data
) в поле longblob моей базы ДАННЫХ.
Все остальные поля в запросе вставляются нормально, то есть я тестировал их по одному, добавляя в запрос, пока не добрался до последнего, а затем вставка завершилась неудачно. Я могу выполнить echo $file_data
перед вставкой и увидеть, что данные есть, я также обнаружил, что жесткое кодирование строкового значения для $file_data
(т. е. $file_data="this will insert"
) вставляет нормально… что расстраивает.
Итак, я предполагаю, что произошла ошибка при чтении файла ( $fp fread
и т.д.) Или что мой longblob настроен неправильно. Размеры файла <16 кб, поэтому я уверен, что это также не проблема с php.ini.
Есть идеи? Спасибо.
$boxtype=$_POST['type'];
$title=$_POST['title'];
if(isset($_POST['submit']) amp;amp; $_FILES['imgfile']['size'] > 0)
{
$filename = $_FILES['imgfile']['name'];
$tmpName = $_FILES['imgfile']['tmp_name'];
$file_size = $_FILES['imgfile']['size'];
$mime_type = $_FILES['imgfile']['type'];
$fp = fopen($tmpName, 'r');
$file_data = fread($fp, filesize($tmpName));
fclose($fp);
$query = "INSERT INTO table
(boxtype,title,filename,mime_type,file_size,file_data)
VALUES
('$boxtype','$title','$filename','$mime_type','$file_size','$file_data')
";
$db = db_connect();
$result = $db->query($query) or die('Error, query failed');
if ($result)
{
echo "<br>Success<br>";
}
}
else die("No Content");
Таблица MySQL:
CREATE TABLE `port` (
`id` int(2) unsigned zerofill NOT NULL AUTO_INCREMENT,
`boxtype` tinytext COLLATE latin1_general_ci NOT NULL,
`title` varchar(40) CHARACTER SET latin1 NOT NULL,
`filename` varchar(255) COLLATE latin1_general_ci NOT NULL,
`mime_type` varchar(255) COLLATE latin1_general_ci NOT NULL,
`file_size` int(11) NOT NULL,
`file_data` longblob NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Комментарии:
1. что произойдет, если вы сначала экранируете данные перед вставкой? Я никогда не использовал загрузку файлов в базу данных, поэтому не уверен, нужно ли это при вставке $ file_data в поле.
2. По-видимому, это так, я подумал то же самое, см. Ниже.
Ответ №1:
Поскольку это двоичный файл, он, вероятно, содержит значения, что означает, что он, вероятно, вызывает колебания
Попробуйте использовать addslashes для переменной file_data, чтобы сохранить ее.
Комментарии:
1. Это сработало, не думал, что экранирование имеет значение за пределами атак xxs, но, конечно же, БД не понравился двоичный файл как есть. Спасибо!
Ответ №2:
Примеры, с которыми я столкнулся при использовании Google, показали, что данные были экранированы либо с помощью addslashes, либо mysql_real_escape_string. Поэтому я предполагаю, что это важная часть, поскольку строка $file_data может содержать различные символы.
Ответ №3:
Если в Windows использовать fopen($tmpName, 'rb');
и использовать mysql_escape_string($file_data)
.
Ответ №4:
Вам придется использовать функции mysqli_ для создания подготовленной инструкции. Вот пример
$sql = 'INSERT INTO Table(boxtype,title,filename,mime_type,file_size,file_data)
VALUES (?,?,?,?,?,?)';
$stmt = mysqli_prepare($link, $sql);
mysqli_stmt_bind_param($stmt, "ssssib", $boxtype,$title,$filename,$mime_type,$file_size,$file_data);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt);
Это также предотвратит атаки SQL-инъекций, к которым, как представляется, может быть уязвим ваш код. В качестве альтернативы вы можете использовать библиотеки PDO для создания подготовленных инструкций.
С помощью PDO вы можете сделать следующее.
$sql = 'INSERT INTO Table(boxtype,title,filename,mime_type,file_size,file_data)
VALUES (:boxtype,:title,:filename,:mime_type,:file_size,:file_data)';
$statement = $con->prepare($sql);
$statement->bindParam(':boxtype',$boxtype,PARAM_STR);
$statement->bindParam(':title',$title,PARAM_STR);
$statement->bindParam(':filename',$filename,PARAM_STR);
$statement->bindParam(':mime_type',$mime_type,PARAM_STR);
$statement->bindParam(':file_size',$file_size,PARAM_INT);
$statement->bindParam(':file_data',$file_data,PARAM_LOB);
$statement->execute();