Проблема с вставкой данных изображения в поле LongBlob

#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();