Es klingt nach einem gängigen Problem: ein hochgeladenes Bild soll in der Datenbank abgespeichert werden. Geht man weiterhin davon aus, dass man den Datenbank-Zugriff per PDO abhandelt, dann sollte doch eigentlich alles ein Selbstläufer sein, oder?
Eine (aber mit Sicherheit nicht die einzige) naheliegende Möglichkeit wäre, die Binärdaten des Bildes als String an die Datenbank zu übergeben und von einer Gespeicherten Prozedur zu varbinary casten zu lassen. Der Weg dahin ist allerdings … sagen wir steinig.
Denn einen Binärstring direkt als \PDO::PARAM_STR
zu übergeben, sorgt dafür, dass vom Wert auf der DB-Seite nur noch Salat ankommt.
Als erstes muss man aus dem Binärstring dessen Hex-Wert ermitteln und dann dessen String-Repräsentation (also das übliche 0xFF00…
) per \PDO::PARAM_STR
an die DB übergeben.
1 2 3 4 5 |
// $sBin enthält den Binärstring eines Bildes /** @var array Array mit dem HexWERT */ $aHex = unpack('H*hex', $sBin); /** @var string HexSTRING */ $sHex = '0x' . $aHex['hex']; |
Die Variable $sHex kann man jetzt wie gewohnt in die DB schreiben.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/** @var \PDO */ $db = new \PDO($connectionstring, $user, $password); /** @var \PDOStatement */ $handle = $db->prepare( 'exec [PROZEDURNAME] @bild=:bild' ); $handle->bindParam(':bild', $sHex, \PDO::PARAM_STR); $handle->setFetchMode(\PDO::FETCH_ASSOC); $handle->execute(); |
Auf dem MS-SQL-Server steuert man dann eine Gespeicherte Prozedur an, die den Bild-Parameter als varchar(max)
erwartet und der dann zu varbinary(max)
konvertiert wird. Die Gespeicherte Prozedur sollte dann in etwa so aussehen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE PROCEDURE [dbo].[PROZEDURNAME] @bild as varchar(max) = null AS BEGIN SET NOCOUNT ON; SET ANSI_PADDING ON; SET ANSI_WARNINGS ON; SET CONCAT_NULL_YIELDS_NULL ON; SET ANSI_NULL_DFLT_ON ON; INSERT INTO tabellenname ( bild ) VALUES ( CONVERT(varbinary(max), @bild, 1) ); END |
Wie immer in der Hoffung, Euch etwas Sucharbeit gespart zu haben 😉