PHP 5.6.0beta1 released

oci_connect

(PHP 5, PECL OCI8 >= 1.1.0)

oci_connectÉtablit une connexion avec un serveur Oracle

Description

resource oci_connect ( string $username , string $password [, string $connection_string [, string $character_set [, int $session_mode ]]] )

Retourne un identifiant de connexion, nécessaire à la plupart des appels OCI8.

Voir la section sur la gestion des connexions pour des informations générales sur la façon dont sont gérées les connexions avec un serveur Oracle.

Depuis PHP 5.1.2 (PECL OCI8 1.1), la fonction oci_close() peut être utilisée pour fermer une connexion.

Les appels suivants (suivant un premier) à la fonction oci_connect() avec les mêmes paramètres retourneront le gestionnaire de connexion retourné lors du premier appel. Cela signifie que les transactions effectuées sur un gestionnaire seront actives sur les autres, sachant qu'elles utilisent la même connexion sous-jacente. Si 2 gestionnaires doivent avoir des transactions isolées, utilisez à la place la fonction oci_new_connect().

Liste de paramètres

username

Le nom d'utilisateur Oracle.

password

Le mot de passe de l'utilisateur.

connection_string

Contient l'instance Oracle sur laquelle nous devons nous connecter. Ce peut être une » chaîne de connexion rapide, un nom de connexion issue du fichier tnsnames.ora, ou le nom d'une instance locale Oracle.

Si non spécifié, PHP utilise des variables d'environnement comme TWO_TASK (sous Linux) ou LOCAL (sous Windows) et ORACLE_SID pour déterminer l'instance Oracle sur laquelle nous devons nous connecter.

Pour utiliser la méthode de connexion rapide, PHP doit être lié avec la bibliothèque cliente Oracle 10g ou supérieur. La chaîne de connexion rapide pour Oracle 10g ou supérieur est de la forme : [//]host_name[:port][/service_name]. Depuis Oracle 11g, la syntaxe est : [//]host_name[:port][/service_name][:server_type][/instance_name]. Les noms des services peuvent être trouvés en exécutant l'utilitaire Oracle lsnrctl status sur la machine exécutant la base de données.

Le fichier tnsnames.ora peut être dans le chemin de recherche d'Oracle Net, qui inclut $ORACLE_HOME/network/admin et /etc. Une solution alternative serait de définit TNS_ADMIN afin que le fichier $TNS_ADMIN/tnsnames.ora soit lu. Assurez-vous que le daemon exécutant le serveur web a accès en lecture à ce fichier.

character_set

Détermine le jeu de caractères utilisé par la bibliothèque cliente Oracle. Le jeu de caractères n'a pas besoin d'être identique à celui utilisé par la base de données. S'il ne correspond pas, Oracle ferait de son mieux pour convertir les données depuis le jeu de caractères de la base de données. Suivant les jeux de caractères, il se peut que le résultat ne soit pas parfait. De plus, cette conversion nécessite un peu de temps système.

Si non spécifié, la bibliothèque cliente Oracle déterminera un jeu de caractères depuis la variable d'environnement NLS_LANG.

Le fait de passer ce paramètre peut réduire la durée de connexion.

session_mode

Ce paramètre est disponible depuis PHP 5 (PECL OCI8 1.1) et accepte les valeurs suivantes : OCI_DEFAULT, OCI_SYSOPER et OCI_SYSDBA. Si soit la constante OCI_SYSOPER, soit la constante OCI_SYSDBA est spécifiée, cette fonction tentera d'établir une connexion privilégiée en utilisant des identifiants externes. Les connexions privilégiées sont désactivées par défault. Pour les activer, vous devez définir l'option oci8.privileged_connect à On.

PHP 5.3 (PECL OCI8 1.3.4) introduisent la valeur de mode OCI_CRED_EXT. Ce mode demande à Oracle d'utiliser une identification externe ou bien issue du système d'exploitation, qui doit être configurée dans la base de données. Le drapeau OCI_CRED_EXT ne peut être utilisé qu'avec le nom d'utilisateur "/" associé à un mot de passe vide. L'option oci8.privileged_connect peut être définie à On ou Off.

OCI_CRED_EXT peut être combiné avec le mode OCI_SYSOPER ou le mode OCI_SYSDBA.

OCI_CRED_EXT n'est pas supporté sous Windows pour des raisons de sécurité.

Valeurs de retour

Retourne un identifiant de connexion ou FALSE si une erreur survient.

Exemples

Exemple #1 Exemple avec oci_connect() en utilisant la syntaxe simplifiée

<?php

// Connexion au service XE (i.e. la base de données) sur la machine "localhost"
$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 employees');
oci_execute($stid);

echo 
"<table border='1'>\n";
while (
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_NULLS)) {
    echo 
"<tr>\n";
    foreach (
$row as $item) {
        echo 
"    <td>" . ($item !== null htmlentities($itemENT_QUOTES) : "") . "</td>\n";
    }
    echo 
"</tr>\n";
}
echo 
"</table>\n";

