blob image uitlezen
Voor een betreffend klein projectje sla ik enkele afbeeldingen op in mijn database. (dat dit niet done is etc weet ik allemaal, maar heb dit gedaan omdat het toch maar enkel foto's zijn, dus dan weten jullie ookal waarom ik ze opslaag in mijn database.)
Nu tot over een week gebruikte ik dit stukje code om mijn foto's uit te lezen:
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$connect = new mysqli('localhost', 'root', 'root', 'ioutfit');
$result = $connect->query('SELECT foto from tblFotos ORDER BY PK_fotoID');
while($row = $result->fetch_array()) {
echo '<img src="data:image/jpeg;base64,' . base64_encode($row['foto']) . '" width="100%" height="100%"/>';
echo '<br>';
//echo $seisoon;
}
?>
$connect = new mysqli('localhost', 'root', 'root', 'ioutfit');
$result = $connect->query('SELECT foto from tblFotos ORDER BY PK_fotoID');
while($row = $result->fetch_array()) {
echo '<img src="data:image/jpeg;base64,' . base64_encode($row['foto']) . '" width="100%" height="100%"/>';
echo '<br>';
//echo $seisoon;
}
?>
Nu wou ik vandaag verder werken aan mijn project blijkt nu dat deze code op mijn server iet meer werkt? lokaal toont hij nog enkele afbeeldingen maar online dus geen enkele meer. (wel toont hij een kader met een gebroken foto in zoals het geen je zou krijgen als je pad naar een image op de server niet gevonden is)
Iemand die ziet wat mijn fout is of hoe je dit op een andere manier kan uitlezen?
Bijkomende vraag, betreffende dezelfde app heb ik dus ook een upload scriptje geschreven, werkt perfect op de computer MAAR mobiel op iphone slaagt hij een blob op van 0 bytes? Android doet het dan weer wel goed. Iemand hier enige ervaring mee?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?php
$connect = new mysqli('localhost', 'root', 'root', 'ioutfit');
if(isset($_POST['send'])) {
var_dump($_FILES['myfile']);
var_dump($_POST);
//echo 'the form has been submitted';
if($_FILES['myfile']['size'] == 0) {
//geen bestand geselecteerd
echo "Gelieve een foto te selecteren";
}
if($_POST['seisoon'] == null) {
echo "gelieve een seisoon in te vullen";
}
else {
$file = file_get_contents($_FILES['myfile']['tmp_name']);
$file = base64_decode($file);
$seisoon = $_POST['seisoon'];
$seisoon = strtolower($seisoon);
$user = 1;
if($seisoon == "winter" || $seisoon == "lente" || $seisoon == "zomer" || $seisoon == "herfst") {
//echo 'check!';
//mysql_ping($connect);
$query = "INSERT INTO tblFotos (FK_userID, foto, seisoon) VALUES (" . $user . ",'" . $file. "','" . $seisoon . "')";
$result = mysqli_query($connect, $query);
echo $file;
if(!$result) {
die("Database query faild : " . mysqli_error($connect));
}
else {echo 'success';}
}
else {
echo 'gelieve een geldig seisoon in te vullen';
}
}
}
?>
<form method="post" action="input-test.php" id="upload-form" name="upload-form" enctype="multipart/form-data">
<input id="myfile" name="myfile" type="file" accept="image/*;capture=camera">
<input id="seisoon" name="seisoon" type="text" />
<input type="submit" name="send" id="send" value="send" />
</form>
$connect = new mysqli('localhost', 'root', 'root', 'ioutfit');
if(isset($_POST['send'])) {
var_dump($_FILES['myfile']);
var_dump($_POST);
//echo 'the form has been submitted';
if($_FILES['myfile']['size'] == 0) {
//geen bestand geselecteerd
echo "Gelieve een foto te selecteren";
}
if($_POST['seisoon'] == null) {
echo "gelieve een seisoon in te vullen";
}
else {
$file = file_get_contents($_FILES['myfile']['tmp_name']);
$file = base64_decode($file);
$seisoon = $_POST['seisoon'];
$seisoon = strtolower($seisoon);
$user = 1;
if($seisoon == "winter" || $seisoon == "lente" || $seisoon == "zomer" || $seisoon == "herfst") {
//echo 'check!';
//mysql_ping($connect);
$query = "INSERT INTO tblFotos (FK_userID, foto, seisoon) VALUES (" . $user . ",'" . $file. "','" . $seisoon . "')";
$result = mysqli_query($connect, $query);
echo $file;
if(!$result) {
die("Database query faild : " . mysqli_error($connect));
}
else {echo 'success';}
}
else {
echo 'gelieve een geldig seisoon in te vullen';
}
}
}
?>
<form method="post" action="input-test.php" id="upload-form" name="upload-form" enctype="multipart/form-data">
<input id="myfile" name="myfile" type="file" accept="image/*;capture=camera">
<input id="seisoon" name="seisoon" type="text" />
<input type="submit" name="send" id="send" value="send" />
</form>
Al vast bedankt,
Joren
http://php.net/manual/en/mysqli-stmt.send-long-data.php
Misschien heb je er wat aan? Ik werk nooit met BLOB namelijk.
Joren van hocht op 10/01/2014 11:55:26:
(dat dit niet done is etc weet ik allemaal, maar heb dit gedaan omdat het toch maar enkel foto's zijn, dus dan weten jullie ookal waarom ik ze opslaag in mijn database.)
Of het not done is of niet is op zich niet zo relevant. Dat is jouw keuze. De vraag die ik mezelf alleen wel zou stellen is 'Zou ik dit probleem ook hebben als ik het niet als BLOB zou opslaan?'. Het antwoord daarop is volgens mij nee. Met andere woorden, ik denk dat je je tijd nu bestaat aan een probleem wat je helemaal niet hoeft te hebben. Verkwanselde tijd en energie dus.
Verder kan ik je net als Aar niet echt helpen, want ik heb er, helaas voor jou, nooit mijn tijd aan besteed....
Erwin, inderdaad ik heb mij hier serieus aan mispakt ben ik mezelf heel erg bewust van, probleem zit hem dus dat heel mijn mobile web app hier opgebasseerd is en en dus opnieuw beginnen geen optie is aangezien mijn deadline volgende week is.
Ik ben er net wel al achtergekomen dat het uitlezen volledig correct gebeurt, het is mijn upload die blijkbaar toch niet werkt op computer. Ik had net al mijn records verwijderd om wat represente data toe te voegen, dit toevoegen deed ik dus via mijn upload script. Blijkbaar had ik in een vorig statium mijn foto's dus via phpmyadmin toegevoegd, wat ik dus vergeten was (wel logisch want toen had ik dit script nog niet geschreven).
Ik weet nu toch al waar mijn fout zit en kan weer wat specifieker gaan zoeken op google, als er hier mensen zijn die ervaring hebben met het upload van een blob in de database, jullie hulp/tips wordt nog steeds erg geapreciërd!
Joren
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
ob_start();
readfile($_FILES['myfile']['tmp_name']);
$file = ob_get_contents();
ob_end_clean();
// EN DAN NIET VERGETEN!!!!
// mysqli_real_escape_string($link, $file)
// geldt tevens voor alle overige user input
?>
ob_start();
readfile($_FILES['myfile']['tmp_name']);
$file = ob_get_contents();
ob_end_clean();
// EN DAN NIET VERGETEN!!!!
// mysqli_real_escape_string($link, $file)
// geldt tevens voor alle overige user input
?>
Gewijzigd op 10/01/2014 13:25:09 door Ger van Steenderen
Joren van hocht op 10/01/2014 12:27:46:
als er hier mensen zijn die ervaring hebben met het upload van een blob in de database
Ja en nee. ;-) Ik heb verschillende databases waar foto's in worden opgeslagen als blobs, alleen bewerk ik die niet in PHP, maar in Perl. Het principe zou hetzelfde moeten zijn.
Een van de verschillen die me opvallen qua werkwijze is dat bij jou de foto's als binary data in de database staan, maar dat ze bij de invoer en uitvoer worden omgezet van of naar base64. Daar zou ik zelf niet per se voor kiezen. Als ze worden aangeleverd als base64 en ook als base64 weer worden aangeboden, zou ik ze ook als base64 opslaan in de database (en dan niet als blob, maar als text).
Zelf verwerk ik alles als binary. De plaatjes komen binnen als POST-data (binair) en gaan rechtstreeks de database in.
Bij het opvragen/tonen van de plaatjes worden ze niet als inline data in de img-tag opgenomen. In plaats daarvan verwijst de img tag naar een los script, dus iets als:
In dat getimage-script wordt het plaatje opgehaald uit de database. Het script genereert een image/jpeg-header en gooit daarna de (binaire) data erachteraan. Zoiets ongeveer:
Code (php)
(disclaimer: dit is conceptuele code; ik garandeer niet dat het werkt en dingen als inputvalidatie en foutafhandeling zul je nog moeten toevoegen)
Gewijzigd op 10/01/2014 15:11:40 door Willem vp
En dan zoals Willem aangeeft de plaatjes ophalen met een script.
En Joren, je controleert nergens of het wel een image is, dus ik kan zomaar een bestand met malicious code erin gooien.
is dan weer dat je voor elk plaatje een apart script met een aparte database verbinding nodig hebt.
Nadeel van de inline-images is weer, dat je html file erg groot dan worden en je mogelijk per saldo weer meer data moet oversturen, ( al dan niet gezipt)
Dat van die database-verbindingen zal in de praktijk wel meevallen. Eventueel kun je een persistent connectie maken door in je mysqli_connect 'p:' voor je hostname te zetten.
Het valt ook heel erg mee, en ik begrijpt niet waarom heel veel mensen het not done vinden. Waarschijnlijk uit onwetendheid.
Dan is het niet 1 aanroep naar PHP gevolgd door het opvragen van die 3 afbeeldingen,
maar nog een keer 3x php aanroepen. Elk script heeft zijn eigen database verbinding nodig. (desnoods uit een pool gehaald ja), voert een query uit op de database-server. Die draagt de data over aan php en php spuugt dat uit.
Zonder maatregelen met extra headers wordt dat niet gecacht. Dus waar een opgeslagen afbeelding bij het herladen van de pagina gewoon met een header "304 not changed" kan worden afgedaan, doe je dat proces opnieuw.
Voor 1 pagina is dat prima te overzien.
Maar als het een site betreft die vaak bezocht wordt, laten we zeggen 60 hits per minuut.
Dan heb je het niet over 1 php aanroep per seconde maar 4
Je afbeeldingen gaan elke keer over de lijn, dus meer data verkeer.
Daarnaast maak je heel regelmatig een backup van je database. (of dat doet je hoster.)
Binaire data neemt een hoop ruimte in in de database. Maar deze data is niet erg aan verandering onderhevig. Dus als file op hd had hij een datum gehad, en had een intelligent backup proces die file kunnen herkennen als oud en niet bij elke backup mee zullen pakken.
Het kan wel.
Maar er is ook een hoop als reden om het niet te doen aan te voeren.
eea hangt samen met hoeveel files en hoe druk je site bezocht is
En natuurlijk heeft het nadelen, maar om nu te stellen dat het not. done is vind ik te ver gaan.
Als je de images inline in je (dynamisch gegenereerde) HTML opneemt, wordt er ook niet veel gecacht. ;-)
Wel is het eenvoudiger om je hele databoeltje mee te nemen naar een andere server: alles zit dan verpakt in je database en je hebt niet directory's aan files om mee te slepen.
elk nadeel hep soms een voordeel
Het is een beetje een afweging van de situatie. Als je duizenden bestandjes hebt van niet meer dan een paar kilobyte kun je ze beter in een database gooien, omdat anders de toegangstijden via het filesysteem te lang worden. En er zijn situaties waarin je moet kunnen garanderen dat je plaatje en de data in de database in dezelfde transactie worden gewijzigd. Dat is niet goed mogelijk wanneer je het plaatje op een filesystem zet.
Bedankt voor jullie antwoorden, sorry dat ik zo laat reageer maar ik zit midden in mijn examen periode en had even gebrek aan tijd om aan deze examenopdracht te werken. Ondertussen heb ik in het weekend de app toch maar even volledig om gegooid en ik upload de images nu naar mijn server ipv naar de database.