I was experiencing issues with Unicode characters being saved incorrectly to my ORA 10 DB. Issue was tracked to not having a NLS_LANG environment variable specified - set this correctly in the Apache environment and the issue was resolved.
oci_connect
(PHP 5, PECL oci8 >= 1.1.0)
oci_connect — Establishes a connection to the Oracle server
Description
Returns a connection identifier needed for most other OCI calls.
Parameters
- username
-
The Oracle user name.
- password
-
The password for username .
- db
-
This optional parameter can either contain the name of the local Oracle instance or the name of the entry in tnsnames.ora.
If the not specified, PHP uses environment variables ORACLE_SID and TWO_TASK to determine the name of local Oracle instance and location of tnsnames.ora accordingly.
- charset
-
Using Oracle server version 9.2 and greater, you can indicate charset by parameter, which will be used in the new connection. If you're using Oracle server < 9.2, this parameter will be ignored and the NLS_LANG environment variable will be used instead.
- session_mode
-
This parameter is available since version 1.1 and accepts the following values: OCI_DEFAULT, OCI_SYSOPER and OCI_SYSDBA. If either OCI_SYSOPER or OCI_SYSDBA were specified, this function will try to establish privileged connection using external credentials. Privileged connections are disabled by default. To enable them you need to set oci8.privileged_connect to On.
Return Values
Returns a connection identifier or FALSE on error.
Examples
Example #1 oci_connect() example
<?php
echo "<pre>";
$db = "";
$c1 = oci_connect("scott", "tiger", $db);
$c2 = oci_connect("scott", "tiger", $db);
function create_table($conn)
{
$stmt = oci_parse($conn, "create table scott.hallo (test varchar2(64))");
oci_execute($stmt);
echo $conn . " created table\n\n";
}
function drop_table($conn)
{
$stmt = oci_parse($conn, "drop table scott.hallo");
oci_execute($stmt);
echo $conn . " dropped table\n\n";
}
function insert_data($conn)
{
$stmt = oci_parse($conn, "insert into scott.hallo
values('$conn' || ' ' || to_char(sysdate,'DD-MON-YY HH24:MI:SS'))");
oci_execute($stmt, OCI_DEFAULT);
echo $conn . " inserted hallo\n\n";
}
function delete_data($conn)
{
$stmt = oci_parse($conn, "delete from scott.hallo");
oci_execute($stmt, OCI_DEFAULT);
echo $conn . " deleted hallo\n\n";
}
function commit($conn)
{
oci_commit($conn);
echo $conn . " committed\n\n";
}
function rollback($conn)
{
oci_rollback($conn);
echo $conn . " rollback\n\n";
}
function select_data($conn)
{
$stmt = oci_parse($conn, "select * from scott.hallo");
oci_execute($stmt, OCI_DEFAULT);
echo $conn."----selecting\n\n";
while (oci_fetch($stmt)) {
echo $conn . " [" . oci_result($stmt, "TEST") . "]\n\n";
}
echo $conn . "----done\n\n";
}
create_table($c1);
insert_data($c1); // Insert a row using c1
insert_data($c2); // Insert a row using c2
select_data($c1); // Results of both inserts are returned
select_data($c2);
rollback($c1); // Rollback using c1
select_data($c1); // Both inserts have been rolled back
select_data($c2);
insert_data($c2); // Insert a row using c2
commit($c2); // Commit using c2
select_data($c1); // Result of c2 insert is returned
delete_data($c1); // Delete all rows in table using c1
select_data($c1); // No rows returned
select_data($c2); // No rows returned
commit($c1); // Commit using c1
select_data($c1); // No rows returned
select_data($c2); // No rows returned
drop_table($c1);
echo "</pre>";
?>
Notes
Note: If you're using PHP with Oracle Instant Client, you can use easy connect naming method described here: » http://download-west.oracle.com/docs/cd/B12037_01/network.101/b10775/naming.htm#i498306. Basically this means you can specify "//db_host[:port]/database_name" as database name. But if you want to use the old way of naming you must set either ORACLE_HOME or TNS_ADMIN.
Note: The second and subsequent calls to oci_connect() with the same parameters will return the connection handle returned from the first call. This means that queries issued against one handle are also applied to the other handles, because they are the same handle. This behaviour is demonstrated in Example 1 below. If you require two handles to be transactionally isolated from each other, you should use oci_new_connect() instead.
Note: In PHP versions before 5.0.0 you must use ocilogon() instead. This name still can be used, it was left as the alias of oci_connect() for downwards compatability. This, however, is deprecated and not recommended.
See Also
- oci_pconnect() - Connect to an Oracle database using a persistent connection
- oci_new_connect() - Establishes a new connection to the Oracle server
- oci_close() - Closes Oracle connection
oci_connect
04-Aug-2009 05:24
03-Jul-2009 08:55
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
11-May-2009 06:04
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()); }
?>
01-Apr-2009 08:40
The docs seem short on information if you want to connect to an Oracle database on a different host. Here's the info shamelessly copied from The Underground PHP Oracle Manual:
If you are running Oracle Database XE on a machine called mymachine, and the PHP-enabled web server is
on the same machine, you could connect to the HR schema with:
$c = oci_connect('hr', 'hrpwd', 'mymachine/XE');
In this guide, we assume the database is on the same machine as Apache and PHP so we use localhost:
$c = oci_connect('hr', 'hrpwd', 'localhost/XE');
Depending on your network configuration, you may need to use the equivalent IP address:
$c = oci_connect('hr', 'hrpwd', '127.0.0.1/XE');
The Easy Connect string is JDBC-like. The Oracle 10g syntax is:
[//]host_name[:port][/service_name]
If PHP links with Oracle 11g libraries, the enhanced 11g syntax can be used:
[//]host_name[:port][/service_name][:server_type][/instance_name]
26-Jan-2009 05:59
Regarding the character set the is to be specified, it should be noted that it has to be the character set the client wishes to recieve and not the character set of the database.
Using this parameter, Oracle will convert the character set of the internal database to the character set specified by the client in this parameter.
22-Nov-2008 05:35
Hi, I use Oracle Database 10g Express Edition Release
10.2.0.1.0 on a Linux workstation for dev purposes, along
with Apache 2 and PHP5. So far I have used it on Kubuntu 8.04.
To get things working on a recently installed notebook with openSUSE
11.0 was a bit more complicated. So I hope someone will be able to
benefit from our experiences. Here is our howto:
# Use the package manager to install the packages php5-pear and
php5-dev, if not installed yet.
# Download the instantclient_11_1, zip files basic, sdk, sqlplus from the Oracle web site
# Switch to user root here, since not all commands to some work sudo
# Unzip these files to /opt/oracle/.
# As a result you will see a dir instantclient_11_1 appearing.
ln -s /opt/oracle/instantclient_11_1/libclntsh.so.11.1 \
/opt/oracle/instantclient_11_1/libclntsh.so
ln -s /opt/oracle/instantclient_11_1/libclntsh.so.11.1 \
/usr/lib/libclntsh.so
ln -s /opt/oracle/instantclient_11_1/libnnz11.so \
/usr/lib/libnnz11.so
ldconfig # to make sure the system will be able to find the libs
pecl install oci8 # interactively enter option 1,
# then instantclient,/opt/oracle/instantclient_11_1,
# then enter
# if needed, add extension=oci8.so to your php.ini
/etc/init.d/apache2 reload
# finished!
Kind regards,
Nico den Boer
21-Jul-2008 08:16
From PHP 5.3 onwards:
A new OCI_CRED_EXT flag can be passed as the "session_mode" parameter
to oci_connect(), oci_new_connect() and oci_pconnect().
$c1 = oci_connect("/", "", $db, null, OCI_CRED_EXT);
This tells Oracle to do external or OS authentication, if configured
in the database.
OCI_CRED_EXT can only be used with username of "/" and a empty
password. Oci8.privileged_connection may be On or Off.
OCI_CRED_EXT is not supported on Windows for security reasons.
The new flag may be combined with the existing OCI_SYSOPER or
OCI_SYSDBA modes (note: oci8.privileged_connection needs to be On for
OCI_SYSDBA and OCI_SYSOPER), e.g.:
$c1 = oci_connect("/", "", $db, null, OCI_CRED_EXT+OCI_SYSOPER);
30-Jun-2008 11:33
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.
20-Jun-2008 10:46
If PHP is built with Oracle 9.2 or greater client libraries, the
charset parameter is used to determine the character set used by the
Oracle client libraries. When PHP is built with older Oracle client
libraries, or if the parameter is not passed, Oracle NLS environment
variables such as NLS_LANG will be used to determine the character
set.
The character set does not need to match that used by the database.
If it doesn't, Oracle will do its best to convert data to and from the
database character set. Depending on the character sets, this may not
which may always be give usable or valid results, and it can reduce
overall performance
Because passing the parameter removes the environment look up, it can
improve connection performance
13-Sep-2006 04:42
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.
01-Aug-2006 04:27
You will get the error ORA-12154 when there seems to be no right to access the tnsnames.ora file.
I could fix the problem set the apache user to oracle and the group to dba. (It depends which user and group for oracle you created on your system).
For me it isen't risky cause I am sitting in an unreachable WAN. After the changes the problem was fixed.
My environment :
php4.4.2, Apache 1.3.29, Oracle 10gR2 on SLES9 (SP2)
24-Jul-2006 04:30
For use PHPv5 functions in PHPv4 i use simple script:
<?php
$funcs=array(
'oci_connect'=>'OCILogon',
'oci_parse'=>'OCIParse',
'oci_execute'=>'OCIExecute',
'oci_fetch'=>'OCIFetch',
'oci_num_fields'=>'OCINumCols',
'oci_field_name'=>'OCIColumnName',
'oci_result'=>'OCIResult',
'oci_free_statement'=>'OCIFreeStatement',
);
// yoy can add yours pairs of funcs.
foreach ($funcs as $k=>$v)
{
if (!function_exists($k))
{
$arg_string='$p0';
for ($i=1;$i<20;$i++) {
$arg_string.=',$p'.$i;
}
eval ('function '.$k.' () {
list('.$arg_string.')=func_get_args();
return '.$v.'('.$arg_string.');
}
');
}
}
?>
simple, but it work. :-)
02-Jun-2006 02:49
Here are the translate of some functions from ORA to OCI:
<?php
function Ora_Logon($usuario, $password)
{
$con = oci_connect($usuario,$password);
return $con;
}
function Ora_Open($conexion) {
$cursor[0]=$conexion;
return $cursor;
}
function Ora_Parse(&$cursor, $consulta) {
$cursor[1]=oci_parse($cursor[0],$consulta);
return $cursor;
}
function Ora_Exec(&$cursor) {
oci_execute($cursor[1]);
$cursor[2]=1;
return $cursor;
}
function Ora_Fetch(&$cursor)
{
if ($cursor[2] == 1) $cursor[2]=0;
return oci_fetch($cursor[1]);
}
function Ora_GetColumn(&$cursor, $indice)
{
if ($cursor[2] == 1) {
Ora_Fetch($cursor);
$cursor[2]=0;
}
$valor = oci_result($cursor[1],$indice+1);
return $valor;
}
function Ora_Close(&$cursor)
{
unset($cursor[1]);
}
function Ora_Logoff($conexion) {
}
?>
07-Nov-2005 01:08
lost oracle connection. need restart apache?
Temporarely you can prevent 'connection lost' by using folowing script (use it at your own risk):
<?php
$rnum=rand(0,99999999);
$dbcon = oci_new_connect('XXXXX', 'XXXXXX',
'
(DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = XXX.XXX.XXX.XXX)
(PORT = 1521)
(HASH = '.$rnum.')
)
(CONNECT_DATA =(SID = XXX))
)
');
?>
07-Nov-2005 08:44
This note is an addendum to note#58378
Seems to be a good workaround set the oracle_home and/instead of the tns_admin.
tnsnames.ora must to be located in
$ORACLE_HOME/network/admin
and in
$TNS_ADMIN/ (if you use it)
---
Best Regards,
Domenico
02-Nov-2005 10:44
Using tnsnames.ora
Apache 2
php 5.0.5
Oracle 10 IstantClient
PHP half of times return this error:
OCISessionBegin: ORA-24327: need explicit attach before authenticating a user in ...
In Oracle manual I find:
ORA-24327 need explicit attach before authenticating a user
Cause: A server context must be initialized before creating a session.
Action: Create and initialize a server handle.
I resolved using Easy Connect Naming Method.
Notice of this problem in bug#29779.
---
Best Regards,
Domenico
28-Oct-2005 12:19
Our tnsnames.ora uses the SERVICE_NAME=mydb - which for some reason wont work with PHP even though it works fine with tnsping. Using SID=mydb worked and a connection was established.
14-Jul-2005 12:25
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
06-Jul-2005 03:51
I spent ages trying work out why I was getting the following message when when using ocilogon() on Windows 2000 using PHP 4 and 5:
ORA-03106 Fatal two-task communication protocol error
This problem is occurs when PHP cannot find ORACLE client environmental variables.
The environmental variables can be set in several ways:
1. Within the root 'Directory' directive on Apache httpd.conf:
<Directory "d:/path/to/webroot">
SetEnv ORACLE_BASE "c:/oracle"
SetEnv ORACLE_HOME "c:/oracle/ora81"
SetEnv NLS_LANG "american_america.WE8DEC"
SetEnv NLS_CHARACTERSET "WE8DEC"
SetEnv NLS_NCHAR_CHARACTERSET "AL16UTF16"
</Directory>
or
2. Within Windows:
Go to the Control Panel>System>Advanced>Environmental Variables
Then enter a name value/pair for each of the variables.
3. Using putenv() statements in the PHP file prior to using ocilogon(). This is not ideal because the statements are required evertime you wish to connect to Oracle.
18-May-2005 12:15
If you want the change NLS_LANG (e.g.: NLS_LANG="FRENCH_FRANCE.WE8ISO8859P1") don't forget to also set LC_ALL and LANG (e.g.: LC_ALL=french and LANG=french) else you'll have a ORA-01756 when you try to call ocilogon.
17-Nov-2004 09:44
In reply to william_poulsen at hotmail dot com:
I was trying to connect to a Oracle database wich worked fine in a web browser but failed when i executed the script from command line.
Thanks to william_poulsen at hotmail dot com i learned that the problem was that the command line can't find the TNSNAMES. His solution was to edit you DB to the TNSNAMES entry. Sadly enough this didn't do the trick. I got segmantation fault when the script was executed. So i started to set my Oracle variables prior to executing the script. ORACLE_SID, ORACLE_HOME, ORACLE_BASE and added $ORACLE_HOME/BIN to the path. After that PHP seems to use this variables and the connection can be made. Problem solved.
I hope this can help somebody out there.
07-Aug-2004 01:15
Hey guys!!!!
I have all these problems and when are solved a php show this:
_oci_server ORA-12159:connection text especified is too long
It's simple!!!
In the TNSNAMES.ORA remove all space, tab, carriage return on the conection string and, wallah!!! All work fine!!!
More info:
PHP 5.0.0 with Oci8
Apache 1.3
Regards,
Romolo (neogodo@yahoo.com.br).
DBA Oracle
Brazil - SP - Sao Paulo
01-Jul-2004 10:04
If you get your connectivity working with putenv on ORACLE_SID and ORACLE_HOME, but you do not want to use putenv because you want safemode on. You will need to pass these from your environment variables. Somehow setenv in httpd.conf did not do the trick for me... the values are set but the connectivity does not work. Then you will need to set the environment in your /etc/init.d/apachectl or /etc/profile and use a "PassEnv ORACLE_HOME ORACLE_SID" directive in httpd.conf so that these variables are picked up by php.
However, when you suexec in Apache 2.0, the server will only allow you to pass a given set of variables which are defined in the apache source code in the file apache-dir/support/suexec.c
In order to pass ORACLE_SID and ORACLE_HOME to PHP you need to add these to that file. The relevant changed piece of code where I added "ORACLE_" looks something like this:
char *safe_env_lst[] =
{
/* variable name starts with */
"HTTP_",
"SSL_",
"ORACLE_",
/* variable name is */
...
You will have to do a "make clean", "./configure", "make", "make install". Do not forget to do the "make clean" or the apache changes will not be picked up.
Here is a nice php test script :)
<?php // test-oracle.php
function dump_array($a_value)
{
reset($a_value);
for ( $s_str = '' ; list($s_key, $x_value) = each($a_value) ; )
{
$s_str .= " ".
"<span style=\"color:green\">[</span>$s_key<span style=\"color:green\">]</span> = ".
"<span style=\"color:red\">[</span>$x_value<span style=\"color:red\">]</span><br />";
}
reset($a_value);
echo $s_str;
}
#putenv("ORACLE_SID=ORTD");
#putenv("ORACLE_HOME=/u01/app/oracle/product/9.2.0.1.0");
$ORACLE_SID = getenv("ORACLE_SID");
$ORACLE_HOME = getenv("ORACLE_HOME");
echo "ORACLE_SID = $ORACLE_SID<br>";
echo "ORACLE_HOME = $ORACLE_HOME<br>";
$cn = ociplogon('scott', 'tiger');
echo "cn = $cn<br />\n";
$st = ociparse($cn, "select tname from tab");
echo "st = $st<br />\n";
$ex = ociexecute($st,OCI_COMMIT_ON_SUCCESS);
echo "ex = $ex<br />\n";
$mr = ocifetchinto($st,$xx,OCI_ASSOC);
while ( $mr )
{
dump_array($xx);
$mr = ocifetchinto($st,$xx,OCI_ASSOC);
}
$fr = ocifreestatement($st);
echo "fr = $fr<br />";
ocicommit($cn);
ocilogoff($cn);
?>
16-Feb-2004 09:06
If PHP is linked with Oracle 10g (or later) client libraries, the Easy
Connection syntax can be used to identify which database to connect
to. This can remove the need for a local tnsnames.ora file or complex
connect string. The new syntax can be used to connect to earlier
versions of Oracle.
With Oracle 10g client libraries, the third parameter "db" for
OCILogon can have the syntax:
[//]host[:port][/service_name]
An example is:
$c = OCILogon('scott', 'tiger', '//mymachine.mydomain/mydbservice');
The pre-10g syntax equivalent is something like:
$c = OCILogon('scott', 'tiger',
'(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)
(HOST=mymachine.mydomain) (PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=MYDBSERVICE)))');
The full syntax continues to work with 10g. It allows for more
complex configuration than available with the Easy Connect method.
Oracle documentation and the fine print for Easy Connect is at:
http://download-west.oracle.com/docs/cd/B12037_01/network.101/
b10775/naming.htm#i498306
(note the split URL due to PHP doc site limitations needs to be recombined for use)
07-Jan-2004 10:35
Using PHP 4.3.4, Apache/2.0.48, Oracle 9.2 the following line would generate the same ORA-12560 errors that lffranco reported, even with the "ORACLE_SID" environmental variable set.
<?php $DBH = OCILogon( "user", "pass" ); ?>
Once I set Oracle's hidden "LOCAL" environmental variable to the same value as "ORACLE_SID", all was well.
17-Dec-2003 08:26
This took me a lot of time to solve, so I'm placing it here for my future reference, and for somebody who finds it useful. I don't know if it will work on your environment, this is what I have:
* Windoze Advanced Server 2003
* IIS 6
* Oracle 8.1.7
So how I configured the whole thing? First do whatever the standard PHP configuration says... it won't work, anyway... but it will help. I installed PHP on C:\PHP; Oracle Home is in E:\Oracle\ora817.
* Install Oracle 8 client. NOTE: You must use an Oracle 8 client, I used an Oracle 9 client and for some reason (dll binding I guess), it didn't work
* Copy $ORACLE_HOME/bin/cli.dll into $WINDOWS/System32
* Modify your SQLNET.ORA file and change the line:
[code]
SQLNET.AUTHENTICATION_SERVICES= (NTS)
[/code]
by this one:
[code]
SQLNET.AUTHENTICATION_SERVICES= (NONE)
[/code]
I dunno WTF NTS is, so if somebody sends me an eMail and explain, I'll be thankful. But if you don't do this you'll get an ORA-12560 error.
And that's it for Oracle. Now, the IIS configuration:
* Open your IIS Administrator and "Web Service Extensions", add a new extension as follows:
** Extension Name: PHP
** Required Files (ADD): C:\php\extensions\php_oci8.dll; c:\php\sapi\php4isapi.dll; c:\WINDOWS\system32\oci.dll
** Check "Set Extension Status as Allowed"
Now you can use your ocli* functions, or better yet, use PEAR::DB functions which was my ultimate goal, with PEAR::DB you can forget about declaring ORACLE_HOME, ORACLE_SID and all that kind of things. Just use:
<?php
$dsn = "oci8://scott:tiger@example"
$db = DB::Connect($dsn);
?>
16-Nov-2003 11:16
Warning: ocilogon(): _oci_open_session: OCIHandleAlloc OCI_HTYPE_SVCCTX: OCI_INVALID_HANDLE can also be caused by running the webserver with an ORACLE_HOME of a (radically?) different version than PHP was linked against.
I experienced this when I accidently used an Oracle 8 ORACLE_HOME for a PHP that was linked against Oracle 9.
23-Oct-2003 01:39
I've had all kinds of errors with RedHat9(yuck), PHP 4.3.4RC1 and Oracle enterprice server 9.2. For some time I thought that --with-oci8 wouldn't work with Oracle9 but that wasn't the case, the solution was many steps.
1) install oracle, might require some tricks, on RedHat9 I had to put this in my .bashrc:
export ORACLE_BASE=/opt/ora9
export ORACLE_HOME=$ORACLE_BASE/product/9.2
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_OWNER=oracle
export ORACLE_SID=netadmdb
export ORACLE_TERM=vt100
export LD_ASSUME_KERNEL=2.4.1
export THREADS_FLAG=native
export LD_LIBRARY_PATH=$ORACLE_BASE/product/9.2/lib:$LD_LIBRARY_PATH
2) compile php, use --with-oci8
3) Make an init-script for the oracle9 database server, as default the TNS listener doesn't run so add that on aswell, example:
#!/bin/bash
export ORACLE_HOME=/opt/ora9/product/9.2
export PATH=$ORACLE_HOME/bin:$PATH
export ORACLE_SID=netadmdb
export DISPLAY=:0
oracle_user=oracle
export oracle_user
case $1 in
start)
su - "$oracle_user"<<EOO
sqlplus /nolog<<EOS
connect / as sysdba
startup
EOS
/opt/ora9/product/9.2/bin/lsnrctl start
EOO
;;
stop)
su - "$oracle_user"<<EOO
/opt/ora9/product/9.2/bin/lsnrctl stop
sqlplus /nolog<<EOS
connect / as sysdba
shutdown immediate
EOS
EOO
;;
*)
echo "Usage: ora9 [start|stop]"
;;
esac
4) Configure Apache. For some reason it requires some tweaking with environment variables, in the begining I put those in the PHP-script with putenv, later in the httpd.conf with SetEnv and the mod_env module. But I was told to not do that and instead set them in the init script for Apache. So I copied apachectl to /etc/init.d and edited envvars in $APACHE_PATH/bin. First I added all kinds of env variables until I got it to work, and then I removed them one at a time and came to the following minimal configuration:
LD_LIBRARY_PATH="/usr/local/apache2/lib:$LD_LIBRARY_PATH"
ORACLE_HOME=/opt/ora9/product/9.2
LANG=sv_SE
export LD_LIBRARY_PATH ORACLE_HOME LANG
Earlier I had added NLS_LANG and TNS_ADMIN above those mentioned above (point 1), but it seems those aren't needed really. So no need for TWO_TASK or ORACLE_SID, only needed one is ORACLE_HOME and if you get missing/invalid option for your OCILogon set LANG to something else like I did. Someone earlier said it might have to do with UTF8.
So if you are sure lsncrtl are started and that you have the correct env-variables set in your $APACHE_PATH/bin/envvars you can just use something like:
$iDBConn=OCILogon("user","pass","netadmdb");
in your PHP-script and it should work.
Hope this helps someone.
02-Oct-2003 06:45
Getting PHP 4.3.3 (and lower versions) to work
with Apache v2.xxx and Oracle 8i was easy.
But just after Oracle upgrade to 9i ugly message
appeared when ocologon () was called :
Warning: ocilogon(): _oci_open_session: OCIHandleAlloc OCI_HTYPE_SVCCTX: OCI_INVALID_HANDLE
What we should do? All environment variables
has been set correctly, tnsnames too (it worked
under oracle 8i).
The solution was posted 2003-09-17 22:24 by
Andy Hassall (andy@andyh.co.uk) responding in
news:comp.lang.php threat "PHP & OCI9. No such..."
"Also check file permissions on the Oracle home; by default, Oracle 9i installs the Oracle home with restricted permissions (this differs from 8i). You may need to grant at least Read and Execute permissions to the web server's user."
That's correct. I've added r-x permissions for others
for oracle user $HOME and got nice message - logged
with success!
Tomasz Kokowski
20-Aug-2003 02:52
For those having Oracle errors, I find out that little something, while using Apache2. I don't know if this applies also to Apache 1.x, but for Apache2, this is the ultimate solution!
Especially with ORA-12154 and ORA-12505, some said to write the following code in your php script, but if you have access to the configuration or your web server, DON'T!
<?php
putenv("ORACLE_SID=TESTDB");
//putenv("ORACLE_HOME=/oracle/ora90");
//putenv("TNS_ADMIN=/oracle/ora90/network/admin");
$username = "scott";
$passwd = "tiger";
$db="(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)
(HOST=yourTargetMachine)(PORT=1521)
)
)
(CONNECT_DATA=(SERVICE_NAME=TESTDB))
)";
$conn = OCILogon($username,$passwd,$db);
...
?>
All right, like I said, if you have access to the configuration of apache, there is a file in $APACHE2/bin called envvars. Simply put the necessary environment variables needed by Oracle in this file: ORACLE_SID, ORACLE_BASE, ORACLE_HOME and myself I also added LD_LIBRARY_PATH with oracle directories.
At first, my problem was that I didn't had all the environment sets when rebooting the server, but if I'd stop apache, then restart it, while beeing root, all the environment was there. Setting the envvars file correctly solved the reboot problem.
Hope this will help!
Franks
27-May-2003 10:12
I had a little problem with ocilogon but only with RedHat 8.0. It always returned some kind of error during connection like 'OCISessionBegin - ... invalid character', or 'OCISessionBegin - ... missing or invalid option in ...'
I have finally found what is this problem! You have to change your LANG enviroment variable disabling UTF-8. Example: LANG=en_US.UTF-8 should become LANG=en_US.
21-Nov-2002 12:13
In addition to the earlier posts here is a further explaination;
Problem: Regular and Remote authentication does not work using Windows 2000 + PHP and Oracle 8i, 9i.
Secondary Issue if using Oracle 9.2.0.1
When using Oracle 9.2.0.1 the Error structure returned by Oracle is different than expected by PHP. As a result there will be no legible error message other than the following;
Warning: _oci_open_server: in ...
Using Oracle 9.0.1.1 the error message returned is any of the following depending on your situation;
Warning: _oci_open_server: ORA-12638: Credential retrieval failed in ...
Warning: _oci_open_server: ORA-12154: TNS:could not resolve service name in ...
Warning: _oci_open_server: ORA-12505: TNS:listener could not resolve SID given in connect descriptor in ...
Resolution:
In order to get this to work properly you need to do the following;
In reference to ORA-12638: Credential retrieval failed in ...
you need to edit your sqlnet.ora file and change the
SQLNET.AUTHENTICATION_SERVICES = (NTS) to
SQLNET.AUTHENTICATION_SERVICES = (NONE)
The reason is that using NTS validation on a Windows 2000 machine essentially means Kerberos.
Using (NONE) will tell oracle not to expect kerberos "Credentials" as a means of validation. In turn it will use the oracle authentication for a database user.
In reference to ORA-12154 and ORA-12505 you need to do the following;
In your php code you are using to connect you need to copy the section in tnsnames.ora
into a variable.
For example;
<?php
putenv("ORACLE_SID=TESTDB");
//putenv("ORACLE_HOME=/oracle/ora90");
//putenv("TNS_ADMIN=/oracle/ora90/network/admin");
$username = "scott";
$passwd = "tiger";
$db="(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)
(HOST=yourTargetMachine)(PORT=1521)
)
)
(CONNECT_DATA=(SERVICE_NAME=TESTDB))
)";
$conn = OCILogon($username,$passwd,$db);
if (!$conn)
{
echo "Connection failed";
echo "Error Message: [" . OCIError($conn) . "]";
exit;
}
else
{
echo "Connected!";
}
...
?>
I left the ORACLE_HOME and TNS_ADMIN putenv lines commented out and your need for them depends on which web server you are using. If you are using Apache, you may need both.
If you are using Microsoft IIS you may need ORACLE_HOME. Putting it in can't hurt and it appears PHP may read them if they are there but either way you should be working at this
point.
Live long and prosper.
09-Apr-2002 02:49
If you're running an apache server, make sure you have php setup as a module. Then just include the environment variables in the apache config, and use all 3 parts of the ocilogon. You don't even have to copy the tsnnames.ora definition, just use the standard sid
03-Oct-2001 12:53
For those of you who are having Oracle errors: ORA-12154 or ORA-12505 or ORA-01005 do the folowing:
The folowing precedures have been tested when connecting to a HP UX with Oracle 7.x using of couse the OCI8 as the client interface.
Add those lines to the web server config files or set and export those ones before the web server starts.
On Apache add these lines to httpd.conf:
SetEnv ORACLE_HOME /usr/local/oracle
SetEnv ORACLE_SID <sid>
SetEnv LD_LIBRARY_PATH /usr/local/oracle/lib
SetEnv TNS_ADMIN /usr/local/oracle/tnsnames.ora
SetEnv TWO_TASK /usr/local/oracle/tnsnames.ora
SetEnv NLS_LANG English_America.WE8ISO8859P1
SetEnv ORACLE_BASE /usr/local
When calling the OCILogon do this:
$db = " (DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP) (HOST =server_ip_or_dns_name)(PORT = 1521))
(CONNECT_DATA= (SID = _sid_))
)";
The previous definition is a copy of the service definition that is stored in the tnsnames.ora file.
Next, call the OCILogon function using the folowing format:
OCILogon("user/password","password", $db);
To avoid ORA-01005 error, set the NLS_LANG environment variable to English_America.WE8ISO8859P1 ( some other values may work...but we have found that this one works for us )
To avoid ORA-12154 and ORA-12505, use the service definition as the OCILogon third parameter.
I'd like to thanks to a friend of mine a.k.a Rosa for the user/password tip.
Regards
Miguel Carvalho
09-Aug-2001 01:14
Some trouble-shooting notes:<br>
When using Apache with dso support and php as a loadable module, be sure to stop/start your web server between tnsnames.ora changes (sending HUP to apache "apachectl restart" doesn't appear to flush cached connect string).<br>
You'll see your changed connect strings in the listener log file.<p>
TNSNAMES.ORA:<br>
This is a very simple file to manage, yet can be very picky about your syntax. Simply ensure that you follow one of these two examples:<br>
Legacy SID:<br>
alias-or-sidname =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(Host = hostname-or-ipaddress)(Port = 1521))
(CONNECT_DATA =
(SID = sidname)
)
)<br>
8i SERVICE NAME:<br>
hostname.domainname.com =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = hostname-or-ipaddress)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = servicename)
)
)</p>
Additional notes:<br>
- ORA/TNS-12514 error can also be caused by listener not being started.
- Ensure that httpd user (i.e. nobody) has the following in its environment (putenv is unnecessary if env is set by os via /etc/profile):
$ORACLE_SID
$ORACLE_HOME<br>
Also, some helpful resources:
- TNS Error Messages:
http://www.oradoc.com/ora817/server.817/a76999/tnsus.htm#1000527
- TNS Listener logs:
$ORACLE_HOME/network/log/...
17-May-2001 12:25
One simple but useful note:check whether your TNS Listener is running! By default, it's not started automatically when an Oracle instance is started. Login as oracle then type :
lsnrctl START
After it's started, I can sucessfully run the sample code on this page! I used to got ora-12514 error before doing this.
06-Mar-2001 10:57
check your tnsnames.ora permission.
ex)
ORACLE_HOME = /home/oracle/oracle
chmod 755 /home/oracle/oracle/network/admin -R
Yahoo!!!!!! I solved it!!!
20-Jan-2001 04:05
If you are experiencing problems logging onto your Oracle DB, maybe a ORA-12154 error or something like that, try setting the ORACLE_HOME, ORACLE_SID, TNS_ADMIN vars in your Apache config, rather than using PutEnv() inside PHP. Its because PHP/Apache needs to know these variables upon server startup, not when it serves the PHP page. Of course, this assumes you have OCI installed locally on the webserver, if you dont, no matter what variables you set and where, it just wont work.
18-Oct-2000 06:45
To avoid the ORACLE_SID problem/not being able to connect to database:
Apache parent thread runs as 'root' - setup root's profile to have ORACLE variables - then when script starts Apache - also initialize profile to current shell.
user 'nobody' inherits all root's profile.
14-Jul-2000 03:39
While login to remote oracle server,you should setup oracle client first.If failed with error ora-12154,Please if you web server account can acess the tnsnames.ora file or not.One way is login as root then 'su nobody' and set the correct envrionment,run sqlplus to test if it works fine.
13-May-2000 10:54
If you try to connect to an Oracle7 database,
and you get the "ora-01005, null password given errror", make sure to do the following:<br>
-install net8 (ok, you already did)<br>
- use net8 as ORACLE_HOME *for the webserver*!<br>
- add the user of the httpd process (nobody or www or whatever) to the group oracle<br>
- use the TWO_TASK env for connecting
01-Apr-2000 07:32
Regarding connecting to an Oracle Db on NT from Linux, here is what you need to do. Little Oracle knowledge is a prerequisite.
1. Install Oracle database client onto Linux.
2. Once installed on Linux, modify the tnsanmes.ora file to create an alias to the database running on the NT box. Follow the syntax already in the tnsnames.ora file
3. Depending on the version of Oracle you have and the Oracle Database has the listener running there is a utility called tnsping(xx) that you can use to verify that you can hit a remote 0racle database syntax is tnsping <alias in tnsnames.ora>
4. You could use sqlplus to conenct to the remote database to verify the login process works. Remember to use login_id@tnsnames_alias/password
5. Once you have gotten this far PHP should be able to hit the database. Give it a shot. You might need to tool around the PHP config to get things to work. use the phpinfo function to debug, its rather useful.
20-Jul-1999 04:08
The ORACLE_SID should be known as it is the ID that designates the database you are wishing to connect to... Your oracle DBA account should have this set and running oraenv should recommend the correct SID if properly setup.