?>

Exemple #2 Exemple avec oci_connect() en utilisant un nom de connexion réseau

<?php

// Connexion à la base de données MYDB décrite dans le fichier tnsnames.ora,
// Un exemple d'entrée tnsnames.ora pour MYDB pourraît être :
//   MYDB =
//     (DESCRIPTION =
//       (ADDRESS = (PROTOCOL = TCP)(HOST = mymachine.oracle.com)(PORT = 1521))
//       (CONNECT_DATA =
//         (SERVER = DEDICATED)
//         (SERVICE_NAME = XE)
//       )
//     )

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

$stid oci_parse($conn'SELECT * FROM employees');
oci_execute($stid);

echo 
"<table border='1'>\n";
while (
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_NULLS)) {
    echo 
"<tr>\n";
    foreach (
$row as $item) {
        echo 
"    <td>" . ($item !== null htmlentities($itemENT_QUOTES) : "") . "</td>\n";
    }
    echo 
"</tr>\n";
}
echo 
"</table>\n";

?>

Exemple #3 Exemple avec oci_connect() en utilisant un jeu de caractère spécifique

<?php

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

$stid oci_parse($conn'SELECT * FROM employees');
oci_execute($stid);

echo 
"<table border='1'>\n";
while (
$row oci_fetch_array($stidOCI_ASSOC+OCI_RETURN_NULLS)) {
    echo 
"<tr>\n";
    foreach (
$row as $item) {
        echo 
"    <td>" . ($item !== null htmlentities($itemENT_QUOTES) : "") . "</td>\n";
    }
    echo 
"</tr>\n";
}
echo 
"</table>\n";

?>

Exemple #4 Exemple avec plusieurs appels à la fonction oci_connect()

<?php

$c1 
oci_connect("hr""welcome"'localhost/XE');
$c2 oci_connect("hr""welcome"'localhost/XE');

// À la fois $c1 et $c2 affichent le même identifiant de ressources PHP, ce qui signifie
// qu'il s'agit de la même connexion à la base de données
echo "c1 is $c1<br>\n";
echo 
"c2 is $c2<br>\n";

function 
create_table($conn)
{
    
$stmt oci_parse($conn"create table hallo (test varchar2(64))");
    
oci_execute($stmt);
    echo 
"Created table<br>\n";
}

function 
drop_table($conn)
{
    
$stmt oci_parse($conn"drop table hallo");
    
oci_execute($stmt);
    echo 
"Dropped table<br>\n";
}

function 
insert_data($connname$conn)
{
    
$stmt oci_parse($conn"insert into hallo
              values(to_char(sysdate,'DD-MON-YY HH24:MI:SS'))"
);
    
oci_execute($stmtOCI_DEFAULT);
    echo 
"$connname inserted row without committing<br>\n";
}

function 
rollback($connname$conn)
{
    
oci_rollback($conn);
    echo 
"$connname rollback<br>\n";
}

function 
select_data($connname$conn)
{
    
$stmt oci_parse($conn"select * from hallo");
    
oci_execute($stmtOCI_DEFAULT);
    echo 
"$connname ----selecting<br>\n";
    while (
oci_fetch($stmt)) {
        echo 
"    " oci_result($stmt"TEST") . "<br>\n";
    }
    echo 
"$connname ----done<br>\n";
}

create_table($c1);

insert_data('c1'$c1);   // Insère une ligne en utilisant c1
sleep(2);                 // On attend afin de voir un timestamp différent pour la seconde ligne
insert_data('c2'$c2);   // Insère une ligne en utilisant c2

select_data('c1'$c1);   // Les résultats des 2 insertions sont retournés
select_data('c2'$c2);   // Les résultats des 2 insertions sont retournés

rollback('c1'$c1);      // Annulation de la transaction en utilisant c1

select_data('c1'$c1);   // Les 2 insertions ont été annulées
select_data('c2'$c2);

drop_table($c1);

