[PHP/MySQL] Afbeelding uit database halen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Ik heb door middel van een standaard form een afbeelding in de database gezet, dit omdat een bestands uploadscript niet altijd even lekker werkt en dit mij de makkelijkste oplossing leek.

Nu heb ik alleen een probleem... ik kan hem niet uitlezen, dan krijg ik een foutmelding.

Mijn code is als volgt:

nieuw.php
code:
1
2
<div class="adminlabel">Foto:</div>
    <input name="foto" type="file" size="30" />


opslaan.php (verwerkingscript)
PHP: filename
1
2
3
4
5
6
$foto = base64_encode(file_get_contents($_FILES['foto']['tmp_name']));

$opslaan = "INSERT INTO producten (naamprod, omschrijving, foto) 
            VALUES ('".$naamprod."',
                    '".$omschrijving."',
                    '".$foto."')";


Nu wil ik hem dus laten tonen wanneer ik het item bewerk, maar
code:
1
2
<div class="adminlabel">Foto:</div>
    <img src="<?php echo $arr_foto['foto']; ?>" /><br />


Geeft de volgende foutmelding
code:
1
2
<img src="
Fatal error: Cannot use object of type stdClass as array in C:\xampp\htdocs\xampp\...\...\product_bewerken.php on line 36


Dus het gaat niet zo makkelijk als ik dacht. Hoe moet ik een afbeelding (gewoon *.jpeg) uitlezen uit de database? Hoop dat iemand mij hier mee kan helpen.

(Een goed upload script kan natuurlijk ook).

Acties:
  • 0 Henk 'm!

  • TeeDee
  • Registratie: Februari 2001
  • Laatst online: 21:07

TeeDee

CQB 241

Bedenk eens waarom dit niet werkt? Je output nu een binary array in je html. Dat gaat over het algemeen niet goed. Je kan nog een base64 als image source gebruiken, maar dat wordt niet altijd gesupport.

Als je <img src="img.php?img=1"> waarbij img=1 correspondeert met het record in de database.
Vervolgens op img.php de img parameter uitlezen en echo-en.

Of je uploadscript goed werkt kan ik niet zeggen.

Heart..pumps blood.Has nothing to do with emotion! Bored


Acties:
  • 0 Henk 'm!

  • Iska
  • Registratie: November 2005
  • Laatst online: 24-08 21:44

Iska

In case of fire, use stairs!

Je zet eerst neer 'file_get_contents', en daarna probeer je een url eruit te krijgen xD, gaat niet werken he ;)
Zoals je het nu doet (wat ik trouwens bijzonder sterk afraadt maar oké) is de data van de afbeelding in de database zetten. Als je die dan wil weergeven moet je hem weer terugtoveren naar een afbeelding (je zult dan dus ook het afbeelding-type moeten opslaan).
Dat terugtoveren kan bijv. via 'imagejpeg' of 'imagepng'. Als eerste argument geef je wat er in de database stond en het resultaat is de afbeelding en dan komt je afbeelding tevoorschijn.

Maar nogmaals, probeer het echt anders te doen.. want je database gaat heel vol en langzaam worden + dat dit relatief veel rekenkracht kost


TeeDee was net eerder

-- All science is either physics or stamp collecting


Acties:
  • 0 Henk 'm!

  • Kettrick
  • Registratie: Augustus 2000
  • Nu online

Kettrick

Rantmeister!

Jasper91 schreef op woensdag 15 oktober 2008 @ 16:42:
Zoals je het nu doet (wat ik trouwens bijzonder sterk afraadt maar oké) is de data van de afbeelding in de database zetten. Als je die dan wil weergeven moet je hem weer terugtoveren naar een afbeelding (je zult dan dus ook het afbeelding-type moeten opslaan).
Dat terugtoveren kan bijv. via 'imagejpeg' of 'imagepng'. Als eerste argument geef je wat er in de database stond en het resultaat is de afbeelding en dan komt je afbeelding tevoorschijn.

Maar nogmaals, probeer het echt anders te doen.. want je database gaat heel vol en langzaam worden + dat dit relatief veel rekenkracht kost
Hier is onlangs nog een discussie over geweest, php en image caching

plaatjes in een database is niet per definitie een slecht idee :)

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
Genosha schreef op woensdag 15 oktober 2008 @ 16:22:
Geeft de volgende foutmelding
code:
1
2
<img src="
Fatal error: Cannot use object of type stdClass as array in C:\xampp\htdocs\xampp\...\...\product_bewerken.php on line 36
Lijkt me vrij evident wat hier mis gaat: je probeert een object uit te lezen alsof het een array is.

