Bild aus Datenbank ausgeben
Kai
- php
Hallöchen,
habe in meiner Datenbank Bilder hinterlegt. Die möchte ich nun in eine Website einbinden und ausgeben lassen. Mit dem Speichern in der Datebank hat geklappt, aber das ausgeben funktioniert nicht. Ich bekomme nur:
Object id #1, wenn ich einfach echo $bild mache.
Füge ich der Datei Content-Type: image/jpeg hinzu, dann bekomm ich die Ausgabe des Pfads der Datei (also der PHP-Datei).
Was mache ich falsche?
Grüße
Kai
Hello,
Was mache ich falsche?
erstaunlich, was manche Leute glauben, wie gut unsere Glaskugeln leisten können. Die Informationen deinerseits sind doch ein Wenig spärlich. Vielleicht hilft dir dieser Artikel weiter...
MfG
Rouven
echo $begrüßung;
Vielleicht hilft dir dieser Artikel weiter...
Man sollte aber mindestens hinzufügen, dass das dort zu sehende addslashes() zugunsten eines mysql_real_escape_string() ausgetauscht werden sollte. Außerdem empfiehlt es sich dies auf alle per SQL zu übergebenden Daten anzuwenden, nicht nur auf die Datei-Daten. (Möglicherweise müssen vorher noch Magic Quotes entsorgt werden.)
$inhalt = fread(fopen(...)) ist auch nicht grade die feine englische Art, werden dabei doch möglicherweise auftretende Fehler völlig ignoriert. Außerdem gibt es heutzutage file_get_contents().
echo "$verabschiedung $name";
Sorry, Informationen sind wohl wirklich etwas dürftig.
Also ich habe mich in der Tag an oben genannten Link gehalten und bin danach vorgegangen. Ich greife aber auf eine Oracle XE Datenbank zu, nicht auf eine MySQL-Datenbank. Wie geschrieben, klappt das Speichern auch. Also 100%ig kann ich es nicht sagen, da ich die Ausgabe ja nicht hinbekomme, aber es werden Binärdaten in der DB abgelegt.
<?php
require("./login.php");
if ($con = oci_connect($user, $password, $database)){
$sql = "begin p_abfrage.bild_bild(:bild_id, :bild);end;";
$curs = oci_new_cursor($con);
$result = oci_parse($con, $sql);
$ID = 1;
oci_bind_by_name ($result, "bild_id", $ID);
oci_bind_by_name($result, "bild", $curs, -1, OCI_B_CURSOR);
oci_execute($result);
oci_execute($curs);
$bild = oci_fetch_row($curs);
$err=OCIError($result);
if($err==TRUE){ echo " <font size=2>Oracle-Fehler: $err[message]</font><br> ";}
echo $bild[3]; // da ist das bild abgelegt
}else{
echo ' Verbindung fehlgeschlagen!';
}
;
?>
Habe die ID im Skript angegeben um sicherzugehen das was drin steht, hat aber mit Übergabe auch funktioniert (nur das Bild gibt er genausowenig aus). Wenn ich nun "Header( "Content-type: image/jpeg"); " hinzufüge, dann bekomme ich beim Aufruf der Datei den Pfad der Datei. Lasse ich es weg, wird "Object id #1" ausgegeben.
Grüße Kai!
Hello,
<?php
require("./login.php");
if ($con = oci_connect($user, $password, $database)){
$sql = "begin p_abfrage.bild_bild(:bild_id, :bild);end;";
$curs = oci_new_cursor($con);
$result = oci_parse($con, $sql);
$ID = 1;
oci_bind_by_name ($result, "bild_id", $ID);
oci_bind_by_name($result, "bild", $curs, -1, OCI_B_CURSOR);
oci_execute($result);
oci_execute($curs);$bild = oci_fetch_row($curs);
$err=OCIError($result);
if($err==TRUE){ echo " <font size=2>Oracle-Fehler: $err[message]</font><br> ";}
Sag dem Browser vorher, dass ein Bild kommt:, also z.B. ein JPG
header('Content-type: image/jpeg');
echo $bild[3]; // da ist das bild abgelegt
}else{
echo ' Verbindung fehlgeschlagen!';
};
?>
Harzliche Grüße vom Berg
http://www.annerschbarrich.de
Tom