// La fermeture d'une connexion rend les variables PHP indisponibles, mais les autres
// peuvent être toujours utilisées
oci_close($c1);
echo 
"c1 is $c1<br>\n";
echo 
"c2 is $c2<br>\n";


// Affichage :
//    c1 is Resource id #5
//    c2 is Resource id #5
//    Created table
//    c1 inserted row without committing
//    c2 inserted row without committing
//    c1 ----selecting
//        09-DEC-09 12:14:43
//        09-DEC-09 12:14:45
//    c1 ----done
//    c2 ----selecting
//        09-DEC-09 12:14:43
//        09-DEC-09 12:14:45
//    c2 ----done
//    c1 rollback
//    c1 ----selecting
//    c1 ----done
//    c2 ----selecting
//    c2 ----done
//    Dropped table
//    c1 is 
//    c2 is Resource id #5

?>

Notes

Note:

Si un problème est survenu lors de l'installation de l'extension OCI8, une des manifestations sera un problème lors de la connexion. Reportez-vous à la section Installation/Configuration pour plus d'informations en cas d'erreurs.

Voir aussi

add a note add a note

User Contributed Notes 12 notes

up
3
peter at goldthorp dot com
2 years ago
I started getting "ORA-12514: TNS:listener does not currently know of service requested in connect descriptor" errors when I upgraded my database instance from 10.2 to 11.2.  For some reason it would not resolve the oci_connect calls with the Easy Connect syntax (easy connect calls from sqlplus were fine).  I was able to workaround the issue by passing a tns connect string:

<?php
$db
= "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.XX.XXX)(PORT = 1521)))(CONNECT_DATA=(SID=XXXX)))";

$c1 = oci_connect("name","password",$db);
?>
up
1
Leandro da Cunha Campos
4 years ago
ONE ALTERNATIVE OF CONNECT IN ORACLE RAC "Real Application Clusters"

<?php
$dbstr
="(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST =ip1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = banco)
(INSTANCE_NAME = banco1)))"
;
 
$dbstr1 ="(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST =ip2)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = banco)
(INSTANCE_NAME = banco2)))"
;
 
if(!@(
$conn = oci_connect('user','password',$dbstr1)))
{
$conn = oci_connect('user','password',$dbstr) or die (ocierror()); }
?>
up
1
M0no at ethonfusino dot com
11 years ago
If your oracle database is on a remote system within your local network and you don't want to worry about the tnsnames file you can try this.

$db = "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.XX.XXX)(PORT = 1521)))(CONNECT_DATA=(SID=XXXX)))";

$c1 = ocilogon("name","password",$db);

Hope this helps someone.
up
0
blake dot lewis at gmail dot com
1 year ago
Using ldap for Oracle name resolution:

  The web server needs the environmental variable TNS_ADMIN='Directory of tnsname.ora'. I use '/etc/tns_admin'. Confirm using the phpinfo() function.

  There are three files needed in the TNS_ADMIN location: tnsnames.ora, sqlnet.ora and ldap.ora. If you are only using ldap, tnsnames.ora is not needed.

  To sqlnet.ora add:
     NAMES.DIRECTORY_PATH=(TNSNAMES,LDAP)

  To ldap.ora add:
     DIRECTORY_SERVERS=(ldap_fqdn_hostname:1575)
     DEFAULT_ADMIN_CONTEXT=""
     DIRECTORY_SERVER_TYPE=OID

  For a quick and dirty ldap tnsnames server use tnsManager by Dave Berry. Oracle OID or Openldap can used, but are complicated to setup. tnsManager is a no brainer. The default port is 1575.

  The order of values in NAMES.DIRECTORY_PATH from sqlnet.ora determines which look up 'adapter' is used first, in this case it is tnsnames.ora file and then ldap. I use ldap for general consumption and tnsnames.ora file to override ldap or entries that are not for general consumption.

  If you have the full Oracle client you have tnsping. 'tnsping ORACLE_SID' will tell you what adapter you are using: 'Used LDAP adapter to resolve the alias'.

<?php
 
echo system("/PATH/tnsping ".$ORACLE_SID." 2>&1")."<br />";
  echo
'TNS_ADMIN='.getenv('TNS_ADMIN');
?>

ISSUE:
  For some reason PHP tries the HOSTNAME adapter first, and if the database name resolves in DNS, it will try connecting using the database name as the hostname with no SID or SERVICE_NAME defined. All other Oracle clients I have used will not try the HOSTNAME adapter unless it is listed in NAMES.DIRECTORY_PATH.
  I have heard that LDAP look up does not work with older instantclients.