Kijken we naar de plek van de foutmelding: "<?php echo $arr_foto['foto']; ?>" - je probeert hier $arr_foto te benaderen alsof het een array is terwijl volgens PHP het een stdClass (ergo, object) is. Hoe kan dit?

Mijn gok: je doet niet mysql_fetch_assoc maar mysql_fetch_object ergens - helaas laat je de essentiele code nou weer net niet zien ;)

Overigens ben ik het in zoverre niet met bovenstaande poster eens dat plaatjes in je DB bijna altijd een slecht plan zijn, performance wise en qua DB handelbaarheid, maar dat is hier nu net niet de discussie ;)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

Verwijderd

Wat ik altijd doe is de bestandsverwijzing in een database zetten, en het plaatje in een uploads mapje zetten. Dat is volgens mij ook beter voor de performance van je database en het uitlezen van de array is dan ook geen probleem. Mocht je het per se in een database willen hebben, moet je dacht ik de binary data in een blob veldje gooien en uitlezen in een php scriptje dat met GD een plaatje vouwt. Dat scriptje spreekje dan aan in je <img> tag.

Zoiets dus:

code:
1
<img src="bakjpg.php?ID=<?=$row['plaatjeID']?>" alt="<?=$row['plaatjeAlt']?>" />


Dat bak jpg script maakt de connectie, haalt de data eruit en maakt een jpg met GD.

Maar het is imho veel gemakkelijker om de bestanden gewoon als een bestand weg te schrijven in httpdocs/img/uploads oid en de bestandslocatie op te slaan in een varchar veldje.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Je hebt helemaal geen GD nodig, je spuugt gewoon die binaire data uit met de juiste header. Overigens moet je wel weten wat voor image t is, GIF, JPG, PNG of misschien BMP of noem maar op want die hebben andere headers :)

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Ik gebruik inderdaad mysql_fetch_object om het foto-veld uit mijn database te halen. $arr_ is gewoon de standaard die ik gebruik zodat ik niet 100 varianten heb die allemaal eigenlijk query results zijn, misschien verwarring hierdoor.

Waarom database? Omdat ik geen goed uploadscript kon vinden en de database mij een goed alternatief leek, vooral omdat de afbeeldingen niet zo heel erg groot in KB worden, worden dus geen foto's van 1MB. Ook moet het systeem noob-proof zijn, niet elke gebruiker gaat snappen dat hij/zij de afbeelding moet uploaden via de FTP en dan de locatie moet vermelden in dat veldje.

Het lijkt me natuurlijk mogelijk om een restrictie op alleen .JPG te maken zodat ik maar met één type header rekening moet houden.

Anyway... nog geen idee hoe ik het moet oplossen. Hoe lees je dat nu precies uit?

Acties:
  • 0 Henk 'm!

  • Kettrick
  • Registratie: Augustus 2000
  • Nu online

Kettrick

Rantmeister!

Genosha schreef op donderdag 16 oktober 2008 @ 10:02:
Waarom database? Omdat ik geen goed uploadscript kon vinden en de database mij een goed alternatief leek,
Ondanks mijn eerdere verhaal over plaatjes in databases is nou niet bepaald de juiste werkwijze ;).
vooral omdat de afbeeldingen niet zo heel erg groot in KB worden, worden dus geen foto's van 1MB.
Elke normale database heeft er geen problemen mee om een bestand van 1MB op te slaan, wat dat betreft maakt het opslaan op disk of in een db weinig uit.
Ook moet het systeem noob-proof zijn, niet elke gebruiker gaat snappen dat hij/zij de afbeelding moet uploaden via de FTP en dan de locatie moet vermelden in dat veldje.
Dat is ook niet nodig, je kan met php de file upload afhandelen en in een dir op de server neerzetten, of je het op filesystem of database niveau opslaat maakt voor de gebruiker niet uit. Googlen op php file upload moet je daar genoeg over kunnen vertellen :)
Het lijkt me natuurlijk mogelijk om een restrictie op alleen .JPG te maken zodat ik maar met één type header rekening moet houden.

Anyway... nog geen idee hoe ik het moet oplossen. Hoe lees je dat nu precies uit?
Kijk naar de eerder genoemde oplossingen, je kan niet simpelweg de image data ergens in je html neer zetten. Ik raad je overigens wel aan om je blob data buiten je normale data neer te zetten, dus niet een zootje binaire data tussen je prijzen en je producten. Ik gebruik zelf voor een project een koppeltabel tussen huizen en blobs, de blobdata wordt dus alleen opgehaald door getblob.php, verder nergens.

