Signatur
Beschreibung
OCICollection ist eine PHP-Klasse, die eine Oracle-Collection kapselt. Oracle unterstützt komplexe Datentypen wie VARRAY (Variable-Length Arrays) und nested TABLEs, die in PL/SQL-Prozeduren, Funktionen oder als Tabellenspalten verwendet werden können. Instanzen dieser Klasse werden typischerweise über oci_new_collection() erzeugt und können als Bind-Parameter an SQL- oder PL/SQL-Anweisungen übergeben werden.
Die Klasse stellt Methoden bereit, um Elemente hinzuzufügen (append()), abzurufen (getElem()), zu ändern (assignElem()), die Größe der Collection zu ermitteln (size()) sowie die Collection zu trimmen (trim()) oder vollständig zu leeren und freizugeben (free()). Mit assign() lässt sich der Inhalt einer anderen Collection übernehmen.
Ein typischer Einsatzfall ist das Übergeben einer Liste von Werten an eine Oracle-Stored-Procedure oder das Auslesen von Collection-Rückgabewerten aus PL/SQL-Blöcken. Diese Klasse ist besonders nützlich, wenn mengenbasierte Operationen auf der Datenbankseite effizient ausgeführt werden sollen, ohne für jeden Wert einen separaten Roundtrip zu benötigen.
Wichtig: Die Klasse ist nur verfügbar, wenn die OCI8-Extension installiert und gegen Oracle-Client-Bibliotheken kompiliert wurde. Ab PHP 8.0 wurde die Klasse von OCI-Collection (interner Name) in OCICollection umbenannt.
Beispiele
Collection erzeugen, befüllen und an PL/SQL übergeben
<?php
// Verbindung zur Oracle-Datenbank herstellen
$conn = oci_connect('user', 'password', 'localhost/XE');
if (!$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message']), E_USER_ERROR);
}
// Collection-Typ muss in Oracle definiert sein:
// CREATE OR REPLACE TYPE num_list AS VARRAY(10) OF NUMBER;
// Neue Collection vom Typ NUM_LIST erzeugen
$collection = oci_new_collection($conn, 'NUM_LIST');
// Elemente hinzufügen
$collection->append(10);
$collection->append(20);
$collection->append(30);
// Anzahl der Elemente ausgeben
echo 'Elementanzahl: ' . $collection->size() . PHP_EOL; // 3
// Ein bestimmtes Element lesen (0-basierter Index)
echo 'Element 1: ' . $collection->getElem(1) . PHP_EOL; // 20
// PL/SQL-Block mit Collection-Bind
$stmt = oci_parse($conn, 'BEGIN my_proc(:col); END;');
oci_bind_by_name($stmt, ':col', $collection, -1, OCI_B_NTY);
oci_execute($stmt);
// Ressourcen freigeben
$collection->free();
oci_free_statement($stmt);
oci_close($conn);
Collection aus PL/SQL-Funktion auslesen
<?php
// Verbindung herstellen
$conn = oci_connect('user', 'password', 'localhost/XE');
// Oracle-Typ: CREATE OR REPLACE TYPE str_list AS TABLE OF VARCHAR2(100);
// PL/SQL-Funktion gibt eine STR_LIST zurück
$collection = oci_new_collection($conn, 'STR_LIST');
$stmt = oci_parse($conn, 'BEGIN :result := get_names(); END;');
oci_bind_by_name($stmt, ':result', $collection, -1, OCI_B_NTY);
oci_execute($stmt);
// Alle Elemente iterieren
$size = $collection->size();
for ($i = 0; $i < $size; $i++) {
echo 'Name[' . $i . ']: ' . $collection->getElem($i) . PHP_EOL;
}
// Letzte 2 Elemente entfernen
$collection->trim(2);
echo 'Nach trim: ' . $collection->size() . ' Elemente' . PHP_EOL;
$collection->free();
oci_free_statement($stmt);
oci_close($conn);
// Wichtig · Fallstricke
Methoden im Überblick:
append(mixed $value): bool— Fügt ein Element am Ende der Collection hinzu.assign(OCICollection $from): bool— Kopiert den Inhalt einer anderen Collection in diese.assignElem(int $index, mixed $value): bool— Setzt den Wert eines Elements an einem bestimmten Index (0-basiert).free(): bool— Gibt die Collection-Ressource frei. Sollte immer aufgerufen werden, um Speicherlecks zu vermeiden.getElem(int $index): mixed— Liefert das Element am angegebenen Index oderfalsebei Fehler.max(): int— Gibt die maximale Anzahl von Elementen zurück (für VARRAY), oder0bei nested TABLEs.size(): int— Gibt die aktuelle Anzahl der Elemente zurück.trim(int $num): bool— Entfernt$numElemente vom Ende der Collection.
Voraussetzungen: Der Oracle-Collection-Typ muss im Datenbankschema vorhanden sein. Beim Binden an SQL/PL/SQL muss die Konstante OCI_B_NTY als Typ angegeben werden.
PHP 8: Der interne Klassenname wurde von OCI-Collection zu OCICollection geändert. Code, der instanceof OCI-Collection verwendet, muss angepasst werden.