Signatur
Beschreibung
sqlsrv_send_stream_data() gehört zum Microsoft SQL Server Driver für PHP (SQLSRV-Erweiterung) und ermöglicht es, große Datenmengen aus PHP-Streams (z. B. geöffnete Dateien oder In-Memory-Streams) schrittweise an den SQL Server zu übertragen. Standardmäßig werden Stream-Daten beim Aufruf von sqlsrv_execute() vollständig gesendet; mit sqlsrv_send_stream_data() kann dieses Verhalten manuell gesteuert werden.
Die Funktion ist besonders nützlich, wenn die Option SendStreamParamsAtExec beim Erstellen des Statements auf false gesetzt wurde. In diesem Fall müssen die Stream-Daten durch wiederholten Aufruf von sqlsrv_send_stream_data() in mehreren Paketen gesendet werden, bis false zurückgegeben wird – was signalisiert, dass alle Daten übermittelt wurden.
Typische Anwendungsfälle sind das Einfügen oder Aktualisieren großer Binärdaten (z. B. Bilder, Dokumente) oder langer Texte in SQL-Server-Spalten vom Typ VARBINARY(MAX), VARCHAR(MAX) oder NVARCHAR(MAX).
- Ein Rückgabewert von
truebedeutet, dass noch weitere Daten gesendet werden müssen. - Ein Rückgabewert von
falsebedeutet entweder, dass alle Daten vollständig übertragen wurden, oder dass ein Fehler aufgetreten ist – beides muss mitsqlsrv_errors()unterschieden werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $stmt Pflicht | resource | Ein gültiges Statement-Ressource-Handle, das mit sqlsrv_prepare() erstellt und mit sqlsrv_execute() ausgeführt wurde. Das Statement muss mindestens einen Stream-Parameter enthalten, und SendStreamParamsAtExec sollte auf false gesetzt sein. |
Rückgabewert
true zurück, wenn noch weitere Stream-Daten gesendet werden müssen. Gibt false zurück, wenn alle Daten übertragen wurden oder ein Fehler aufgetreten ist. Um einen Fehler von einem erfolgreichen Abschluss zu unterscheiden, muss sqlsrv_errors() aufgerufen werden.Beispiele
Großes Bild als Stream in SQL Server einfügen
<?php
$serverName = 'localhost';
$connectionInfo = [
'Database' => 'TestDB',
'UID' => 'sa',
'PWD' => 'geheim'
];
$conn = sqlsrv_connect($serverName, $connectionInfo);
if (!$conn) {
die('Verbindung fehlgeschlagen: ' . print_r(sqlsrv_errors(), true));
}
// Datei als Stream öffnen
$fileStream = fopen('/pfad/zur/datei/bild.jpg', 'rb');
if (!$fileStream) {
die('Datei konnte nicht geöffnet werden.');
}
$sql = 'INSERT INTO Bilder (Name, Daten) VALUES (?, ?)';
$params = [
'Mein Bild',
[
$fileStream,
SQLSRV_PARAM_IN,
null,
SQLSRV_SQLTYPE_VARBINARY('max')
]
];
// Statement vorbereiten, Streams NICHT sofort senden
$stmt = sqlsrv_prepare($conn, $sql, $params, ['SendStreamParamsAtExec' => false]);
if (!$stmt) {
die('Prepare fehlgeschlagen: ' . print_r(sqlsrv_errors(), true));
}
// Statement ausführen (ohne Stream-Daten)
if (sqlsrv_execute($stmt) === false) {
die('Execute fehlgeschlagen: ' . print_r(sqlsrv_errors(), true));
}
// Stream-Daten paketweise senden
while (sqlsrv_send_stream_data($stmt)) {
// Schleife läuft, bis alle Daten gesendet wurden
echo 'Datenpaket gesendet...' . PHP_EOL;
}
// Prüfen, ob ein Fehler aufgetreten ist
if (sqlsrv_errors()) {
echo 'Fehler beim Senden: ' . print_r(sqlsrv_errors(), true);
} else {
echo 'Alle Stream-Daten erfolgreich übertragen.';
}
fclose($fileStream);
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>
In-Memory-Stream mit Text-Daten senden
<?php
$serverName = 'localhost';
$connectionInfo = [
'Database' => 'TestDB',
'UID' => 'sa',
'PWD' => 'geheim'
];
$conn = sqlsrv_connect($serverName, $connectionInfo);
if (!$conn) {
die('Verbindung fehlgeschlagen.');
}
// Großen Text als In-Memory-Stream simulieren
$textStream = fopen('php://memory', 'a+');
fwrite($textStream, str_repeat('Lorem ipsum dolor sit amet. ', 1000));
rewind($textStream);
$sql = 'INSERT INTO Dokumente (Titel, Inhalt) VALUES (?, ?)';
$params = [
'Testdokument',
[
$textStream,
SQLSRV_PARAM_IN,
SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_CHAR),
SQLSRV_SQLTYPE_NVARCHAR('max')
]
];
$stmt = sqlsrv_prepare($conn, $sql, $params, ['SendStreamParamsAtExec' => false]);
sqlsrv_execute($stmt);
// Alle Pakete senden
$pakete = 0;
while (sqlsrv_send_stream_data($stmt)) {
$pakete++;
}
if (!sqlsrv_errors()) {
echo "Stream-Übertragung abgeschlossen. Pakete gesendet: {$pakete}";
} else {
echo 'Fehler: ' . print_r(sqlsrv_errors(), true);
}
fclose($textStream);
sqlsrv_free_stmt($stmt);
sqlsrv_close($conn);
?>
// Wichtig · Fallstricke
Fehlerunterscheidung: Da sqlsrv_send_stream_data() sowohl bei erfolgreichem Abschluss als auch bei einem Fehler false zurückgibt, muss nach der Schleife immer sqlsrv_errors() aufgerufen werden, um sicherzustellen, dass kein Fehler aufgetreten ist.
Voraussetzung: Die Option SendStreamParamsAtExec muss beim Aufruf von sqlsrv_prepare() auf false gesetzt sein. Andernfalls werden alle Stream-Daten bereits bei sqlsrv_execute() gesendet und sqlsrv_send_stream_data() hat keine Wirkung.
Paketgröße: Die Paketgröße pro Aufruf wird durch den Verbindungsparameter PacketSize beeinflusst (Standard: 4096 Bytes). Für sehr große Datenmengen empfiehlt sich eine größere Paketgröße zur Optimierung der Übertragungsgeschwindigkeit.
Sicherheit: Stellen Sie sicher, dass Eingaben, die in Stream-Parametern verarbeitet werden, validiert und ggf. auf Dateityp und Größe geprüft werden, um unerwünschte Datei-Uploads oder Ressourcenerschöpfung zu vermeiden.