Kijk ook nog even naar http header / cache control, zorg er dan voor dat je niet de hele dag blobs loopt te maken maar dat deze door de client gecached worden.

Acties:
  • 0 Henk 'm!

  • Equator
  • Registratie: April 2001
  • Laatst online: 09-09 15:29

Equator

Crew Council

#whisky #barista

Genosha schreef op donderdag 16 oktober 2008 @ 10:02:
Waarom database? Omdat ik geen goed uploadscript kon vinden
Zo moeilijk is dat anders niet.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
if(!empty($_FILES['poelaatje']['name']))
{
    if (move_uploaded_file($_FILES['poelaatje']['tmp_name'], "/path/to/dir/" . $_FILES['poelaatje']['name'] ))
    {
        //upload sucessfull
    }
    else
    {
        //upload unsuccessfull
        echo "upload error";
        die();
    }
}

Voor error checking zien: http://www.php.net/features.file-upload

Acties:
  • 0 Henk 'm!

Verwijderd

Cartman! schreef op donderdag 16 oktober 2008 @ 09:46:
Je hebt helemaal geen GD nodig, je spuugt gewoon die binaire data uit met de juiste header. Overigens moet je wel weten wat voor image t is, GIF, JPG, PNG of misschien BMP of noem maar op want die hebben andere headers :)
|:( Klopt natuurlijk, dom.
Genosha schreef op donderdag 16 oktober 2008 @ 10:02:
Het lijkt me natuurlijk mogelijk om een restrictie op alleen .JPG te maken zodat ik maar met één type header rekening moet houden.
Dit is niet nodig. Gewoon kijken wat voor Content Type je plaatje is, vergelijken met de extentie en vervolgens de juiste header zetten.

Uitlezen van de database is geen probleem toch? RoeLz says it pretty much all. je moet de data niet direct in je <img> tag gooien, maar in een php script dat een plaatje maakt, en die aanroepen in je <img> tag. De data is namelijk (nog) geen plaatje, maar is binary data. Dat van die Cache control is een hele goeie tip, dat scheelt je weer een hoop performance.

Acties:
  • 0 Henk 'm!

  • Equator
  • Registratie: April 2001
  • Laatst online: 09-09 15:29

Equator

Crew Council

#whisky #barista

Verwijderd schreef op donderdag 16 oktober 2008 @ 10:35:
Uitlezen van de database is geen probleem toch? RoeLz says it pretty much all. je moet de data niet direct in je <img> tag gooien, maar in een php script dat een plaatje maakt, en die aanroepen in je <img> tag. De data is namelijk (nog) geen plaatje, maar is binary data. Dat van die Cache control is een hele goeie tip, dat scheelt je weer een hoop performance.
Op het feit na dat mysql_fetch_object() geen array returned, maar een mysql object.
Hij kan veel beter naar mysql_fetch_array / mysql_fetch_assoc kijken.

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Altijd geklooi met dat filepath, alles geprobeerd en helemaal niets.

Acties:
  • 0 Henk 'm!

  • Kettrick
  • Registratie: Augustus 2000
  • Nu online

Kettrick

Rantmeister!

Genosha schreef op donderdag 16 oktober 2008 @ 11:12:
[...]


Altijd geklooi met dat filepath, alles geprobeerd en helemaal niets.
Equator heeft al een hele opzet gegeven, wat gaat er precies mis ?
Let er wel op dat, afhankelijk van je hoster, je aan de slag moet met chmod e.d., maar in dat geval zou je iets als permission denied moeten krijgen.

error_reporting(E_ALL) is iig je vriend in dit soort situaties :)

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Ik draai momenteel locaal d.m.v. Xampp op een Windows systeem, geen CHMOD dus.

code:
1
2
3
4
Warning: move_uploaded_file(/htdocs/xampp/iwood/final/fotos/lowl.JPG) [function.move-uploaded-file]: failed to open stream: No such file or directory in C:\xampp\htdocs\xampp\iwood\final\admin\product_nieuw_opslaan.php on line 18

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move 'C:\xampp\tmp\php31C.tmp' to '/htdocs/xampp/iwood/final/fotos/lowl.JPG' in C:\xampp\htdocs\xampp\iwood\final\admin\product_nieuw_opslaan.php on line 18
upload errorArray ( [foto] => Array ( [name] => lowl.JPG [type] => image/pjpeg [tmp_name] => C:\xampp\tmp\php31C.tmp [error] => 0 [size] => 27192 ) )

Acties:
  • 0 Henk 'm!

  • Equator
  • Registratie: April 2001
  • Laatst online: 09-09 15:29

Equator

Crew Council

#whisky #barista

C:\xampp\tmp\php31C.tmp' to '/htdocs/xampp/iwood/final/fotos/lowl.JPG'
Ik heb nog nooit php op een windows systeem gehad, maar bovenstaande lijkt me vrij 'logisch' :?

2e hit @Google: http://php.meetup.com/93/messages/boards/thread/1950602
Dat gaat welliswaar over een persission probleem, maar je ziet wel de correcte syntax met pad namen op Windows

[ Voor 35% gewijzigd door Equator op 16-10-2008 11:28 ]


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 22:47
Genosha schreef op donderdag 16 oktober 2008 @ 10:02:
Ik gebruik inderdaad mysql_fetch_object om het foto-veld uit mijn database te halen. $arr_ is gewoon de standaard die ik gebruik zodat ik niet 100 varianten heb die allemaal eigenlijk query results zijn, misschien verwarring hierdoor.
[..]

Anyway... nog geen idee hoe ik het moet oplossen. Hoe lees je dat nu precies uit?
Ik gaf al aan wat er fout ging: je leest een object uit alsof het een array is, daarover geeft PHP een error. De PHP manual is dan vrij simpel te vinden: http://php.net/mysql_fetch_object

Op die pagina staat een uitstekend voorbeeld hoe je dan wel data uit zo'n object haalt. Alternatief is, zoals ik al zei, mysql_fetch_assoc te gebruiken in plaats van mysql_fetch_object.

//edit @ hierboven
Onder windows mag je met PHP zowel de dubbele forward-slash als backslash gebruiken. Ie, zowel /pad/naar/folder als \\pad\\naar\\folder zijn goed. Die temp name wordt door Apache gegenereerd en is (in theorie) ook gewoon goed. Relatieve paden mogen voor zover ik weet ook gewoon, dus de error is volgens mij helemaal niet zo evident.

Ik gok persoonlijk dat er een folder niet bestaat danwel het script in een subfolder aan het zoeken is ernaar, wat je uiteraard wel weer op kan lossen door daar een absoluut pad vanaf de root van te maken (eventueel met $_SERVER['script_name'] / $_SERVER['script_filename']). Zou echter niet moeten hoeven :)

//edit
Bedenk me net trouwens een minder voor de hand liggend probleem: je gebruikt Xampp. Dit is in mijn ervaring zo'n brak pakket dat random dingen die op een normale apache + mysql + php install perfect werken daar ineens stuk gaan. Dingen als driedubbele configfiles die op volslagen debiele locaties worden opgeslagen, vage security-defaults, etc. Als je dan toch een all-in-one pakket wilt hebben ben je beter af met AppServ, levert bij mij veel minder vaak dit soort problemen op.

[ Voor 45% gewijzigd door FragFrog op 16-10-2008 11:42 ]

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

Verwijderd

Equator schreef op donderdag 16 oktober 2008 @ 10:39:
[...]

Op het feit na dat mysql_fetch_object() geen array returned, maar een mysql object.
Hij kan veel beter naar mysql_fetch_array / mysql_fetch_assoc kijken.
Klopt maar

PHP:
1
echo $row->fotodata;


Kan toch ook gewoon neem ik aan?

En die foutmelding lijkt me nogal self explainatory, een bestand naar een windows machine wegschrijven met een linux bestandslocatie gaat niet werken :O

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik kan melden dat fileuploads op xampp geen probleem hoeft te zijn, hier werkt het namelijk uitstekend. Als je je paden maar goed weet in te stellen :)

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Ik heb het script nu draaien op een Linux webhost waar doormiddel van een andere pagina al een upload script gebruikt wordt, het zal dus moeten werken, maar helaas. Een foutmelding

Warning: move_uploaded_file(/public_html/iwood/fotos/rick_astley-gal-goodweek.jpg) [function.move-uploaded-file]: failed to open stream: No such file or directory in /home/(site)/domains/(site).com/public_html/iwood/admin/product_nieuw_opslaan.php on line 18

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/phpS0YGSr' to '/public_html/iwood/fotos/rick_astley-gal-goodweek.jpg' in /home/(site)/domains/(site).com/public_html/iwood/admin/product_nieuw_opslaan.php on line 18
upload errorArray ( [foto] => Array ( [name] => rick_astley-gal-goodweek.jpg [type] => image/pjpeg [tmp_name] => /tmp/phpS0YGSr [error] => 0 [size] => 32083 ) )

