PHP Conference Nagoya 2025

oci_fetch_array

(PHP 5, PHP 7, PHP 8, PECL OCI8 >= 1.1.0)

oci_fetch_arrayLit une ligne d'un résultat sous forme de tableau associatif ou numérique

Description

oci_fetch_array(resource $statement, int $mode = OCI_BOTH | OCI_RETURN_NULLS): array|false

Retourne un tableau contenant la prochaine ligne d'une requête. Chaque entrée de ce tableau correspond à une colonne de la ligne. Cette fonction est appelée typiquement dans une boucle qui retourne false lorsqu'il n'y a plus de ligne de disponible.

Si le paramètre statement correspond à un bloc PL/SQL retourné par des jeux de résultats implicites Oracle Database, alors les lignes depuis tous les jeux de résultats seront récupérées consécutivement. Si statement est retourné par la fonction oci_get_implicit_resultset(), alors seul le sous-jeu de lignes d'une seule requête enfant sera retourné.

Pour plus de détails sur le mapping des types de données effectué par l'extension OCI8, lisez les types de données supportés par le driver.

Liste de paramètres

statement

Un identifiant de requête OCI8 créé par la fonction oci_parse() et exécuté par la fonction oci_execute(), ou un identifiant de requête REF CURSOR.

Peut également être un identifiant de requête retourné par la fonction oci_get_implicit_resultset().

mode

Le paramètre optionnel mode peut être la combinaison des constantes suivantes :

Modes pour oci_fetch_array()
Constante Description
OCI_BOTH Retourne une tableau, indexé numériquement et avec les noms de colonnes. Identique à OCI_ASSOC + OCI_NUM). C'est le comportement par défaut.
OCI_ASSOC Retourne un tableau associatif.
OCI_NUM Retourne un tableau indexé numériquement.
OCI_RETURN_NULLS Crée des éléments vides pour les valeurs null. La valeur des éléments sera la valeur null PHP.
OCI_RETURN_LOBS Retourne le contenu du LOB au lieu de leur descripteur.

Le mode par défaut est OCI_BOTH.

Utilisez l'opérateur d'addition "+" pour spécifier plus d'un mode à la fois.

Valeurs de retour

Retourne un tableau avec des indices numériques ou associatifs. S'il n'y a plus de ligne de disponible pour la requête statement alors false sera retourné.

Par défaut, les colonnes LOB sont retournées sous la forme de descripteurs LOB.

Les colonnes DATE sont retournées sous la forme d'une chaîne formatée avec le format de date courante. Le format par défaut peut être modifié grâce aux variables d'environnement Oracle, comme NLS_LANG ou par l'exécution de la commande ALTER SESSION SET NLS_DATE_FORMAT.

Les noms de colonnes qui ne sont pas sensibles à la casse (par défaut sous Oracle), auront des noms d'attributs en majuscule. Les noms de colonnes qui sont sensibles à la casse, auront des noms d'attributs utilisant exactement la même casse de la colonne. Utilisez la fonction var_dump() sur l'objet de résultat pour vérifier la casse appropriée à utiliser pour chaque requête.

Le nom de la table n'est pas inclus dans l'index du tableau. Si votre requête contient deux colonnes différentes avec le même nom, utilisez la constante OCI_NUM ou ajoutez un alias à la colonne à la requête pour s'assurer l'unicité du nom ; voir l'exemple #7. Sinon, seulement une colonne sera retournée via PHP.

Exemples

Exemple #1 Exemple avec oci_fetch_array() avec OCI_BOTH

<?php

$conn
= oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'SELECT department_id, department_name FROM departments');
oci_execute($stid);

while ((
$row = oci_fetch_array($stid, OCI_BOTH)) != false) {
// Utilisez des noms de colonne en majuscule pour les indices des tableau associatif
echo $row[0] . " and " . $row['DEPARTMENT_ID'] . " are the same<br>\n";
echo
$row[1] . " and " . $row['DEPARTMENT_NAME'] . " are the same<br>\n";
}

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #2 Exemple avec oci_fetch_array() avec OCI_NUM

