Archief - 'Bestand uit mysql halen' probleem

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

GammaGamer

Legacy Member
Hallo beste mede webprogrammeurs

Ik zit me probleem dat nu toch al een tijdje aansleept en TOCH niet opgelost geraakt...

Ik heb een kleine website met een uploadscript waar documenten kunnen geüpload worden. Deze worden in een MySQL database geplaatst.

Via een andere webpagina kan je dan die documenten die geüpload zijn terug downloaden (stel er u niet teveel van voor, het is HEEL simplistisch).

Nu, als je iets download zoals een .doc file of een .pdf file, springt direct het correcte programma open of wordt het juiste programma aangesproken.

Wat heb ik gemerkt: Office 2010 bestanden (.docx of .xlsx) bestanden worden NIET op de correcte manier geopend. Deze worden uitgelezen als een .xml bestand (wat ze in feit wel zijn maar soit).

Het 'type' bestand wordt automatisch bij het uploaden gedefinieerd.

Bvb:
Een '.doc' document krijgt als type 'application/msword' mee.
Een '.docx' document krijgt als type 'application/vnd.openxmlformats' mee.

Volgens andere fora moet ik prutsen met mijn .htaccess om dit in orde te brengen maar ik zou begot niet weten wat daar allemaal in te noteren.

Heefd iemand een idee hoe ik ervoor kan zorgen dat deze documenten uitgelezen worden als een Word bestand of ik het nodige kan toevoegen aan mijn .htaccess bestand?

Dank bij voorbaat ;)

Bumbolt

Legacy Member
Heb je het al laten testen voor andere mensen? Ik zou zeggen geef een link...

Lijkt erop dat die instellingen meer bij de gebruiker liggen dan bij de site. Als je zegt dat ze als Xml worden uitgelezen. Eens de echte extensie checken van die gedownloade bestanden. En zo terug gaan kijken in jouw code. Waarschijnlijk converteer je het dan ergens naar een xml.

Je zegt dat de bestanden in je SQL zitten maar daar bedoel je dan toch het path naar de bestanden mee? Bestanden rechstreeks in een sql database gaan droppen lijkt me nogal raar.

GammaGamer

Legacy Member
Bumbolt zei:
Heb je het al laten testen voor andere mensen? Ik zou zeggen geef een link...

Lijkt erop dat die instellingen meer bij de gebruiker liggen dan bij de site. Als je zegt dat ze als Xml worden uitgelezen. Eens de echte extensie checken van die gedownloade bestanden. En zo terug gaan kijken in jouw code. Waarschijnlijk converteer je het dan ergens naar een xml.

Je zegt dat de bestanden in je SQL zitten maar daar bedoel je dan toch het path naar de bestanden mee? Bestanden rechstreeks in een sql database gaan droppen lijkt me nogal raar.
Al zeker een 50 tal mensen hebben dit getest ;)
(geen link omdat het in zekere zin onbeveiligd is)

En ja, dat was ik vergeten te vermelden, hij maakt er een .xml bestand van (je kan het bestand openen van zodra je 'openen' via Word selecteert)

Het probleem bevind zich in de MIME-types maar hoe of wat ik moet toevoegen om het in orde te krijgen weet ik echt niet...

Disa

Legacy Member
Stuur je de mimetype wel mee in de headers?
IIRC, is dat in php zoiets:
Code:
// De content type header
header('Content-Type: ' . $mimetype);

// Als je wil dat het gedownload moet worden
header('Content-disposition: attachment; filename=' . $my_filename);

Dit kan waarschijnlijk ook wel in de .htaccess gedaan worden.

GammaGamer

Legacy Member
Disa zei:
Stuur je de mimetype wel mee in de headers?
IIRC, is dat in php zoiets:
Code:
// De content type header
header('Content-Type: ' . $mimetype);

// Als je wil dat het gedownload moet worden
header('Content-disposition: attachment; filename=' . $my_filename);

Dit kan waarschijnlijk ook wel in de .htaccess gedaan worden.
Er wordt mij aangeraden dit in .htacces te doen :unsure:

Can ik met dat stukje code zelf de mimetype aan bestanden toekennen?

wonko