up
0
Anonymous
2 years ago
How to connect from PHP to an Oracle database using OID (Oracle Internet Directory):

OID is like a lookup index that contains connection strings for connecting to various databases. Without OID, a database connection string would be stored directly in the code settings and used by the PHP code to connect to a database. With OID, a lookup can be made to the OID LDAP to acquire the database connection string. Then the PHP code will use the acquired database connection string to connect to the database as before.

OID allows a DBA to manage/change which database server that an application uses without having to change any database settings in the PHP application itself or on the application server.

Here are the basic steps for PHP to connect to a database via OID:

- The DBA should provide you the connection information for the OID LDAP as well as the username/password for the database connection.
- Connect to the OID LDAP using the provided information
- Search for the appropriate LDAP record
- Get the connection string data from the record attribute, \&quot;orclnetdescstring\&quot;
- Close the LDAP connection
- Use the acquired connection string data to connect to the database as usual using the provided database username/password.

Here is basic sample code to do this:

// Get connection string from OID LDAP

    $ds=ldap_connect($servername,$serverport); // Connect to ldap
    $r=ldap_bind($ds); // Bind to ldap
    $sr = ldap_search($ds, \&quot;cn=OracleContext,dc=___,dc=___,dc=___\&quot;, \&quot;cn=$sid\&quot;); // Run query
    $info = ldap_get_entries($ds, $sr); // Get entries
    ldap_close($ds); // Close connection

    $dbconnectstring = $info[0][\&quot;orclnetdescstring\&quot;][0]; // Extract db connect string from ldap search result array

// Connect to database using acquired connection string from OID

    $dbconnection = oci_connect ($username,$password,$dbconnectstring);
up
0
Jonathon Robinson
3 years ago
Regarding the following statement in the documentation:
"The second and subsequent calls to oci_connect() with the same parameters will return the connection handle returned from the first call."

There's one caveat here.  Subsequent calls to oci_connect() will only return the same connection handle as the first call as long as a reference is held to the original handle.

For example, the following code will generate *one* connection handle:

<?php
$dbh
= oci_connect($username, $password, $conn_info);
// Do stuff
$dbh = oci_connect$username, $password, $conn_info);
// Do more stuff

The follow code will generate *two* connection handles:
getData();
// Do stuff
getData();
// Do more stuff

getData() {
   
$dbh = oci_connect($username, $password, $conn_info);
   
// Do stuff
}
?>

This is the result of PHP garbage collecting the handle at the end of the method scope.

If you want to isolate your DB layer through function calls but still want to leverage the fact that oci_connect can return the same handle, just keep a reference to the handle like so:

<?php
getData
($username, $password, $conn_info) {
   
$dbh = oci_connect($username, $password, $conn_info);
   
$key = hash('md5', "$username|$password|$conn_info");
   
$GLOBALS[$key] = $dbh;
   
// Do stuff
}
?>

I originally logged this as a bug but apparently this is the expected behaviour, likely because oci_close($dbh) just calls unset($dbh).
up
0
drew dot carmichael at gmail dot com
4 years ago
When using the OCI_CRED_EXT in php
if the ENV $ORACLE_SID is set the DB does not need to be specified explicitly and the connection will fail unless you provide a NULL DB value when creating the connection.

The $ORACLE_SID trumps the TNS name look up for the connection. So even a manual connection string in the DB parameter will fail.

So when the $ORACLE_SID Env is set a NULL passed instead of the DB name connects successfully.

Hope this saves some hair pulling when moving to %.3 and OS Authentications
up
0
sixd at php dot net
5 years ago
If you want to specify a connection timeout in case there is network problem, you can edit the client side (e.g. PHP side) sqlnet.ora file and set SQLNET.OUTBOUND_CONNECT_TIMEOUT. This sets the upper time limit for establishing a connection right through to the DB, including the time for attempts to connect to other services.   It is available from Oracle 10.2.0.3 onwards.

In Oracle 11.1, a slightly lighter-weight solution TCP.CONNECT_TIMEOUT was introduced.  It also is a sqlnet.ora parameter.  It bounds just the TCP connection establishment time, which is mostly where connection problem are seen.

The client sqlnet.ora file should be put in the same directory as the tnsnames.ora file.
up
0
sebastien.barbieri _at_ gmail dot com
7 years ago
When you are using Oracle 9.2+ I would say that you MUST use the CHARSET parameter.

Of course, you will not notice it until there is accented character... so just specify it and you will avoid a big headache.

So for example here is our Oracle internal conf:
select * from nls_database_parameters;
 
PARAMETER                      VALUE
------------------------------ ----------------------------------------

NLS_LANGUAGE                   AMERICAN
NLS_TERRITORY                  AMERICA
NLS_ISO_CURRENCY               AMERICA
NLS_CHARACTERSET               WE8ISO8859P15

 
And there our oci_connect call:

$dbch=ocilogon($user,$pass,$connectString,"WE8ISO8859P15");

Without that, you will get question mark (inversed), squares… instead of most accented character.

Don’t forget to use that for writing as well as for reading.
up
0
ben at onshop dot co dot uk
8 years ago
There is a useful solution to the problem of securing connection information in the PHP Cookbook (O'Reilly) by David Sklar and Adam Trachtenberg. They propose using 'SetEnv' in the Apache configuration and then accessing the values from within a script using $_SERVER.

Unfortunately using the 'SetEnv' solution exposes your connection information to all users of that virtual host. If they run phpinfo.php or display $_SERVER, I found that they will see the password from any file under the root of that virtual host.

To restrict exposure to a particular directory or specific file:

1. First put an 'Include' to the secret file in httpd.conf. For example:

Include "/web/private/secret.txt"

2. In the password file, use the 'SetEnvIf' directive to enable the Environment variables by directory only or within a specific file. For example:

- For all files in the directory:

SetEnvIf Request_URI "/path/to/my/directory" ORACLE_PASS=5gHj790j

- For a specific file in the directory

SetEnvIf Request_URI "/path/to/my/directory/connection.oracle.php" ORACLE_PASS=5gHj790j
up
-1
blake dot lewis at gmail dot com
1 year ago
Using ldap for Oracle name resolution:

  The web server will need the environmental variable TNS_ADMIN='Directory of tnsname.ora' unless the default location is used. I use '/etc/tns_admin'. Confirm using the phpinfo().

  There are three files needed in the TNS_ADMIN location: tnsnames.ora, sqlnet.ora and ldap.ora. If you are only using ldap, tnsnames.ora is not needed.

  To sqlnet.ora add:
     NAMES.DIRECTORY_PATH=(TNSNAMES,LDAP)

  To ldap.ora add:
     DIRECTORY_SERVERS=(ldap_server_fqdn:port)
     DEFAULT_ADMIN_CONTEXT=""
     DIRECTORY_SERVER_TYPE=OID

  For a quick and dirty ldap tnsnames server use tnsManager by Dave Berry. Oracle OID or Openldap can used, but are complicated to setup. tnsManager is a no brainer. The quick part: give it a tnsnames.ora file and start it up. The dirty parts: I can't get Toad and SQLDeveloper to work with it, it ignores the domain and it is no longer being maintained.

  The order of values in NAMES.DIRECTORY_PATH in sqlnet.ora determines which look up 'adapter' is used, in this case it is tnsnames.ora file and then ldap. I use ldap for general consumption and tnsnames.ora file to override ldap or entries that are not for general consumption.

  If you have the full Oracle client you have tnsping. 'tnsping ORACLE_SID' will tell you what adapter you are using: 'Used LDAP adapter to resolve the alias'.

<?php
 
echo system("/PATH/tnsping ".$ORACLE_SID." 2>&1")."<br />";
  echo
'TNS_ADMIN='.getenv('TNS_ADMIN');
?>

ISSUE:
  If connecting with only ORACLE_SID and not ORACLE_SID.DB_DOMAIN, the value of NAMES.DEFAULT_DOMAIN from sqlnet.ora is appended, then for some reason PHP tries the HOSTNAME adapter, and if the database name resolves in DNS, it will fail connecting using the database name as the hostname, because neither SID nor SERVICE_NAME are defined.
  If using tnsManager append '.ANY_DOMAIN' to $ORACLE_SID to hack around the issue above.

  I have tested with:
       11.1.0.7 full client and PHP 5.1.6
       11.2.0.2 full client and PHP 5.4.11

  I have heard that LDAP lookup does not work with older instantclients.
up
-1
jtacon at php dot net
3 years ago
If you upgrades the OCI8, be sure to use the latest oracle instantclient version, otherwise you can receive an "ORA-24315: illegal attribute type" when trying to connect due to incompatibility with some versions.

HTH,
Javier Tacón
To Top