<?php

/*
Avant l'exécution, créez la table :
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'A very long string');
COMMIT;
*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'SELECT id, description FROM mytab');
oci_execute($stid);

while ((
$row = oci_fetch_array($stid, OCI_NUM)) != false) {
echo
$row[0] . "<br>\n";
echo
$row[1]->read(11) . "<br>\n"; // ceci affichera les 11 premiers octets depuis DESCRIPTION
}

// Affiche :
// 1
// A very long

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #3 Exemple avec oci_fetch_array() avec OCI_ASSOC

<?php

/*
Avant l'exécution, créez la table :
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'A very long string');
COMMIT;
*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'SELECT id, description FROM mytab');
oci_execute($stid);

while ((
$row = oci_fetch_array($stid, OCI_ASSOC)) != false) {
echo
$row['ID'] . "<br>\n";
echo
$row['DESCRIPTION']->read(11) . "<br>\n"; // ceci affichera les 11 premiers octets depuis DESCRIPTION
}

// Affiche :
// 1
// A very long

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #4 Exemple avec oci_fetch_array() avec OCI_RETURN_NULLS

<?php

$conn
= oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'SELECT 1, null FROM dual');
oci_execute($stid);
while ((
$row = oci_fetch_array ($stid, OCI_ASSOC)) != false) { // Ignore NULLs
var_dump($row);
}

/*
Le code ci-dessus affiche :
array(1) {
[1]=>
string(1) "1"
}
*/

$stid = oci_parse($conn, 'SELECT 1, null FROM dual');
oci_execute($stid);
while ((
$row = oci_fetch_array ($stid, OCI_ASSOC+OCI_RETURN_NULLS)) != false) { // Récupère NULLs
var_dump($row);
}

/*
Le code ci-dessus affiche :
array(2) {
[1]=>
string(1) "1"
["NULL"]=>
NULL
}
*/

?>

Exemple #5 oci_fetch_array() with OCI_RETURN_LOBS

<?php

/*
Avant l'exécution, créez la table :
CREATE TABLE mytab (id NUMBER, description CLOB);
INSERT INTO mytab (id, description) values (1, 'A very long string');
COMMIT;
*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'SELECT id, description FROM mytab');
oci_execute($stid);

while ((
$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_LOBS)) != false) {
echo
$row['ID'] . "<br>\n";
echo
$row['DESCRIPTION'] . "<br>\n"; // contient la totalité de DESCRIPTION

// Dans une boucle, le fait de libérer la variable avant de récupérer une seconde
// ligne permet de réduire l'utilisation mémoire de PHP
unset($row);
}

// Affiche :
// 1
// A very long string

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #6 Exemple avec oci_fetch_array() avec des noms de colonnes sensibles à la casse

<?php

/*
Avant l'exécution, créez la table :
CREATE TABLE mytab ("Name" VARCHAR2(20), city VARCHAR2(20));
INSERT INTO mytab ("Name", city) values ('Chris', 'Melbourne');
COMMIT;
*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'select * from mytab');
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS);

// Vu que 'Name' a été créé comme une colonne sensible à la casse, la même casse
// est utilisé pour les index du tableau. Cependant, 'CITY' doit être utilisé
// pour les index de colonne non sensible à la casse
print $row['Name'] . "<br>\n"; // affiche Chris
print $row['CITY'] . "<br>\n"; // affiche Melbourne

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #7 Exemple avec oci_fetch_array() avec des colonnes possédant des noms dupliqués

<?php

/*
Avant l'exécution, créez la table :
CREATE TABLE mycity (id NUMBER, name VARCHAR2(20));
INSERT INTO mycity (id, name) values (1, 'Melbourne');
CREATE TABLE mycountry (id NUMBER, name VARCHAR2(20));
INSERT INTO mycountry (id, name) values (1, 'Australia');
COMMIT;
*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$sql = 'SELECT mycity.name, mycountry.name
FROM mycity, mycountry
WHERE mycity.id = mycountry.id'
;
$stid = oci_parse($conn, $sql);
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC);
var_dump($row);

// L'affiche ne contient que UNE entrée "NAME" :
// array(1) {
// ["NAME"]=>
// string(9) "Australia"
// }

// Pour interroger un nom de colonne dupliqué, utilisez un alias de colonne SQL
// comme "AS ctnm":
$sql = 'SELECT mycity.name AS ctnm, mycountry.name
FROM mycity, mycountry
WHERE mycity.id = mycountry.id'
;
$stid = oci_parse($conn, $sql);
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC);
var_dump($row);

// L'affichage contient maintenant 2 colonnes :
// array(2) {
// ["CTNM"]=>
// string(9) "Melbourne"
// ["NAME"]=>
// string(9) "Australia"
// }


oci_free_statement($stid);
oci_close($conn);

?>

Exemple #8 Exemple avec oci_fetch_array() et des colonnes DATE

<?php

$conn
= oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// Définit le format utilisé pour les dates sur cette connexion.
// Pour des raisons de performance, vous devriez modifier le format via un trigger ou
// en utilisant les variables d'environnement
$stid = oci_parse($conn, "ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'");
oci_execute($stid);

$stid = oci_parse($conn, 'SELECT hire_date FROM employees WHERE employee_id = 188');
oci_execute($stid);
$row = oci_fetch_array($stid, OCI_ASSOC);
echo
$row['HIRE_DATE'] . "<br>\n"; // Affiche 1997-06-14

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #9 Exemple avec oci_fetch_array() et REF CURSOR

<?php
/*
Créez la procédure stockée PL/SQL suivante avant l'exécution :

CREATE OR REPLACE PROCEDURE myproc(p1 OUT SYS_REFCURSOR) AS
BEGIN
OPEN p1 FOR SELECT * FROM all_objects WHERE ROWNUM < 5000;
END;
*/