Legacy Member
Aangezien je het terugstuurt via PHP, zal je zelf moeten instaan voor het doorgeven van de juiste headers met mime-types. Via .htaccess gaat dit enkel voor bestanden die door de webserver doorgestuurd worden (een .docx of zo in een map op de webserver).

Idealiter ga je het mime-type detecteren wanneer de upload gebeurt, en sla je dit mee op in een veldje in je database; daarna ga je bij het terug doorsturen van het bestand het correcte mimetype doorsturen.

Trouwens, files in een db is eigenlijk minder slim... sla de files op op disk, en hou een referentie bij in de DB.

adrianhates

Legacy Member
wonko zei:
Aangezien je het terugstuurt via PHP, zal je zelf moeten instaan voor het doorgeven van de juiste headers met mime-types. Via .htaccess gaat dit enkel voor bestanden die door de webserver doorgestuurd worden (een .docx of zo in een map op de webserver).

Idealiter ga je het mime-type detecteren wanneer de upload gebeurt, en sla je dit mee op in een veldje in je database; daarna ga je bij het terug doorsturen van het bestand het correcte mimetype doorsturen.

Trouwens, files in een db is eigenlijk minder slim... sla de files op op disk, en hou een referentie bij in de DB.

yes sir!
Mimetypes detecteren is trouwens niet zo simpel met PHP als ge lager dan 5.3 draait.
Met PHP > 5.2 kunt ge fileinfo gebruiken, oftewel de PECL extensie zelf mee installeren / compilen op PHP < 5.3
http://www.php.net/manual/en/function.finfo-file.php

Functieke voor PHP < 5.3:

Code:
$file_shell = escapeshellarg( $filename );
$mime_type = shell_exec("file -bi " . $file_shell);

GammaGamer

Legacy Member
wonko zei:
Aangezien je het terugstuurt via PHP, zal je zelf moeten instaan voor het doorgeven van de juiste headers met mime-types. Via .htaccess gaat dit enkel voor bestanden die door de webserver doorgestuurd worden (een .docx of zo in een map op de webserver).

Idealiter ga je het mime-type detecteren wanneer de upload gebeurt, en sla je dit mee op in een veldje in je database; daarna ga je bij het terug doorsturen van het bestand het correcte mimetype doorsturen.

Trouwens, files in een db is eigenlijk minder slim... sla de files op op disk, en hou een referentie bij in de DB.
De Mimetypes worden automatisch gedetecteerd van zodra het bestand upgeload wordt, die mimetypes worden dan apart in die database geplaatst ;)

Aan dat laatste had ik ook al gedacht maar aangezien de bestanden niet groot zijn (hoewel ik laatste problemen had met een te groot bestand...) en mijn kennis van PHP niet zo uitgebreid is, heb ik het maar in een database gepropt :p (het bestaat al een jaar dusja)

adrianhates zei:
yes sir!
Mimetypes detecteren is trouwens niet zo simpel met PHP als ge lager dan 5.3 draait.
Met PHP > 5.2 kunt ge fileinfo gebruiken, oftewel de PECL extensie zelf mee installeren / compilen op PHP < 5.3
PHP: finfo_file - Manual

Functieke voor PHP < 5.3:

Code:
$file_shell = escapeshellarg( $filename );
$mime_type = shell_exec("file -bi " . $file_shell);
tot nogtoe eigelijk geen problemen gehad om mimetypes te selecteren, effe de code plakken:

Code:
$fileType = $_FILES['userfile']['type'];

Bovenstaande is een deel van het 'uploadscript' waarbij het type bepaald wordt

Code:
header("Content-type: $type");

Dit is het 'downloadscript' waarbij het type terug wordt toegewezen aan het gedownloade :)

Alles gaat perfect tot ik .docx bestanden en companie er op plaats :sad:

adrianhates

Legacy Member
Code:
$fileType = $_FILES['userfile']['type'];

$_FILES['userfile']['type'] is niet te vertrouwen ...
http://stackoverflow.com/questions/6000229/reliability-of-mimetypes-in-uploads-php

en dan is finfo zelfs nog niet 100% te vertrouwen.. PHP code kunde ook in images steken en dan zal da nog steeds image/jpeg teruggeven. Een al ouder documentje maar nog steeds toepasbaar meen ik:
http://www.scanit.be/uploads/php-file-upload.pdf

