правильный способ загрузки изображения в базу данных

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

теперь, когда это очищено

у меня был вопрос: я вставил изображение в базу данных, набрав это.

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

$filename = $security->secure($_FILES['imgschool']['name']);
$tmpname = $security->secure($_FILES['imgschool']['tmp_name']);
$imgsize = $security->secure($_FILES['imgschool']['size']);
$imgtype = $security->secure($_FILES['imgschool']['type']);
$school = $security->secure($_POST['school']);


//begin upload
if($imgsize > 0) {
$handle = fopen($tmpname, "r");
$content = fread($handle, filesize($tmpname));
$content = addslashes($content);

//code to add all this to database
}

переменная $content — это изображение, и все его получение — это добавление слэшей. Я помню, как кто-то однажды упомянул сделать это с помощью чего-то под названием base64, но я едва могу вспомнить, как это было написано.

вот как я вызываю изображение из базы данных

помимо всех запросов и многого другого, это основная часть, которая вызывает изображение

header("Content-length: ".$imgsize);
header("Content-type: ".$imgtype);
header("Content-Disposition: attachment; filename=".$imgname);
print $row['img'];

проблема, с которой я сталкиваюсь, заключается в том, что вместо отображения изображения. URL-адрес только отображается, поэтому в этом случае я вижу только это

http://localhost/admin/school-catalog.php?page=gallery&id= 4

при открытии страницы для просмотра изображения с правильными параметрами, установленными в URL-адресе.


для тех, кто хотел увидеть запрос, который делается для сохранения изображения и т. д., я скопировал весь раздел

//save image to db
if(isset($_POST['btnupload'])) {

$filename = $security->secure($_FILES['imgschool']['name']);
$tmpname = $security->secure($_FILES['imgschool']['tmp_name']);
$imgsize = $security->secure($_FILES['imgschool']['size']);
$imgtype = $security->secure($_FILES['imgschool']['type']);
$school = $security->secure($_POST['school']);


//begin upload
if($imgsize > 0) {
$handle = fopen($tmpname, "r");
$content = fread($handle, filesize($tmpname));
$content = base64_encode($content);
}

$save = mysql_query("insert into tbl_schoolgallery(id,hash,img,imgtype,imgsize) values(null,'$school','$content','$imgtype','$imgsize')") or die(mysql_error());
header("Location: school-catalog.php?page=school_gallery");

}


//call image from db
$query = mysql_query("select * from $tbl where id = '$id'") or die(mysql_error());
while($row = mysql_fetch_assoc($query)) {

$imgtypeget = explode("/", $row['imgtype']);

$imgname = "img.".$imgtypeget[1];
$imgtype = $row['imgtype'];
$imgsize = $row['imgsize'];

header("Content-length: ".$imgsize);
header("Content-type: ".$imgtype);
print base64_decode($row['img']);

print $row['img'];
}

person SarmenHB    schedule 26.06.2009    source источник
comment
Разве вы не должны использовать print $content?   -  person Vinko Vrsalovic    schedule 26.06.2009
comment
я не могу, потому что я вызываю изображение из базы данных   -  person SarmenHB    schedule 26.06.2009
comment
Эта часть кода и образец данных отсутствуют. Вы уверены, что столбец img содержит правильное значение?   -  person Vinko Vrsalovic    schedule 26.06.2009
comment
Можем ли мы увидеть ваши запросы для вставки и чтения из базы данных? У меня такое чувство, что твоя ошибка там.   -  person Zarel    schedule 26.06.2009
comment
Требуется ли Content-Disposition для отображения файла?   -  person karim79    schedule 26.06.2009
comment
Content-Disposition используется для установки имени загруженного файла (скажем, если вы отправляете пользователю документ Word и хотите значение по умолчанию, когда появляется приглашение «Сохранить как...»). При правильном использовании в этом случае это приведет к тому, что прямой переход к URL-адресу изображения вызовет загрузку, а не отображение.   -  person Tom Mayfield    schedule 26.06.2009
comment
Я думаю, вы обнаружите, что ссылка на локальный хост будет работать только на вашей машине :)   -  person Benjol    schedule 26.06.2009
comment
Хотя у хранения двоичных данных в базе данных SQL есть проблемы, это имеет смысл, если вы заботитесь о транзакциях (попробуйте синхронизировать файловую систему с серверной частью sql), масштабируемости (множество инструментов, помогающих с этим для RDMS), резервных копиях (зачем писать/ использовать еще одну систему резервного копирования?), и особенно взаимодействие всех этих проблем.   -  person    schedule 26.06.2009
comment
часть размещения контента, которая мне действительно не нужна. я просто забыл его вынуть.   -  person SarmenHB    schedule 26.06.2009


Ответы (1)


Использование addslashes крайне некорректно. В зависимости от того, является ли ваш столбец полем TEXT или полем BLOB, вы должны использовать Base64 или mysql_real_escape_string.

Использование Base64 не так сложно; вы можете также использовать этот путь. Просто замените addslashes на base64_encode и повторите изображение с помощью base64_decode.

Если на то пошло, есть немного более простой способ написать все это:

// begin upload
if ($imgsize > 0)
{
  $content = file_get_content($tmpname);
  $content = base64_encode($content);
}

И тогда для вывода вам действительно нужно всего лишь сделать

header("Content-type: ".$imgtype);
echo base64_decode($img);

Однако, если столбец является BLOB, вы можете напрямую использовать mysql_real_escape_string:

// begin upload
if ($imgsize > 0)
{
  $content = file_get_content($tmpname);
  $content = mysql_real_escape_string($content);
}

А потом:

header("Content-type: ".$imgtype);
echo $img;

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


Ваш текущий код выглядит в основном нормально. Несколько вопросов:

print base64_decode($row['img']);

print $row['img'];

Вероятно, вы хотели избавиться от второго ряда. Кроме того, вы должны использовать echo вместо print; все используют его, иногда он может быть немного быстрее, и print на самом деле не имеет никаких преимуществ, кроме возврата значения:

echo base64_decode($row['img']);

$security->secure() похоже на какую-то функцию очистки. Просто используйте mysql_real_escape_string() - это тот, который вы должны использовать. Кроме $imgsize; вы можете использовать intval() для этого, так как вы знаете, что это должно быть целым числом.

Также здесь:

$query = mysql_query("select * from $tbl where id = '$id'") or die(mysql_error());

Вы называете таблицу tbl_schoolgallery несколькими строками выше. Я предполагаю $tbl == 'tbl_schoolgallery', но для согласованности вы должны либо использовать $tbl в обоих местах, либо tbl_schoolgallery в обоих местах.

Кроме того, замените это while на if - в любом случае ваш код вызовет проблемы, если он когда-либо зациклится более одного раза.

person Zarel    schedule 26.06.2009
comment
я добавил кусок кода: P, вы можете просмотреть его. Спасибо за уделенное время. - person SarmenHB; 26.06.2009
comment
у меня такое ощущение, что ошибка здесь: $tmpname = $security-›secure($_FILES['imgschool']['tmp_name']); то, что делает класс, это его значение через mysql_real_escape_string и htmlencode. поэтому файл временного изображения проходит через то, что его уничтожает, лол. забавно то, что я использую стороннюю программу просмотра базы данных и могу четко видеть изображение внутри базы данных. - person SarmenHB; 26.06.2009
comment
Да, вам не нужно защищать $tmpname. - person Zarel; 26.06.2009