$conn = oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

$stid = oci_parse($conn, 'BEGIN myproc(:rc); END;');
$refcur = oci_new_cursor($conn);
oci_bind_by_name($stid, ':rc', $refcur, -1, OCI_B_CURSOR);
oci_execute($stid);

// Exécute le REF CURSOR retourné et y récupère un identifiant de requête
oci_execute($refcur);
echo
"<table border='1'>\n";
while ((
$row = oci_fetch_array($refcur, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo
"<tr>\n";
foreach (
$row as $item) {
echo
" <td>".($item !== null ? htmlentities($item, ENT_QUOTES) : "")."</td>\n";
}
echo
"</tr>\n";
}
echo
"</table>\n";

oci_free_statement($refcur);
oci_free_statement($stid);
oci_close($conn);

?>

Exemple #10 Pagination avec oci_fetch_array() en utilisant une requête utilisant le paramètre LIMIT

<?php

$conn
= oci_connect('hr', 'welcome', 'localhost/XE');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// Retrouve la version de la base de données
preg_match('/Release ([0-9]+)\./', oci_server_version($conn), $matches);
$oracleversion = $matches[1];

// Requête pour la pagination
$sql = 'SELECT city, postal_code FROM locations ORDER BY city';

if (
$oracleversion >= 12) {
// Utilisation de la syntaxe Oracle 12c OFFSET / FETCH NEXT
$sql = $sql . ' OFFSET :offset ROWS FETCH NEXT :numrows ROWS ONLY';
} else {
// Les versions anciennes d'Oracle ont besoin d'une requête imbriquée
// pour sélectionner un sous-jeu depuis $sql. Ou, si la requête SQL
// est connue au moment du développement, utilisez plutôt une fonction
// row_number() au lieu de cette solution d'imbrication. Dans les
// environnements de production, assurez-vous d'éviter les injections
// SQL avec la concaténation.
$sql = "SELECT * FROM (SELECT a.*, ROWNUM AS my_rnum
FROM (
$sql) a
WHERE ROWNUM <= :offset + :numrows)
WHERE my_rnum > :offset"
;
}

$offset = 0; // Ne pas traiter les premières lignes
$numrows = 5; // Retourne 5 lignes
$stid = oci_parse($conn, $sql);
oci_bind_by_name($stid, ':numrows', $numrows);
oci_bind_by_name($stid, ':offset', $offset);
oci_execute($stid);

while ((
$row = oci_fetch_array($stid, OCI_ASSOC + OCI_RETURN_NULLS)) != false) {
echo
$row['CITY'] . " " . $row['POSTAL_CODE'] . "<br>\n";
}

// Affiche :
// Beijing 190518
// Bern 3095
// Bombay 490231
// Geneva 1730
// Hiroshima 6823

oci_free_statement($stid);
oci_close($conn);

?>

Exemple #11 Exemple avec oci_fetch_array() avec Oracle Database

<?php

$conn
= oci_connect('hr', 'welcome', 'localhost/pdborcl');
if (!
$conn) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
}