maar zolang ge geen code toont zal niemand u kunnen helpen denk ik :) Het is zeker en vast zonder .htaccess te doen want ik heb het gisteren zelfs nog gemaakt ..

edit : hebt ge ook verschillende browsers gechecked? Zit ge op IIS? of Apache?

GammaGamer

Legacy Member
adrianhates zei:
Code:
$fileType = $_FILES['userfile']['type'];

$_FILES['userfile']['type'] is niet te vertrouwen ...
security - Reliability of Mimetypes in Uploads (PHP) - Stack Overflow

en dan is finfo zelfs nog niet 100% te vertrouwen.. PHP code kunde ook in images steken en dan zal da nog steeds image/jpeg teruggeven. Een al ouder documentje maar nog steeds toepasbaar meen ik:
http://www.scanit.be/uploads/php-file-upload.pdf

maar zolang ge geen code toont zal niemand u kunnen helpen denk ik :) Het is zeker en vast zonder .htaccess te doen want ik heb het gisteren zelfs nog gemaakt ..

edit : hebt ge ook verschillende browsers gechecked? Zit ge op IIS? of Apache?
Kudos voor het document, daar kan ik proberen info uit te halen ;)
(again, mijn kennis van php is zeer beperkt...)


Downloadscript
Code:
<?php
if(isset($_GET['id']))
{
include 'hostgegevens';
$id    = $_GET['id'];
$query = "SELECT name, type, size, content " .
         "FROM upload WHERE id = '$id'";
		 
$result = mysql_query($query) or die('Error, query failed');

list($name, $type, $size, $content) =  mysql_fetch_array($result);

header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$name");
echo $content;
exit;
}
?>

Uploadscript
Code:
<?php
include "hostgegevens";

if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0)
{
$naam = $_POST['naam'];
$bestandsnaam = $_POST['bestandsnaam'];
$Vak = $_POST['Vak'];
$fileName = $_FILES['userfile']['name'];
$tmpName  = $_FILES['userfile']['tmp_name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];
$fp      = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = addslashes($content);
fclose($fp);

if(!get_magic_quotes_gpc())
{
    $fileName = addslashes($fileName);
}

$query = "INSERT INTO upload (name, size, type, content, naam_ll, bestandsnaam, Vak ) ".
"VALUES ('$fileName', '$fileSize', '$fileType', '$content', '$naam', '$bestandsnaam', '$Vak')";
mysql_query($query) or die('Error, query failed');
echo "<br>Bestand '$fileName' opgeladen<br>";
}
?>

GammaGamer

Legacy Member
Zir0h zei:
Beetje offtopic, maar uw script is wel héél sql injectable.
Welk deel van 'ik ben niet zo goed in php' wordt er niet gesnapt? :unsure:

Kheb een bestaand script gevonden, zo goed mogelijk aangespast en het werkte :unsure:
Ik ben gwn content DA het werkt :p

(trouwes, de mensen die het gebruiken, weten niks van programmeren en code ;) )

adrianhates

Legacy Member
ge kunt met 1 SQL injection heel uw tabel verwijderen.. Die opmerkingen hebben dus zeker wel iets bij te dragen! Die van Lame ook , want uw opmerking was echt wel lame. Der kan altijd iemand bij zitten dat er wel kennis van heeft .. En dan bende gefucked als da ne klootzak is!

En het werkt niet! :) Omdat op te lossen zulde toch een live voorbeeld moeten geven..
Of beter ook niet want dan riskeerde dat uw tabel verdwijnt ..

GammaGamer

Legacy Member
adrianhates zei:
ge kunt met 1 SQL injection heel uw tabel verwijderen.. Die opmerkingen hebben dus zeker wel iets bij te dragen! Die van Lame ook , want uw opmerking was echt wel lame. Der kan altijd iemand bij zitten dat er wel kennis van heeft .. En dan bende gefucked als da ne klootzak is!

En het werkt niet! :) Omdat op te lossen zulde toch een live voorbeeld moeten geven..
Of beter ook niet want dan riskeerde dat uw tabel verdwijnt ..
Laat maar, ik laat een mod deze topic wel verwijderen want als ik een live voorbeeld geef (aka, de link), zal er wel een of andere douchebag gans den boel om zeep helpen...

Toch bedankt voor de mensen die informatie gegeven hebben :applause:
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan