mysqli - bild auslesen funktioniert nicht

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • mysqli - bild auslesen funktioniert nicht

    Hallo zusammen,

    ich habe jetzt (Gefühl) stundenlang (und in wirklichkeit ca. 2 Stunden) in Google gesucht, wie man ein Bild aus MySQL auslesen kann. Gut, cih hab hunderte gerbnisse gefunden, die angeblich alle funktionieren - mit MySQL.
    Ich allerdings benutzte MySQLi und habe deshalb die Scripte so umgebaut, dass sie zu MySQLi passen.

    Quellcode

    1. //Also aus:
    2. $abfrage = "SELECT[...]";
    3. $ergebnis = mysql_query($abfrage);
    4. $row = mysql_fetch_object($ergebnis);
    5. // wurde:
    6. $abfrage = "SELECT[...]";
    7. $ergebnis = $mysqli->query($sql);
    8. $result = $ergebnis->fetch_object();


    Ich dachte bisher, dass das so funktioniert, bei text-, Datems- und anderen ausgaben tut es das auch, aber nicht bei Bilder.
    Weiß jemand, woran das liegt?

    LG

    Fipsi

    P.S.:

    Fals jemand das Script sehen will:

    Quellcode

    1. $type = $_GET['type'];
    2. $id = $_GET['id'];
    3. if ($type == "user")
    4. {
    5. $sql = "SELECT profilpic, profilpic_type FROM user WHERE id = '$id'";
    6. $result = $mysqli->query($sql);
    7. $result= $result->fetch_object();
    8. header( "Content-type: ".$result->profilpic_type);
    9. echo $result->profilpic;
    10. echo $mysqli->error;
    Alles anzeigen

    (Und als Fehlermeldung kommt immer nur: Trying to get property of non-object in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 18/20)
  • Versteh ich Dich richtig, Du hast eine MySQL Datenbank, in der Du Bilder als BLOB (Binary Large Object) speicherst?
    Das Tablefeld würde dann so oder ähnlich aussehen:

    Quellcode

    1. "fieldname" blob not null


    Du solltest außerdem in einem Feld die Dateierweiterung speichern (jpg, png, oder ähnliches)


    Dein PHP-Insert sollte dann so oder ähnlich aussehen

    Quellcode

    1. $handle = fopen("testpic.jpg", "rb");
    2. $img = fread($handle, filesize('testpic.jpg'));
    3. fclose($handle);
    4. $img = base64_encode($img);
    5. $sql = "insert into pictures values(null,'$img','jpg','female')";


    Und so liest Du das Bild wieder mit PHP aus und stellst es da:

    Quellcode

    1. // Datenbankverbindung
    2. $sql = "select pic, ext from pictures where id='1'";
    3. $result = mysql_query($sql) or die();
    4. while($row = mysql_fetch_array($result,MYSQL_ASSOC)){
    5. $db_img = $row['pic'];
    6. $type = $row['ext'];
    7. }
    8. $db_img = base64_decode($db_img);
    9. $db_img = imagecreatefromstring($db_img);
    10. if ($db_img !== false) {
    11. switch ($type) {
    12. case "jpg":
    13. header("Content-Type: image/jpeg");
    14. imagejpeg($db_img);
    15. break;
    16. case "gif":
    17. header("Content-Type: image/gif");
    18. imagegif($db_img);
    19. break;
    20. case "png":
    21. header("Content-Type: image/png");
    22. imagepng($db_img);
    23. break;
    24. }
    25. }
    26. imagedestroy($db_img);
    Alles anzeigen


    Und nun kannst Du das Bild unter Referenz der PHP-Datei in der der select pic gemacht wird verlinkt

    Quellcode

    1. <img src="selectImage.php"/>


    Da ich gerade keinen MySQL zum Testen parat habe, habe ich den Code und das Vorgehen von dieser Seite:
    mrarrowhead.com

    // Edit
    Hier noch ein feiner Beitrag von Oracle über das "Storing and retrieving blobs ":
    blogs.oracle.com


    Ich hoffe ich konnt Dir etwas weiter helfen.

    Viele Grüße
    Heppner
  • Naja das hat ja nichts mit mysli zu tun. Die Datenbankverbindung und das Auslesen des Resultsets machst Du dann halt nach MySQLi Standard, aber der Select und Insert bleibt ja davon unberührt ;) Wie Du den Insert und den Select abfeuerst bleibt Dir überlassen. Das darstellen des Bildes kannst Du sowohl mit mysql als auch mit der Erwieterung mysqli.

    Hier noch die Gegenüberstellung der beiden.
    Der alte MySQL

    Quellcode

    1. // Links der MySQL Befehl, rechts das MySQLi Gegenstueck. Der Pfeil bedeutet "wird zu"
    2. mysql_connect() -> mysqli_connect()
    3. mysql_query() -> mysqli_query()
    4. mysql_fetch_array() -> mysqli_fetch_array()
    5. // und so weiter


    Die erweiterung MySQLi

    Quellcode

    1. // Angenommen unser Objekt traegt den Name $objekt dann sehen die Methoden wie folgt aus
    2. mysqli_query() -> $objekt->query()
    3. mysqli_fetch_array() -> $objekt->fetch_array()
    4. // und so weiter
  • Ne, MySQLi beschreibt nicht die Art wie das Bild "rauskommt" sondern wie Du den Select, Insert, o.Ä. an das Datenbanksystem gibst und mit der Rückgabe der Datenbank (Result) umgehst. Die Statements (Select, Insert, u.Ä.) werden von der SQL-Datenbank interpretiert. Da hat Dein PHP Scriptp nichts mit zu tun ;)
    Versuch einfach mal, Deine bereits geschriebenen Zeilen mit meinen zu verbinden. Vor allem überprüfe ob der Feldtyp Deiner Datenbank BLOB entspricht und versuch auch mal per Hand die MySQL Statements durchzuführen. Ich kann Dir als MySQL-Client HeidiSQL empfehlen.
    Sollte alles nicht klappen, schreib hier einfach wieder ins Forum mit Angabe Deines Quelltextes. Ich helf Dir dann gern weiter ;)
  • hm... ich steh grad im Bahnhof...

    also cih hab deinen Code genommen und meinem MySQLi angepasst, dass er so ausschaut:

    Quellcode

    1. $sql = "SELECT profilpic, profilpic_type FROM user WHERE id = '$id'";
    2. $result = $mysqli->query($sql);
    3. while($row = $result->fetch_array(MYSQL_ASSOC))
    4. {
    5. $db_img = $row->profilpic;
    6. $type = $row->profilpic_type;
    7. }
    8. $db_img = base64_decode($db_img);
    9. $db_img = imagecreatefromstring($db_img);
    10. if ($db_img != false)
    11. {
    12. switch ($type)
    13. {
    14. case "jpg":
    15. header("Content-Type: image/jpeg");
    16. imagejpeg($db_img);
    17. break;
    18. case "gif":
    19. header("Content-Type: image/gif");
    20. imagegif($db_img);
    21. break;
    22. case "png":
    23. header("Content-Type: image/png");
    24. imagepng($db_img);
    25. break;
    26. }
    27. }
    28. imagedestroy($db_img);
    Alles anzeigen


    also Fehlermeldung kommt folgendes:

    Notice: Undefined variable: db_img in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 9

    Warning: imagecreatefromstring() [function.imagecreatefromstring]: Empty string or invalid image in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 11

    Warning: imagedestroy() expects parameter 1 to be resource, boolean given in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 30
  • das ist ja nur ein teil der datei, ein aufruf-link der datei schaut so aus: bild.php?type=user&id=$id.
    Dafür steht das type, weil ich über diese Datei beizeiten auch andere Bilder abrufen will, damit der weiß, dass Profilbilder gemeint sind.
    Und das id steht hierbei für die id des Users.

    Und mit JavaScript kenn ich mcih noch nicht wirklich allzu aus, ich arbeite aber auch daran, das zu ändern.

    Wenn ich $mysqli->error; setzt kommt keine dazu entsprechende antwort.
    und bei var_dump($sql); steht genau das, was in der $sql drin steht (was anderes würde mich wundern)
  • Ja und poste doch mal was in der $sql drinnen steht? Die $id muss ja ersetzt werden. Wenn Du Sie aus dem GET holst musst Du sie über den Befehl $_GET['id'] holen. Aber ich empfehle Dir ausdrücklich keinen GET oder POST direkt mit einem Datenbankzugriff zu kopeln. SQL Injection ist dabei das Zauberwort. Außerdem müsste Dein Link zum Beispiel so aussehen: bild.php?type=png&id=1
    Aber wieso rufst Du überhaupt die Grafik über einen Link auf?
    <img src="selectImage.php"/> - So sollte das aussehen...
  • var_dump($sql); gibt aus:

    string(57) "SELECT profilpic, profilpic_type FROM user WHERE id = '1'"

    ok Leute, ich seh gerade erst, ihr dürft mich schlagen, da ich im link andauert die falsche id angegeben habe ( den id steht auf 2).

    jetzt steht allerdings da:
    Notice: Trying to get property of non-object in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 20
    Notice: Trying to get property of non-object in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 21

    wie schon vermutet.

    Und wenn ich diese Datei dann hochlade, werde ich das Verzeichnis sowieso sperren (per htaccs-Datei (oder wir auch nochmal das genau heißt^^)), damit kein Zugriff möglich ist. Außerdem hat die Datei am Anfang noch einen Teil, welcher das Script beendet, sofern keine bestimmten Daten übertragen wurden (was genau poste ich jetzt aus Sicherheitsgründen nicht).

    Nein, das type ist mit absicht auf User gesetzt, damit der weiß, dass ein Profilbild eines Users gewünscht ist, da ich auch noch andere Bilder-datenbanken einbauen werde, damit er immer was, aus welcher er es ziehen muss.

    Und wie soll ich die Datei sonst abrufen, wenn nicht über einen Link? mit nur <img src="bild.php" /> weiß er ja nicht, welches.
  • Moment, wie Du willst den Ordner sperren, in der die Datei liegt? Dir ist aber schon bewusst, dass Du versuchst diese Datei in einer Datenbank zu speichern? Dies ist zwar möglich, ist aber unüblich und hat gewisse Nachteile. Ich hätte Dir von Anfang an empfohlen die Datein in einem Verzeichnis auf Deinem Server zu speichern. Dann musst Du in der Datenbank nur den Pfad zu der jeweiligen Datei speichern und mit PHP kannst Du wunderbar Bilder hochladen und auf dem Server ablegen... Ich würde dann Dein Vorgehen mit dem Speichern der Datei in der Datenbank noch einmal gründlich überdenken.
  • wenn ich den Teil jetzt zu

    Quellcode

    1. while($row = $result->fetch_object())
    2. {
    3. $db_img = $row->profilpic;
    4. $type = $row->profilpic_type;
    5. }


    mach (wenn ich "MYSQL_ASSOC" drin lass quetiert er mir das mit einem Fatal), dann kommt immernoch folgendes:

    Warning: imagecreatefromstring() [function.imagecreatefromstring]: Empty string or invalid image in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 26

    Warning: imagedestroy() expects parameter 1 to be resource, boolean given in F:\Webserver\xampp\htdocs\data\templates\function\bild.php on line 45

    Edit für Heppner:

    Ich habe diese bedenken schon 100x gelesen, und schon einige male wirklich lange überdacht, aber ich glaube es ist besser, wnen cih sie in einer Datenbank speichere, da
    1) sie leichter zu verwalten sind
    2) sie besser für unbefugten blicken geschützt sind
    3) ich programmieren kann, wer sie sehen darf und wer nicht
    4) ich dann nicht so viele Dateien im Verzeichnis habe, was es ja "sperig" macht
  • Ok, gut

    Nein, ist es nicht, weshalb ich es gerade Entfernt habe.
    Jetzt wird der bei Firefox für Bilder übliche graue Hintergrun angezeigt, nach den anpassungen, allerdings ohne das Bild.
    Habe eben die Datenbank nochmal gecheckt, Bild ist drin, und type auch, somit stehen gerade Fragezeichen in meinem Kopf.
  • Hast Du das Bild auch so oder ähnlich in die Datenbank gefügt?

    Quellcode

    1. $handle = fopen("testpic.jpg", "rb");
    2. $img = fread($handle, filesize('testpic.jpg'));
    3. fclose($handle);
    4. $img = base64_encode($img);
    5. $sql = "insert into pictures values(null,'$img','jpg','female')";


    Wichtig ist hierbei auch wieder die base64 Encodierung!