De CHMOD op de map foto's is 777

De map locatie is /public_html/iwood/fotos/ zoals mijn FTP client ook aangeeft. Heb geen idee wat er mis gaat.

Acties:
  • 0 Henk 'm!

Verwijderd

post heel je serveruploadcode eens. Want zo tasten we in het duister

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Heb het scriptje wat Equator hier poste gebruikt maar is als volgt;

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
42
43
44
45
46
47
48
<?php 
// header("Location: admin.php?pagina=producten&id=product_overzicht"); 

include 'config.php'; 

$naamprod= $_POST['naamprod'];
$omschrijving= $_POST['omschrijving'];
//$foto = base64_encode(file_get_contents($_FILES['foto']['tmp_name']));
$foto= $_POST['foto'];
$video = $_POST['video'];
$datum_ingang = $_POST['datum_ingang'];
$datum_stop = $_POST['datum_stop'];
$kliks = $_POST['kliks'];

 
if(!empty($_FILES['foto']['name'])) 
{ 
    if (move_uploaded_file($_FILES['foto']['tmp_name'], "/public_html/iwood/fotos/" . $_FILES['foto']['name'] )) 
    { 
        //upload sucessfull 
    } 
    else 
    { 
        //upload unsuccessfull 
        echo "upload error"; 
        print_r($_FILES);
        
        print
        
        die(); 
    } 
} 


$opslaan = "INSERT INTO iwood_producten (naamprod, omschrijving, foto, video, datum_ingang, datum_stop, kliks) 
            VALUES ('".$naamprod."',
                    '".$omschrijving."',
                    '".$foto."',
                    '".$video."',
                    '".$datum_ingang."',
                    '".$datum_stop."',
                    '".$kliks."')";

if (!($temp = mysql_query($opslaan))) 

showerror(); 

?> 

Acties:
  • 0 Henk 'm!

  • Kettrick
  • Registratie: Augustus 2000
  • Nu online

Kettrick

Rantmeister!

Verander de 2e param op regel 18 eens in :

code:
1
$_SERVER['DOCUMENT_ROOT']."/iwood/fotos/" . $_FILES['foto']['name'] ))


Je probeert de fofo's op de verkeerde plaats op te slaan.

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
WOW! Hij upload!
Maar nu ik geen locatie van mijn afbeelding in mijn database staan, kan ik dit combineren of uitroepen uit het script?

Acties:
  • 0 Henk 'm!

Verwijderd

Genosha schreef op vrijdag 17 oktober 2008 @ 14:42:
WOW! Hij upload!
Maar nu ik geen locatie van mijn afbeelding in mijn database staan, kan ik dit combineren of uitroepen uit het script?
ofwel sla je dat mee op, ofwel stopt je dat in een config-file, ofwel stop je dat in een configtabel, ofwel verzin je nog iets anders. De keuze is aan jou.

[ Voor 4% gewijzigd door Verwijderd op 17-10-2008 14:45 ]


Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
Verwijderd schreef op vrijdag 17 oktober 2008 @ 14:45:
[...]

ofwel sla je dat mee op, ofwel stopt je dat in een config-file, ofwel stop je dat in een configtabel, ofwel verzin je nog iets anders. De keuze is aan jou.
Als ik niet weet hoe zal ik het niet vragen natuurlijk...

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Je weet toch de locatie waar die image wordt opgeslagen? Die kun je opslaan als varchar in je tabel...

Acties:
  • 0 Henk 'm!

  • Genosha
  • Registratie: November 2007
  • Laatst online: 14-02 21:22
'".$_SERVER['DOCUMENT_ROOT']$_FILES['name']."',

Dit werkt natuurlijk niet om de locatie en bestandnaam op te halen en wegteschrijven naar me VARCHAR(255) veldje.

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Een beetje zelf nadenken mag best hoor... verzin gewoon dat je het deel moet opslaan in je database zoals je t vanaf web moet benaderen bijv.

Acties:
  • 0 Henk 'm!

  • Bolukan
  • Registratie: Oktober 2002
  • Laatst online: 23-08 23:43
Waarom zou je $_SERVER['DOCUMENT_ROOT'] opslaan ??
Pagina: 1