hi,
$ID = 1;
oci_bind_by_name ($result, "bild_id", $ID);woher komt $ID ?
Aus der Zeile darüber - wie er zuvor auch schon beschrieb.
gruß,
wahsaga
Hello,
woher komt $ID ?
Aus der Zeile darüber - wie er zuvor auch schon beschrieb.
Ach. Manchmal nützt es tatsächlich, genauer zu lesen ;-)
Hab keine Übung mehr mit dem Forum. Sollte ich mal auffrischen.
Harzliche Grüße vom Berg
http://www.annerschbarrich.de
Tom

hi Tom,
War lang schon nicht hier ...
Stimmt auffallend - wo hast du dich rumgetrieben? :-)
gruß,
wahsaga
Hallo,
danke für die Hilfe. Nur leider funktioniert es noch immer nicht. Habe das Content-Type... hinzugefügt und unten drunter auch den else-zweig entfernt und vor das Content-Type gesetzt. Aber die Ausgabe ist "http://localhost/bild.php". Bild ist ein jpg als CLOB in der DB abgelegt. Sonst noch eine Idee woran es liegen könnte?
Grüße Kai!
Hello,
danke für die Hilfe. Nur leider funktioniert es noch immer nicht. Habe das Content-Type... hinzugefügt und unten drunter auch den else-zweig entfernt und vor das Content-Type gesetzt. Aber die Ausgabe ist "http://localhost/bild.php". Bild ist ein jpg als CLOB in der DB abgelegt. Sonst noch eine Idee woran es liegen könnte?
Der Else-Zweig ist hier immer witzlos, egal ob über dem Content-Type oder drunter.
Sinnvoll wäre er nur, wenn Du den Accept-Header des Browsers vorher abfragen würdest. Wenn Text erwartet wird, muss man auch Text ausgeben und wenn Bilddaten erwartet werden, dann muss mam eben Bilddaten ausgeben. Nur wenn man die Ressource direkt anspricht, könnte es der Browser verkraften...
Zu Deiner Frage, woran es liegt:
Was hast Du denn bisher alles untersucht?
Unterschiedliche Requests aufgebaut?
Wie rufst Du as Script denn auf?
An welchen Stellen hast Du bisher schon Testausgaben eingebeut, und welche?
Testausgaben haben natürlich auch zur Voraussetzung, dass die Antwort verarbeitet (angezeigt) werden kann.
Harzliche Grüße vom Berg
http://www.annerschbarrich.de
Tom

Also ich habe mal versucht andere Spalten des Datensatzes auszugeben. Ohne Angabe des Content-Types funktioniert das, mit Angabe des Content-Types (Ausgabe vor Content-Type) funktioniert es nicht.
Also wenn ich das Skript, so wie es ist, direkt aufrufe, kommt die Ausgabe "http://localhost/bild.php".
Wenn ich die ID übergebe und das Skript mit "http://localhost/bild.php?id=1" aufrufe, kommt auch diese Ausgabe.
Rufe ich die Datei aus einer anderen Datei mit <img src="bild.php"> bzw. <img src="bild.php?id=1"> auf, kommt ein broken link. Also Bild kann nicht angezeigt werden.
Grüße Kai!
Hello,
Also wenn ich das Skript, so wie es ist, direkt aufrufe, kommt die Ausgabe "http://localhost/bild.php".
Wenn ich die ID übergebe und das Skript mit "http://localhost/bild.php?id=1" aufrufe, kommt auch diese Ausgabe.
Rufe ich die Datei aus einer anderen Datei mit <img src="bild.php"> bzw. <img src="bild.php?id=1"> auf, kommt ein broken link. Also Bild kann nicht angezeigt werden.
Das ist die Folge Deiner ersten Aussage.
Ich befürchte, dass der (Denk-)Fehler in den Qracle-Abfragen liegt. Da kann ich Dir aber nicht weiterhelfen, da ich Oracle nicht kenne.
Aber Du könntest ja Dein Script mal pingelig genau erklären. Welches Statement bewirkt was bzw. soll was bewirken?
Hast Du beim Index [3] auch daran gedacht, dass oci_fetch_row mit [0] anfängt zu zählen? Also steht unter Index [3] die vierte Ergebnisspalte.
Harzliche Grüße vom Berg
http://www.annerschbarrich.de
Tom