// Requiert OCI8 2.0 (ou ultérieur) et Oracle Database 12c (ou ultérieur)
// Voir aussi oci_get_implicit_resultset()
$sql = 'DECLARE
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR SELECT city, postal_code FROM locations WHERE ROWNUM < 4 ORDER BY city;
DBMS_SQL.RETURN_RESULT(c1);
OPEN c1 FOR SELECT country_id FROM locations WHERE ROWNUM < 4 ORDER BY city;
DBMS_SQL.RETURN_RESULT(c1);
END;'
;

$stid = oci_parse($conn, $sql);
oci_execute($stid);

// Note : oci_fetch_all et oci_fetch() ne peuvent être utilisées de cette façon
echo "<table>\n";
while ((
$row = oci_fetch_array($stid, OCI_ASSOC+OCI_RETURN_NULLS)) != false) {
echo
"<tr>\n";
foreach (
$row as $item) {
echo
" <td>".($item!==null?htmlentities($item, ENT_QUOTES|ENT_SUBSTITUTE):"")."</td>\n";
}
echo
"</tr>\n";
}
echo
"</table>\n";

// Affiche :
// Beijing 190518
// Bern 3095
// Bombay 490231
// CN
// CH
// IN

oci_free_statement($stid);
oci_close($conn);

?>

Notes

Note:

Les indices des tableaux associatifs doivent être en majuscule pour les colonnes standards Oracle qui ont été créée avec des noms sensibles à la casse.

Note:

Pour les requêtes retournant un très grand nombre de lignes, les performances peuvent être très grandement accrues en augmentant la valeur de l'option oci8.default_prefetch ou en utilisant la fonction oci_set_prefetch().

Note:

La fonction oci_fetch_array() est significativement plus lente que la fonction oci_fetch_assoc() ou oci_fetch_row(), mais est plus flexible.

Voir aussi

  • oci_fetch() - Lit la prochaine ligne d'un résultat Oracle dans un buffer interne
  • oci_fetch_all() - Lit plusieurs lignes d'un résultat dans un tableau multidimensionnel
  • oci_fetch_assoc() - Lit une ligne d'un résultat sous forme de tableau associatif
  • oci_fetch_object() - Lit une ligne d'un résultat sous forme d'objet
  • oci_fetch_row() - Lit la prochaine ligne d'une requête sous forme de tableau numérique
  • oci_set_prefetch() - Indique le nombre de lignes qui doivent être lues à l'avance par Oracle

add a note

User Contributed Notes 2 notes

up
1
Maxwell_Smart at ThePentagon dot com
22 years ago
When using OCI_RETURN_LOBS to get a BFILE (stored with a DIRECTORY) the user needs READ on the DIRECTORY. (GRANT READ on DIRECTORY <directory name> TO <user>;) Otherwise, you'll get a cryptic error. Warning: OCILobFileOpen: ORA-22285: non-existent directory or file for FILEOPEN operation in ... on line ...
<BR>
The user that CREATEs the DIRECTORY is automatically GRANTed READ WITH THE GRANT OPTION.
up
-1
junk at netburp dot com
24 years ago
Here's a clue about rowid.

Don't forget about the oracle functions:

"rowidtochar" and "chartorowid"

"select rowidtochar(rowid) as FOO from table ...."

When you want to pass the rowid in a form or link, that's
the only way to go.
To Top