<?php
require("./config.php"); // hier stehen einfach die Verbindungsdaten zur Datenbank drin
$con = oci_connect($user, $password, $database); // Verbindung zur DB wird hergestellt
$sql = "begin p_abfrage.bild_bild(:bild_id, :bild);end;"; // In diesem Package wird eine Abfrage gestartet, die einen kompletten Datensatz (in Form eines Cursors) zurückgibt
$curs = oci_new_cursor($con); // Cursor wird angemeldet
$result = oci_parse($con, $sql); // Verbindung und Abfrage werden verknüpft und analysiert
$ID = 1; // Wert für ID wird zugewiesen um einen bestimmten Datensatz zu bekommen
oci_bind_by_name ($result, "bild_id", $ID); // Variable ID wird angemeldet
oci_bind_by_name($result, "bild", $curs, -1, OCI_B_CURSOR);
// Cursor wird angemeldet
oci_execute($result); // Abfrage wird executet
oci_execute($curs); // Cursor wird executet
$bild = oci_fetch_row($curs); // 1. Reihe des Cursors, also ein Datensatz wird der Variablen zugewiesen
Header( "Content-type: Image/jpeg");
echo $bild[3];
;
?>
------------------------------------
Das war der kommentierte Quelltext. Die Datenbank-Abfrage scheint zu passen. Ja, das Bild ist in der 4. Spalte, also $bild[3]. Alle Werte werden richtig aus der Datenbank gezogen und auch alles richtig ausgegeben, außer halt das Bild. Von daher sehe ich den Fehler weniger in der DB-Abfrage.
Mensch, irgendwie muss das doch klappen.... :\
Hallo,
Das war der kommentierte Quelltext. Die Datenbank-Abfrage scheint zu passen. Ja, das Bild ist in der 4. Spalte, also $bild[3]. Alle Werte werden richtig aus der Datenbank gezogen und auch alles richtig ausgegeben, außer halt das Bild. Von daher sehe ich den Fehler weniger in der DB-Abfrage.
Der Fehler liegt in der Art, wie Du das LOB aus der Datenbank holen willst. Oracle behandelt LOBs anders als alle anderen Felder. Ferner: Warum verwendest Du überhaupt einen Cursor, obwohl der hier überhaupt nicht notwendig ist?
Lies Dir mal folgenden Artikel im Oracle Technet durch: http://www.oracle.com/technology/pub/articles/oracle_php_cookbook/fuecks_lobs.html Dort wird erklärt, wie man LOBs in Oracle und PHP richtig einsetzt.
Viele Grüße,
Christian
Hallo,
super! Ist schon mal ein konkreter Hinweis. Hab mich mal versucht, aber funzt leider nicht. Hier mein Code:
<?php
if ($submit){
// hier stünden jetzt meine Verbindungsdaten
$conn = oci_connect($user, $password, $database);
$sql = "INSERT INTO
bild
(
bildid,
logo
)
VALUES
(
sequence_pk_bild.nextval,
--Initialize as an empty CLOB
EMPTY_BLOB()
)
RETURNING
--Return the LOB locator
logo INTO :logo_loc";
$stmt = oci_parse($conn, $sql);
// Creates an "empty" OCI-Lob object to bind to the locator
$myLOB = oci_new_descriptor($conn, OCI_D_LOB);
// Bind the returned Oracle LOB locator to the PHP LOB object
oci_bind_by_name($stmt, ":logo_loc", $myLOB, -1, OCI_B_BLOB);
// Execute the statement using , OCI_DEFAULT - as a transaction
oci_execute($stmt, OCI_DEFAULT)
or die ("Unable to execute query\n");
$BILD = $_POST['form_data'];
// Now save a value to the LOB
if ( !$myLOB->save('INSERT: '.$BILD) ) {
// On error, rollback the transaction
oci_rollback($conn);
} else {
// On success, commit the transaction
oci_commit($conn);
}
// Free resources
oci_free_statement($stmt);
$myLOB->free();}
echo '
<html><head></head><body>
<form method="post" action="lob.php" enctype="multipart/form-data">
<input type="file" name="form_data" size="40">
<p><input type="submit" name="submit" value="submit">
</form><br></body></html>';
// disconnect from DB etc.
?>
----------------------
Das Statement kann nicht ausgeführt werden: "Unable to execute query"
Idee woran es liegen könnte? Mit dem Wert der Variablen im Lob speichern müsste doch passen, oder?
Hello,
Object id #1, wenn ich einfach echo $bild mache.
Das Bild wird vom Browser über einen eigenen Subrequest angefordert:
<img scr="http://example.com/bilder/bild2003.jpg" alt="Bild von xy">
Wie Du nun dafür sorgst, dass dieser Request vom PHP-Parser bearbeitet wird, ist die erste Aufgabenstellung. Man könnte das mittels htaccess (bei Apache) festlegen, oder man benutzt gleich die Rewirte-Engine des Webserver.
siehe http://httpd.apache.org/docs/2.0/mod/mod_mime.html#addhandler
Für das Verzeichnis ~/bilder/ müsstest Du also z.B. festlegen:
AddHandler get-bild.php .jpg .gif .png
und ein Script get-bild.php bereitstellen, dass die Anfrage abarbeitet.
Das Scripüt besorgt sich als erstes den Aufrufparamter (den letzten Teil des Ressource-Name) und entscheidet dann, welches Bild geholt werden soll.
Es kann dann auch feststellen, ob der User dieses Bild überhaupt erhalten darf, oder ob ein Ersatzbild geliefert werden muss.
Schließlich beschafft es das Bild aus der Datei oder Datenbank und liefert es mit dem vorangestellten passenden Header aus.
Da der Browser ein Bild erwartet, kann auch nur ein Bildtyp geliefert werden. Alles andere wäre unsinnig.
Harzliche Grüße vom Berg
http://www.annerschbarrich.de
Tom

Hallöchen,
Hi
Object id #1, wenn ich einfach echo $bild mache.
Ich denke hier liegt der Hund begraben, echo gibt nur strings aus (jedenfalls sagt das php.net) und $bild[3] sind Bild-Daten wenn ich das richtig verstanden habe, also kein String. Wenn $bild[3] eine "resurce" ist und ein Bild, dann musst du es mit
imagepng($bild[3]);
imagejpeg($bild[3]);
oder mit
imagegif($bild[3]);
ausgeben (je nachdem was der Server kann und welcher Art die Bilder sind).
Ich denke dann sollte es gehen.
Andererseits tendiere ich dazu Bilder nicht direkt in eine Datenbank zu speichern sondern in ein Unterverzeichnis und in die Datenbank dann nur den Verweis (den Dateinamen) darauf. Aber das soll deine Sorge bleiben.
Wichtig ist eben... mit "echo" kann das eigentlich nicht funktionieren.
Nachtrag: Sollte das nicht klappen kannst du ja die Art der ausgelesenen Daten nochmal via var_dump überprüfen, da sollte dann stehen, ob die Daten als Bild geeignet sind.
echo $begrüßung;
Object id #1, wenn ich einfach echo $bild mache.
Ich denke hier liegt der Hund begraben, echo gibt nur strings aus (jedenfalls sagt das php.net) und $bild[3] sind Bild-Daten wenn ich das richtig verstanden habe, also kein String.
Das kann man so pauschal nicht sagen. Wenn die Bilddaten aus einer MySQL-Datenbank kämen, wären sie von Typ string. Objekte allerdings kann man aber ohne Magie nicht wie ein String ausgeben.
Wenn $bild[3] eine "resurce" ist und ein Bild,
Dieser Typ kommt als Ergebnis eines Fetch-Vorgangs nicht vor. Im Allgemeinen sind es Strings. Oracle gibt auch im speziellen Fällen Objekte zurück.
dann musst du es mit
imagepng($bild[3]);
Dazu müsste der Fetch-Vorgang eine Bildressource angelegt haben und wäre auch noch auf das Vorhandensein der Image Functions angewiesen. Das ist aber nicht der Fall.
Wichtig ist eben... mit "echo" kann das eigentlich nicht funktionieren.
Oh doch, das geht sogar problemlos für beispielsweise Daten aus BLOB-Feldern von MySQL. Und wenn man die Daten aus einem Oracle-LOB-Objekt befreit hat, liegen sie ebenfalls in einem echo-fähigen String vor.
echo "$verabschiedung $name";
echo $begrüßung;
(...)
echo "$verabschiedung $name";
Danke für die Belehrung, wieder 'was gelernt. :-)