The Underground PHP and Oracle® Manual

Release 1.4

CHRISTOPHER JONES AND ALISON HOLLOWAY

The Underground PHP and Oracle® Manual, Release 1.4 Copyright © 2007, Oracle. All rights reserved. Authors: Christopher Jones and Alison Holloway Contributors and acknowledgements: Vladimir Barriere, Luxi Chidambaran, Robert Clevenger, Sue Harper, Ken Jacobs, Srinath Krishnaswamy, Shoaib Lari, Simon Law, Krishna Mohan, Kevin Neel, Charles Poulsen, Roy Rossebo, Sreekumar Seshadri, Makoto Tozawa, Todd Trichler, Simon Watt The Programs (which include both the software and documentation) contain proprietary information; they are provided under a license agreement containing restrictions on use and disclosure and are also protected by copyright, patent, and other intellectual and industrial property laws. Reverse engineering, disassembly, or decompilation of the Programs, except to the extent required to obtain interoperability with other independently created software or as specified by law, is prohibited. The information contained in this document is subject to change without notice. If you find any problems in the documentation, please report them to us in writing. This document is not warranted to be error-free. Except as may be expressly permitted in your license agreement for these Programs, no part of these Programs may be reproduced or transmitted in any form or by any means, electronic or mechanical, for any purpose. U.S. GOVERNMENT RIGHTS Programs, software, databases, and related documentation and technical data delivered to U.S. Government customers are "commercial computer software" or "commercial technical data" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the Programs, including documentation and technical data, shall be subject to the licensing restrictions set forth in the applicable Oracle license agreement, and, to the extent applicable, the additional rights set forth in FAR 52.227-19, Commercial Computer Software--Restricted Rights (June 1987). Oracle USA, Inc., 500 Oracle Parkway, Redwood City, CA 94065. The Programs are not intended for use in any nuclear, aviation, mass transit, medical, or other inherently dangerous applications. It shall be the licensee's responsibility to take all appropriate fail-safe, backup, redundancy and other measures to ensure the safe use of such applications if the Programs are used for such purposes, and we disclaim liability for any damages caused by such use of the Programs. The Programs may provide links to Web sites and access to content, products, and services from third parties. Oracle is not responsible for the availability of, or any content provided on, third-party Web sites. You bear all risks associated with the use of such content. If you choose to purchase any products or services from a third party, the relationship is directly between you and the third party. Oracle is not responsible for: (a) the quality of thirdparty products or services; or (b) fulfilling any of the terms of the agreement with the third party, including delivery of products or services and warranty obligations related to purchased products or services. Oracle is not responsible for any loss or damage of any sort that you may incur from dealing with any third party. Oracle, JD Edwards, and PeopleSoft are registered trademarks of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Contents
Chapter 1 ..................................................................................................................................9 Introduction..............................................................................................................................9 Who Should Read This Book? ........................................................................................ 9 Introduction to Oracle...................................................................................................... 9 Databases and Instances ............................................................................................. 10 Tablespaces ................................................................................................................ 10 Schemas and Users..................................................................................................... 10 Introduction to PHP ....................................................................................................... 11 Chapter 2 ................................................................................................................................13 PHP Oracle Extensions .........................................................................................................13 Choosing a PHP Oracle Extension ................................................................................ 13 PHP Oracle Extensions.................................................................................................. 13 Oracle Extension ........................................................................................................ 13 OCI8 Extension .......................................................................................................... 13 PDO Extension........................................................................................................... 15 PHP Database Abstraction Libraries ............................................................................. 15 ADOdb ....................................................................................................................... 15 PEAR DB ................................................................................................................... 16 PEAR MDB2 ............................................................................................................. 16 Getting the OCI8 and PDO_OCI Extensions ................................................................ 16 OCI8 and PDO_OCI Installation Options ..................................................................... 17 Zend Core for Oracle ..................................................................................................... 19 OCI8 and PDO_OCI Development Cycle..................................................................... 19 Chapter 3 ................................................................................................................................21 Installing Oracle Database 10g Express Edition.................................................................21 Oracle Database Editions............................................................................................... 21 Oracle Database XE....................................................................................................... 21 Installing Oracle Database XE on Linux ....................................................................... 22 Installing Oracle Database XE on Debian, Ubuntu, and Kubuntu ................................ 23 Installing Oracle Database XE on Windows ................................................................. 24 Testing the Oracle Database XE Installation................................................................. 26 Configuring Oracle Database XE .................................................................................. 28 Setting the Oracle Database XE Environment Variables on Linux ........................... 28 Enabling Database Startup and Shutdown from Menus on Linux ............................. 28 Starting and Stopping the Listener and Database....................................................... 28 Enabling Remote Client Connection.......................................................................... 32 Chapter 4 ................................................................................................................................33

...................................................................................................................... 61 Editing.. 33 Logging In To Oracle Application Express ............................................... 81 Installing PHP 4 on Windows ...................................................... 85 Installing PDO on Linux ..............89 Zend Core for Oracle 2....................... 76 Chapter 6 ................................................... 75 Starting and Stopping Apache HTTP Server ................................. 82 Installing OCI8 With Oracle Instant Client ........................................................................................................................................................................................................................................................................................33 Oracle Application Express ................................................................................................................................................................................................................................................................................................................................ Compiling and Running PL/SQL ..... 56 Creating a Database Connection ......................................................................................................................................... 65 Running Reports.......................................................................................................................................................................................................75 Installing Apache HTTP Server on Linux ............. 56 Editing Data......................... 87 Chapter 7 ..........................................................................................................................................................................................................................................................................0 ....................................................................................... 80 Installing OCI8 with PHP 4............................................................................................................. 36 Working with SQL Scripts.......................................... 89 ................. 79 Installing OCI8 on Linux ............................................... 33 Unlocking the HR User ............................................................................................................... 76 Starting and Stopping Apache HTTP Server .......89 Installing Zend Core for Oracle ................................................................................................................................................................................................................. 35 Creating Database Objects ...........................................Using Oracle Database 10g ............. 45 Creating a Database User ........................... 47 Monitoring Database Sessions ............................................................................................................................................................................................................................................. 81 Installing PHP 4 on Linux............................................................... 52 Oracle SQL Developer ............................ 79 Installing OCI8 on Windows...........................75 Installing Apache HTTP Server .................................... 68 Creating Reports.............................................. 58 Creating a Table ........................................................................................................... 83 Installing OCI8 with Instant Client on Linux ........................................ 59 Executing a SQL Query ................................................................................................. 70 Chapter 5 .......................... 75 Installing Apache HTTP Server on Windows .................................................................................................. 50 Database Backup and Recovery...............................................................................................................................................................................79 Installing PHP .............. 42 Creating a PL/SQL Procedure................................................................................................ 85 Installing PDO ................................................................................................................................................................ 83 Installing OCI8 with Instant Client on Windows.............................79 Installing OCI8 with PHP 5............................................................................... 86 Installing PDO on Windows ............

.................................................................... 110 Connection Management in Scalable Systems.......................................................................................................113 SQL Statement Execution Steps........................................................................................................................................................................... 93 Chapter 8 ................................................................. 122 ......................................... 98 Full Database Connection String..............................97 Connecting to Oracle Using OCI8......................................................................................................... 114 Fetch Functions......... 105 Connection Decisions.................................................................................................................................................. 90 Testing the Zend Core for Oracle Installation on Linux ..................................................................................................................................................................................................................................... Create and Drop................................................... 111 Chapter 9 ..................................... 115 Insert.............................................................. 103 Connection Privilege Level....................................97 Oracle Connection Types ...... 106 Tuning Persistent Connections................................................................................................................................. 99 Database Alias................ 107 Tuning Oracle Net........... 98 Easy Connect String ............................................................................................ Delete............................................................................................................. 93 Configuring Zend Core for Oracle ................... 120 Tuning SQL Statements in PHP Applications......................... 92 Testing the Zend Core for Oracle Installation on Windows ......................................................................... 109 Other Oracle Net Optimizations................................................................... 117 Transactions............................................................................................ 97 Persistent Connections .................................................................................................................................................. 97 Oracle Database Name Connection Strings.............................................................................................................................................................. 110 Tracing Oracle Net ....................................... 91 Installing Zend Core for Oracle on Windows ..................................113 Executing SQL Statements With OCI8 ............................................................................ 119 The Transactional Behavior of Connections..... 103 Tuning Oracle Connections in PHP...........................Installing Zend Core for Oracle......................................... 100 Closing Oracle Connections ......................................................................... 113 Query Example.................................................... Update..................... 101 Connection Cleanliness with Persistent Connections............... 89 Installing Zend Core for Oracle on Linux.................................................... 113 Oracle Datatypes ............................ 117 Autonomous Transactions....................................................................................................................... 99 Oracle Environment Variables for Connections............................................................................................................................................................................................................................................................................................................ 119 Handling OCI8 Errors ................... 97 Multiple Unique Connections .... 97 Standard Connections............................................................................................................................................................ 102 Optional Connection Parameters ........................................................................................................................................... 103 Connection Character Set......................................................................................................................................................

........................................... 124 Default Statement Cache Size ...................................... 137 Array Binding and PL/SQL Bulk Processing .................................................................................. 157 Chapter 13 ........................ 129 Regular Expressions in SQL ............................................................................................... 131 Blocks............... 136 Oracle Collections in PHP ...................................................... 132 Stored or Standalone Procedures and Functions ..................................................... 144 Chapter 11 .. 128 Exploring SQL...........131 Using PL/SQL with OCI8 ............................................................................................................................................................. 141 Using REF CURSORS for Result Sets............................................................................................................................159 Globalization ................................................ 153 Fetching Rows as Fully Formed XML .......................153 Using XML with Oracle and PHP............................................ 155 XQuery XML Query Language.............................................................................................................................................. 156 Accessing Data from Oracle over HTTP .................................................................................................................................................. 134 PL/SQL Errors in PHP ...................................................................................................................... 133 Creating PL/SQL Procedures in PHP ............................... 135 End of Line Terminators in PL/SQL with Windows PHP .................................................................................................................... 132 Packages ....................................................Using Bind Variables ....................................................................................................................................................................................................................... 133 Triggers ................................................................................ 132 Anonymous Blocks .................................131 PL/SQL Overview ................................................................... 148 Working with BFILEs .....................159 Establishing the Environment Between Oracle and PHP ....................................................................................... 147 Other LOB Methods....................................................147 Working with LOBs ...................................................... 143 Getting Output with DBMS_OUTPUT .............................................................................................. 125 Auto-Increment Columns ......................................................................................................................................................................... 129 Analytic Functions in SQL..................................................................................................................................... 139 Using PL/SQL Types in PHP.............................................................................................. Procedures......................................................... 129 Chapter 10 ..................................................................................................................................... 135 PL/SQL Success With Information Warnings ........................................................................153 Fetching Relational Rows as XML ........................................... 125 Limiting Rows and Creating Paged Datasets ...............................147 Using Large Objects in OCI8 ........................................................................................................................................................ 149 Chapter 12 ....................................... Packages and Triggers ...................................... 122 Default Prefetch Size.................................................................................................................................................................................................................................................. 159 ....................................................................... 133 Calling PL/SQL Procedures and Functions................................................................................................. 154 Using the SimpleXML Extension in PHP...................................................................

............................................................................................................................................................................................................... 164 Presenting Data Using Conventions Expected by the User......................................................169 Tracing OCI8 Internals.....................................................186 General Information and Forums . 171 Tests that Fail.......... 186 ........................................................................... 164 Oracle Date Formats....................................... 175 Chapter 16 .............................................................................................................................................................................................................................................................................................................................................................. 163 Specifying the Encoding in the HTML Page Header................... 168 Chapter 14 .................................................................................................................................................................................... 169 Chapter 15 .................................................. 186 PHP and Oracle Books ............................................................... 186 PHP .................................................................................................................................................................................................171 Testing PHP and the OCI8 Extension................................................. 164 Strings in PHP .........................................................169 Enabling OCI8 Debugging output ................................................... 186 Documentation...........Manipulating Strings ...................................................... 174 Running a Single Test...................................................................... 161 Developing Locale Awareness .......... 167 Oracle Error Messages ................................181 The Obsolete Oracle Extension ................................................................................................................................................................................................ 186 Source and Binaries ................. 160 Determining the Locale of the User ............... 162 Specifying the Encoding in the HTTP Header............................................................. 172 Creating a Test....................................................................................... 163 Specifying the Page Encoding in PHP ................................ 186 Articles and Other References ................................................................................................................................................................................................................................................................................................................................................................................................................................177 Chapter 17 .......................................................................................................................................................................177 OCI8 Function Names in PHP 4 and PHP 5 ........................................................................... 164 Static Files ................................................................................................................................................................................................................................ 181 Glossary ........................................................... 164 Data from the Database ................. 163 Organizing the Content of HTML Pages for Translation.................................................................................................................................................................................................. 174 Configuring the Database For Testing.............................................. 165 Oracle Number Formats ................... 166 Oracle Linguistic Sorts.............................................................................................................................................................................. 161 Encoding HTML Pages .......................... 173 OCI8 Test Helper Scripts ..............................................................................................................................................181 Oracle and OCI8 Comparison .............171 Running OCI8 Tests .............................................................185 Resources ............................................................................................................... 162 Specifying the Page Encoding for HTML Pages ..........

........................................... 186 ................................................................Utilities ..............

It is assumed that you already have basic PHP and SQL knowledge and want best practices in using PHP against an Oracle database. Oracle’s documentation is freely available online. which walks through building a PHP application against an Oracle database. It is the leading database and is available on many platforms. This book is not a complete PHP or Oracle guide. The book contains much new material on PHP’s Oracle OCI8 and PDO_OCI extensions. We gratefully acknowledge all the Oracle staff that contributed to this book. It covers installation of both Oracle and PHP. URLs to the online resources and most useful books are listed in the Resources chapter. Introduction to Oracle The Oracle Database is well known for its scalability. There are many great books on Oracle.CHAPTER 1 Introduction This book shows how to use the PHP scripting language with the Oracle database. The chapter on globalization is derived from the Oracle Database Express Edition 2 Day Plus PHP Developer Guide. For newcomers we suggest reading the Oracle Database Express Edition 2 Day Plus PHP Developer Guide. against all editions of the Oracle database as well. reliability and features. this book covers PHP and Oracle together in detail and shows how to make them work well. You may already be using another database and have a requirement or a preference to move to Oracle. without change. Extensive PHP documentation and resources are also online and in books. It also incorporates several updated installation guides previously published on the Oracle Technology Network web site. You may be starting out with PHP database development. However. but everything covered in this book also applies to the other editions of the Oracle database. Sue Harper contributed the chapter on SQL Developer. The installation and database discussion in this book highlights the Oracle Database 10g Express Edition. The PHP you write against Oracle Database 10g Express Edition can be run. This book aims to remove any confusion. including Oracle’s own extensive set of documentation you can read for more in-depth information on the architecture and commands to use with Oracle. Who Should Read This Book? This book is aimed at PHP developers who are developing applications against an Oracle database. Since the first release of the Underground PHP and Oracle Manual there have been several commercially available books on PHP and Oracle published. 9 . You may be unsure how to install PHP and Oracle. They are worthwhile additions to your library. and shows how to use them together efficiently. for the first time.

a shared memory region called the system global area (SGA) is allocated and the Oracle background processes are started. Tablespaces Tablespaces are the logical units of data storage made up of one or more datafiles. Each database consists of one or more data files. Databases and Instances An Oracle database stores and retrieves data. Tablespaces are often created for individual applications because tablespaces can be conveniently managed. Instead of using a CREATE DATABASE command for new applications. A database is made up of default and DBA-created tablespaces. to connect to the HR schema. typically a single Oracle database contains multiple schemas. For example. Check the Glossary for more descriptions. The combination of the background processes and SGA is called an Oracle instance. Instead threads run within the Oracle image. Users are assigned a default tablespace that holds all the data the users creates. use the CREATE USER command to create a new schema in the database. The following overview of the main Oracle terms might help you to understand the Oracle terminology. An Oracle database server consists of an Oracle database and an Oracle instance. you would use the username hr in PHP’s connection string. On some operating systems. A schema is owned by a database user and has the same name as that user. Many people use the words schema and user interchangeably. there are no separate background processes. Once you have installed PHP and want to write scripts that interact with Oracle. In Oracle Database Express Edition (known as “Oracle XE”) there is a wizard to create new users in the Application Express management console. like Windows. Every time a server is started. you need to connect as the owner of the schema that contains the objects you want to interact with. Schemas and Users A schema is a collection of database objects such as tables and indexes.Introduction There are some subtle differences between the terminology used when describing an Oracle database and a database from other software vendors. Some of the most common schema objects are: * * * Tables Indexes Views Although you may have more than one database per machine. 10 . Multiple applications can use the same database without any conflict by using different schemas.

The language is dynamically typed and easy to use. It runs on many platforms. The HTML output from the above script would therefore be: <p>Hello</p><p>World</p> The PHP command line interface (CLI) can also be used to run PHP scripts from an operating system shell window. PHP comes with many extensions offering all kinds of functionality such as database access. PHP 5 introduced strong object orientated capabilities. It powers over twenty million web sites on the Internet and has a huge user community behind it. making it corporation-friendly. interpreted scripting language commonly used for web applications.Introduction to PHP Introduction to PHP PHP is a hugely popular. When the PHP parser processes a file. PHP is perfect for rapidly developing applications both big and small.0 applications. it executes the PHP code and outputs any results. and is great for creating Web 2. PHP is open source and free. and has a BSD-style license. PHP code is commonly embedded in HTML: <?php echo "<p>Hello</p>". 11 . The HTML sections are echoed to the web browser verbatim. ?> <p>World</p> PHP is typically installed as an Apache module. or run by the web server using FastCGI.

.

it is worth knowing the alternative libraries and extensions you can use. 4. For basic database operations your PHP application will work with different database vendors simply by changing the extension driver. OCI8 Extension The OCI8 extension is included in PHP 3.0. If you want to make full use of Oracle features and want high performance use PHP’s main Oracle extension. New development using this extension is not recommended. 4 and 5. It had limited functionality. consider using the PHP Data Object (PDO) extension or ADOdb. which is in the early stage of development. You can also use the ODBC extension. Choosing a PHP Oracle Extension Several PHP extensions provide PHP functions for accessing Oracle databases and there are also database abstraction layers written in PHP which are popular. is no longer in PHP and is not maintained. 13 . and 5. Basic database access in each extension and abstraction library is very similar. The extensions are: * * * Oracle OCI8 PDO They are all included in the PHP source code with PHP’s open source license. Although this book concentrates on the OCI8 extension for PHP.CHAPTER 2 PHP Oracle Extensions There are various ways PHP can connect to Oracle. PHP Oracle Extensions The PHP Oracle extensions can be compiled into the PHP binary. The differences are in their support for advanced features and the programming methodology promoted. Oracle Extension The extension called “Oracle” was included in PHP 3. the OCI8 extension. It is also in PHP 6. If you want database independence. This extension accessed the database using Oracle’s obsolete C code OCI7 API.

"<br>".PHP Oracle Extensions For PHP 5. The 14 . the OCI8 extension function names were standardized. An example script that finds city names from the locations table using OCI8: connectoci8. oci_execute($s). If you are using PHP 4 and cannot upgrade to PHP 5. $s = oci_parse($c. ?> When invoked in a web browser. The refactored extension builds and runs with PHP 4 too. while ($res = oci_fetch_array($s)) { echo $res['CITY'] . 'hrpwd'. PHP 4 functions like OCILogin() became oci_connect().1.php <?php $c = oci_connect('hr'. The query is executed and a web page of results is displayed in the browser: Figure 2. OCIParse() became oci_parse() and so on.1 PHP output in a web browser In PHP 5. Steps for this are shown later in this book. The PHP interfaces are the same as the original OCI8 extension but there are new connection management and performance settings. '//localhost/XE'). you should replace the OCI8 code with the new version to get improved stability and performance optimizations. 'select city from locations'). OCI8 was refactored by Zend and Oracle to increase stability and performance. it connects to Oracle as the demonstration user hr of the Oracle XE database running on the local machine. and released as open source.2. } oci_close($c).

PDO_OCI has no code in common with OCI8. The name “OCI8” is also the name for Oracle’s Call Interface API used by C programs including the PHP OCI8 extension. so PHP 4 scripts do not need to be changed. Each database has its own driver.1 onwards. ADOdb The popular ADOdb library is available from http://adodb. They are written in PHP and when configured for Oracle. The abstraction libraries are: * * * ADOdb PEAR DB PEAR MDB2 You can freely download and use the PHP code for these libraries. There is an optional C extension plug-in if you need extra performance. PDO Extension PHP Data Objects (PDO) is a data abstraction layer that provides PHP functions for accessing databases using a common core of database independent methods. $s = $dbh->prepare("select city from locations"). An example script that finds city names from the locations table using ADOdb: 15 . } $dbh = null. // release the connection ?> The output is the same as the previous OCI8 example.PHP Database Abstraction Libraries old names still exist as aliases.sourceforge. they use functionality provided by the OCI8 extension. 'hrpwd'). All unqualified references to OCI8 in this book refer to the PHP extension. PDO_OCI provides the Oracle functionality for PDO. while ($r = $s->fetch(PDO::FETCH_ASSOC)) { echo $r['CITY'] . which may also support vendor specific functionality. 'hr'. The PDO extension is included in PHP 5. $s->execute().net. An example script that finds city names from the locations table using PDO_OCI: connectpdo.php <?php $dbh = new PDO('oci:dbname=//localhost/XE'. "<br>". A table showing old and new names appears later in this book. PHP Database Abstraction Libraries There are three main database abstraction libraries for PHP.

and the PHP Extension Community Library (PECL) site. PEAR MDB2 The PEAR MDB2 package is available from http://pear. $db = ADONewConnection("oci8").net/package/DB. It is available from http://pear.2. ?> PEAR DB The PHP Extension and Application Repository (PEAR) contains many useful packages that extend PHP’s functionality. OCI8 was available in PHP releases prior to PHP 5.php <?php require("MDB2.php").net/package/MDB2. There are three main distribution channels for PHP: the PHP releases.php <?php require_once("adodb. $res = $mdb2->query("select city from locations"). It is a library aiming to combine the best of PEAR DB and the PHP Metabase abstraction packages. PEAR DB is a package for database abstraction.1. $db->Connect("//localhost/XE". } $conn->Close(). "<br>". An example script that finds city names from the locations table using MDB2: connectpear.php"). $mdb2 = MDB2::connect('oci8://hr:hrpwd@//localhost/XE').PHP Oracle Extensions connectadodb. which contains PHP extensions as individual downloads.php. "</br>". while ($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)) { echo $row['city'] .1 shows the locations and files to download for Linux and Windows. ?> Getting the OCI8 and PDO_OCI Extensions The OCI8 and PDO_OCI extensions are included in various PHP bundles. PEAR DB has been superceded by PEAR MDB2. } $mdb2->disconnect(). Table 2.php. "hr". $s = $db->Execute("select city from locations"). but it is strongly recommended to upgrade the old OCI8 extension to the refactored version in PECL.inc. Zend Core for Oracle. "hrpwd"). 16 . while ($r = $s->FetchRow()) { echo $r['CITY'] .

10 Yes Code onwards PECL Source PHP 5.oracle.tar.1 OCI8 andPDO_OCI Availability Matrix Bundle PHP Release Source Code PHP Release Windows Binaries PHP Version Contains OCI8 Contains PDO_OCI Location and Current Release PHP 5.dll PHP 5.0. These provide underlying connectivity to the database.php/php _oci8. The extensions are available in several forms because of the differing needs of the community.zip Other platforms are also available - http://pecl.0 for Oracle used PHP 5.0 PECL Source PHP 4.0.dll php_oci8.2.tgz - Yes http://pecl.2. Many PHP users install the full PHP source or binaries and do their own custom configuration.php. 17 .php.3 onwards - Yes http://pecl4win.2 onwards PHP 5.gz ZendCoreforOracle-v.2.1.gz Compiles and runs on many platforms PHP 5.net/ext.0.php.com/technology/t ech/php/zendcore/ No ZendCoreForOracle-v2.net/package/oci8 oci8-1.2.OCI8 and PDO_OCI Installation Options Table 2.0. there are several configuration options you could use when installing PHP.1-Linuxx86.2-Win32.2.php.10 Yes onwards - http://pecl4win.tgz PHP 4.tar.dll php_pdo_oci. For Oracle database access the PHP binary is linked with Oracle client libraries.3. which may be local or remote on your network.2.net/package/PDO_O CI PDO_OCI-1. and what you want to achieve.3.php/php _pdo_oci.php.3.net/ext.net/downloads php-5.1.php.1-Windowsx86.net/downloads Yes Yes php-5.dll OCI8 and PDO_OCI Installation Options Depending what software you have already installed.3 Code onwards PECL Windows Binaries PECL Windows Binaries http://www.0.1 or 5. If they need a specific bug fix they use PECL or PHP’s latest development source code to get it.2 onwards http://www.2 Yes Yes http://www.zip Earlier Zend Core for versions of Zend Core Yes Oracle 2.

dll PHP Version PHP 5. 9i. 10g 18 .2 Refactored OCI8 and Oracle Compatibility Matrix Bundle containing OCI8 PHP Release Source Code PHP Release Windows Binaries Zend Core for Oracle 2.3 shows the compatibility of the PDO_OCI extension with PHP and Oracle. 10g Table 2. 9i. you can compile your own PHP and link with Oracle’s libraries used by the database. install Zend Core for Oracle. or this is your first time with PHP and Oracle. On Windows you can use the Windows PHP binaries with Oracle Instant Client.PHP Oracle Extensions Figure 2.2 PHP 4. 10g 8i.3. 9i.3. 10g 8i. 9i. 10g 10g Oracle Database Version 8i. On Windows you can use PHP’s pre-supplied binaries. PHP 4. Table 2. 9i. 10g 8i. 9i. Table 2. 10g 8i. If your database is installed on another machine on your network. you can install the small Oracle Instant Client and compile PHP with that. 9i. 9i.2 onwards PHP 5.2 onwards PHP 5.2 shows the compatibility of the refactored OCI8 extension with PHP and Oracle. If you do not want to compile PHP.2 PHP links with Oracle client libraries If your database is installed on the same machine as the web server and PHP.10 onwards.1 onwards Oracle Client Version 8i. 9i. 10g 10g Inbuilt Oracle 10g client 8i. 10g Oracle Database Version 8i.0 PECL OCI8 Source Code PECL Windows php_oci8.1.1.3 PDO_OCI and Oracle Compatibility Matrix Bundle containing PDO_OCI PHP Version PHP Release Source Code PHP 5.10 onwards Oracle Client Version 8i. Table 2.

10g also available. connecting to Oracle 7 databases is possible. 10g also included.dll library is 8i.net/. Zend Core for Oracle Zend Core for Oracle is the result of a joint project between Oracle and Zend.1 onwards PHP 5. On Windows the php_pdo_oci8.dll library is 8i.dll library may be used with Oracle 8i or 9i clients.php. The code in CVS is used to create the various PHP distributions: * Two-hourly snap-shots are created containing a complete set of all PHP’s source in CVS at the time the snapshot was created. It supports Oracle 8i and 9i clients 8i. PECL Windows binaries of the OCI8 and PDO_OCI DLLs for various versions of PHP are built from the latest CVS source at frequent intervals 19 * * * . or by downloading the Windows binaries. It has a simple installer. A support package that includes support for the PHP language is available from Zend.3 onwards PHP 5. 10g If OCI8 or PDO_OCI are linked with Oracle 8i or 9i client libraries. The snapshots may be relatively unstable because the code is in flux. 9i.dll PHP 5. 9i.net/. The code is open source and anyone can access the code in CVS or seek approval to contribute too.php. After several months of development the PHP release manager will release a new stable version of PHP. Zend Core for Oracle can connect to local and remote Oracle databases. PECL source code snapshots are taken from CVS at infrequent intervals.Zend Core for Oracle 10g PHP Release Windows Binaries PECL PDO_OCI Source Code PECL Windows php_pdo_oci. It supports Oracle 8i and 9i clients 8i. OCI8 and PDO_OCI Development Cycle PHP’s source code is under continual development in a CVS source code control system viewable at http://cvs.0. Not all functionality may be available unless the Oracle client and server are both Oracle 10g.0. 9i. Zend Core for Oracle is available for many platforms and has a convenient browser-based management console for configuration and getting updates. It is a pre-built release of PHP that comes enabled with the OCI8 extension. comes with Oracle Instant Client 10g and includes an optional Apache web server. 10g 10g A php_pdo_oci8. You can update your PHP environment by getting this source code and recompiling. Bugs are rapidly fixed and the code changes made available via CVS. The snapshots are located at http://snaps. It uses the most current CVS code at the time of release.3 onwards A php_pdo_oci8. Zend Core for Oracle is free to download and use. 9i.

the PECL source snapshots. the PECL Windows binary builds. 20 . Various operating systems bundle the version of PHP current at the time the OS is released. The schedules of PHP releases. often with various critical patches applied.PHP Oracle Extensions * * Zend Core for Oracle also takes snapshots of PHP from CVS. and Zend Core for Oracle are not synchronized.

Oracle Database 10g Express Edition (Oracle Database XE). The installation instructions are given for Linux. The Oracle database edition names are: * * * * Express Edition Standard Edition One Standard Edition Enterprise Edition All the editions are built using the same code base. licensing options and costs. There’s a comprehensive list of the features for each Oracle edition at http://www. and.oracle. Oracle Database XE is available on the Oracle Technology Network (http://otn. but different features are implemented in each edition. That is.CHAPTER 3 Installing Oracle Database 10g Express Edition This chapter contains an overview of. Just change the Oracle software and you’re away. whereas the Express Edition has a limited feature set. Free to distribute with your applications. Yes. Ubuntu and Kubuntu. free. each with different features. Windows. as needed. Oracle Database Editions There are a number of editions of the Oracle database. Enterprise Edition has all the bells and whistles. Free to download. small footprint database.com/xe) for the following operating systems: * * * Windows 2000 Service Pack 4 or later Windows Server 2003 Windows XP Professional Service Pack 1 or later 21 . Free to develop against. and installation instructions for. they all have the same source code. Oracle Database XE is a good choice for development of PHP applications that require a free.oracle. free! Oracle Database XE Oracle Database XE is available on 32-bit Windows and Linux platforms. Debian. but still has all the reliability and performance of the Enterprise Edition. You could do this without changing any of your underlying table structure or code. This book discusses working with Oracle Database XE. move up to another edition as your scalability and support requirements change. This is the free edition. that is free. You could start off with the Express Edition.com/database/product_editions.html.

If you need a fully supported version for the Oracle database.1 The following libraries are required for the Linux-based operating systems: * * glibc release 2.3.oracle.1-1. even if multiple CPUs exist 1GB RAM used.0. Install the RPM rpm -ivh oracle-xe-univ-10.oracle.Installing Oracle Database 10g Express Edition * * * * * Red Hat Enterprise Linux RHEL3 and RHEL4 Suse SLES-9 Fedora Core 4 Red Flag DC Server 5.0. Support for Oracle Database XE is through an Oracle Technology Network (http://otn. Oracle Application Express. You cannot buy support from Oracle for Oracle Database XE. Installing Oracle Database XE on Linux If you do not have a version of libaio over release 0.96 There are some limitations with Oracle Database XE: * * * * 4GB of data Single database instance Single CPU used.com/) discussion forum. but when you go production.0/Haansoft Linux 2006 Server (Asianux 2. you’ll need to pay Oracle for the license costs.2 libaio release 0. 2.com/xe. 4.rpm Oracle Database XE installs.0 Inside) Debian 3.96. Download the Oracle Database XE from http://otn. You can download all the editions of the Oracle Database from the Oracle Technology Network. Log in or su as root su Password: 3. even if more RAM is installed Oracle Database XE has a browser-based management interface. you need to install this library before you can install Oracle Database XE.3. and use these for application development and testing.2.0/MIRACLE LINUX V4.i386. which is populated by peers and product experts.3. To install Oracle Database XE: 1. you should consider Oracle Standard Edition or Enterprise Edition. Configure the database 22 .

The database and database listener are configured and started. but not on the server version. and Kubuntu There is an Advanced Package Tool (apt-get) repository available on the Oracle Open Source web site for Oracle Database XE. 3.0. If you use the Oracle Unbreakable Linux Network and have the Oracle Software channel enabled. Ubuntu and Kubuntu.com/xe. add the following to the file /etc/apt/sources. follow the configuration step 4 onwards. Install Oracle Database XE apt-get update apt-get install oracle-xe If you have not added the apt-get repository. To include this repository. you can install Oracle XE with: up2date oracle-xe After this download completes.com/xe).oracle. and will be installed from the repository if you do not already have them installed. Ubuntu. To install Oracle Database XE on Debian. follow these steps: 1. Log in or su as root su Password: 2. and run the following command to begin the install: dpkg -i downloads/oracle-xe-universal_10. Ubuntu. and 5. 6. If you download Oracle Database XE from the Oracle Technology Network (http://otn. Enter and confirm the password for the default users.deb Oracle Database XE installs. you need to make sure that you have already installed the libaio and bc packages. Installing Oracle Database XE on Debian. Configure the database /etc/init.oracle.oracle. 7.list: deb http://oss.d/oracle-xe configure 23 . Enter Y or N for whether you want the database to start automatically on reboot.1-1.d/oracle-xe configure Installing Oracle Database XE on Debian.Kubuntu /etc/init.2. the bc package is installed by default on the desktop version. you can download Oracle Database XE from http://otn. and 1521 for the Database Listener.0_i386.com/debian unstable main non-free libaio and bc are included in the repository. If you are using Ubuntu or Kubuntu. Accept the default ports of 8080 for Application Express.

In the Choose Destination Location window. and 1521 for the Database Listener.Install Wizard welcome window. Installing Oracle Database XE on Windows To install Oracle Database XE on Windows. The database and database listener are configured and started. In the License Agreement window. Log on to Windows as a user with Administrative privileges. 4. In the Oracle Database XE . either accept the default or click Browse to select a different installation directory.exe file. Click Next. Enter and confirm the password for the default users. click Next. delete it using the Control Panel > System dialog. follow these steps: 1. 5. Accept the default ports of 8080 for Application Express. 2. 2. Download the Oracle Database XE from http://otn. 3. Double click on the OracleXEUniv. Enter Y or N for whether you want the database to start automatically on reboot. select I accept and click Next.oracle.Installing Oracle Database 10g Express Edition 4. If the ORACLE_HOME environment variable has been set. 24 . Figure 3-1 Oracle Database XE install welcome dialog.com/xe. 5. 6. 6.

7. Click Next. In the Specify Database Passwords window. If these ports are already being used. you are prompted to enter another port number. 8. Figure 3-3 Oracle Database XE database password dialog 25 . Oracle Database XE requires a number of ports and selects a number of default ports. enter and confirm the password to use for the sys and system database accounts.Installing Oracle Database XE on Windows Figure 3-2 Oracle Database XE install location dialog.

Installing Oracle Database 10g Express Edition 9. In the Summary window. Figure 3-4 Oracle Database 10g install summary dialog. open a web browser and enter: http://127. Testing the Oracle Database XE Installation To test the installation of Oracle Database XE: 1. 26 . If you do not already have the Database homepage displayed in your web browser. Click Finish.0. 10. review the installation settings. click Launch the Database homepage to display the Database Home Page. In the InstallShield Wizard Complete window.1:8080/apex The Database homepage is displayed. Click Install.0.

Figure 3-6 Oracle Database XE home page 27 .Testing the Oracle Database XE Installation Figure 3-5 Database home page login screen 2. You should now be logged into the Oracle Database homepage. Log in as user system with the password you entered during the installation.

csh Enabling Database Startup and Shutdown from Menus on Linux You may not be able to start and stop the database using the menu on Linux platforms. After installing Oracle Database XE. The more commonly used settings are discussed here. If you need to manually start or stop the database listener. To enable this functionality. the listener and database should already be running. add the user name to the dba group using the System Settings. and you may have requested during the installation that the listener and database should be started when the operating system starts up. This is because your user is not a member of the operating system dba group. the options and commands for this are listed below.login or . This applies to all the methods of starting and stopping the database. Bash or Korn shell. The script is located in: /usr/lib/oracle/xe/app/oracle/product/10. Run the appropriate script for your shell to set your Oracle XE environment variables. To add the script to your Bourne.bash_profile or .sh for Bourne. add the following lines to your .0/server source $OH/bin/oracle_env.2. you must log in as a user who is a member of the operating system dba user group.cshrc file: setenv OH /usr/lib/oracle/xe/app/oracle/product/10. there are a number of environment variables that should be set when you start up the database. and oracle_env. The database is another process that runs in memory. Bash and Korn shells. You can also add this script to your login profile to have the environment variables set up automatically when you log in.2. To start the database. Starting and Stopping the Listener and Database The database listener is an Oracle Net program that listens for and responds to requests to the database. The database listener must be running to handle these requests.bashrc file: export OH=/usr/lib/oracle/xe/app/oracle/product/10.0/server/bin and named oracle_env.Installing Oracle Database 10g Express Edition Configuring Oracle Database XE There are a number of environment settings and configuration options you can set for Oracle Database XE. add the following lines to your . A script is provided to enable you to set the Oracle environment variables when you log in.sh To add the script to your login profile for C and tcsh shells. $OH/bin/oracle_env. and needs to be started before Oracle Net can handle connection requests to it.2.csh for C and tcsh shells.0/server . 28 . Setting the Oracle Database XE Environment Variables on Linux On Linux platforms.

Starting and Stopping the Listener and Database on Windows To start the listener and database on Windows platforms. A Window is displayed showing the status of the listener and database startup process. To stop the listener and database from the Desktop Services dialog. select Applications > System Settings > Server Settings > Services. To start the listener and database on Linux platforms using the command line. To shut down the database on Linux platforms using the desktop. do one of the following: * * On Linux with Gnome: Select Applications > Oracle Database 10g Express Edition > Start Database. Select oracle-xe from the list of services and select Stop. run the following command in your shell: /etc/init. To start the listener and database from the Desktop Services dialog. On Linux with KDE: Select K Menu > Oracle Database 10g Express Edition > Stop Database.Configuring Oracle Database XE Starting and Stopping the Listener and Database on Linux To start up the listener and database on Linux platforms using the desktop.d/oracle-xe stop You can also use the Services dialog from the Desktop to start and stop the listener and database.d/oracle-xe start To stop the listener and database on Linux platforms using the command line. do one of the following: * * On Linux with Gnome: Select Applications > Oracle Database 10g Express Edition > Stop Database. select Start > Oracle Database 10g Express Edition > Start Database. Select oracle-xe from the list of services and select Start. run the following command in your shell: /etc/init. 29 . select Applications > System Settings > Server Settings > Services. On Linux with KDE: Select K Menu > Oracle Database 10g Express Edition > Start Database.

open the Services dialog using Start > Settings > Control Panel > Administrative Tools > Services. You can also start and stop the listener separately on Windows platforms using the Services dialog. select Start > Oracle Database 10g Express Edition > Stop Database. Figure 3. To start the listener on Windows platforms. The listener and database are now started. and select Start.7 Start Database Dialog Type exit and press Enter to close the Window. To stop the listener and database on Windows platforms.Installing Oracle Database 10g Express Edition Figure 3. The listener and database are now stopped.8 Stop Database Dialog Type exit and press Enter to close the Window. and select the OracleXETNSListener service. Right click on the Listener service. 30 . A Window is displayed showing the status of the listener and database shutdown process.

If you want to shut down the listener manually. To shut down the database. Starting and Stopping the Listener and Database Using SQL*Plus You can also use the command line shell and SQL*Plus command line to start and stop the listener and database.Configuring Oracle Database XE To stop the listener on Windows platforms. To start up the listener. Make sure that you have your operating system environment set up correctly as discussed in an earlier section of this chapter. To start up a database using SQL*Plus. enter the following commands to connect to the database and start it up: SQL>connect / as sysdba SQL>startup The database is started. this is a useful option for you. This is the sys user in default installations. and select the OracleXETNSListener service. To stop the database using the Services dialog on Windows platforms. open the Services dialog using Start > Settings > Control Panel > Administrative Tools > Services. and issue the SHUTDOWN IMMEDIATE command. 31 . Log into SQL*Plus as before and issue the following command: SQL>connect / as sysdba SQL>shutdown immediate The SQL*Plus User’s Guide and Reference gives you the full syntax for starting up and shutting down the database if you need more help. open the Services dialog using Start > Settings > Control Panel > Administrative Tools > Services. You can use SQL*Plus on all operating systems. You can also start and stop the database separately on Windows platforms using the Services dialog. Right click on the database service. and select the OracleServiceXE service. To use SQL*Plus to start and stop the database. you need to log in as sysdba. Right click on the database service. open a command line window and run the following command: lsnrctl start Oracle Net starts the listener and it is ready to take database requests. so if you want one single set of commands to use for all your operating systems. and select Stop. At the SQL*Plus command line prompt. You can also start SQL*Plus from the Applications > Oracle Database 10g Express Edition > Run SQL Command Line on Linux. you also need to start the database using SQL*Plus. or you can use operating system authentication if you are on the local machine. or Start > Programs > Oracle Database 10g Express Edition > Run SQL Command Line on Windows. and select the OracleServiceXE service. To start the database using the Services dialog on Windows platforms. you use the similar command from the operating system command prompt: lsnrctl stop After starting the listener. enter the following at the command line prompt: sqlplus /nolog SQL*Plus command line starts. you must log in as a user with the sysdba role. and select Start. and select Stop. open the Services dialog using Start > Settings > Control Panel > Administrative Tools > Services. Right click on the Listener service.

5. you should be aware that HTTPS cannot be used (only HTTP). log into SQL*Plus as system. Click Apply Changes. Select Manage HTTP Access from the Tasks option. You can also use SQL*Plus command line to enable access from remote clients. and are not encrypted. To use SQL*Plus command line to change this setting. Open a web browser and load the Oracle Database XE home page: http://127. 32 . Select Administration from the home page. not remotely.Installing Oracle Database 10g Express Edition Enabling Remote Client Connection The Oracle Database XE home page is only available from the local machine. 3.SETLISTENERLOCALACCESS(FALSE). follow these steps: 1. To enable connection to the Oracle Database XE home page from remote machines. so your login credentials are sent in clear text.0. and run the following command: EXEC DBMS_XDB. so if you don’t need to set this up.1:8080/apex 2.0. Check the Available from local server and remote clients radio button. it is more secure to leave it as the default setup. If you want to enable access from a remote client. Log in as the system user. 4.

Oracle Application Express enables you to perform database administration. Oracle Application Express also contains a database development tool.oracle.0.0. Logging In To Oracle Application Express To start and log in to Oracle Application Express: 1.1:8080/apex The Oracle Application Express login screen is displayed. and Oracle SQL Developer. 33 . It is also available for download from Oracle’s Technology Network (http://otn. and we will show you both the GUI and command line tools in this book.CHAPTER 4 Using Oracle Database 10g This chapter contains an overview of Oracle Application Express. Command line utilities are also available. but this book does not cover that part of the product. two applications that you can use to perform database development and administration with Oracle Database 10g Express Edition. Open a web browser and enter the URL: http://127. Oracle Application Express Oracle Application Express is a browser-based interface to the Oracle Express Edition database. monitoring and maintenance.com) as a standalone product. just the database management and scripting components.

Log in as system. There is no default system password set by the Oracle Installer.Using Oracle Database 10g Figure 4-1 Oracle Application Express login screen. 2. The password you enter here is the password you entered when you installed Oracle. Figure 4-2 Oracle Application Express Interface 34 .

Select Administration > Database Users > Manage Users. To unlock the hr user: 1. Log in to Oracle Application Express as shown in the previous section. 2. Select the HR icon. 35 .Oracle Application Express Unlocking the HR User Many of the examples in this book. You may want to unlock this user now so that many of the examples in this book work correctly. and other Oracle books use the hr user. which is automatically installed and configured during an Oracle database installation. Figure 4-3 Manage Database Users menu 3.

To unlock the hr user. Change Account Status to Unlocked. and click the Alter User button. enter a password in the Password and Confirm Password fields.Using Oracle Database 10g Figure 4-4 Manage Database Users screen 4. Figure 4-5 User screen The hr account is now unlocked. Creating Database Objects The Oracle Application Express Object Browser can be used to create or edit the following objects: * Table 36 .

On the Database home page. 37 . To create a new table: 1.Oracle Application Express * * * * * * * * * * * View Index Sequence Collection Type Package Procedure Function Trigger Database Link Materialized View Synonym Oracle Application Express uses wizards to guide you through creating these database objects. The following example covers creating a table. click the Object Browser icon. but you will see that the interface is wizard-based and creating and editing different objects can all be performed through the Object Browser. The Object Browser page is displayed.

Using Oracle Database 10g Figure 4-6 Oracle Application Express create object screen 38 .

Oracle Application Express

2. Click Create.
Figure 4-7 Oracle Application Express create table object screen

3. From the list of object types, select Table.

39

Using Oracle Database 10g

Figure 4-8 Oracle Application Express table definition screen

4. Enter a table name in the Table Name field, and details for each column. Click Next. 6. Define the primary key for this table (optional). 7. Add foreign keys (optional). 8. Add a constraint (optional). 9. Click Finish. To view the SQL used to create the table, click SQL Syntax.

40

Oracle Application Express

Figure 4-9 Oracle Application Express confirm create table screen.

The SQL that is generated to create the table is:
CREATE table "MYTABLE" ( "FIRST_NAME" CHAR(100) NOT NULL, "SECOND_NAME" CHAR(100) NOT NULL, "SALARY" NUMBER, "BIRTHDATE" DATE ) /

You could also run this command in SQL*Plus command line to create the table.

41

The table is created and a description of the table is displayed. click the SQL icon. To access Query Builder: 1. 2. Click Create. Click the Query Builder icon. To get a better set of tables to work with in this example. log in as the hr user. Working with SQL Scripts The SQL Console enables you to: * * * Write SQL and PL/SQL Load and save SQL scripts Graphically build SQL The following example guides you through creating a SQL script. On the Database home page. Figure 4-10 Oracle Application Express table created confirmation screen. 42 .Using Oracle Database 10g 10. This example uses the Query Builder to graphically create a SQL script to query data.

43 .Oracle Application Express Figure 4-11 Oracle Application Express SQL options screen.

Using Oracle Database 10g 3. 7. 5. Establish relationships between objects by clicking on the right-hand column of each table (optional). 44 . 4. When you click on the object name. Figure 4-12 Oracle Application Express SQL query builder screen. Select columns from the objects in the Design pane to select which columns to include in the query results. it is displayed in the Design pane. Create query conditions (optional). Select objects from the Object Selection pane. 6. Click Run to execute the query and view the results.

and click Run. / 45 . Creating a PL/SQL Procedure To enter and run PL/SQL code in the SQL Commands page: 1. create or replace package emp_sal as procedure emp_stat. On the Database home page. click the SQL icon to display the SQL page. enter some PL/SQL code. 3. You can save your query using the Save button. Here is some PL/SQL code to try if you aren’t familiar with PL/SQL.Oracle Application Express Figure 4-13 Oracle Application Express SQL query results screen. 2. You need to enter each block separately. and is encapsulated in a PL/SQL package called emp_sal. Click the SQL Commands icon to display the SQL Commands page. On the SQL Commands page. 8. emp_stat. This procedure. averages the salary for departments in the hr schema. end emp_sal.

' ')|| TO_CHAR(EmpStatVar. For EmpStatVar in (select round(avg(e. end emp_sal. Dept_avg number).16. BEGIN DBMS_OUTPUT. END. Click Run.Using Oracle Database 10g Figure 4-14 Oracle Application Express PL/SQL and SQL command screen.b. END LOOP.99')). EmpStatVar EmpStatTyp.999.PUT_LINE('-------------------------').a.PUT_LINE(RPAD(EmpStatVar.d.department_name) LOOP DBMS_OUTPUT. Click Run to execute the PL/SQL. DBMS_OUTPUT.department_name b from departments d. 46 .salary). The PL/SQL code is executed.999.'999.2) a. employees e where d.department_id group by d.PUT_LINE('Department Avg Salary'). Then enter the following code: create or replace package body emp_sal as Procedure emp_stat is TYPE EmpStatTyp is record (Dept_name varchar2(20).department_id=e.

This account is considered an administrator account because it has DBA privileges (SYSDBA).emp_stat. If you want to save the PL/SQL code for future use.Oracle Application Express 4. 5. begin emp_sal. log into Oracle Application Express as the system user. Creating a Database User The Administration console is used to manage database: * * * * Storage Memory Users Activity of sessions and operations The installation process creates an account named system. To perform database administration such as creating new users. end. click Save. You can execute the stored procedure by entering the following PL/SQL code and clicking Run. To create a database user: 47 .

click the Administration icon. Click the Database Users icon. Figure 4-15 Oracle Application Express Administration screen. 48 .Using Oracle Database 10g 1. On the Database home page. Figure 4-16 Oracle Application Express Manage Database Users screen.

Oracle Application Express 2.4 In the Username field. On the Manage Database Users page. enter a username. gives the user the ability to create schema objects in other users' schemas. click Create. Grant all create object system privileges by clicking Check All at the lower right-hand corner of the User Privileges box.2 3. Figure 4-17 Oracle Application Express Create Database User screen. and to create other users. The DBA privilege. The Create Database User page is displayed.3 3. enter a password. In the Password and Confirm Password fields. Enter user information into text fields: 3. The DBA role is by default not selected. 49 . 3.1 3.

You can also use the Oracle Database XE graphical user interface to kill a session—to cause it to be disconnected and its resources to be relinquished. The Manage Database Users page displays a confirmation that the user was created. Click Create. Monitoring Database Sessions You can use the Oracle Database XE graphical user interface to monitor the current database sessions. you can view: * * * All sessions Active sessions only Sessions that match a search string You should be logged in as the system user to perform any database administration. When you view sessions. This enables you to determine the users who are currently logged in to the database and what applications they are running.Using Oracle Database 10g 4. To view the current sessions: 50 . Figure 4-18 Oracle Application Express Manage Database Users screen.

On the Database home page. click Sessions. Figure 4-20 Oracle Application Express Administration Monitor screen.Oracle Application Express 1. Click Monitor. 3. 51 . Figure 4-19 Oracle Application Express Administration screen. click the Administration icon. On the Database Monitor page.

including idle sessions. database backup and recovery is handled by Recovery Manager (RMAN). and. Database User. and click Go. In ARCHIVELOG mode. 6. In Oracle Database XE. These scripts perform a full backup and restore of the entire database. Oracle Database XE implements a backup retention policy that dictates that two complete backups of the database must be retained. OS User. The page displays all sessions. and store backup files in the flash recovery area. (Optional) Narrow down the sessions list by entering search text into the Search field and clicking Go. click a session ID to view the Session Details page for that session. if in ARCHIVELOG mode. A session is shown if any of the following fields contain the search text: SID. Machine. (Optional) In the Status list.Using Oracle Database 10g The Sessions page is displayed and shows the current active sessions. 7. the redo log files. 4. the control file. The Session Details page enables you to kill the session. Figure 4-21 Oracle Application Express Sessions screen. all archived logs required for media recovery from either backup are also retained. the server parameter file (SPFILE). Client Information. Oracle Database XE includes backup and restore scripts that you access using menu on your desktop. select All. and open cursors. Client Identifier. (An example of an idle session is a SQL*Plus command line session that is not currently running a command. Input/Output (I/O). Waits. (Optional) Under the SID column. The database automatically 52 . (Optional) Click any of the hyperlinks above the Search field to view the following information for all sessions: Locks. and Module.) 5. Database Backup and Recovery Backing up and restoring Oracle Database XE is based on protecting the physical files that make up the database: the datafiles. running SQL statements.

If running in ARCHIVELOG mode. the script displays the following output: 53 . Log in to the Oracle Database XE host computer as a user who is a member of the dba user group. Log archiving off (NOARCHIVELOG mode) restores the database to its state at the last backup. and deletes obsolete backups and archived logs at the end of each backup job. Offline backups are backups that run when the database is shut down. select Applications > Oracle Database 10g Express Edition > Backup Database. All committed transactions that took place after the last backup are recovered. Backing Up The Database To back up the database: 1. select Start > Programs > Oracle Database 10g Express Edition > Backup Database. Log archiving on (ARCHIVELOG mode) restores the backed up database files. * On Windows.Oracle Application Express manages backups and archived logs in the flash recovery area. The restore script restores the database differently depending on whether log archiving is on or off. select K Menu > Oracle Database 10g Express Edition > Backup Database. 2. and any uncommitted transactions that were under way when the failure took place are rolled back (using undo data from the restored undo tablespace). Any transactions that took place after the last backup are lost. A console window opens so that you can interact with the backup script. Online backups are backups that can run while the database is running. Do one of the following: * On Linux with Gnome. and then uses the online and archived redo log files to recover the database to the state it was in before the software or media failure occurred. * On Linux with KDE. The backup script performs online backups of databases in ARCHIVELOG mode and offline backups of databases in NOARCHIVELOG mode.

log Restoring the Database To restore a database from a backup: 1. the script displays the following output: Figure 4-23 Oracle Application Express backup successful message 4. Log in to the Oracle Database XE host computer as a user who is a member of the dba user group.Using Oracle Database 10g Figure 4-22 Oracle Application Express backup dialog 3. 54 . If prompted. answer y to confirm the database shutdown and begin the backup. Press any key to close the Backup Database window.log $ORACLE_HOME/oxe_backup_previous. After the backup is complete. Logs containing the output from the backups are stored in the following locations: $ORACLE_HOME/oxe_backup_current.

Do one of the following: * On Linux with Gnome. The script displays the following output: Figure 4-24 Oracle Application Express restore dialog 3. the script displays the following output: Figure 4-25 Oracle Application Express restore successful message 4. Press any key to close the Restore Database window. select Start > Programs > Oracle Database 10g Express Edition > Restore Database. After the restore is complete. * On Windows. select K Menu > Oracle Database 10g Express Edition > Restore Database. * On Linux with KDE.Oracle Application Express 2. Answer y to confirm the database shutdown and begin the restore. 55 . select Applications > Oracle Database 10g Express Edition > Restore Database. A console window opens so that you can interact with the restore script.

and to run a few SQL*Plus commands (like DESCRIBE).0.com/technology/products/database/sql_developer. there are no database connections configured. execute and debug PL/SQL statements. Oracle SQL Developer is a free. documentation. Creating a Database Connection When you start SQL Developer for the first time.1 onwards. extensions. Figure 4-26 Oracle SQL Developer login screen 56 .log. and is available on Linux. SQL Developer can connect to Oracle databases from version 9. There is also a discussion forum for you to ask questions of other users. Windows and Mac OSX.Using Oracle Database 10g A log containing the output from the restore is stored in $ORACLE_HOME/oxe_restore. You can download SQL Developer from the Oracle Technology Network at http://www. SQL Developer includes some prebuilt reports. and you can create and save your own reports. You can use SQL Developer to execute SQL statements.2. thick client graphical tool for database development. and give feedback to the SQL Developer product team. Oracle SQL Developer In addition to Oracle Application Express.oracle. and other resources from this site. You can also download patches. so the first thing you need to do is create one. The default SQL Developer screen is shown in figure 4-26. you can also use Oracle SQL Developer for database development and maintenance.

the hostname localhost. and password you created for the hr user. A message is displayed at the bottom left side of the dialog to tell you whether the test connection succeeded.Oracle SQL Developer To create a database connection to the local Oracle XE database: 1. and the SID XE. Enter the login credentials for the Oracle Database XE with the username hr. Select Connections in the left pane. Click the Test button to test the connection. Click the Connect button to save the connection and connect to it. Figure 4-27 Oracle SQL Developer Connection screen 2. 57 . right click and select New Connection.

Fig 4-26 shows the choice of context menus available in the data grid. and the right pane shows the contents of the object. you can browse through the database objects displayed in the left pane. 58 . You can add rows. update data and delete rows using the data grid. there are context sensitive menus. In Figure 4-28. the employees table is displayed. the records are marked with an asterisk. Editing Data You can view and edit data using the Data tab for a table definition.Using Oracle Database 10g Figure 4-28 Oracle SQL Developer main screen When you have connected to a database. Throughout SQL Developer. Select the Data tab for the employees table to display the records available. If you make any changes.

views. To create a database object. To create a new table: 1. right click and select Create Table. types and other parameters as required. indexes. and follow the dialogs. right click on the database object type you want to create. Select Tables in the left pane. You can use this method to create any of the database objects displayed in the left pane.Oracle SQL Developer Figure 4-29 Oracle SQL Developer Data Grid Creating a Table You can create database objects such as tables. The Create Table dialog is displayed. and PL/SQL procedures using SQL Developer. Enter the column names. 59 .

indexes. foreign keys. The new table mytable is now listed in the left pane.Using Oracle Database 10g Figure 4-30 Oracle SQL Developer Create Table screen Click the Advanced check box to see more advanced options like constraints. Click OK to create the table. 60 . Figure 4-31 Oracle SQL Developer Advanced Create Table screen 2. and partitions.

Oracle SQL Developer Figure 4-32 Oracle SQL Developer screen showing the new table. This is the connection created earlier in Creating a Database Connection. such as the Data tab. If the tab is not available. 61 . sort. which enables you to add. You are prompted for the database connection name. The SQL Worksheet component is displayed. and shows an area to enter statements. mytable Click on the tabs displayed in the right pane to see the options available on the table. Executing a SQL Query The SQL Worksheet component included in SQL Developer can be used to execute SQL and PL/SQL statements. and a set of tabs below that for further options. Select the Database Connection tab in the right hand pane. select the menu Tools >SQL Worksheet. Some SQL*Plus commands can also be executed. To execute a SQL statement in SQL Developer: 1. modify. and filter rows in the table. delete.

You can view the output of the SELECT statement in the Results tab.Using Oracle Database 10g Figure 4-33 Oracle SQL Developer screen showing SQL Worksheet 2. Enter the following two statements in the SQL Worksheet: DESCRIBE HR. If you have used Oracle’s command line tool SQL*Plus. and the output of the whole script (including the DESCRIBE and SELECT statements) in the Script Output tab. by using F5. Click the Run Script icon (the second from the left in the right hand pane). the output in the Script Output window is likely to be familiar to you. Both the lines of this script are run and the output is displayed in tabs below.EMPLOYEES SELECT * FROM HR. 62 .EMPLOYEES. using F9. or press F5.

Oracle SQL Developer Figure 4-34 Oracle SQL Developer screen showing SQL Worksheet with output 63 .

If you want to execute a single line of the two-line statement. the SELECT statement (second line) is selected. 64 . and the results are shown in the Results tab. Snippets are a handy set of SQL and PL/SQL code snippets that you can drag into the SQL Worksheet component. In this case.Using Oracle Database 10g 3. Figure 4-35 Oracle SQL Developer screen showing SQL Worksheet with output You should also take a moment to click on the Snippets on the top right hand of the interface. or press F9. select the line you want to execute and click on the Execute Statement icon (the first from the left in the right hand pane).

Compiling and Running PL/SQL You can use SQL Developer to browse. compile. create. edit. Right click the Procedures node and select New Procedure from the context menu. 65 .Oracle SQL Developer Figure 4-36 Oracle SQL Developer screen showing code snippets Editing. and debug PL/SQL. 1. Add the name ADD_DEPT and click OK. run.

END ADD_DEPT. they will appear in the Message-Log window below 66 . NAME. LOC IN DEPARTMENTS.DEPARTMENT_NAME%TYPE. The PL/SQL Editor is opened. DEPARTMENT_NAME. LOCATION_ID) VALUES(DEPARTMENTS_SEQ. LOC). 2. Compile the code by selecting the compile icon in the toolbar.LOCATION_ID%TYPE) IS BEGIN INSERT INTO DEPARTMENTS(DEPARTMENT_ID.NEXTVAL.Using Oracle Database 10g Figure 4-37 SQL Developer new procedure dialog 1. Replace or add the text so that your code is as follows: CREATE OR REPLACE PROCEDURE ADD_DEPT (NAME IN DEPARTMENTS. If there are errors.

SQL Developer provides dialog with an anonymous block to help test and run your code. 4. Training and 1800. Run the procedure.Oracle SQL Developer Figure 4-38 SQL Developer PL/SQL Code Editor 3. Query the Departments table to see the results added. Find and replace the NULL values with values of your own. for example. 67 . The green arrow icon runs the code.

or all the views available in the data dictionary. all the tables owned by a user. To display the version numbers of the database components using one of the supplied reports: 68 . getting lists of all users in a database.Using Oracle Database 10g Figure 4-39 SQL Developer Run PL/SQL dialog Running Reports There are a number of reports included with SQL Developer that may be useful to you. for example. and include them in SQL Developer. You can also create your own reports (using SQL and PL/SQL).

Select the Reports tab in the left hand pane. The source code is written to the SQL Worksheet.Oracle SQL Developer 1. The report is run and the results are displayed in the right hand pane. Navigate down to Reports > Data Dictionary Reports > About Your Database > Version Banner. You can also export the supplied reports to edit and add back as user defined reports. 69 . Figure 4-40 Oracle SQL Developer screen showing output from a report 2. Click the Run Report in SQL Worksheet icon (next to Refresh).

and right click. You can use this folder to import or add new reports. to categorize them. Complete the details in the dialog. Right click the User Defined Reports node and select Add Folder.Using Oracle Database 10g Figure 4-41 Oracle SQL Developer screen showing the source code of a report Creating Reports To create your own reports. 1. It is good practice to create folder for your reports. select User Defined Reports. 70 .

DEPARTMENT_ID= D.LOCATION_ID) AND(D.Oracle SQL Developer Figure 4-42 SQL Developer User Defined Reports 5. CITY FROM DEPARTMENTS D. 6. Click the Test button on the Details tab.DEPARTMENT_ID) order by CITY. without leaving the dialog.LOCATION_ID = L. You can test the report to ensure your SQL is correct. SELECT Last_name. Give the report a name and description and enter the following SQL text. DEPARTMENT_NAME. Notice that the default style is table. EMPLOYEES E WHERE(D. 71 . Select the folder you created and right click to select Add Report.MANAGER_ID= E. DEPARTMENT_NAME 7.EMPLOYEE_ID) AND(E. LOCATIONS L.

Using Oracle Database 10g Figure 4-43 SQL Developer Create Report Dialog 8. 9. select it in the Reports Navigator. To run the report. You are prompted for a database connection. Click Apply to save and close. 72 .

Tabular Report You can create tabular reports. 73 . drill down reports and master/detail reports. For all reports. charts. import and share your reports.Oracle SQL Developer Figure 4-44 SQL Developer User Defined. supplied and user defined. you can export.

.

To start Apache HTTP Server: /usr/local/apache/bin/apachectl start 75 . If you downloaded the .bz2 cd httpd-2.tar.59. Use this script to start and stop Apache HTTP Server. you may be wondering why we did not need to invoke bunzip2 to extract the . Log in as the root user and execute the following commands: tar -jxvf httpd-2.59 available from http://httpd. The installation shows Oracle Enterprise Linux and Windows XP Professional Edition and uses Apache HTTP Server Release 2. the --prefix= option sets where Apache HTTP Server will be installed during the command make install. The version used in this installation is httpd-2.apache. 2.cgi. Linux includes the GNU version of tar. 1. Download the Apache HTTP Server from http://httpd. you can use it instead.CHAPTER 5 Installing Apache HTTP Server This chapter gives you the steps needed to install and configure the Apache HTTP Server for use with PHP.0.apache.org/download.0./configure --prefix=/usr/local/apache --enable-module=so make make install When configuring the web server. the option --enable-module=so allows PHP to be compiled as a Dynamic Shared Object (DSO). Note: With Apache 2.org/download.tar. Starting and Stopping Apache HTTP Server The apachectl script is installed in the Apache bin directory.tar file.59 . you should use the default pre-fork MPM (“Multi-Processing Module”).0. you could have used the z flag instead. which has a new j flag to automatically uncompress a bzipped . Also.gz gzipped file.59.cgi. The procedure to install on other Linux platforms is the same as for Oracle Enterprise Linux. If you are familiar with the tar command on UNIX systems. Installing Apache HTTP Server on Linux To install the Apache HTTP Server for use with PHP on Oracle Enterprise Linux. because threadsafety of many of the PHP libraries is not known.0.bz2.tar file. If you already have Apache installed.

for example: start_apache #!/bin/sh ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.conf and php. Double click the downloaded file apache_2.2.0.0.0. and make corrections.msi.apache. Download the Apache HTTP Server Windows binaries from http://www. You should now test that Apache HTTP Server has been installed properly and started on your machine by opening your web browser to http://localhost/ to display the Apache home page.2. check your httpd. If you have problems. you must at least have the environment variable $ORACLE_HOME defined.2. Errors may also be recorded in /usr/local/apache/logs/error_log.0/server export ORACLE_HOME echo "Oracle Home: $ORACLE_HOME" echo Starting Apache /usr/local/apache/bin/apachectl start Installing Apache HTTP Server on Windows The following procedure describes how to install the Apache HTTP Server on Windows. When you start Apache HTTP Server. 1.59win32-x86-no_ssl. If there are errors.ini configuration files for any incorrect settings.Installing Apache HTTP Server You should test that Apache has been installed properly and is started on your machine by opening your web browser to http://localhost/ to display the Apache home page.2. and the downloaded file is named apache_2.sh or the /usr/local/bin/oraenv scripts. These are the same variables set by the $ORACLE_HOME/bin/oracle_env. they are displayed on your screen. but not the Express Edition. on Port 80.59.59-win32-x86-no_ssl. 2.0. the Apache HTTP Server is started. there is a script located in $ORACLE_HOME/install/changePerm. The release used in this installation is Apache HTTP Server 2. Follow the Apache HTTP Server installation wizards.sh to do this. Starting and Stopping Apache HTTP Server As part of installation. You should select to install Apache HTTP Server for All Users. you must give the nobody user access to the Oracle directory. With Oracle 10g Release 10. 76 .msi. Now stop Apache so it can be configured for PHP: /usr/local/apache/bin/apachectl stop Note: If you are using Oracle 10g Release 10. 3.org/dist/httpd/binaries/win32/. Any other required Oracle environment variables must be set before Apache HTTP Server starts as well. you may create a script to start Apache HTTP Server. To simplify things. because the only for the Current User alternative will clash with Oracle Database Express Edition’s default port 8080.

use the Apache options added to your Windows Start menu.Installing Apache HTTP Server on Windows Your system tray has an Apache Monitor control that makes it easy to stop and restart the Apache HTTP Server when needed. Alternatively. 77 .

.

CHAPTER 6

Installing PHP
This chapter discusses installing PHP as an Apache module on Linux and Windows using a local Oracle database. It also discusses installing OCI8 with Oracle Instant Client if have a remote database. You can use either the OCI8 extension for native access to Oracle, or the PHP Data Object (PDO) abstraction layer extension. PDO is a new PHP extension that enables you to abstract the database code and have the extension handle the translation and execution of that code with the native database extension, in this case, OCI8.

Note: The Oracle database and Apache HTTP Server need to be installed before following the steps in this chapter. Alternatively, if you have a remote database, you can use the Oracle Instant Client configuration steps. If you installed Apache to a different location or use a pre-installed version, you will need to adjust the path to its location in the installation steps.

Installing OCI8 with PHP 5
The OCI8 extension is included with PHP 5.1.2 onwards, or available from the PECL download site. This section gives steps on installing the OCI8 extension with PHP 5. The installation uses PHP 5.2.2, Oracle Enterprise Linux, and Windows XP Professional Edition.

Installing OCI8 on Linux
To install OCI8 on Oracle Enterprise Linux: 1. Download PHP 5.2.2 from http://www.php.net/downloads.php. 2. Log in as the root user and extract the PHP source code:
tar -jxvf php-5.2.2.tar.bz2 cd php-5.2.2

3. Configure PHP with OCI8 and Oracle:
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/ 10.2.0/server ./configure \ --with-apxs2=/usr/local/apache/bin/apxs \ --with-config-file-path=/usr/local/apache/conf \ --with-oci8=$ORACLE_HOME \ --enable-sigchild 79

Installing PHP

If you are using the default Apache on Oracle Enterprise Linux, the path to the Apache extension tool is /usr/sbin/apxs. If you have installed Apache 1.3 instead of Apache 2, change the option to –-withapxs.

4. Make and install PHP.
make make install

5. Copy PHP’s supplied initialization file, php.ini-recommended:
cp php.ini-recommended /usr/local/apache/conf/php.ini

6. For testing it is helpful to edit /usr/local/apache/conf/php.ini and set display_errors to On so you see any problems in your code. Make sure you change this configuration option to Off before you make your application available to users. 7. Edit Apache’s configuration file /usr/local/apache/conf/httpd.conf and add the following lines:
# # This section will call PHP for .php, .phtml, and .phps files # AddType application/x-httpd-php .php AddType application/x-httpd-php .phtml AddType application/x-httpd-php-source .phps # # This is the directory containing php.ini # PHPIniDir "/usr/local/apache/conf"

8. If a LoadModule line was not already inserted by the PHP install, add it too:
LoadModule php5_module modules/libphp5.so

9. Set any required Oracle environment variables, such as NLS_LANG. 10. Restart Apache.
/usr/local/apache/bin/apachectl start

If you are using an Oracle Database 10g Release 2 database other than the Express Edition (“XE”), you may need to give the Apache process access to Oracle’s libraries and globalization data. Refer to the $ORACLE_HOME/install/changePerm.sh script. Each time you restart Apache, make sure you have the same environment variables set for Oracle. In particular ORACLE_HOME should always be set.

Installing OCI8 on Windows
To install OCI8 on Windows XP Professional Edition: 1. Download the PHP 5.2.2 installer package from http://www.php.net/downloads.php.
80

Installing OCI8 with PHP 4

2. Double click on the downloaded file php-5.2.2-win32-installer.msi. The PHP Windows installer starts. 3. Click Next on the Welcome screen. The license agreement is displayed. 4. Accept the license agreement by checking the box and click Next. 5. Select the installation location of the PHP files and click Next. 6. In the Web Server Setup screen, select the web server you want to use. This installation uses the Apache 2.0 module option. Select Apache 2.0.x Module and click Next. 7. In the Apache Configuration Directory screen, select the location of the Apache conf directory and click Next. 8. In the Choose Items to Install screen, scroll down to the Extensions branch and add the Oracle 8 extension to the installation. Click Next. 9. In the Ready to Install PHP 5.2.2 screen, click Install. The installer installs PHP. 10. A dialog is displayed asking whether you want to configure Apache. Click Yes. 11. A confirmation message is displayed to confirm that the httpd.conf file has been updated. Click OK. 12. A confirmation message is displayed to confirm that the mime.types file has been updated. Click OK. 13. A final confirmation message is displayed to confirm that the PHP installation has completed. Click Finish. 14. Restart Apache with Start > Programs > Apache HTTP Server 2.0.59 > Control Apache Server > Restart. This opens a console window showing any error messages. Errors may also be recorded in C:\Program Files\Apache Group\Apache2\logs\error.log. If you have errors, double check your httpd.conf and php.ini files, and correct any problems.

Installing OCI8 with PHP 4
PHP 4 ships with the old OCI8 extension. If you use PHP 4, you should get the re-factored OCI8 from PECL. It works with PHP 4.3.10 onwards.

Installing PHP 4 on Linux
To install OCI8 on Oracle Enterprise Linux: 1. Download php-4.4.6.tar.bz2 from http://www.php.net/downloads.php. 2. Extract the files and delete the included oci8 extension
tar -jxf php-4.4.6.tar.bz2 rm -rf php-4.4.6/ext/oci8 81

net/downloads. Installing PHP 4 on Windows To install OCI8 on Windows XP Professional Edition: 1.2. so you see any problems in your code.4.4.php.6-Win32\sapi directory. 2.4 branch from http://pecl4win.6-Win32\cli directory too. Make sure to use forward slashes ‘/’ instead of back slashes ‘\’: 82 .ini-recommended to C:\Program Files\Apache Group\Apache2\conf\php. 6.4. by following the steps in the section Installing OCI8 With Oracle Instant Client.6/ext/oci8 4. Copy C:\php-4.6Win32\extensions\php_oci8. it is helpful to set display_errors to On.4.conf and add the following lines.4.4.4. Delete the old OCI8 extension file C:\php-4.ini and perform the following: 7. Edit php. which is the directory containing php_oci8.net/package/oci8 Extract the files and move the directory to ext/oci8: tar -zxf oci8-1.6-Win32.4. Download the latest OCI8 extension from http://pecl. Rebuild the configuration script with the updated extension’s options: cd php-4.dll and move it to C:\php-4. Edit the file httpd.1 Change extension_dir to C:\php-4. If you run the PHP command line interface copy it to the C:\php-4.4.Installing PHP If you only rename the oci8 directory the configuration script will not be properly built.3 php-4.dll.dll into the C:\php-4. Download php_oci8.6-Win32. Uncompress php-4.6 ZIP file from http://www.cache autom4te.2. 7.net/ext.dll for the 4. 9.dll. Configure and build PHP following step 2 onward in the previous section Installing PHP on Linux or.6-Win32\extensions\php_oci8. Download the PHP 4. 3.conf . 5.php/php_oci8. 4.ini.tgz mv oci8-1.6-Win32\php4ts. if you intend to use Oracle Instant Client.dll and the other PHP extensions.dll. 7./buildconf --force 5.4.php.zip to a directory called C:\php-4. 3. 8.4. Copy php.6-Win32\extensions.6 rm –rf config. For testing. Note the OCI8 DLLs from PECL require Oracle 10g client libraries.php.3.php.2 Uncomment (remove the semicolon from the beginning of the line) the option extension=php_oci8.

2.2. for example $HOME/instantclient10_2.html. and .oracle. as Instant Client does not include one.rpm rpm -Uvh oracle-instantclient-devel-10. . Typically the database is on another machine.3/client/lib and the second creates headers in /usr/include/oracle/10.3/client.2.2.php.php AddType application/x-httpd-php .ini # PHPIniDir "C:/Program Files/Apache Group/Apache2/conf" Installing OCI8 With Oracle Instant Client The free Oracle 10g Instant Client is the easiest way for PHP to connect to a remote Oracle database.0.i386.Installing OCI8 With Oracle Instant Client # # This will load the PHP module into Apache # LoadModule php4_module C:/php-4.3/client/lib 83 . http://www.phtml. If you are using the Instant Client ZIP files.0.rpm The first RPM puts the Oracle libraries in /usr/lib/oracle/10. This section shows how to install the OCI8 extension with PHP using Oracle Instant Client. An existing Oracle database is needed in this installation scenario.com/technology/tech/oci/instantclient/instantclient. To install: 1.i386.phps files # AddType application/x-httpd-php .phtml AddType application/x-httpd-php-source . 3.3-1. install the RPMs as the root user: rpm -Uvh oracle-instantclient-basic-10.2. Installing OCI8 with Instant Client on Linux After installing the Apache HTTP Server.0.dll # # This section will call PHP for . The files should be unzipped together so the SDK is in $HOME/instantclient10_2/sdk. unzip the Basic and the SDK packages to a directory of your choice. Collectively. Download the Basic and SDK Instant Client packages from the Instant Client page on the Oracle Technology Network. requiring installation of only a few libraries and header files.0.2.phps # # This is the directory containing php. Set LD_LIBRARY_PATH to include the location of the Instant Client libraries: export LD_LIBRARY_PATH=\ $LD_LIBRARY_PATH:/usr/lib/oracle/10. the two packages are about 32 MB in size.3-1.4. then Oracle libraries will generally already be accessible and Instant Client is not required.6-Win32/sapi/php4apache2. If you are using the RPMs. If the database is local. you can install Oracle Instant Client and configure PHP to enable connections to Oracle databases.0.

ini 9. Log in as the root user and extract the PHP source code: tar -jxvf php-5. Unset any Oracle environment variables that are not required by Instant Client. such as NLS_LANG. Restart the Apache HTTP Server.2.0. for more information on globalization with PHP and Oracle. Download PHP 5.2. 5.2 6.3/client/lib \ --enable-sigchild If you are using the ZIP files then change the --with-oci8 option to the unzipped directory: --with-oci8=instantclient. 10.tar.Installing PHP If you installed Instant Client from the ZIP files. 84 . 4.2.php. If you are using a tnsnames. Rebuild PHP: make make install 8./usr/lib/oracle/10. you also need to apply a PHP patch given in PHP bug 31084 to build PHP with Oracle Instant Client. Note: The configuration option in older versions of PHP is --with-oci8-instant-client.2 from http://www. set the TNS_ADMIN environment variable to the directory containing the file.ora file to define Oracle Net service names (database aliases). See the configuration help using the ./configure \ --with-apxs2=/usr/local/apache/bin/apxs \ --with-config-file-path=/usr/local/apache/conf \ --with-oci8=instantclient.$HOME/instantclient10_2 7. If you are using a version of PHP that is earlier than releases 4. Configure PHP with: . Copy PHP’s supplied initialization file to the location given by --with-configfile-path: cp php. 11.11 and 5.bz2 cd php-5.php.ini-recommended /usr/local/apache/conf/php.net/downloads./configure –-help command to check which syntax you should use.5. such as ORACLE_HOME and ORACLE_SID. See the Globalization chapter.3.2. use $HOME/instantclient10_2 instead. Set any required Oracle environment variables.0.2.

If nothing is set. The PDO extensions are included in PHP from release 5. This procedure works for all versions of PHP after release 5.2. 2.1. 5. when the extension is more stable and widely used.59. Install PHP following the steps in the previous chapter. you can install Oracle Instant Client and configure PHP.0. Set any other required Oracle globalization language environment variables. before any other Oracle directories. for more information on globalization with PHP and Oracle. Unset any Oracle environment variables that are not required.2.html. Create a new directory (for example. C:\instantclient10_2). http://www. Apache 2. Zend Core for Oracle release 2. copy the tnsnames. The Windows 32 bit ZIP file is called instantclient-basic-win32-10. See the Globalization chapter. Download the Instant Client Basic package for Windows from the Instant Client page on the Oracle Technology Network. C:\instantclient10_2. A default service name can optionally be set in the user environment variable LOCAL. use Start > Settings > Control Panel > System > Advanced > Environment Variables.0 does not support the Oracle PDO extension. Edit the environment and add the location of the Oracle Instant Client files. It will likely be supported in a future release. You 85 .com/technology/tech/oci/instantclient/instantclient. If you want to use the minimum files required.Installing PDO Installing OCI8 with Instant Client on Windows After installing the Apache HTTP Server.dll * oci. such as ORACLE_HOME and ORACLE_SID.oracle.ora file to C:\instantclient10_2. 4. Installing PDO To use PDO with Oracle.3-20061115. Installing PHP. Unzip the downloaded file into the new directory. you can unzip just the following files to the new directory: * oraociei10. install the PDO extension and the native database extension for Oracle.1. To install: 1. Restart the Apache HTTP Server. Oracle Enterprise Linux. If you are using a tnsnames. such as NLS_LANG. PDO_OCI. and edit PATH in the System Variables list.ora file to define Oracle Net service names (database aliases). For example. and Windows XP Professional Edition.dll * orannzsbb10.dll 3. the default local environment is used. The installation uses PHP 5.zip and is around 32 MB in size. on Windows XP.2. to the PATH environment variable.0. and set the user environment variable TNS_ADMIN to C:\instantclient10_2.

0/server . Log in as the root user and extract the PHP source code using the following commands: tar -jxvf php-5. PHP’s configure script ignores options it does not recognize and will not warn if you make a mistake with the name. PDO_OCI and Oracle: export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/ 10.ini script and configure Apache.3 or --with-pdo-oci=instantclient. change the –-with-pdo-oci option to: --with-pdo-oci=instantclient.10. Installing PDO on Linux To install PDO on Oracle Enterprise Linux: 1.2.php.2.2.tar. 6.2. you should see PDO and PDO_OCI.10.0.net/downloads.0. make make install 5. 86 . Check the extension has been installed correctly: php -m In the list of modules. Configure PHP with PDO. Make and install PHP.3 4.2 3. Review the output of configure and check that the extension was enabled successfully before continuing.$HOME/instantclient_10_2./usr.Installing PHP can install PDO_OCI and OCI8 at the same time by combining the appropriate options to configure.php. Download PHP 5. 2.2. Continue from step 5 of the previous section Installing OCI8 on Linux to create the php.bz2 cd php-5.2.2. If you want to build PDO_OCI with the Oracle Instant Client (See the chapter Installing PHP With Oracle Instant Client).2 from http://www./configure \ --with-apxs2=/usr/local/apache/bin/apxs \ --with-config-file-path=/usr/local/apache/conf \ --enable-pdo \ --with-pdo-oci=$ORACLE_HOME \ --enable-sigchild Note there is no “8” in the –-with-pdo-oci option name.

Restart Apache. Figure 6-1 PDO Installation on Windows 4. The Oracle PDO_OCI extension is now installed and configured with PHP. 87 . 2.Installing PDO Installing PDO on Windows To install PDO on Windows XP Professional Edition: 1. 3. 5. Continue with the rest of the PHP installation. Follow the steps in Installing OCI8 on Windows. This procedure uses Oracle Instant Client 10g. add the PDO extension by also selecting to install PHP > Extensions > PDO > Oracle 8i +. See the section Installing OCI8 With Oracle Instant Client for steps on installing Oracle Instant Client 10g. Install an Oracle Client or Oracle Database. At step 8.

.

Installing Zend Core for Oracle This procedure installs Zend Core for Oracle on Linux and Windows platforms.2.0 (on Linux and Windows x86) Microsoft IIS 5.CHAPTER 7 Installing Zend Core for Oracle Zend Core for Oracle 2.2. Oracle Instant Client. Zend Core for Oracle is supported by Zend on the following operating systems: * * * * * * * Oracle Enterprise Linux X86 running SLES9 or RHEL3 or RHEL4 X86 running Windows XP/2003/Vista X86-64 running Windows Vista in 32bit mode X86-64 running SLES9 or RHEL3 or RHEL4 pSeries running AIX 5.3 Sun Solaris Sparc 8. That means that you can have a fully supported stack of database. So you can use this procedure on all supported operating systems. and an optional Apache HTTP Server 2. The collaboration between Oracle and Zend reinforces Oracle’s commitment to the open source PHP community. as all the hard work of installation and configuration has been done for you. 7 Zend Core for Oracle is supported against Oracle Database 10g and 9i. 6. There are some slight differences. 89 .0. 9 10 The web servers that are supported are: * * * Apache 1. but the installation is similar on all platforms. web server and PHP.x Oracle HTTP Server 10.3.1.0 includes PHP 5.0 is a fully tested and supported PHP distribution that includes integration with Oracle Database 10g client libraries.2.2. It is a pre-built stack that makes it easier to get started with PHP and Oracle.x (except on Windows Vista).1. Apache 2.2 or 5. like the names and locations of the web server. Zend Core for Oracle release 2.0 Zend Core for Oracle 2. the refactored OCI8 driver. The procedure to install on other operating systems is similar as the installer is the same on all operating systems.

This is the password for the webbased interface to Zend Core for Oracle.tar. click Yes. and click OK. Download the Zend Core for Oracle file from the Oracle Technology Network (http://otn. 8. select Yes. accept the default (or enter your preferred location). Zend Core for Oracle can install Apache if you don’t have it on your system. at the "Do you wish to proceed?" prompt. Extract the contents of the downloaded Zend Core for Oracle software file.Installing Zend Core for Oracle Installing Zend Core for Oracle on Linux To install Zend Core for Oracle on Linux: 1. or do not want to track updates. This rest of this installation assumes that you have selected No and have in instance of Apache already installed on your machine. Enter a password for the Administration Console. If you want to install and configure Apache. You may optionally enter your Zend network user ID and password to be able to use the Zend Core Console to track when updates to Zend Core and PHP components are available. 7.oracle.gz Files are extracted to a subdirectory called ZendCoreForOracle-v2.0. click OK.tar. or if you want to use an existing web server. 9.1-Linux-x86. 6. Select the your web server from the list.0. 11.1-Linux-x86. select No. When prompted to accept the terms of the license. In the page confirming your web server selection.1-Linux-x86 . Click OK.0. Log in or su as root if you are not already. click Yes. The next page prompts you to select the web server to use for the Zend Core for Oracle installation. 10. 90 ./install 5. When prompted to specify the location for installing Zend Core for Oracle. 13. select No. 12. 4. su Password: 3.0.gz: tar -zxf ZendCoreForOracle-v2. In the initial Zend Core for Oracle Installation page. Change directory to ZendCoreForOracle-v2.1-Linux-x86 and start the Zend Core for Oracle installation: cd ZendCoreForOracle-v2.com/php). If you have not registered. The installer begins extracting the files required for the installation. 2.0. and click OK. named ZendCoreForOracle-v2. Confirm the password and click OK.1-Linux-x86.

You can also use the FastCGI or CGI options if you prefer. Click OK. In the next installation page. Testing the Zend Core for Oracle Installation on Linux To test the Zend Core for Oracle installation on Linux platforms: 1. A page containing “Thank you for installing Zend Core for Oracle” lists useful configuration commands and the URL for the Zend Core for Oracle Administration Console. 15. you are prompted to “Please select an installation method for Apache 2. and change directory to the newly created directory. edit APACHE_HOME/conf/httpd.php that contains the following PHP code: <?php echo "Hello world!".0.” select Main Server. when you are prompted to ”Please select a virtual server for the Zend Core GUI. and click OK. create a directory called public_html in your home directory. As root. 16. The Zend Core for Oracle installation is now complete. Make sure Oracle OCI DB Drivers is selected. Take note of the information and click Next. enter the following commands in a command window: cd $HOME mkdir public_html cd public_html 3. ?> 4. 19. In the next installation page. at the “Would you like to restart the Web Server” prompt.conf and add a comment to the following line: #UserDir “disable” Then remove the "#" from the following line: UserDir public_html 2. Create a file called hello. a notice is displayed stating that the apachectl script has been updated. As your normal user (not root). In the next installation page. and the directories above it are set to 755 so the web server can read and execute them.” Select Apache module as the method. click Yes.59. In the next installation page. 17. and click OK. 18. 91 . Configure Apache to use a public virtual directory. A final confirmation page is displayed. and click OK.Installing Zend Core for Oracle 14. Make sure the permissions on any files in the public_html directory. 20. Click OK to finish the installation. The next installation page contains a list of extra components to install.

In the initial Zend Core for Oracle installation page. click Next. 8. 4. There is a link to the Zend site available on the Oracle Technology Network at http://otn. Extract the contents of the downloaded Zend Core for Oracle software using WinZip or similar software. Click Next. accept the default (or enter your preferred location).exe into the location of your choice. The ZendCoreforOracle-v.1-Windows-x86.1/~<username>/hello. 5. you can choose to perform a Complete installation. Select Zend Core PHP and Extensions.zip file extracts a file named ZendCoreforOracle-v.oracle. On Windows platforms. When prompted to specify the location for installing Zend Core for Oracle.2.0. Double click on the file named ZendCoreforOracle-v.0.2. select the Apache root folder. select the Complete installation for the default install options. 10. 9. The installer begins extracting the files required for the installation. Zend Core Administration.exe to start the Zend Core for Oracle installation.1-Windows-x86.com/php. If you prefer. select the port number you want Apache to listen on. 11. and click Next.0. or a Custom installation. Download the Zend Core for Oracle. Select the extensions you want to associate with PHP from the check boxes and click Next. 6. Click Next. When prompted to accept the terms of the license.2. or if you do not have Apache installed. 7. select Install bundled Apache 2. 3.0. If you have chosen to install a new Apache server. or a user with system administrator privileges. and if you do not have Apache installed yet.Installing Zend Core for Oracle 5. select Specify Apache’s location.2. Click Next. If you have chosen to use an existing Apache install. Open a web browser and enter the following URL in your browser: http://127. you can install it now by selecting Apache 2. Installing Zend Core for Oracle on Windows To install Zend Core for Oracle on Windows platforms: 1. Any errors in your PHP code are displayed as you have configured PHP to display errors.0. Log in as a system administrator.php The line “Hello world!” appears in the browser. click Next. 12.2. 2. If you have an Apache install already. This installation procedure assumes you select the Custom installation. 92 .1-Windows-x86.

0. The installer runs through the installation. 14. Confirm the password and click Next. Click Finish.1/ZendCore 93 .1/hello.php The line “Hello world!” appears in the browser. ?> 2.0. Open a web browser and enter the following URL in your browser: http://127. Enter a password for the Administration Console.0.Configuring Zend Core for Oracle 13. A dialog is displayed giving the URL of the Zend Core Administration console. or do not want to track updates. Enter the following URL in a web browser to access the Zend Core for Oracle Administration console: http://127. Click the Install button to begin the installation.php in the Apache C:\Program Files\Apache Group\Apache2\htdocs directory that contains the following PHP code: <?php echo "Hello world!". select No. 16. and the release notes. Configuring Zend Core for Oracle In this section. you configure environment variables and Zend Core directives that control default error reporting in web pages. 15. Testing the Zend Core for Oracle Installation on Windows To test the Zend Core for Oracle installation on Windows platforms: 1. Any errors in your PHP code are displayed if you have configured PHP to display errors. 17. Create a file called hello.0. If you have not registered. The Zend Core for Oracle installation is now complete. In the Zend Network Registration page. The final installation page is displayed confirming the installation is complete. 1. Click OK. Click Next. you may optionally enter your Zend network user ID and password to be able to use the Zend Core Console to track when updates to Zend Core and PHP components are available.

Set the display_errors directive to On to enable the display of errors in the HTML script output during development. Click the + icon to expand the Error Handling and Logging configuration entry. Click the login >>> icon.Installing Zend Core for Oracle Figure 7-1 Zend Core for Oracle login screen. 3. 2. Make sure you set this back to Off before you release any applications you build as users will see the errors and gain information about your system that you otherwise don’t want them to see or know. 94 . Enter the GUI password that you provided during Zend Core for Oracle installation. Click the Configuration tab to display the configuration options. 5. 4.

If you are using a Windows operating system. Under the page header notice the "Please Restart Apache" message reminding you to do so. Click Save Settings to save the configuration change. Because there are unsaved changes. 6. 95 . you must restart the Apache web server. or the Apache Monitor in the system tray. 7. Because you have made configuration changes.Configuring Zend Core for Oracle Figure 7-2 Zend Core for Oracle configuration screen. you should restart the Apache server using the Services dialog in Control Panel. Click Restart Server to restart the Apache server. 8. Click Logout to exit the Zend Core for Oracle Administration page. the "Unsaved configuration" message appears under the page header.

.

$password.CHAPTER 8 Connecting to Oracle Using OCI8 This section covers the ways in which you can connect to an Oracle database from your PHP application. Multiple Unique Connections To get a totally independent connection use oci_new_connect(): $c = oci_new_connect($username. using standard connections. Persistent Connections Persistent connections can be made with oci_pconnect(): $c = oci_pconnect($username. Each connection is separate from any other. Persistent connections are not automatically closed at the end of a PHP script and remain open in PHP’s persistent connection cache for reuse in other scripts. You can call oci_connect() more than once in a script. 97 . Oracle Connection Types There are three ways to connect to an Oracle database in a PHP application. then you get a pointer to the original connection. Standard Connections For basic connection to Oracle use PHP’s oci_connect() call: $c = oci_connect($username. Each method returns a connection “resource” that is used in subsequent OCI8 calls. This lets you have more than one database session open at the same time. This makes oci_pconnect() fast for frequently used applications. environment variables that may effect connections. $dbname). including the types of Oracle connections. $dbname). or persistent connections. and tuning your connections. $password. $dbname). unique connections. $password. This can be useful when you want to do database operations independently from each other. If you do this and use the same username and database name.

2). 'hrpwd'. This syntax is usable in Zend Core for Oracle. 98 . This uses the Easy Connect string. you could connect to the HR schema with: $c = oci_connect('hr'. The parameters for tuning persistent connections are discussed later in this chapter. which is JDBC-like. The // prefix is part of the syntax and is not a PHP line comment. and the PHP-enabled web server is on the same machine. You can use this syntax to connect to Oracle8i. and connections can be automatically expired to free up resources. Oracle9i and Oracle10g databases as long as PHP is linked with Oracle 10g libraries. The database name can be one of: * * * An Easy Connect string A full connection string A database alias Having an invalid connection string can lead to the Oracle error: ORA-12514 TNS:listener does not currently know of service requested in connect descriptor Easy Connect String If you are running Oracle XE on a machine called mymachine. The syntax is: [//]hostname[:port][/service_name] The port defaults to Oracle’s standard port. Oracle Database Name Connection Strings The $dbname connection string is the name of the local or remote database that you want to attach to. More information on the syntax can be found in the Oracle® Database Net Services Administrator's Guide 10g Release 2 (10. '//mymachine/XE'). the character set and the connection privilege to ensure reconnections are the same as the original. The service name defaults to same name as the host computer.Connecting to Oracle Using OCI8 Figure 8-1 Persistent connection are cached in PHP Each cache entry uses the username. 1521. the database name. Limits on the number of persistent connections in the cache can be set.

$password. The search path always includes the directory specified by the TNS_ADMIN environment variable and a default location. $ORACLE_HOME is: /usr/lib/oracle/xe/app/oracle/product/10.ora and refer to it in PHP using an alias: # tnsnames. you can enable Oracle Net features like load balancing and tweak packet sizes. depending on the database and Oracle Net features used. 99 .ora In Oracle XE.mydomain)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = MYDB. $password. For example.ora file will automatically be found without needing to set TNS_ADMIN. The directory paths that Oracle searches for tnsnames.2.Oracle Database Name Connection Strings Full Database Connection String The full Oracle Net connection string gives total flexibility over the connection. set the TNS_ADMIN variable in the Apache startup script to the location of your tnsnames. PHP needs to be able to find the tnsnames.MYDOMAIN)))'.ora MYA = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP) (HOST = mymachine. copy the connection string used by other Oracle tools and users. In an “ORACLE_HOME” style install the default tnsnames. and there is no default file. Database Alias You can store the full connection string in a file called tnsnames. then you would typically have ORACLE_HOME set and the default tnsnames. Instead. When in doubt.0/server If you have compiled PHP yourself and are running it with the Oracle libraries in an ORACLE_HOME-style install.ora. In Zend Core for Oracle. by using the full syntax. $db).ora depend on your operating system. The syntax can be more complex than the example. $c = oci_connect($username.ora file to resolve the MYA alias. $db = '(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP) (HOST = mymachine.mydomain)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = MYDB. 'MYA'). the ORACLE_HOME variable is generally not set.ora is in: $ORACLE_HOME/network/admin/tnsnames. The Easy Connect syntax does not allow this flexibility.MYDOMAIN))) In PHP you would use the alias MYA to connect to the database: $c = oci_connect($username.

Environment variables must be set in the shell that starts Apache. Not finding the files can lead to errors like Error while trying to retrieve text for error ORA-12154. Do not set Oracle environment variables in PHP scripts with putenv(). In Oracle XE. Not used for Oracle Instant Client. This message means that an error ORA-12154 occurred (which is one problem. you can set the environment by using the oracle_env. in this case a connection problem). LD_LIBRARY_PATH NLS_LANG TNS_ADMIN Should include the Oracle libraries.sh script: export OH=/usr/lib/oracle/xe/app/oracle/product/10.sh 100 . for example $ORACLE_HOME/lib or $HOME/instantclient_10_2 Sets the globalization options for Oracle. Using putenv() causes hard to track errors as the behavior is not consistent for all web servers. or are building PHP yourself. you will need to set some environment variables in the shell that starts the web server. Not used for Oracle Instant Client. The OCI8 extension always needs to find Oracle libraries and message files. Table 8-1 Oracle Environment Variables Oracle Environment Variable ORACLE_HOME ORACLE_SID Purpose The directory containing the Oracle software. Finding mismatched versions of Oracle libraries and files can lead to PHP returning errors such as ORA-12705: Cannot access NLS data files or invalid environment specified. The location of the tnsnames. The bottom line is that your environment should be set correctly and consistently. Only used when PHP is on same machine as the database and the connection string is not specified in the PHP connect function. platforms. or OCI8 functions.ora file is not in $ORACLE_HOME/network/admin. The solution for both problems is often the same: to set the environment correctly. The Oracle Net alias of the database. The web server may load Oracle libraries before running your script. Only needed if a database alias is used in the PHP connect function and the tnsnames. The common Oracle environment variables are listed in table 8-1. It also means that OCI8 could not find Oracle’s message files to get the text describing the error (a second problem). Another potential source of problems is having multiple installations of Oracle.ora and other Oracle Net configuration files.Connecting to Oracle Using OCI8 Oracle Environment Variables for Connections If you need to change Oracle environment settings like the language and territory conventions.2. $OH/bin/oracle_env.0/server .

sh #!/bin/sh ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.ini setting: oci8. set the environment in a calling script. and never actually closed a connection. Any uncommitted data is rolled back. That is.old_oci_close_semantics = 1 oci_close() works by reference counting. You can also explicitly close them at any time by calling: oci_close($c). You could not explicitly close connections even if you wanted to! This has now changed. If you have environment related problems. it modifies /usr/local/Zend/apache2/bin/envvars to add LD_LIBRARY_PATH. but only at the end of script when $c2 is closed is the database connection really released.Closing Oracle Connections Note the space after the period. If a long running script only spends a small amount of time interacting with the database. 101 .2. If you start Apache manually. In this example $c1 and $c2 are the one database connection (because oci_connect() returns the same connection resource when called more than once in a script). check the output from the phpinfo() function. Idle persistent connections can be set to expire. Closing Oracle Connections At the end of each script. Connections opened with oci_pconnect() will not be closed by oci_close().WE8ISO8859P1 export ORACLE_HOME LD_LIBRARY_PATH NLS_LANG echo Starting Apache #export > /tmp/envvars # uncomment to debug /usr/local/apache/bin/apachectl start Zend Core for Oracle is automatically configured to use Oracle Instant Client. connections opened with oci_connect() or oci_new_connect() are automatically closed. For example: start_apache. This is similar to the way persistent resources work in other PHP extensions. Make sure you preserve this file inclusion if you later modify the apachectl script. but you can revert to the old behavior if necessary with this php. it had no functional code. The oci_close() function was a “no-op” prior to the re-factoring of OCI8. The envvars file is called by apachectl. Look at the Environment section and make sure the Oracle variables are set to the values you expect.0/server LD_LIBRARY_PATH=$LD_LIBRARY_PATH/$ORACLE_HOME/lib NLS_LANG=American_America. As part of the install. This command allows the script to set the environment of the shell itself. you may want to close connections to free resources for other users. The common Oracle environment variables you may want to set explicitly for Zend Core for Oracle are NLS_LANG and TNS_ADMIN. Only when all references to the PHP connection are finished will the database connection actually be closed.

Calling the script a second time gives: 2007-04-18 14:21:10 2007-04-18 14:21:10 102 . do_query($c.php <?php function do_query($c. oci_close($c1). echo "</pre>". The first time this is called. "select sysdate from dual"). 'select user from dual'). the two dates returned by the queries are: 18/APR/07 2007-04-18 14:21:09 The first date has the system default format. oci_execute($s). 'hrpwd'. } $c1 = oci_connect('hr'. 'select user from dual'). For oci_pconnect() this means subsequent scripts reusing the cached database connection will not see any data they should not. do_query($c1. "alter session set nls_date_format=’YYYY-MM-DD HH24:MI:SS’"). echo "<pre>". $query). $r = oci_execute($s). "hrpwd". $c2 = oci_connect('hr'. it is possible for a script to change session attributes for oci_pconnect() that are not reset at the end of the script. do_query($c2. '//localhost/XE'). the second query fails. ?>7 // fails // succeeds In the example. var_dump($res). the connection resource in $c1 is not usable after oci_close($c1) is executed. 'hrpwd'. $query) { $s = oci_parse($c. "select sysdate from dual"). oci_fetch_all($s. do_query($c1. oci_close($c2). However. Although the reference counting algorithm keeps the database connection physically open. $s = oci_parse($c. One example is the globalization setting for the date format: $c = oci_pconnect("hr". but the third succeeds. "//localhost/XE"). 'select user from dual'). Connection Cleanliness with Persistent Connections Uncommitted data is rolled back at the end of a PHP script. The second is different because the ALTER SESSION command changed the date format. $res). do_query($c. '//localhost/XE'). (The Oracle term “session” is effectively the same as the PHP term “connection”).Connecting to Oracle Using OCI8 close.

you grant privileges to enable the user to connect to the database. When creating a database user. make sure your application resets necessary values after connecting. and to create schema objects.privileged_connect = 1 The SYSDBA and SYSOPER privileges give you the ability to change the state of the database. The following administrative user accounts are automatically created when you install Oracle. ja16euc. If there is a possibility incorrect settings will be inherited. that is. to run queries and make updates. "//localhost/XE". Privileged connections are disabled by default. system — This is the user account that you log in with to perform all administrative functions. Be very careful about exposing this on customer facing web sites. When not specified or NULL. This only happens if the same Apache process serves both HTTP requests. If the characters sets are not equivalent some data may get converted abnormally. If a new Apache process serves the second request then it will open a new connection to the database. They are both created with the password that you supplied upon configuration.Optional Connection Parameters The persistent connection has retained the session setting and the first query no longer uses the system default format. $c = oci_connect("hr". perform data recovery. This setting determines how Oracle translates data when it is transferred from the database to PHP. It is up to your application to handle returned data correctly. 'ja16euc'). Optional Connection Parameters The oci_connect(). and even access the database when it has not fully started. They can be enabled in php. 103 . do not do it! It might be more useful for command line PHP scripts. for example. (Also the system will have two persistent connections left open instead of one.) Session changes like this may not be a concern. Your applications may never need to do anything like it.ini using: oci8. "hrpwd". perhaps by using PHP’s mb_string or iconv functionality. Globalization is discussed in more detail in the Globalization chapter. Connection Privilege Level One of the new features of the re-factored OCI8 extension is the ability to allow privileged SYSDBA and SYSOPER connections. or all connections may need the same values anyway. the NLS_LANG environment variable setting is used. which will have the original default date format. other than starting up and shutting down the database. oci_new_connect() and oci_pconnect() functions take an optional extra two parameters: * * Connection character set Connection privilege level Connection Character Set The character set is a string containing an Oracle character set name.

a username and password must be given when connecting. In PHP use OCI_SYSOPER in oci_connect(). "". all these must be true: * * * The operating system process user is run as a member of the dba group PHP is linked with the ORACLE_HOME software (that is.Connecting to Oracle Using OCI8 sys — All base tables and views for the database data dictionary are stored in the sys schema and are critical for the operation of Oracle. AS SYSOPER access is available for members of the oper group. in the operating system dba group. OCI_SYSDBA). for example. Scripts that contain operating system authenticated privileged connection calls will connect successfully: $c = oci_connect("/". Remote Privileged Access With Zend Core for Oracle and any other PHP based on Oracle Instant Client. A database administrator can grant SYSDBA or SYSOPER to any user. theoretically. Operating System Authenticated Privileged Connections You can have the operating system perform the authentication for privileged connections based around the user that is running the web server system process. An operating system authenticated privileged connection is equivalent to the SQL*Plus connection: $ sqlplus / as sydba In PHP for / as sysdba access (where no username and password is used). Similarly. for example. 104 . In SQL*Plus a privileged session would be started like: $ sqlplus username/password@sid as sysdba The database will not permit the (possibly physically) “remote” operating system to authorize access. the library path needs to contain the same Oracle libraries. This is not recommended. Remote users can make privileged connections only when they have been given the appropriate Oracle access. If PHP is invoked by Apache. On Windows. not Oracle Instant Client. the SYSDBA privilege is assigned only to user sys. null. Also. null. the nobody user must be in the privileged Oracle group. the operating system groups are called ORA_DBA and ORA_OPER. By default. or Zend Core for Oracle) that the database is running as The database is your default local database. specified by the ORACLE_SID environment variable This would be typically be done by compiling and running PHP with the Oracle libraries used by the database. An extra Oracle password file needs to be created and a password needs to be used in the database connection. These connections are considered “remote” from the database because the libraries used by PHP are not those used by the running database.

If this parameter is not set to EXCLUSIVE. any OCI_SYSDBA connection will show the user as sys not c1. null.pwd that allows up to 10 privileged users with different passwords (this number can be changed later).Tuning Oracle Connections in PHP To set up a password file. USERNAME SYSDBA SYSOPER -----------------------------. Tuning Oracle Connections in PHP Connections to Oracle can be tuned by changing the OCI8 calls made. To do this.----------. and by tuning the database. create an Oracle password file: $ $ORACLE_HOME/bin/orapwd file=$ORACLE_HOME/dbs/acct. SQL> grant sysdba to c1. SQL> select * from v$pwfile_users. and enables you to have multiple users connect to the database as themselves.------SYS TRUE TRUE C1 TRUE FALSE Now in PHP you can use the following connection string: $c = oci_connect("c1". To add a new user to the password file use SQL*Plus: SQL> create user c1 identified by c1pw. by changing the network configuration. 105 . log in to the operating system shell as the Oracle database software owner. This is the default value.-----------remote_login_passwordfile string EXCLUSIVE EXCLUSIVE means the password file is only used with one database and not shared among several databases on the host. SQL> grant connect to c1. and start SQL*Plus: $ sqlplus / as sysdba SQL> show parameter remote_login_passwordfile NAME TYPE VALUE ----------------------------. OCI_SYSDBA). and not just as sys. One feature of a privileged connection is that if you issue a SELECT USER FROM DUAL statement.-----. "c1pw". From the operating system shell.pwd \ password=secret entries=10 This creates a password file named acct. '//localhost/XE'. The file is initially created with the password secret for users connecting with the username sys. A connection made with OCI_SYSOPER will show a user of public. you can change the value with the SQL*Plus and enter a command similar to the following command: SQL> alter system set remote_login_passwordfile='exclusive' 2 scope=spfile sid='*'. check the database initialization parameter remote_login_passwordfile is EXCLUSIVE.

Use the Best Connection Function Using oci_pconnect() makes a big improvement in overall connection speed of frequently used applications because it uses the connection cache in PHP. A new. } One way to optimize this is to simply set the environment variable NLS_DATE_FORMAT in the shell that starts the web server. This may involve a potentially expensive environment lookup. $pw.Connecting to Oracle Using OCI8 Connection Decisions There are a number of ways you can improve the performance of the PHP to Oracle connections. Pass the Character Set Explicitly passing the client character set name as the fourth parameter to the connection functions improves performance: $c = oci_connect("hr". return $c. "hrpwd". 'ja16euc'). $db) { $c = oci_pconnect($un. Sometimes different database users should have different session values so setting NLS_DATE_FORMAT globally is not possible. physical connection to the database does not have to be created if one already exists in PHP’s cache. Do Not Set the Date Format Unnecessarily You can often remove ALTER SESSION statements used after connecting. and optimizing common connection steps. consider tuning the timeout parameters or using oci_connect(). by choosing the best connection function. However if currently unused. $pw. Using a trigger means the date format is only set when the physical database connection is created the first time. PHP has to determine which client character set to use. "//localhost/XE". open persistent connections consume too much memory on the database server. oci_execute($s). This is because session settings are retained in cached connections. the ALTER SESSION can be moved to a logon trigger. $db). if your connection routine always sets the date format: function my_connect($un. $s = oci_parse($c. A logon trigger can be created using SQL*Plus by connecting as a privileged database user: $ sqlplus system/systempwd@//localhost/XE 106 . If you do not enter a character set and use the default. Each PHP connection will have the required date format automatically. The trigger does not fire when subsequent connect calls return a cached connection. For example. "alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS'"). passing the character set on connection. When oci_connect() is called multiple times in the one script or when persistent connections are used.

$pw. } Oracle does all the work setting the date format when the physical database connection is originally established and first used. / Trigger created. end my_set_date. Note the use of single quotes. 'hrpwd'. What you consider high depends on your application requirements and on implementation issues such as whether the web server and database are on the same host. Tuning Persistent Connections Persistent connections are great if the cost of opening a connection is high.Tuning Oracle Connections in PHP SQL> 2 3 4 5 6 7 8 create or replace trigger my_set_date after logon on database begin if (user = 'HR') then execute immediate 'alter session set nls_date_format = ''YYYY-MM-DD HH24:MI:SS'' '. And if Apache spawns a number of server processes. After connecting you can call the PL/SQL procedure. In PHP. '//localhost/XE'). If you cannot use a trigger because each PHP invocation needs different settings. 'select sysdate from dual'). $pw. $row = oci_fetch_array($s). $s = oci_parse($c. you can put the statements inside a PL/SQL procedure. The drawback is the connection uses Oracle resources even when no one is accessing the application or database. This trigger sets the session’s date format every time hr connects to the database from any client tool. which is one oci_execute() call to the database. which is the Oracle method of nesting single quotes inside a quoted string. and you need more than one session value changed. oci_execute($s). When PHP later uses a cached connection it will already have the desired date format. end if. each of them may have its own set of 107 . instead of multiple calls to execute ALTER SESSION statements. the connection function can simply become: function my_connect($un. $c = my_connect('hr'. $db). This connects as hr and queries the current date. return $c. The date format string is enclosed in a pair of two quotes. It shows the new format set by the trigger: 2007-05-04 13:50:35 If the connection is any user other than hr the standard default date format will be displayed: 04-MAY-07 Using a trigger like this only works when the required session setting is the same for all PHP application users that share the same database user name. $db) { $c = oci_pconnect($un. "\n". echo $row['SYSDATE'] .

ping_interval = 60 This parameter is the number of seconds that pass before OCI8 does a ping during oci_pconnect(). Setting oci8. Good application design gracefully recovers from failures. This is a quick operation. Regardless of the value of oci8. The expiry check happens whenever a PHP script finishes regardless of whether the script calls OCI8 functions. Pinging for Closed Persistent Connections There is no guarantee that the connection descriptor returned by oci_pconnect() represents a usable connection to the database. Timeout for Unused Persistent Connections oci8. the connection to the database may have become unusable due to a network error. In any application there are a number of potential points of failure including the network. all oci_pconnect() calls are treated like oci_connect() calls and are closed at the end of the script.ping_interval. a new connection is transparently created and returned by oci_pconnect().ini directives. the next time oci_pconnect() is called a new connection is created. a database error. If the ping determines the connection is no longer usable. The database administrator may have installed user profiles with CREATE PROFILE IDLE_TIMEOUT. This is a bad thing for scalability. causing a “round-trip” over the network. The proliferation of connections can be controlled with php. Oracle itself may be configured to close idle connections and release their database resources. If a connection has been expired. You need to balance performance (no pings) with having to handle disconnected Oracle sessions (or other changes in the Oracle environment) in your PHP code. oci_pconnect() will always check an Oracle client-side setting to see if the server was known to be available the last time anything was received from the server. To disable pinging. The default value is 60 seconds. the hardware and user actions such as shutting down the database. oci8. The ping interval is an easy way to improve connection reliability for persistent connections. or the Oracle network layer may time out the network. Setting this parameter to -1 (the default) means there is no timeout. Maximum Number of Persistent Connections Allowed oci8. For highest 108 . oci_pconnect() appears to be successful but an error is thrown when the connection is later used. When the limit is reached.ping_interval additionally physically sends a message to the server. When set to 0. for example in oci_execute(). PHP checks the database each time oci_pconnect() is called.persistent_timeout = -1 This parameter is the length in seconds that an Apache process maintains an idle persistent connection. If this happens. set the value to -1.Connecting to Oracle Using OCI8 connections to the database.max_persistent = -1 This parameter limits the number of persistent connections cached by each Apache process. or being timed out. Setting it to -1 (the default) means there is no limit. During the time PHP stored an unaccessed connection resource in its cache.

Both internal connection methods may be tried in sequence adding to the time delay before a PHP script gets the error. Tuning Oracle Net There are many ways to configure connection and authentication.ora file: NAMES. but do error recovery in your application code. In a basic Oracle10g installation.Tuning Oracle Connections in PHP reliability and scalability it is generally recommended that you do not use oci8. John Coggeshall’s article Improving Performance Through Persistent Connections discusses Apache configuration in more depth. Defines whether Apache can serve a number of documents to the one user over the same HTTP connection.DIRECTORY_PATH = (TNSNAMES) SQLNET. Table 8-2 Apache configuration parameters Parameter MaxRequestsPerChild MaxSpareServers KeepAlive Purpose Sets how many requests Apache will serve before restarting. Sets how many servers to keep in memory that are not handling requests. The issue is not specific to PHP. "abc").ping_interval.ora file. "hrpwd".ini directives work in harmony with your Apache settings and your timeouts happen predictably.AUTHENTICATION_SERVICES = (NONE) 109 . This depends on your Oracle Net and DNS settings. Apache Configuration Parameters You can also tune Apache to kill idle processes. Ideally your php. How Oracle is configured to authenticate the user’s credentials (here a username and password) can also have an effect. In SQL*Plus the connection: $ sqlplus hr/hr@abc Would be the same. The flexibility can cause a delay in getting an error back if the connection details are invalid or a database is not operational. For example a connection: $c = oci_connect("hr". one way to return an error as soon as possible is to set this in your client sqlnet. Could be evaluated by Oracle10g as using the Easy Connect syntax to host machine abc (using the default port and database service) or using a net alias abc configured in a tnsnames. which will also free up Oracle resources used by persistent connections. Table 8-2 lists the Apache configuration parameters that can be used to tune PHP.

// invalid db name The trace file.. you can tune the QUEUESIZE option in the listener.trc. Other Oracle Net Optimizations Oracle Net lets you tune a lot of other options too. If you are not using a tnsnames.ora file and see where time is being spent. with a USER level trace in sqlnet.ora file. (This may also add a small measure of security if your scripts accidentally allow arbitrary connection strings. The sqlnet. create a tnsnames.ora file. Check the Oracle Net documentation for details and for other authentication methods and authentication-type specific timeout parameters. 110 .. again. [10-MAY-2006 09:55:00:854] snlinGetAddrInfo: Name resolution failed for #c .. set the environment variable TNS_ADMIN to the directory that contains the sqlnet. "hrpwd".ora: trace_level_client = USER trace_directory_client = /tmp And the PHP code: $c = oci_connect("hr".ora in $ORACLE_HOME/network/admin/sample has some notes on the parameters that help.ora file should be on the machine running Apache and in the same directory as your tnsnames. The sample sqlnet. Another potential Oracle Net optimization.. Instead of using Easy Connect syntax. might be beneficial. If network consumption is an issue.ora and use a network alias. If you suspect this is the case. It stops users guessing database server hostnames they should not know about. [10-MAY-2006 09:54:58:100] nnftmlf_make_system_addrfile: system names file is .Connecting to Oracle Using OCI8 The DIRECTORY_PATH value disables Easy Connect’s //hostname:port/service syntax. For sites that have a large number of connections being made.ora file. The drawback is greatly reduced reliability.ora file.ora file. Although this may prevent privileged database connections.. including the session data unit size. for example /tmp/cli_3232.. but one to be used with caution. is to hardcode the database host IP address in the tnsnames. this. turn on Oracle Net tracing in your client sqlnet. Oracle Net’s Connection Pooling and Session Multiplexing features should be evaluated. The benefit may be small on platforms that cache the IP address well. Database resource usage of a large number of connections is potentially more likely to be significant than network consumption. which require operating system authorization.) Setting AUTHENTICATION_SERVICES to NONE stops different authentication methods being tried. This removes the need to do a hostname lookup. Check the Oracle Net Services Administrator’s Guide and the Oracle Net Services Reference for details of all the wonderful variety of Oracle Net options available. Tracing Oracle Net Sometimes your network is the bottleneck. shows: . You may also be able to tune your TCP/IP stack. "#c"). For example.

Here.1 on Oracle’s Metalink support site: Session based load balancing takes into account the number of sessions connected to each node and then distributes new connections to balance the number of sessions across the different nodes This can help when there is a connection “storm” and the normal allocation metrics do not get a chance to get updated fast enough.audses$ cache 10000. Make sure that you understand the lifetime of your applications connections. Shared Servers reduce the numbers of processes needed to handle database requests. the DBMS_SERVICE package lets you specify workload management goals. make sure that your applications are as efficient as possible.ini parameters to expire persistent connections. This is also recommended if you are using Oracle RAC (“Real Application Clusters”). This is documented in Note 220970. Reusing a previously opened connection is significantly faster than opening a fresh one. sys. This is a detailed topic.Tuning Oracle Connections in PHP The left hand column is the timestamp of each low level call. refer to Oracle’s manuals for more information. Large sites should benchmark persistent PHP connections and Oracle Shared Servers also known as “Multi Threaded Servers” (MTS).ora parameter PREFER_LEAST_LOADED_NODE_<listener_name> to OFF to use session based load balancing. Each connection will take some Oracle memory. so overall load can be reduced if idle connections are closed with Apache process timeouts or with the php. Connection Management in Scalable Systems Oracle achieves its well-known scalability in part through a multi-threaded architecture. Finally. 111 . tune the cache size of an internal sequence generator. A starting point is to change it to perhaps 10000: SQL> alter sequence sys. Reuse connections where possible. it shows a relatively big time delay doing name resolution for the non-existent host #c. This difference means care is required when designing scalable applications. but don’t be afraid to create new connections and close them as needed. Set the listener. This minimizes the length of time connections are held.audses$. PHP instead has a multi-process architecture. The cause is the configuration of the machine network name resolution. With Oracle RAC you can adjust the algorithm that decides which Oracle node handles each new connection. Using persistent connections is common for web sites that have high numbers of connections being established. For both RAC and non-RAC database. For sites with hundreds of connections a second.

.

"//localhost/XE"). 3. There is no one-stop function to do all these steps in a single PHP call. the functions available. Fetch ― Gets any query results back from the database. 'select city. "hrpwd". Bind ― Optionally lets you bind data values. transactions. but almost all scripts let the OCI8 fetch functions take care of this. Define ― Optional step allowing you to specify which PHP variables will hold the results. postal_code from locations'). You can also “define” where you want the results to be stored. for example.php <?php $c = oci_connect("hr". since Oracle’s actual text parse can occur at the execution stage. but it is trivial to create one in your application and you can then add custom error handling requirements. 4. oci_execute($s). Execute ― The database processes the statement and buffers any results. execute and fetch. Statements like CREATE and INSERT require only parsing and executing. Parsing is really just a preparatory step. The possible steps are: 1. tuning your queries. This is not commonly used. in the WHERE clause. Query Example A basic query in OCI8 is: query.CHAPTER 9 Executing SQL Statements With OCI8 This chapter discusses executing SQL statements using the Oracle OCI8 extension. Parse ― Prepares a statement for execution. 2. including how statements are executed. You can optionally “bind” local values into a statement similar to the way you use %s print format specifications in strings. and some tips and tricks that you might find useful in your applications. for better performance and security. 113 . $s = oci_parse($c. SQL Statement Execution Steps Queries using the OCI8 extension follow a model familiar in the Oracle world: parse. 5. This improves performance and security.

"select * from locations where city = 'Sydney'").'</td>'.php In PHP. Oracle Datatypes Each column has a datatype. The common built-in Oracle datatypes are: * * CHAR VARCHAR2 114 . which is associated with a specific storage format.$item. while ($row = oci_fetch_array($s. print '</tr>'. or by using both quoting styles. it is fully enclosed in double quotes: $s = oci_parse($c. } print '</table>'. oci_close($c). Strings with embedded quotes can be made by escaping the nested quotes with a backslash. single and double quotes are used for strings.php is: Figure 9-1 Output from query.Executing SQL Statements With OCI8 print '<table border="1">'. ?> The output from the script query. foreach ($row as $item) print '<td>'. OCI_RETURN_NULLS)) { print '<tr>'. To make the query a PHP string. The next example shows single quotes around the city name.

NVARCHAR2. Gets a new row as an object. Table 9-2 fetch_array() options. Parameter OCI_ASSOC OCI_NUM OCI_BOTH Purpose Return results as an associative array. for table 9-2 lists the oci_fetch_array() options. CLOB. VARCHAR2. XMLTypes are returned as strings. and DATE datatypes are stored directly in PHP variables. Table 9-1 OCI8 fetch functions OCI8 Function oci_fetch_all() oci_fetch_array() oci_fetch_assoc() oci_fetch_object() oci_fetch_row() oci_fetch() Purpose Gets all the results at once. Gets the next row as an array of your choice. NUMBER. BLOB. and BFILE datatypes use PHP descriptors and are shown in the Using Large Objects in OCI8 chapter. which returns the result of a given field. Table 9-1 lists the OCI8 fetch functions. all carefully documented in the PHP OCI8 Reference Manual. Gets the next row as an integer indexed array. Return results as a numerically indexed array. Return results as both associative and numeric arrays. Fetch Functions There are a number of fetch functions. and NCLOB are not supported in the OCI8 extension. Some of the functions have optional parameters that alter their behavior. NCHAR. Used with oci_result(). 115 . Gets the next row as an associative array.Fetch Functions * * * * * * * NCHAR and NVARCHAR2 NUMBER DATE BLOB CLOB and NCLOB BFILE XMLType The CHAR.

. country_name. } This displays: Roma . Associative arrays are keyed by the uppercase column name."<br>\n". A basic example to fetch results in a numerically indexed PHP array is: $s = oci_parse($c.10934 Tokyo . .. Otherwise only one of the similarly named columns will be returned by PHP: $s = oci_parse($c. "select postal_code from locations"). "select region_name.$res[1].". Note: Numbers and dates are fetched as strings and the Oracle globalization settings may affect their formatting.1689 Hiroshima . If you join tables where the same column name occurs with different meanings in both tables. postal_code from locations").LOB resource. $s = oci_parse($c.6823 Southlake – 26192 . while ($res = oci_fetch_array($s)) { echo $res["POSTAL_CODE"] . use a column alias in the query. " . "select city. } This displays: 00989 10934 1689 6823 26192 . Return the actual LOB data instead of an OCI..00989 Venice . oci_execute($s). In an associative array there is no table prefix for the column name. oci_execute($s). Refer to the chapter Globalization for more information. countries.Executing SQL Statements With OCI8 Parameter OCI_RETURN_NULLS OCI_RETURN_LOBS Purpose Return PHP NULL value for NULL data. "<br>\n".region_id as myreg. regions. while ($res = oci_fetch_array($s. OCI_NUM)) { echo $res[0] .region_id 116 .

The default mode of oci_execute() is OCI_COMMIT_ON_SUCCESS to commit changes. OCI_NUM+OCI_RETURN_NULLS). The result array can appear to have fewer columns than selected.region_id"). " " . Except in special cases. Update. The script output is: Americas Asia 3 Europe 1 Americas Americas . Delete. 2 . Update. Temporary tables are expensive to create and have no statistics for the Oracle optimizer to evaluate. "<br>\n". Delete. $res["REGION_ID"] . oci_execute($s). and you can’t always tell which column was NULL.Brazil 2 2 . This can be tricky when using numerically indexed arrays. $res["COUNTRY_NAME"] . or specify the OCI_RETURN_NULLS flag: $res = oci_fetch_array($s. Tom Kyte talks about global temporary tables on http://asktom. " . you want either all your changes to be committed. or none of them. . OCI8’s default commit behavior is like other PHP extensions and different from Oracle’s standard. or join tables when required.oracle. Transactions Using transactions to protect the integrity of data is as important in PHP as any other relational database application.com/. Create and Drop from countries inner join regions on countries. " " . The only-run-once installation sections of applications should contain almost all the CREATE TABLE statements used. "create table i1test (col1 number)"). .Argentina 2 Australia 3 . At the end of a script any uncommitted changes are automatically rolled back. } The query column alias MYREG is used as the index to the result array.Insert.Canada 2 Some of the fetch functions do not return NULL data by default. " " . Either use associative arrays so the column names are directly associated with their values. Applications in Oracle do not commonly need to create temporary tables at run time. 117 . while ($res = oci_fetch_array($s)) { echo $res["REGION_NAME"] ." . $res["MYREG"] . Create and Drop Executing Data Definition Language (DDL) and Data Manipulation Language (DML) statements. oci_execute($s). simply requires a parse and execute: $s = oci_parse($c1.region_id = regions.Belgium 1 2 . Insert. like CREATE and INSERT. Use inline views.

// automatically committed This can be handy for single INSERTs and UPDATEs. To commit any un-committed transactions for your connection. OCI_DEFAULT). do: oci_commit($c). Unnecessarily committing or rolling back impacts database performance as it causes unnecessary network traffic (“round trips”) between PHP and the database. In PHP a better name would have been NO_AUTO_COMMIT. To rollback. You specify not to auto-commit and begin a transaction with: $s = oci_parse($c. where the value of the C macro with the same name is actually the default value when nothing else is specified. To maximize efficiency. but transactional and performance requirements should be thought about before using the default mode everywhere. use transactions where appropriate. but we are stuck with the awkward usage. since you may end up auto-committing and later also unnecessarily explicitly committing. Be careful mixing and matching oci_execute() calls with both commit modes in one script. "insert into testtable values ('my data')"). do: oci_rollback($c).Executing SQL Statements With OCI8 In the following example the changes are committed immediately when the oci_execute() call is called: $s = oci_parse($c. Figure 9-2 Each round trip between PHP and the Database reduces scalability It is also causes extra processing and more IO to the database files. Transactions are automatically rolled back when you close the connection or at the end of the script. oci_execute($s. 118 . Benchmarking and testing your applications in your environment is wise. oci_execute($s). or you may simply commit at incorrect times. "insert into testtest values ('my data 2')"). // not committed The PHP parameter name OCI_DEFAULT is borrowed from Oracle’s Call Interface.

select name from logtable. changing oci_connect() to oci_new_connect() and oci_pconnect(): transactions. oci_fetch_all($s. } $c1 = oci_connect("hr". An audit record can be inserted even if the user decides to rollback their main change. Rerun this script a few times. end. var_dump($res). echo "</pre>". rollback. allows you to do autonomous transactions. execute updatelog('Fred’). "//localhost/XE"). 119 . $res). which are effectively sub-transactions. / SQL> SQL> SQL> SQL> insert into logtable values ('Sally'). echo "<pre>". An autonomous transaction can be committed or rolled back without affecting the main transaction. use SQL*Plus to create a table with a single date column: SQL> create table mytable (col1 date). NAME -----------------------------Fred You could call the PL/SQL function from PHP to log access. $query). The Transactional Behavior of Connections To see the transactional behavior of the three connection functions. SQL> create or replace procedure updatelog(name_p in varchar2) as pragma autonomous_transaction. begin insert into logtable (name) values(name_p). OCI_DEFAULT). PL/SQL. This might be useful for logging data access. An example is: SQL> create table logtable (name varchar2(30)). $query) { $s = oci_parse($c. "hrpwd". oci_execute($s.php <?php function do_query($c.Transactions Autonomous Transactions Oracle’s procedural language for SQL. commit.

To handle errors in OCI8. "')"). "select * from mytable"). For development. "select * from mytable"). do_query($c2. and you do not want your application pages to contain ugly error messages. enable the E_STRICT level for error_reporting in php. // No parameter passed 120 . "insert into mytable values ('" . Figure 9-3 Output from transactions. $r = oci_execute($s. Using oci_new_connect() for $c2 gives a new connection which cannot see the uncommitted data. ?> Using oci_connect() connection lets you query the newly inserted (but uncommitted) data because $c1 and $c2 refer to the same Oracle connection.php Handling OCI8 Errors The error handing of any solid application adds complexity and requires careful design. using the oci_error() function. Using oci_pconnect() is the same as oci_connect(). For a start. // No COMMIT occurs do_query($c1. "//localhost/XE").Executing SQL Statements With OCI8 $s = oci_parse($c1.ini. For connection errors.ini so you can catch any problems that will cause upgrade issues. $c2 = oci_connect("hr". "hrpwd". date('j:M:y') . "hrpwd". "//localhost/XE"). no argument is needed: $c = oci_connect("hr". Expect the unexpected. in a production system you would turn off display_errors in php. OCI_DEFAULT). if (!$c) { $e = oci_error(). Check all return codes. You do not want to leak internal information to web users.

$e = ob_get_contents(). pass the connection resource: $s = oci_parse($c.Handling OCI8 Errors var_dump($e). } ob_end_clean(). $pw. } For execution and fetching errors. function Connect(&$e. pass the statement resource: $rc = oci_execute($s). if (!$con) { DisplayOCIError(). using PHP’s output buffering functions may be a way to help hide errors from users. } For parse errors. return($con). $db). 121 . else $err = @oci_error(). } function DisplayOCIError($r = false) { if ($r) $err = @oci_error($r). if (isset($err['message'])) { echo htmlspecialchars($err['message']). $db) { ob_start(). // Statement handle passed var_dump($e). $un."\n". "select city from locations"). if (!$rc) { $e = oci_error($s). echo "<p><b>Error</b>:</p>\n". } You might consider using PHP’s @ to suppress function errors. // Connection handle passed var_dump($e). // Statement handle passed var_dump($e). if (!$s) { $e = oci_error($c). } $rc = oci_fetch_all($s. } else { echo 'Unknown DB error'. $pw. For pretty output. if (!$rc) { $e = oci_error($s). } echo '</pre>'. $con = @oci_connect($un. $results). echo "<pre>\n".

next tune the SQL. Figure 9-4 Not binding wastes database resources Binding is highly recommended. indexes and the Oracle optimizer. and finally tune the database. The database-centric approach to tuning is to first tune the application. Oracle must reparse and cache multiple statements. It can improve overall database throughput. It is almost always more efficient to select the minimum amount of data necessary and only return rows and columns that will be used by PHP. Consider using PL/SQL packages for complex data operations to minimize data transfers. even if someone else originally executed it. SQL tuning and Database tuning are covered in the Oracle documentation. If you do not bind.Executing SQL Statements With OCI8 } Tuning SQL Statements in PHP Applications Tuning is an art and a science. Efficient caching of statements by having reusable code and using bind variables are fundamental in improving database performance. 122 . Database tuning maximizes throughput and allows efficient use of buffering and I/O strategies. SQL tuning will help make efficient use of table design. On the OCI8 side. They let you re-execute a statement with different values for the variables and get different results. Oracle is more likely to find the matching statement in its cache and be able to reuse the execution plan and context for that statement. transaction management can help reduce round trips from PHP to the database. Using Bind Variables Bind variables are just like %s print format specifiers.

These are mostly used to return values from PL/SQL procedures and functions. $myeid). One of the notorious features is “magic quotes”. "select ". If the 123 . this syntax has been deprecated. there are also OUT binds that return values. oci_execute($s)." from mytable"). echo "Last name is: ". $res). extra functionality was added to PHP in an attempt to work around this kind of problem.Tuning SQL Statements in PHP Applications Figure 9-5 Binding improves performance and security Bind variables are also an important way to prevent SQL injection security attacks. A lot of the older documentation uses & in calls to oci_bind_by_name(). // No need to re-parse $myeid = 102. oci_fetch_all($s. oci_execute($s). oci_bind_by_name($s. then it may be possible for a malicious user to execute a SQL statement of their choice instead of the one you intended. echo "Last name is: ". Bind variables give a high level of automatic protection against SQL injection attacks and you do not need to resort to workarounds. $myeid = 101.$col."<br>\n". Over the years. Do not do this. The bind data needs to be accessible when oci_execute() is called. which will go away in PHP 6 because of the confusion caused. "select last_name from employees where employee_id = :eidbv"). oci_fetch_all($s. $res['LAST_NAME'][0] . $res). Using a local variable in a sub function may cause a scope problem. $res['LAST_NAME'][0] . SQL injection may occur when SQL statements are hard coded text concatenated with user input: $s = oci_parse($c. It may even cause you problems."<br>\n". which pass data into Oracle. Since the recent PHP call-by-reference clean up. As well as IN binds. $s = oci_parse($c. User data is always treated as data and never as part of the SQL statement. If the user input is not carefully checked. ":EIDBV".

you need to specify the otherwise optional length parameter. There is one case where you might decide not to use bind variables. This means the length parameter should also be passed to OCIBindByName() when returning a number: oci_bind_by_name($s. “:MB”. the optimizer does not have any information about the value you may eventually use when the statement is executed. Figure 9-6 Each individual request to the database returns a number of rows to a cache You can also change the value at runtime with the oci_set_prefetch() function: 124 .default_prefetch bytes. Another case when the length should be specified is when returning numbers. Subsequent OCI8 fetches will consume the data in the cache until eventually another batch of records is fetched from the database. The default value is 10. Default Prefetch Size You can tune PHP’s overall query performance with two configuration parameters: oci8. Increasing the prefetch value can significantly improve performance of queries that return a large number of rows. When queries contain bind variables. $mb. It minimizes database server “round-trips” by returning as much data as possible each time. Testing will show the optimal size. If your data is highly skewed. The OCI8 extension also caps the memory used by the prefetch buffer at 1024 * oci8. but Oracle handles the caching. you might want to hard code values. There is also an optional fifth parameter.default_prefetch = 10 This parameter sets the number of records to be returned by the database when each fetch occurs. numbers are converted to and from strings when they are bound.Executing SQL Statements With OCI8 PHP variable associated with an OUT bind does not exist. the database will return the specified number of rows to a cache in its client buffers and give PHP only the row (or rows) the OCI8 function call requested. Prefetching is similar to an “array fetch”. But if the data is derived from user input be sure to sanitize it. which is the datatype. When pre-fetching is enabled. This mostly used for binding LOBS and result sets as shown in a later chapter. 10). By default in OCI8. There is no benefit using too large a prefetch value.

100). The database can directly look up the statement in its cache without having to parse the statement. further reducing network traffic and database server load. Figure 9-7 The second time a statement is issued the statement text does not need to be sent to the server The cache is per-Oracle session so this feature is most likely to be useful when persistent connections are used. // 10 is default oci8. Default Statement Cache Size You can set a client cache for SQL statement text with the php. Limiting Rows and Creating Paged Datasets Oracle’s SQL does not have a LIMIT keyword.Limiting Rows and Creating Paged Datasets $s = oci_parse($c. There are several ways to limit the rows returned in OCI8.ini directive: oci8. offsetting the reduced load on the database host. The statement cache also means slightly more load is put on the PHP host. It is not in the SQL standard and the vendors that use it have different implementations. "select city from locations"). oci_execute($s). The client cache means even the text of the statement does not need to be transmitted to the database more than once. The oci_fetch_all() function has optional arguments to specify a range of results to fetch. The client-side statement cache is in addition to the standard database statement cache.statement_cache_size = 20 The default is 20 statements. All rows preceding those you want still have to be fetched from the database. not by Oracle’s native functionality. there is a time/memory trade-off when tweaking this parameter.default_prefetch $res = oci_fetch_array($s). This is implemented by the extension. Like many tuning options. Caching can be disabled by setting the value to 0. 125 . oci_set_prefetch($s.

so you cannot bind the text of the statement and expect it to be executed. rownum as rnum from (YOUR_QUERY_GOES_HERE -. ":maxrow". $res. // row number of first row to return $maxrow = 8. oci_fetch_all($s. $maxrow).Executing SQL Statements With OCI8 $firstrow = 3. oci_bind_by_name($s. // row number of last row to return $pagesql = "select * from ( select a. $res). var_dump($res). Bind data is not treated as code. oci_bind_by_name($s. var_dump($res). ?> Note that $mystmt is not bound. $minrow). In PHP you might do this: <?php $mystmt = "select city from locations order by city". The canonical paging query for Oracle8i onwards is given on http://asktom. oci_execute($s). It is more efficient to let Oracle do the row selection. ":minrow".including the order by) a where rownum <= MAX_ROWS ) where rnum >= MIN_ROWS MIN_ROWS is the row number of first row and MAX_ROWS is the row number of the last row to return.com: select * from ( select a.*. $pagesql).*. oci_fetch_all($s.oracle. The output of the script is: array(2) { ["CITY"]=> array(5) { [0]=> string(6) "Geneva" [1]=> string(9) "Hiroshima" [2]=> string(6) "London" [3]=> string(11) "Mexico City" 126 . $numrows). $minrow = 4. oci_execute($s). $numrows = 5. $s = oci_parse($c. rownum as rnum from ( $mystmt ) a where rownum <= :maxrow) where rnum >= :minrow". $firstrow.

For example to get the 11th to 20th names the query is: SELECT last_name FROM (SELECT last_name. The query: SELECT last_name.Limiting Rows and Creating Paged Datasets [4]=> string(6) "Munich" } ["RNUM"]=> array(5) { [0]=> string(1) [1]=> string(1) [2]=> string(1) [3]=> string(1) [4]=> string(1) } } "4" "5" "6" "7" "8" An alternative query syntax uses Oracle’s analytic ROW_NUMBER() function.---------Abel 1 Ande 2 Atkinson 3 . . ROW_NUMBER() OVER (ORDER BY last_name) AS MYR FROM employees) WHERE MYR BETWEEN 11 and 20 In SQL*Plus the output is: LAST_NAME ------------------------Bissot Bloom Bull Cabrio Cambrault Cambrault Chen Chung Colmenares Davies 127 . ROW_NUMBER() OVER (ORDER BY last_name) AS myr FROM employees Returns two columns identifying the last name with its row number: LAST_NAME MYR ------------------------. . By turning this into a subquery and using a WHERE condition any range of names can be queried.

"insert into mytable (mydata) values ('Hello')”). SQL> SELECT myseq. Sequence generation is useful to generate unique primary keys for your data and to coordinate keys across multiple tables. Together they can automatically insert incrementing identifiers when table rows are created. Sequence generators are defined in the database and return Oracle numbers. oci_execute($s). Sequence numbers are generated independently of tables. the same sequence generator can be used for more than one table or anywhere that you want to use a unique number. oci_execute($s).Executing SQL Statements With OCI8 Auto-Increment Columns Auto increment columns in Oracle can be created using a sequence generator and a trigger. NEXTVAL ---------1 To create an auto-increment column on a table SQL> CREATE TABLE mytable (myid number. In SQL*Plus a sequence can be created and called like: SQL> CREATE SEQUENCE myseq. Querying the table in SQL*Plus shows the MYID values were automatically inserted: SQL> select * from mytable. "insert into mytable (mydata) values ('Bye')”).nextval FROM dual. The similar CURRVAL operator returns the current value of a sequence without incrementing the generator.nextval INTO :new. 128 . / In PHP insert two rows: $s = oci_parse($c. A sequence generator returns unique values when it is called. This gives the next available number and increments the generator. Therefore. MYID ---------2 3 MYDATA -------------------Hello Bye The identifier numbers start at 2 because the example query shown above when the sequence was created returned 1 and incremented the generator.myid FROM DUAL. $s = oci_parse($c. A trigger is a PL/SQL procedure that is automatically invoked at a pre-determined point. END. SQL> CREATE TRIGGER mytrigger BEFORE INSERT ON mytable FOR EACH ROW BEGIN SELECT myseq. mydata VARCHAR2(20)). You can get a new value from a sequence generator using the NEXTVAL operator in a SQL statement.

You must be connected as the system user in this particular example. Oracle’s general guideline is to let the database manage data and to transfer the minimum amount across the network. last_name from employees where regexp_like(first_name. Some examples of useful database features are regular expressions and analytic functions.oracle.Exploring SQL Exploring SQL Explore the SQL and PL/SQL languages. Keeping a thin interface between your application layer and the database is also good programming practice. The following query gets both spellings of Stephen: select first_name. Tom Kyte’s popular site. Regular Expressions in SQL Regular expressions were first introduced in Oracle 10g Release 10. initial_extent) from all_tables group by max_extents. and extended in Release 10. Other analytic functions allow you to get basic information like standard deviations or do tasks such as ranking (for Top-N or Bottom-N queries) or do linear regressions. 129 . http://asktom. corr(max_trans. Data is a core asset of your business. Oracle’s regular expressions conform to POSIX regular expression standard and the Unicode Regular Expression Guidelines. autonomous transactions and spatial functionality are left for you to investigate further. CORR() returns the coefficient of correlation of a set of number pairs.2. has a lot of very useful information. Here is an example of a correlation. Make maximum reuse of functionality that already exists. '^Ste(v|ph)en$'). Avoid shipping data from the database to PHP for unnecessary post processing. since it depends on table data not available to hr: select max_extents.com.1. Analytic Functions in SQL Oracle’s Analytic functions are a useful tool to compute aggregate values based on a group of rows. It should be treated consistently across your applications. Many more features including.

.

It is a server-side. If you turn on SET SERVEROUTPUT beforehand. When deciding whether to write PHP on the client or PL/SQL in the server. In Oracle’s SQL*Plus it is run by entering the text at the prompt and finishing with a single / to tell SQL*Plus to run the code. sending emails. Using PL/SQL gives your application access to Oracle’s better date and number handling.. change notification. If you write in PL/SQL. Some functionality should only ever be in the database. In Oracle. the cost of data transfer across the network and the re-usability of the code.. You can run this in many tools. just to name a few. dbms_output. PL/SQL enables you to mix SQL statements with procedural constructs.CHAPTER 10 Using PL/SQL with OCI8 PL/SQL is Oracle’s procedural language extension to SQL. job scheduling and TCP access. Packages exist for full text indexing. you can create these to be fired when an event such as a data insert or a user logon occurs. You can create stored procedures. begin select salary into sal_l from employees where employee_id = 191.put_line('No results returned'). PL/SQL Overview There are a number of pre-supplied PL/SQL packages to make application development easier. and can use it to efficiently insert and fetch data. consider your skill levels in the languages. queuing. for example to make sure your financial data is not affected by PHP’s floating point semantics.put_line('Salary is ' || sal_l). END) An exception-handling (EXCEPTION) part that handles error conditions For example: declare sal_l pls_integer. stored procedural language that is easy-to-use. PHP can call PL/SQL blocks to make use of advanced database functionality. exception when no_data_found then dbms_output. then SQL*Plus will display the output messages after execution: 131 . A PL/SQL block has three basic parts: * * * A declarative part (DECLARE) An executable part (BEGIN . such as data change triggers. functions and packages so your business logic is reusable in all your applications. end. including PHP. all your Oracle applications in any tool or client language can reuse the functionality. PL/SQL has a ‘wrap’ code obfuscation facility to protect the intellectual property of your applications.

Anonymous Blocks An anonymous block is a PL/SQL block that appears in your application and is not named or stored in the database. Errors that occur during execution can be dealt with in the exception-handling part. and similar items. procedures. PL/SQL blocks can appear wherever SQL statements can appear. they are generally for one-time use either in a script or as SQL text dynamically submitted to the Oracle server. The optional declarative part is written first. 12 / Salary is 2500 Other tools have different ways of indicating the end of the statements and how to switch server output on.put_line('No results returned'). Procedures can be created in SQL*Plus like: 132 . where you define types. They can be enabled and disabled to prevent them being used. Stored or Standalone Procedures and Functions A stored procedure or function is a PL/SQL block that Oracle stores in the database and can be called by name from an application. 7 dbms_output. 11 end. In many applications. and variables in packages can be used from other packages. or functions. 3 begin 4 select salary into sal_l 5 from employees 6 where employee_id = 191. if anything they reference is not available. Blocks.Using PL/SQL with OCI8 SQL> set serveroutput on SQL> declare 2 sal_l pls_integer. When you create a stored procedure or function. The previous example is an anonymous block. Procedures. 8 exception 9 when no_data_found then 10 dbms_output. Oracle stores its parsed representation in the database for efficient reuse.put_line('Salary is ' || sal_l). A PL/SQL block groups related declarations and statements. Packages and Triggers PL/SQL code is generally categorized as one of the following: * * * * Anonymous block Stored procedure or function Package Trigger Procedures. Because these blocks are not stored in the database. variables. functions. Only the executable part of a PL/SQL block is required. Functions return a value when executed. They may also have an invalid state.

functions and triggers can be created using PHP. use the SQL*Plus SHOW ERRORS command to display any error messages Packages Typically. Executing SQL Statements with OCI8. 8 end mypack. i_p). SQL> 2 3 4 5 6 create or replace procedure myproc(d_p in varchar2. end. 4 / SQL> create or replace package body mypack as 2 function myfunc(i_p in number) return varchar2 as 3 d_l varchar2(20). stored procedures and functions are encapsulated into packages. Creating PL/SQL Procedures in PHP Procedures. 3 end mypack. i_p in number) as begin insert into mytab (mydata. If that definition is unchanged. myid number). or event. This helps minimizes recompilation of dependent objects. myid) values (d_p. If you have errors creating a PL/SQL block. view. 9 / Triggers A database trigger is a stored procedure associated with a database table. Programs like PHP can run the procedure later. The package specification defines the signatures of the functions and procedures.Creating PL/SQL Procedures in PHP SQL> create table mytab (mydata varchar2(40). or take some follow-up action. to record it. to prevent erroneous operations or fix new data so that it conforms to business rules. 7 end. / The procedure is just created. 6 return d_l. For example. The trigger can be called after the event. 4 begin 5 select mydata into d_l from mytab where myid = i_p. SQL> create or replace package mypack as 2 function myfunc(i_p in number) return varchar2. under the heading Auto-Increment Columns.php <?php 133 . An example of a trigger was shown in the previous chapter. The trigger can be called before the event. to create the procedure myproc the code is: createmyproc. code that invokes it will not need to be recompiled even if the implementation in the package body changes. not run.

the block contains a single procedure call.php <?php $c = oci_connect('hr'. oci_execute($s). $plsql). Calling PL/SQL Procedures and Functions To invoke the previously created PL/SQL procedure. '//localhost/XE'). $s = oci_parse($c. ?> 134 . '//localhost/XE'). "begin myproc('Alison'. end. '//localhost/XE').php <?php $c = oci_connect('hr'. if ($r) { echo 'Procedure created'. echo "Name is: ". "end. which is different to the way SQL statements are written. 123)"). i_p in number) as " .myfunc(123). "myproc(d_p in varchar2. oci_bind_by_name($s. 20). oci_execute($s). $plsql = "create or replace procedure " . In the next example. 'hrpwd'. ':ret'. $s = oci_parse($c. $r. ?> The call command is actually a SQL command and does not have a trailing semi-colon. "begin " . ?> Calling a PL/SQL function needs a bind variable to hold the return value. } ?> Note that there is a semi-colon after the PL/SQL keyword end. oci_execute($s).".Using PL/SQL with OCI8 $c = oci_connect('hr'. i_p)."). '//localhost/XE'). $r = oci_execute($s). 'hrpwd'. 456). Using the function myfunc() created above: plsqlfunc.php <?php $c = oci_connect('hr'. You can also use an anonymous block."). 'hrpwd'. end. $s = oci_parse($c.$r. 'hrpwd'. but you could include any number of other PL/SQL statements: anonplsql. "begin :ret := mypack. $s = oci_parse($c. use the SQL CALL statement like: callplsql. "insert into mytab (mydata. "call myproc('Chris'." . myid) values (d_p.

$s = oci_parse($c. if (!$r) { $m = oci_error($s). $r = oci_execute($s).php <?php $c = oci_connect('hr'. myid) values (d_p. PL/SQL Success With Information Warnings A common PL/SQL error when creating packages. // A PL/SQL statement with deliberate error: not_mytab doesn’t exist $plsql = "create or replace procedure myproc(d_p in varchar2. } else { // A normal SQL-style error 135 . PL/SQL Errors in PHP Some common PL/SQL errors you might encounter are: * * Success with information warnings Incorrect end of line terminators on Windows platforms This section gives a description of what may cause these errors. procedures or triggers is: Warning: oci_execute(): OCI_SUCCESS_WITH_INFO: ORA-24344: success with compilation error You can get more information about the problem cause by querying Oracle’s user_errors table. 'hrpwd'. i_p in number) as begin insert into not_mytab (mydata. i_p). The PHP code to check for informational errors and warnings is shown by this example that creates a procedure referencing a non-existent table and then queries the user_errors table when an ORA-24344 error occurs: plsqlerr. end. '//localhost/XE').PL/SQL Errors in PHP The output is: Name is: Chris This example also shows how to call a function inside a package using the syntax packagename. and ways to resolve them. $plsql).".procedurename(). if ($m['code'] == 24344) { // A PL/SQL "success with compilation error" show_compilation_errors($c).

connect to SQL*Plus and use SHOW ERRORS: SQL> connect hr/hrpwd@//localhost/XE Connected. Alternatively to show the PL/SQL errors. "\n".' || TEXT FROM USER_ERRORS ORDER BY NAME. MESSAGE_NUMBER"). "SELECT NAME || ': ' || ATTRIBUTE || ' at character ' || POSITION || ' of line ' || LINE || ' . SQL> show errors procedure myproc Errors for PROCEDURE MYPROC: LINE/COL -------4/7 4/19 ERROR --------------------------------------------------------PL/SQL: SQL Statement ignored PL/SQL: ORA-00942: table or view does not End of Line Terminators in PL/SQL with Windows PHP On Windows platforms the additional messages from show_compilatation_errors() sometimes include: 136 . $m['message'].Using PL/SQL with OCI8 echo "Error is ". foreach ($row as $item) { print "<td>". } print "</table>". while ($row = oci_fetch_array($s.php on line 11 MYPROC: ERROR at character 7 of line 4 . Character 19 is the not_mytab table name. LINE. print "<table border='1'>\n".PL/SQL: ORA-00942: table or view does not exist Looking at the PL/SQL code creating the procedure."</td>". OCI_ASSOC+OCI_RETURN_NULLS)) { print "<tr>". ATTRIBUTE. } } // Display PL/SQL errors function show_compilation_errors($c) { $s = oci_parse($c. character 7 on line 4 of the PL/SQL code is the INSERT statement. } print "</tr>\n".PL/SQL: SQL Statement ignored MYPROC: ERROR at character 19 of line 4 . } ?> This displays: Warning: oci_execute(): OCI_SUCCESS_WITH_INFO: ORA-24344: success with compilation error in plsqlerr.($item?htmlentities($item):" "). oci_execute($s). POSITION.

which is allocated with oci_new_collection(). i_p). Collections work like the arrays found in most third-generation programming languages. i_p).Oracle Collections in PHP PLS-00103: Encountered the symbol "" when expecting one of the following: Followed by a list of keywords or tokens the PL/SQL parser was expecting. " "end. * Convert the file to UNIX-style line-feeds using a conversion utility or editor. collections are manipulated by methods on a collection resource. one for an array of people’s names. 137 . and trees. myid) values (d_p. 3 friend_name varchar2(20). nested tables. SQL> create table emails ( 2 user_id varchar2(10). SQL> drop table emails. nested tables. .". and one for an array of email addresses. . .". you can use them to move columns of data into and out of database tables or between client-side applications and stored subprograms. . Oracle Collections in PHP Many programming techniques use collection types such as arrays. Collections are effectively arrays. This can happen when the end of line characters in a multi-line PL/SQL string are Windows carriage-return line-feeds: $plsql = "create or replace procedure myproc(d_p in varchar2. VARRAYs (short for variable-size arrays) use sequential numbers as subscripts to access a fixed number of elements. i_p in number) as " "begin " "insert into mytab (mydata. To support these techniques in database applications. Use PHP string concatenation with appropriate white space padding: $plsql = . In a simple email address book demonstration (created by Charles Poulsen from Oracle). 4 email_address varchar2(20)). and variable-size arrays. i_p in number) as begin insert into mytab (mydata. sets. lists. two VARRAYs are created. Use one of these solutions to fix the problem: * * Write the PL/SQL code on a single line: $plsql = "create or replace procedure myproc . collections can be passed as parameters. A collection is an ordered group of elements. PL/SQL provides the datatypes TABLE and VARRAY. end. . Similar to LOBs. which allow you to declare index-by tables. bags. So. Also. all of the same type. "create or replace procedure " "myproc(d_p in varchar2. Each element has a unique subscript that determines its position in the collection.". myid) values (d_p.

p_email_addresses. :friends. 138 . 3 / SQL> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 create or replace procedure update_address_book( p_user_id in varchar2. $email_coll->append($friends_emails[$i]). :emails). p_friend_name(i). 3 / SQL> create or replace type friend_array as 2 varray(100) of varchar2(20). friend_name. end. $email_coll = oci_new_collection($c. $user_name = 'cjones'. 'FRIEND_ARRAY').count loop insert into emails (user_id. $i++) { $friend_coll->append($friends_names[$i]). "begin update_address_book(:name. the names and email addresses are inserted into the database. updateaddresses."). When this executes. $friends_names = array('alison'. The following PHP code creates a collection of names and a collection of email addresses. 'EMAIL_ARRAY'). 'aslam'). By binding as OCI_B_NTY (“Named Type”) we can pass collections to the PL/SQL procedure arguments. / The update_address_book() procedure loops over all elements of the address collection and inserts each one. $i < count($friends_names).com'. end update_address_book. '//localhost/XE'). end loop. These collections are bound to the arguments of the PL/SQL address_book() call. In PHP we create collection variables and use the append() method to add elements to each array.Using PL/SQL with OCI8 SQL> create or replace type email_array as 2 varray(100) of varchar2(20). $friend_coll = oci_new_collection($c. for i in 1 . $friends_emails = array('alison@example. email_address) values (p_user_id. 'hrpwd'.php <?php $c = oci_connect('hr'. p_email_addresses(i)).com'). p_email_addresses email_array) is begin delete from emails where user_id = p_user_id.. } $s = oci_parse($c. for ($i=0. 'aslam@example. p_friend_name friend_array.

this can be very efficient for insertion. OCI_B_NTY). 4 procedure myselproc(p_arr out arrtype. USER_ID ---------cjones cjones FRIEND_NAME -------------------alison aslam EMAIL_ADDRESS -------------------alison@example. We can bind a PHP array containing all data and send it to the database with a single oci_execute(). The p_count parameter is used to make sure PL/SQL does not try to return more values than the PHP array can handle. ':name'. -1.2 improved collection support with a new function oci_bind_array_by_name().com Other OCI8 collection methods allow accessing or copying data in a collection. 7 procedure myselproc(p_arr out arrtype. Array Binding and PL/SQL Bulk Processing PHP 5. myinsproc(). 5 end mypkg. OCI_B_NTY). p_count in number). The second procedure. selects from the table using the BULK COLLECT clause and returns the array as the OUT parameter p_arr. -1. $friend_coll. 6 / SQL> create or replace package body mypkg as 2 procedure myinsproc(p_arr in arrtype) is 3 begin 4 forall i in indices of p_arr 5 insert into mytab values (p_arr(i)). will be passed a PHP array to insert. SQL> create or replace package mypkg as 2 type arrtype is table of varchar2(20) index by pls_integer. 3 procedure myinsproc(p_arr in arrtype). SQL> drop table mytab. oci_bind_by_name($s.com aslam@example.1. The first. ?> The emails table now has the inserted data: SQL> select * from emails. Coupled with a helper PL/SQL function. p_count in number) is 8 begin 9 select name bulk collect 10 into p_arr 11 from mytab 12 where rownum <= p_count. This example creates a PL/SQL package with two procedures. $user_name). oci_bind_by_name($s. 139 . ':emails'. It uses Oracle’s “bulk” FORALL statement for fast insertion. $email_coll. oci_execute($s). 6 end myinsproc. SQL> create table mytab(name varchar2(20)).Oracle Collections in PHP oci_bind_by_name($s. myselproc(). ':friends'.

end. var_dump($r). meaning use the actual length of the character data. The value 20 is the width of the database column. SQLT_CHR). SQLT_CHR). In this example. count($a). The number of elements $numelems to be fetched is passed into myselproc() by being bound to :n. 'hrpwd'. end mypkg. $a. oci_bind_by_name($s. 20. $s = oci_parse($c. $a = array('abc'. oci_execute($s). 140 . The value is also used in the oci_bind_array_by_name() call so the output array $r is correctly sized to accept that number of rows back. NAME -------------------abc def ghi jkl To query the table in PHP. This limits the query to return $numelems rows. the number of elements is count($a).php <?php $c = oci_connect('hr'. "begin mypkg. ":p1". $numelems = 4. and the data length is given as –1. 'jkl'). $c = oci_connect("hr". $r. $numelems). -1. end. oci_execute($s). // print the array A number of other Oracle types can be bound with oci_array_bind_by_name(). "hrpwd".myselproc(:p1.myinsproc(:p1). use: arrayinsert. It takes not just the upper data length. There are more examples of oci_bind_array_by_name() in the automated tests under the OCI8 CVS tree. ?> The oci_bind_array_by_name() function is similar to oci_bind_by_name(). for example SQLT_FLT for floating point numbers. ":n"."). the myselproc() function can be called. These are also bundled with the PHP source code. Any lower value could result in shorter strings being returned to PHP. oci_bind_array_by_name($s. $numelems. oci_bind_array_by_name($s. / To insert a PHP array into mytab. $s = oci_parse($c. :n). 'def'. but also the number of elements in the array. "//localhost/XE"). ":p1". '//localhost/XE'). "begin mypkg."). 'ghi'.Using PL/SQL with OCI8 13 14 15 end myselproc. The inserted data shown in SQL*Plus is: SQL> select * from mytab.

It can render search results in various formats including unformatted text. Oracle Text also offers advanced features like classification. / 141 .Oracle Collections in PHP Using PL/SQL Types in PHP Sometime you have to call PL/SQL procedures that are designed for interacting with other PL/SQL code. the Oracle Text CTX_THES package procedures return Oracle PL/SQL types that are not easily accessible in OCI8.” Let’s set up an example package with a similar interface to CTX_THES. end SuppliedPkg. just returns random data in the parameter: ctx. end SuppliedProc. p_p(i). and support for information visualization metaphors. procedure SuppliedProc(p_p in out nocopy SuppliedTabType). in files. ctx. for i in 1. For example.delete. Oracle Text supports multiple languages and uses advanced relevance-ranking technology to improve search quality. and so on. and original document format. / create or replace package body SuppliedPkg as procedure SuppliedProc(p_p in out nocopy SuppliedTabType) is begin -. search. HTML/XML section searching.Package "SuppliedPkg" simulates Oracle Text's CTX_THES. context queries. This example. -. Oracle Text is described in the Oracle marketing datasheets like this: “Oracle Text uses standard SQL to index. type SuppliedTabType is table of SuppliedRec index by binary_integer.sql -.random. end SuppliedPkg. create or replace package SuppliedPkg as type SuppliedRec is record ( id number. and on the web. Oracle Text can perform linguistic analysis on documents.It has a procedure that returns a PL/SQL type.Create some random results p_p. HTML with term highlighting. end loop.5 loop p_p(i).data := 'Random: ' || i || (1+ABS(MOD(dbms_random.id := i.100000))).. and analyze text and documents stored in the Oracle database.sql. Boolean operations. data varchar2(100) ). pattern matching. PL/SQL types differ from SQL types that are created with the CREATE TYPE command. clustering. mixed thematic queries. as well as search text using a variety of strategies including keyword searching.

data.id. ':res_id'. p_data IN OUT MyDataRec) as l_results SuppliedPkg.count loop p_id. oci_bind_by_name($s.SuppliedTabType.Using PL/SQL with OCI8 Run the file ctx. create or replace type MyIdRec as table of number.. To call SuppliedProc().sql in SQL*Plus: $ sqlplus hr/hrpwd@//localhost/XE @ctx. p_data(i) := l_results(i). create a wrapper function in PL/SQL to convert the PL/SQL type SuppliedTabType to a pair of SQL types. 'MYDATAREC'). "//localhost/XE"). $res_data. p_data. $s = oci_parse($c. OCI_B_NTY). :res_data).sql and use SQL*Plus to run it like the previous script: myproc. 'begin MyProc(:res_id. 'MYIDREC'). oci_execute($s).get results from existing procedure SuppliedPkg. for i in 1. 142 . ':res_data'. OCI_B_NTY). Create myproc. "hr". $res_id.').extend. begin -. $res_data = oci_new_collection($c. -1. $res_id = oci_new_collection($c.php <?php $c = oci_connect("hr".copy to a type we can pass back to PHP p_id. p_id(i) := l_results(i). p_data.SuppliedProc() and converts its output to SQL types. -. / create or replace procedure MyProc (p_id IN OUT MyIdRec.delete. / create or replace type MyDataRec as table of varchar2(100).extend.delete. end. representing the pre-supplied functionality. end MyProc.Create a wrapper procedure that calls the pre-supplied -.sql -.sql This is the “fixed” part of the problem. -1. end loop. oci_bind_by_name($s.l_results. / Now you can call MyProc(): ctx.SuppliedProc(l_results).

refcur. $i++) { $id = $res_id->getElem($i). Using REF CURSORS for Result Sets REF CURSORS let you return a set of query results to PHP. Once the PL/SQL procedure has completed the value in $refcur is treated like a prepared statement identifier. 4. Data: $data<br>". In PHP you bind an OCI_B_CURSOR variable to a PL/SQL REFCURSOR procedure parameter and retrieve the rows of the result set in a normal fetch loop. After MyProc() has been called. $data = $res_data->getElem($i). // Excute the call to the PL/SQL stored procedure $stid = oci_parse($c. } ?> This allocates two collections and binds them as the parameters to MyProc().php <?php $c = oci_connect('hr'. the collection method getElem() is used to access each value returned. The procedure returns a REF CURSOR containing the employees’ last names. As an example. echo "Id: $id. 'hrpwd'.Using REF CURSORS for Result Sets for ($i = 0. 5. '//localhost/XE'). $refcur = oci_new_cursor($c). Data: Data: Data: Data: Data: Random: Random: Random: Random: Random: 155942 247783 365553 487553 589879 An alternative implementation could be to create MyProc() to return arrays and use oci_bind_array_by_name(). 3. $i < $res_id->size(). It is simply executed like a normal query and used in a fetch loop. 2. SQL> 2 3 4 5 6 7 create or replace procedure myproc(p1 out sys_refcursor) as begin open p1 for select last_name from employees where rownum <= 5. / In PHP the oci_new_cursor() function returns a REF CURSOR. The output is similar to: Id: Id: Id: Id: Id: 1. 143 . "call myproc(:rc)"). This is bound to :rc in the call to myproc(). The PL/SQL procedure contains the code. end. we create a PL/SQL package with a procedure that queries the employees table.

$r = oci_execute($s). } 144 . $s). DBMS_OUTPUT is like a buffer. return $r. Here are sample functions to enable and fetch DBMS_OUTPUT.ENABLE(NULL). The drawback is that it is not asynchronous. $refcur. } echo '</table>'. $p) { if ($p) $s = "BEGIN DBMS_OUTPUT. END. Your code turns on buffering. else $s = "BEGIN DBMS_OUTPUT.Using PL/SQL with OCI8 oci_bind_by_name($stid. echo '<table border="1">'. oci_execute($stid). -1. The PL/SQL procedure or block runs to completion before any output is returned. Getting Output with DBMS_OUTPUT The DBMS_OUTPUT package is the standard way to “print” output in PL/SQL.". OCI_B_CURSOR). ?> The output is: Abel Ande Atkinson Austin Baer Records returned by REF CURSORS cannot currently take advantage of row pre-fetching.DISABLE(). puts some output in the buffer. END. while($row = oci_fetch_assoc($refcur)) { echo '<tr>'. // Execute and fetch from the cursor oci_execute($refcur). oci_free_statement($s). ':rc'. foreach ($row as $c) { echo "<td>$c</td>\n".". dbmsoutput.inc <?php // Turn dbms_output ON or OFF function SetServerOutput($c. $s = oci_parse($c. Other database connections cannot access your buffer. } echo '</tr>'. and then fetches from the buffer.

"call dbms_output. $ln.GET_LINE(:LN. you may want to write your own code to stream results as they are fetched from the database instead of returning them in one array from DbmsOutputFetch(). "//localhost/XE"). function GetDbmsOutput($c) { $res = false.").php <?php include("dbmsoutput. To use GetDbmsOutput(). ?> The output is the put_line() text: Hello. $s = oci_parse($c. 255) && oci_bind_by_name($s. enable buffering before executing the PL/SQL code that creates output. $st)) { $res = array(). oci_execute($s). world! If you expect large amounts of output. or false. END. ":ST". return $res. // Display the output $output = GetDbmsOutput($c).put_line('Hello.2. // Turn on buffering of output SetServerOutput($c. This was the DBMS_OUTPUT line size limit prior to Oracle 10g Release 10. while (($succ = oci_execute($s)) && !$st) $res[] = $ln.Getting Output with DBMS_OUTPUT // Returns an array of dbms_output lines. foreach ($output as $line) echo "$line<br>". } oci_free_statement($s). "BEGIN DBMS_OUTPUT. ":LN". world!')"). // Create some output $s = oci_parse($c. if (oci_bind_by_name($s. } ?> In GetDbmsOutput() the :LN line variable is arbitrarily bound as length 255. true).inc"). :ST). $c = oci_connect("hr". 145 . dbmsoutput. "hrpwd". if (!$succ) $res = false.

then it is easy to slow performance or get memory errors. especially if the database is running in Oracle’s shared server mode. you can also get output by logging to database tables or using packages like UTL_FILE and DBMS_PIPE to asynchronously display output to a separate terminal window. If you bind this size. Avoid binding 32Kb. 146 . If DBMS_OUTPUT does not suit your application.Using PL/SQL with OCI8 In Oracle 10g Release 10. the maximum line length was changed from 255 bytes to 32Kb and a theoretically infinite number of lines can now be returned.2.

'INSERT INTO mybtab (blobid. oci_commit($c). They can be used for table columns and PL/SQL variables. the PHP descriptor in $lob references this locator. By binding as OCI_B_BLOB. ':MYBLOBID'. A pre-supplied DBMS_LOB package makes manipulation in PL/SQL easy. $lob->save($myv). There are various ways to specify them for optimal Oracle storage.php <?php $c = oci_connect('hr'. Working with LOBs In PHP. -1. OCI_DEFAULT). $lob = oci_new_descriptor($c.CHAPTER 11 Using Large Objects in OCI8 Oracle Character Large Object (CLOB) and Binary Large Object (BLOB) types can contain very large amounts of data. '//localhost/XE'). $myv = 'a very large amount of binary data'. blobdata blob). 147 . Oracle also has a BFILE type for large objects stored outside the database. $myblobid). 'VALUES(:myblobid. ':BLOBDATA'. 'RETURNING blobdata INTO :blobdata'). oci_bind_by_name($s. $myblobid = 123. in SQL*Plus create a table that has a BLOB column: SQL> create table mybtab (blobid number. PHP code to insert data into this table is: blobinsert. oci_bind_by_name($s. $s = oci_parse($c. $lob. 'hrpwd'. The OCI_DEFAULT flag is used for oci_execute() so the descriptor remains valid for the save method. blobdata) ' . oci_execute($s. LOBs are manipulated using a descriptor. To show this. EMPTY_BLOB()) ' . ?> The RETURNING clause returns the Oracle LOB locator of the new row. OCI_B_BLOB). OCI_B_LOB). The $lob->save() method then stores the data in $myv into the BLOB column. The commit concludes the insert and makes the data visible to other database users.

set with memory_limit in php. The PHP manual recommends using read() instead of load() because it allows the data size of data to be limited. $arr = oci_fetch_assoc($stmt). $result = $arr['BLOBDATA']->read(50). and the data is retrieved by using a load() or read() method: $query = 'SELECT blobdata FROM mybtab WHERE blobid = 123'. Other LOB Methods A number of other methods on the LOB descriptor allow seeking to a specified offset. $query).Using Large Objects in OCI8 If the application uploads LOB data using a web form. it can be inserted directly from the upload directory with $lob->import($filename). This can help avoid the PHP process abruptly terminating when it reaches its allocated maximum memory size.ini using the upload_max_filesize parameter. Using CLOBs is almost identical to using BLOBs. $data = $arr['BLOBDATA']->load(). OCI_SEEK_SET). and copying or comparing a LOB. The bind type becomes OCI_B_CLOB. erasing data. $stmt = oci_parse ($c. exporting data directly to file. This code snippet shows seeking to the 10th position in the result descriptor. Table 11-1 LOB methods and functions PHP Function or Method OCI-Lob->close OCI-Lob->eof OCI-Lob->erase OCI-Lob->export OCI-Lob->writeToFile OCI-Lob->flush OCI-Lob->free OCI-Lob->getBuffering Action Close a LOB descriptor Test for LOB end-of-file Erases a specified part of the LOB Write a LOB to a file Flushes buffer of the LOB to the server Frees resources associated with the LOB Returns current state of buffering for the LOB 148 . PHP’s maximum allowed size for uploaded files is set in php.ini. oci_execute($stmt). OCI8 returns the LOB descriptor. and the table must obviously contain a CLOB column. and then storing the next 50 bytes in $result: $arr['BLOBDATA']->seek(10. The full list of LOB methods and functions is shown in table 11-1. Check the PHP manual for usage. When fetching a LOB.

They are also useful for loading text or binary data into Oracle tables. the image data is not loaded and printed in PHP. a BFILE is accessed via a locator. In SQL and PL/SQL. There are numerous pre-supplied functions that operate on BFILE locators. externally created content. The image will not be loaded into the database but the picture description is loaded so it can be queried. Instead. The BFILE allows the image to be related to the description. BFILEs are a handy way for using relatively static. To allow Apache to serve the image. which is simply a pointer to the external file. To show how BFILEs work in PHP this section creates a sample application that accesses and displays a single image. For example if the file is /tmp/cj. the browser is redirected to the image URL of the external file.conf and map a URL to the directory containing the file.jpg add: 149 .Working with BFILEs PHP Function or Method OCI-Lob->import OCI-Lob->saveFile OCI-Lob->load OCI-Lob->read OCI-Lob->rewind OCI-Lob->save OCI-Lob->seek OCI-Lob->setBuffering OCI-Lob->size OCI-Lob->tell OCI-Lob->truncate OCI-Lob->write OCI-Lob->writeTemporary oci_lob_copy oci_lob_is_equal Action Loads data from a file to a LOB Returns LOB contents Returns part of the LOB Moves the LOB’s internal pointer back to the beginning Saves data to the LOB Sets the LOB's internal position pointer Changes LOB's current state of buffering Returns size of LOB Returns current pointer position Truncates a LOB Writes data to the LOB Writes a temporary LOB Copies a LOB Compare two LOB locators for equality Working with BFILEs A BFILE is an Oracle large object (LOB) datatype for files stored outside the database. edit httpd. Also the application could be extended in future to use PL/SQL packages to read and manipulate the image. In this example. This significantly reduces the amount of data that needs to be handled by the application.

$name. -1. This is Oracle’s pointer to the operating system and forms part of each BFILE. "insert into FileTest (FileNum.jpg. $name = "cj. $fdsc = "Some description to search". ":name". grant read on directory TestDir to hr.jpg loads the picture in /tmp/cj. This new BFILE can be queried back in PHP: bfilequery1.php <?php $fnum = 1. SQLT_INT). and the BFILE itself. FileDesc varchar2(30). $fnum. FileDesc. $c = oci_connect("hr". $fdsc. "hrpwd".php <?php 150 . oci_commit($c).Using Large Objects in OCI8 Alias /tmp/ "/tmp/" <Directory "/tmp/"> Options None AllowOverride None Order allow. $s = oci_parse($c. ":fnum". bfilename('TESTDIR'. connect hr/hrpwd@//localhost/XE create table FileTest ( FileNum number primary key. :fdsc. -1. a text description of the file. "//localhost/XE"). Bind variables are used for efficiency and security. SQLT_CHR). oci_execute($s. create a DIRECTORY alias for /tmp. oci_bind_by_name($s. PHP code to insert the image name into the FileTest table looks like: bfileinsert. OCI_DEFAULT). ":fdsc". :name))"). The image data is not loaded into this table. Image bfile). In Oracle. The directory must be on the same machine that the database server runs on. the BFILE in the table is a pointer to the file on your filesystem. SQLT_CHR). -1.deny Allow from all </Directory> Using /tmp like this is not recommended for anything except testing! Restart Apache and use a browser to check that http://localhost/tmp/cj.jpg". Image) values (:fnum. ?> The bfilename() constructor inserts into the BFILE-type column using the TESTDIR directory alias created earlier. This gives the hr user access to the /tmp directory and creates a table FileTest containing a file number identifier. oci_bind_by_name($s. In SQL*Plus run: SQL> SQL> SQL> SQL> SQL> connect system/systempwd@//localhost/XE create directory TestDir AS '/tmp'. oci_bind_by_name($s.

$s = oci_parse($c. oci_bind_by_name($s.Working with BFILEs $c = oci_connect("hr". :name). SQLT_CHR).' .php <?php $c = oci_connect("hr". header("Location: http://localhost/tmp/$name"). Instead of executing the query in PHP and using PL/SQL to find the filename. 'da_l varchar2(255). $fnum).filegetname(b_l. oci_execute($s). oci_bind_by_name($s. 'declare ' . In real life it might use a regular expression on the FileDesc field like: select Image from FileTest where regexp_like(FileDesc. 255. $fnum = 1. 'b_l bfile. "hrpwd". But if you have (or create) an Oracle procedure you could pass it the BFILE descriptor and get the name.'). echo "</pre>". da_l. 'select image into b_l from filetest where filenum = :fnum. // This is a BFILE descriptor echo "<pre>". ?> The filename cj. The header() function redirects the user to the 151 . $s = oci_parse($c. "//localhost/XE"). ":name". "hrpwd". $fnum). var_dump($bf).' . $bf = $row['IMAGE']. ":fnum". Now what? In this example the file name is needed so the browser can redirect to a page showing the image. 'somepattern') The PHP script returns a BFILE descriptor. "//localhost/XE").php can be replaced with: bfilequery2. 'dbms_lob. $fnum = 1. The previous query code in bfilequery1. oci_bind_by_name($s. "select Image from FileTest where FileNum = :fnum"). 'begin ' . 'end. the query condition is the file number of the new record. oci_execute($s). a more efficient method is to create a PL/SQL anonymous block that does both the query and extracts the filename from its returned BFILE.' . ":fnum". ?> For simplicity. $row = oci_fetch_assoc($s).FILEGETNAME() function. $name.' . Unfortunately there is no direct method in PHP to get the filename from the descriptor.jpg is returned in $name courtesy of the :name bind variable argument to the DBMS_LOB.

BFILEs are very useful for many purposes including loading images into the database. You can have dangling references to BFILEs because Oracle does not check the validity of BFILEs until the data is explicitly read (this allows you to precreate BFILEs or to change the physical data on disk). If you have problems. da_l. BFILE data does not participate in transactions. oci_execute($s). / Back in PHP the filename is easily fetched from the database with an anonymous block. oci_bind_by_name($s. :name). 152 . but BLOBs may be better in some circumstances. or even returned to PHP using OCI8’s LOB features. comment out the header() call and check that $name is valid. BFILEs need to be backed up manually. Finally. $name.FILEEXISTS(). Changes to BFILE locators can be rolled back or committed but since the files themselves are outside the database. oci_bind_by_name($s. Another example is DBMS_LOB. end. the HTTP headers will not be correct and the image will not display. name_p out varchar2) as bf_l bfile. dbms_lob. This lets Oracle parse and optimize the code at creation time. The browser is redirected to the image similar to the previous example: getpic.LOADFROMFILE() reads BFILE data from the file system into a PL/SQL BLOB or CLOB. For example DBMS_LOB. which can be used to check whether the FileTest table contains references to images that do not exist. ?> BFILEs are easy to work with in PL/SQL because the presupplied DBMS_LOB package has a number of useful functions. begin select image into bf_l from FileTest where FileNum = fnum_p. This could be loaded into a BLOB table column. manipulated in PL/SQL. da_l varchar2(255). BFILE data files are read-only and cannot be changed within Oracle. "//localhost/XE").filegetname(bf_l. SQLT_CHR). To create a PL/SQL procedure MyGetFileName() in SQL*Plus: SQL> connect hr/hrpwd@//localhost/XE SQL> create or replace procedure MyGetFileName (fnum_p in number. Because of these points. If any text is printed before the header() is output.Using Large Objects in OCI8 image. name_p). 255. "hrpwd". there might be times you should use BLOBs to store images inside the database to ensure data and application consistency but BFILEs are there if you want them. ":name". end."). $fnum = 1. ":fnum".php <?php $c = oci_connect("hr". $fnum). "begin MyGetFileName(:fnum. The application can be improved by putting the PL/SQL into a stored procedure. header("Location: http://localhost/tmp/$name"). $s = oci_parse($c.

CHAPTER 12

Using XML with Oracle and PHP
Both Oracle and PHP 5 have excellent XML capabilities, allowing lots of choice for processing information. All editions of Oracle contain what is known as “XML DB”, the XML capabilities of the database. When tables are created, XML can be stored in linear LOB format, or according to the structure of your XML schema. This chapter covers the basics of returning XML data from Oracle to PHP.

Fetching Relational Rows as XML
One useful feature of XML DB is that relational SQL tables can automatically be retrieved as XML. The queried XML is in XML fragments, and not fully formed XML documents.
xmlfrag.php
<?php $c = oci_connect('hr', 'hrpwd', '//localhost/XE'); $query = 'SELECT XMLELEMENT("Employees", XMLELEMENT("Name", employees.last_name), XMLELEMENT("Id", employees.employee_id)) as result FROM employees WHERE employee_id > 200'; $s = oci_parse($c, $query); oci_execute($s); while ($row = oci_fetch_row($s)) foreach ($row as $item) echo htmlentities($item)." "; ?>

The output is:
<Employees><Name>Hartstein</Name><Id>201</Id></Employees> <Employees><Name>Fay</Name><Id>202</Id></Employees> <Employees><Name>Mavris</Name><Id>203</Id></Employees> <Employees><Name>Baer</Name><Id>204</Id></Employees> <Employees><Name>Higgins</Name><Id>205</Id></Employees> <Employees><Name>Gietz</Name><Id>206</Id></Employees>

153

Fetching Rows as Fully Formed XML

Tip: Watch out for the quoting of XML queries. The XML functions can have embedded double-quotes. This is the exact opposite of standard SQL queries, which can have embedded single quotes.

There are a number of other XML functions that can be similarly used. See the Oracle Database SQL Reference.

Fetching Rows as Fully Formed XML
Another way to create XML from relational data is to use the PL/SQL package DBMS_XMLGEN(). This package returns a fully formed XML document, with the XML header. Queries that use DBMS_XMLGEN() return a CLOB column, so the initial result needs to be treated in PHP as a LOB descriptor. There is effectively no length limit for CLOBs. The following example queries the first name of employees in department 30 and stores the XML marked-up output in $mylob:
getxml.php
<?php $c = oci_connect('hr', 'hrpwd', '//localhost/XE'); $query = "select dbms_xmlgen.getxml(' select first_name from employees where department_id = 30') xml from dual"; $s = oci_parse($c, $query); oci_execute($s); $res = oci_fetch_row($s); $mylob = $res[0]->load(); // treat result as a LOB descriptor echo "<pre>\n"; echo htmlentities($mylob); echo "</pre>\n"; ?>

The value of $mylob is:
<?xml version="1.0"?> <ROWSET> <ROW> <FIRST_NAME>Den</FIRST_NAME> </ROW> <ROW> <FIRST_NAME>Alexander</FIRST_NAME> </ROW> <ROW>

154

Fetching Rows as Fully Formed XML

<FIRST_NAME>Shelli</FIRST_NAME> </ROW> <ROW> <FIRST_NAME>Sigal</FIRST_NAME> </ROW> <ROW> <FIRST_NAME>Guy</FIRST_NAME> </ROW> <ROW> <FIRST_NAME>Karen</FIRST_NAME> </ROW> </ROWSET>

Using the SimpleXML Extension in PHP
You can use PHP 5’s SimpleXML extension to convert XML to a PHP object. Following on from the previous example the query results can be converted with:
$xo = simplexml_load_string((binary)$mylob); var_dump($xo);

Note the cast to binary which ensures consistent encoding. The output is:
object(SimpleXMLElement)#2 (1) ["ROW"]=> array(6) { [0]=> object(SimpleXMLElement)#3 ["FIRST_NAME"]=> string(3) "Den" } [1]=> object(SimpleXMLElement)#4 ["FIRST_NAME"]=> string(9) "Alexander" } [2]=> object(SimpleXMLElement)#5 ["FIRST_NAME"]=> string(6) "Shelli" } [3]=> object(SimpleXMLElement)#6 ["FIRST_NAME"]=> string(5) "Sigal" } [4]=> object(SimpleXMLElement)#7 ["FIRST_NAME"]=> string(3) "Guy" } [5]=> object(SimpleXMLElement)#8 ["FIRST_NAME"]=> {

(1) {

(1) {

(1) {

(1) {

(1) {

(1) {

155

" ". "hrpwd". XQuery XML Query Language Oracle’s support for XQuery was introduced in Oracle Database 10g Release 2. but it is in the other editions of Oracle. A basic XQuery to return the records in the employees table is: for $i in ora:view("employees") return $i This XQuery syntax is in a special SELECT: SELECT COLUMN_VALUE FROM XMLTABLE('for $i in ora:view("employees") return $i') The different quoting styles used by SQL and XQuery need careful attention in PHP. ?> 156 .'\')'. $r->FIRST_NAME . There is an article Using PHP5 with Oracle XML DB by Yuli Vasiliev in the July/August 2005 Oracle Magazine that discusses this. to keep the footprint of Oracle XE small. It can be coded: xquery. $s = oci_parse($c. "//localhost/XE"). $query = 'SELECT COLUMN_VALUE FROM XMLTABLE(\''. "<br>\n".XQuery XML Query Language string(5) "Karen" } } } This object can be accessed with array iterators or properties: foreach ($xo->ROW as $r) { echo "Name: " . oci_execute($s). XQuery is not available in the Oracle XE release. $xq = 'for $i in ora:view("employees") return $i'. while ($row = oci_fetch_row($s)) foreach ($row as $item) echo htmlentities($item). Unfortunately.php <?php $c = oci_connect("hr". } This output from the loop is: Name: Name: Name: Name: Name: Name: Den Alexander Shelli Sigal Guy Karen As an alternative to SimpleXML you could use PHP’s older DOM extension. $query).$xq.

XQuery XML Query Language

Table rows are automatically wrapped in tags and returned:
<ROW> <EMPLOYEE_ID>100</EMPLOYEE_ID> <FIRST_NAME>Steven</FIRST_NAME> <LAST_NAME>King</LAST_NAME> <EMAIL>SKING</EMAIL> <PHONE_NUMBER>515.123.4567</PHONE_NUMBER> <HIRE_DATE>1987-06-17</HIRE_DATE> <JOB_ID>AD_PRES</JOB_ID> <SALARY>24000</SALARY> <DEPARTMENT_ID>90</DEPARTMENT_ID> </ROW> … <ROW> <EMPLOYEE_ID>206</EMPLOYEE_ID> <FIRST_NAME>William</FIRST_NAME> <LAST_NAME>Gietz</LAST_NAME> <EMAIL>WGIETZ</EMAIL> <PHONE_NUMBER>515.123.8181</PHONE_NUMBER> <HIRE_DATE>1994-06-07</HIRE_DATE> <JOB_ID>AC_ACCOUNT</JOB_ID> <SALARY>8300</SALARY> <MANAGER_ID>205</MANAGER_ID> <DEPARTMENT_ID>110</DEPARTMENT_ID> </ROW>

You can also use RETURNING CONTENT to return a single document node:
$xq = 'for $i in ora:view("hr","locations")/ROW return $i/CITY'; $query = 'SELECT XMLQUERY(\''.$xq.'\' RETURNING CONTENT) FROM DUAL';

Since this result is treated as a single SQL query row, there are restrictions on its length.

Accessing Data from Oracle over HTTP
XML DB allows you to access data directly via HTTP, FTP or WebDAV. The Oracle Network listener will handle all these requests. As an example of HTTP, use the PL/SQL DBMS_XDB package to create a resource, which here is some simple text:
SQL> declare 2 res boolean; 3 begin 4 begin 5 -- delete if it already exists 6 dbms_xdb.deleteResource('/public/test1.txt'); 7 exception 8 when others then 9 null; 10 end; 11 -- create the file 12 res := dbms_xdb.createResource('/public/test1.txt', 13 'the text to store'); 14 commit; -- don’t forget to commit 15 end; 157

XQuery XML Query Language

16

/

For testing, remove access control on the public resource:
SQL> connect system/systempwd SQL> alter user anonymous identified by anonymous account unlock;

Sometimes it takes a few minutes for this all to take effect, but the file can now be accessed from a browser (or PHP application) using:

http://localhost:8080/public/test1.txt
If you are accessing Oracle XE from a remote browser, you may need to enable remote client connection as described in the chapter Installing Oracle Database 10g Express Edition. There is extensive Oracle documentation on XML DB on the Oracle Technology network at http://otn.oracle.com/tech/xml/xmldb.

158

CHAPTER 13

Globalization
This chapter discusses global application development in a PHP and Oracle Database XE environment. It addresses the basic tasks associated with developing and deploying global Internet applications, including developing locale awareness, constructing HTML content in the user-preferred language, and presenting data following the cultural conventions of the locale of the user. Building a global Internet application that supports different locales requires good development practices. A locale refers to a national language and the region in which the language is spoken. The application itself must be aware of the locale preference of the user and be able to present content following the cultural conventions expected by the user. It is important to present data with appropriate locale characteristics, such as the correct date and number formats. Oracle Database XE is fully internationalized to provide a global platform for developing and deploying global applications.

Establishing the Environment Between Oracle and PHP
Correctly setting up the connectivity between the PHP engine and the Oracle database is the first step in building a global application. It guarantees data integrity across all tiers. Most Internet based standards support Unicode as a character encoding. This chapter focuses on using Unicode as the character set for data exchange. OCI8 is an Oracle OCI application, and rules that apply to OCI also apply to PHP. Oracle locale behavior (including the client character set used in OCI applications) is defined by Oracle’s “national language support” NLS_LANG environment variable. This environment variable has the form:
<language>_<territory>.<character set>

For example, for a German user in Germany running an application in Unicode, NLS_LANG should be set to
GERMAN_GERMANY.AL32UTF8

The language and territory settings control Oracle behaviors such as the Oracle date format, error message language, and the rules used for sort order. The character set AL32UTF8 is the Oracle name for UTF-8. For information on the NLS_LANG and other Oracle language environment variables, see the Oracle documentation. When Zend Core for Oracle is installed on Apache, you can set NLS_LANG in /etc/profile:
export NLS_LANG GERMAN_GERMANY.AL32UTF8

If the globalization settings are invalid, PHP may fail to connect to Oracle and give an error like
159

After executing this. you must set NLS_LANG as an environment variable in $ORACLE_HOME/opmn/conf/opmn. To handle other character sets. Open the Zend Core for Oracle Administration Console by entering the URL in a web browser: http://<machine_name>/ZendCore 2. Manipulating Strings PHP was designed to work with the ISO-8859-1 character set.Globalization ORA-12705: Cannot access NLS data files or invalid environment specified Some globalization values can be changed per connection. The next time the connection is used. If PHP is installed on Oracle HTTP Server. the altered values will still be in effect. "alter session set nls_territory=germany nls_language=german"). Oracle error messages will be in German and the default date format will have changed. oci_execute($s).6. a set of “MultiByte String Functions” is available.1\lib"/> <variable id="PHPRC" value="D:\oracle\1012J2EE\Apache\Apache\conf"/> <variable id="NLS_LANG" value="german_germany. 160 . $s = oci_parse($c.al32utf8"/> </environment> <module-data> <category id="start-parameters"> <data id="start-mode" value="ssl-disabled"/> </category> </module-data> <process-set id="HTTP_Server" numprocs="1"/> </process-type> </ias-component> You must restart the Web listener to implement the change. To enable multibyte strings in PHP using the Zend Core for Oracle Administration Console. specifically multibyte character sets. 1. Login in and navigate to Configuration > Extensions > Zend Core Extensions. Caution: Be careful changing the globalization settings when using a persistent connection.xml: <ias-component id="HTTP_Server"> <process-type id="HTTP_Server" module-id="OHS"> <environment> <variable id="PERL5LIB" value="D:\oracle\1012J2EE\Apache\Apache\mod_perl\site\5.

and monetary formatting to format the HTML pages according to the cultural conventions of the locale. This may return different values than strlen().func_overload to one of the “Overload” settings. Usually a browser sends its locale preference setting to the HTTP server with the Accept Language HTTP header. your application should accommodate users with different locale preferences. $s = $_SERVER["HTTP_ACCEPT_LANGUAGE"] Developing Locale Awareness Once the locale preference of the user has been determined. which returns the number of bytes in a string.net/mbstring. If the Accept Language header is NULL. and the application should fall back to a predefined default locale. Your application code should use functions such as mb_strlen() to calculate the number of characters in strings. Once it has determined the preferred locale of the user. Restart Apache. you should enable the synchronization of user locale settings between the different environments. Save the configuration. 5. Determining the Locale of the User In a global environment. such as date.php. see the PHP mbstring reference manual at http://www. then there is no locale preference information available. the application can call localesensitive functions. PHP applications that call PL/SQL procedures should map the ISO locales to the corresponding NLS_LANGUAGE and NLS_TERRITORY values and change the parameter values to match the locale of the user before calling the PL/SQL procedures.Determining the Locale of the User 3. Enable the mbstring extension. 4. A common method to determine the locale of a user is from the default ISO locale setting of the browser. When you write global applications implemented in different programming environments. You can change the behavior of the standard PHP string functions by setting mbstring. the application should construct HTML content in the language of the locale and follow the cultural conventions implied by the locale. Refresh the browser on the Extension Configuration page to see these mbstring configuration options. For example. For more information. The PL/SQL UTL_I18N package contains mapping functions that can map between ISO and Oracle locales. When you have enabled the mbstring extension and restarted the web server. 161 . several configuration options become available in the Zend Core for Oracle Administration Console. time. The following PHP code retrieves the ISO locale from the Accept-Language HTTP header through the $_SERVER Server variable. Table 13-1 shows how some commonly used locales are defined in ISO and Oracle environments.

R. Oracle recommends that you use UTF-8 (Unicode encoding) for all page encodings. 162 .S.A) English (United Kingdom) French (Canada) French (France) German Italian Japanese Korean Portuguese (Brazil) Portuguese Spanish Locale ID zh-CN zh-TW en-US en-GB fr-CA fr-FR de it ja ko pt-BR pt es NLS_LANGUAGE SIMPLIFIED CHINESE TRADITIONAL CHINESE AMERICAN ENGLISH CANADIAN FRENCH FRENCH GERMAN ITALIAN JAPANESE KOREAN BRAZILIAN PORTUGUESE PORTUGUESE SPANISH NLS_TERRITORY CHINA TAIWAN AMERICA UNITED KINGDOM CANADA FRANCE GERMANY ITALY JAPAN KOREA BRAZIL PORTUGAL SPAIN Encoding HTML Pages The encoding of an HTML page is important information for a browser and an Internet application. but it also enables multilingual content on a single page.Globalization Table 13-1 Locale Representations in ISO. Instead of using different native encodings for the different locales. This encoding not only simplifies the coding for global applications. or in HTML page header. Specifying the Page Encoding for HTML Pages You can specify the encoding of an HTML page either in the HTTP header. Internet applications must know about the HTML page encoding so they can process input data from an HTML form.C. SQL.) Chinese (Taiwan) English (U. You can think of the page encoding as the character set used for the locale that an Internet application is serving. The browser must know about the page encoding so that it can use the correct fonts and character set mapping tables to display the HTML pages. and PL/SQL Programming Environments Locale Chinese (P.

163 . Specifying the Page Encoding in PHP You can specify the encoding of an HTML page in the Content-Type HTTP header in PHP by setting the default_charset configuration variable as follows: default_charset = UTF-8 To enable character set encoding of HTML pages using the Zend Core for Oracle Administration Console. This setting does not imply any conversion of outgoing pages. As with the ContentType HTTP Header. 4. Specifying the Encoding in the HTML Page Header Use this method primarily for static HTML pages. Restart Apache. Enter UTF-8 for the default_charset parameter. Save the configuration. It specifies the content type and character set. The Content-Type HTTP header has the following form: Content-Type: text/html. Your application must ensure that the server-generated pages are encoded in UTF-8. 5. include the Content-Type HTTP header in the HTTP specification.charset=utf-8"> The charset parameter specifies the encoding for the HTML page. specify the character encoding in the HTML header as follows: <meta http-equiv="Content-Type" content="text/html. charset=utf-8 The charset parameter specifies the encoding for the HTML page. 3. the possible values for the charset parameter are the IANA (Internet Assigned Numbers Authority) names for the character encodings that the browser supports. The possible values for the charset parameter are the IANA names for the character encodings that the browser supports. To specify HTML page encoding in the HTML page header. Open the Zend Core for Oracle Administration Console by entering the URL in a web browser: http://<machine_name>/ZendCore 2.Encoding HTML Pages Specifying the Encoding in the HTTP Header To specify HTML page encoding in the HTTP header. Login in and navigate to Configuration > PHP > Data Handling. 1.

When these files are translated. Translatable sources for the content of an HTML page belong to the following categories: * * * Text strings included in the application code Static HTML files. the date ‘12/11/05’ implies ‘11th December 2005’ in the United States. some according to the number of stroke counts in the letter. Otherwise. Presenting data not sorted in the linguistic sequence that your users are accustomed to can make searching for information difficult and time consuming. in Germany this symbol is a thousand separator. stage the static files of different languages in different directories or with different file names. For example. you must include a WHERE clause in your query. To differentiate various translations. For example. Similar confusion exists for number and monetary formats of the users. the meaning of the data can be misinterpreted. These text messages can be stored in flat files or database tables depending on the type and the volume of the data being translated. Different languages have their own sorting rules. and template files such as CSS Dynamic data stored in the database Strings in PHP You should externalize translatable strings within your PHP application logic. This can be a particular problem in PHP when database numbers are fetched as PHP strings. To select the desired language.’ is a decimal separator in the United States. To differentiate the languages of the translated files. images files. and some languages are ordered by the pronunciation of the words. 164 . so that the text is readily available for translation. Static Files Static files such as HTML and text stored as images are readily translatable. they should be translated into the corresponding language with UTF-8 as the file encoding. Some languages are collated according to the letter sequence in the alphabet. Data from the Database Dynamic information such as product names and product descriptions is typically stored in the database. the database schema holding this information should include a column to indicate the language.Globalization Organizing the Content of HTML Pages for Translation Making the user interface available in the local language of the user is a fundamental task in globalizing an application. the symbol ‘. Presenting Data Using Conventions Expected by the User Data in the application must be presented in a way that conforms to the expectation of the user. whereas in the United Kingdom it means ‘12th November 2005’.

substr(first_name. to_char(hire_date.90 21.'DS') "Hiredate".'DL') "Long HireDate" from employees where employee_id <105. 1990 Tuesday. 1993 Wednesday. 3. January 3. and long dates.'DL') "Long HireDate" from employees where employee_id <105.'||last_name "EmpName". 1989 Wednesday. to_char(hire_date. Oracle offers many features that help to refine the presentation of data when the locale preference of the user is known.1)||'. SQL> 2 3 4 5 6* select employee_id EmpID. May 21. short. January 13.06.King N. to_char(hire_date.93 03. 1987 Thursday. to_char(hire_date.87 21.01.01. 17. substr(first_name. EmpName ---------------S.De Haan A. June 17.Ernst Hiredate -------17.Kochhar L.User Presenting Data Using Conventions Expected by the Depending on the application logic and the volume of data retrieved from the database. 13. Session altered. SQL> 2 3 4 5 6* select employee_id EmpID. Januar 1993 Mittwoch.King N. 1991 EMPID ---------100 101 102 103 104 SQL> alter session set nls_territory=germany nls_language=german. EmpName ----------------S. it may be more appropriate to format the data at the database level rather than at the application level. Session altered.'DS') "Hiredate". to set the format to ’YYYYMM-DD HH24:MI:SS’ use: 165 . September 1989 Mittwoch. For example. The following examples illustrate the differences between the short date and long date formats for both the United States and Germany. 21.Hunold B. September 21. The following sections provide examples of locale-sensitive operations in SQL.De Haan A. Januar 1990 Dienstag.1.'||last_name "EmpName".Ernst Hiredate ---------06/17/1987 09/21/1989 01/13/1993 01/03/1990 05/21/1991 Long HireDate ----------------------------Wednesday. Mai 1991 EMPID ---------100 101 102 103 104 In PHP you can override any default date format. Juni 1987 Donnerstag.Kochhar L.09.05. SQL> alter session set nls_territory=america nls_language=american.89 13. 21.Hunold B.1)||'.1.91 Long HireDate -----------------------------Mittwoch. Oracle Date Formats The three different date presentation formats in Oracle are standard.

'99G999D99') "Salary" from employees where employee_id <105 EmpName Salary --------------------------. $r = oci_execute($s).000. Session altered. SQL> alter session set nls_territory=america.00 A.000. "alter session set nls_date_format=’YYYY-MM-DD HH24:MI:SS’").Kochhar 17.00 EMPID ---------100 101 102 103 104 Because OCI8 fetches numbers as PHP strings it possible to lose decimal places or have other errors when PHP converts a string with an incorrect decimal separator. to_char(salary.1)||'.000.00 N. 166 . "//localhost/XE").000.---------S. do_query($c.00 B.00 A.1)||'. SQL> 2 3 4 5* select employee_id EmpID.000.'||last_name "EmpName".Globalization $c = oci_pconnect("hr". substr(first_name.Hunold 9.Hunold 9.00 L.'||last_name "EmpName". "hrpwd".1.00 EMPID ---------100 101 102 103 104 SQL> alter session set nls_territory=germany.000.00 N. "select sysdate from dual").Ernst 6.000.De Haan 17. Session altered. to_char(salary. Oracle Number Formats The following examples illustrate the differences in the decimal character and group separator between the United States and Germany.000. See the tip “Do Not Set the Date Format Unnecessarily” in the chapter Connecting to Oracle Using OCI8 for how to set the format in a database logon trigger.Ernst 6. SQL> 2 3 4 5* select employee_id EmpID.De Haan 17.King 24.---------S.00 B. $s = oci_parse($c.000.1.Kochhar 17. '99G999D99') "Salary" from employees where employee_id <105 EmpName Salary --------------------------.00 L. substr(first_name.000.King 24.

var_dump($n2). ordered after c. ?> // value as fetched // now cast it to a number The output is: string(7) "123.567) The problem can also occur depending on the territory component of NLS_LANG. 'hrpwd'.User Presenting Data Using Conventions Expected by the numformat. '//localhost/XE'). $s = oci_parse($c. "alter session set nls_territory=germany"). $n1 = $r['NUM']. $s = oci_parse($c. $r = oci_fetch_assoc($s). or the value of NLS_NUMERIC_CHARACTERS. Session altered. $n2 = (float)$n1. ll as well as ñ as unique letters. l and n.php <?php $c = oci_connect('hr'. "select 123. Oracle Linguistic Sorts Spain traditionally treats ch. The following examples illustrate the effect of using a Spanish sort against the employee names Chen and Chung.567" float(123. SQL> alter session set nls_sort=binary. SQL> 2 3 4 5* select employee_id EmpID. oci_execute($s). last_name "Last Name" from employees where last_name like 'C%' order by last_name Last Name ------------------------Cabrio Cambrault 167 EMPID ---------187 148 . The latter variable can be used to override the number format while other territory settings remain in effect. respectively.567 as num from dual"). oci_execute($s). var_dump($n1).567" float(123) If NLS_TERRITORY had instead been set to america the output would have been correct: string(7) "123.

SQL> 2 3 4 5* select employee_id EmpID. 168 .Globalization 154 110 188 119 Cambrault Chen Chung Colmenares 6 rows selected. SQL> alter session set nls_sort=spanish_m. last_name "Last Name" from employees where last_name like 'C%' order by last_name Last Name ------------------------Cabrio Cambrault Cambrault Colmenares Chen Chung EMPID ---------187 148 154 119 110 188 6 rows selected. Oracle Error Messages The NLS_LANGUAGE parameter also controls the language of the database error messages being returned from the database. Consider the following server message: ORA-00942: table or view does not exist When the NLS_LANGUAGE parameter is set to French. Session altered. the server message appears as follows: ORA-00942: table ou vue inexistante For more discussion of globalization support features in Oracle Database XE. Setting this parameter prior to submitting your SQL statement ensures that the language-specific database error messages will be returned to the application. see Working in a Global Environment in the Oracle Database Express Edition 2 Day Developer Guide.

1/ext/oci8/oci8.1/ext/oci8/oci8.c:321) OCI8 DEBUG: OCIStmtRelease at (/tmp/php5.2.2.c:128) OCI8 DEBUG: OCIAttrGet at (/tmp/php5.2.1/ext/oci8/oci8.2.c:1223) OCI8 DEBUG: OCIAttrSet at (/tmp/php-5.2.1/ext/oci8/oci8.2.c:995) OCI8 DEBUG: OCIEnvNlsCreate at (/tmp/php-5.1/ext/oci8/oci8_statement.1/ext/oci8/oci8.2.c:1204) OCI8 DEBUG: OCIHandleAlloc at (/tmp/php-5.2.2.1/ext/oci8/oci8_statement.1/ext/oci8/oci8.1/ext/oci8/oci8_statement.2.2. $s = oci_parse($conn.c:65) OCI8 DEBUG: OCIAttrSet at (/tmp/php5.2.1/ext/oci8/oci8.c:61) OCI8 DEBUG: OCIStmtPrepare2 at (/tmp/php5.2.c:1185) OCI8 DEBUG: OCIHandleAlloc at (/tmp/php-5.1/ext/oci8/oci8_statement.c:1244) OCI8 DEBUG: OCIAttrSet at (/tmp/php-5.2.2.1/ext/oci8/oci8.1/ext/oci8/oci8_statement.1/ext/oci8/oci8_statement.1/ext/oci8/oci8.1/ext/oci8/oci8_statement.2. OCI_DEFAULT).c:1195) OCI8 DEBUG: OCIHandleAlloc at (/tmp/php-5. "hrpwd". Enabling OCI8 Debugging output Tracing can be turned on in your script with oci_internal_debug().2.2. oci_execute($s.c:1151) OCI8 DEBUG: OCIHandleAlloc at (/tmp/php-5.c:1213) OCI8 DEBUG: OCIAttrSet at (/tmp/php-5.CHAPTER 14 Tracing OCI8 Internals To see exactly what calls to the Oracle database the OCI8 extension makes.c:1253) OCI8 DEBUG: OCISessionBegin at (/tmp/php-5.c:1234) OCI8 DEBUG: OCIAttrSet at (/tmp/php-5.1/ext/oci8/oci8.c:1176) OCI8 DEBUG: OCIServerAttach at (/tmp/php-5.c:589) 169 .c:119) OCI8 DEBUG: OCIAttrSet at (/tmp/php5. "insert into testtable values ('my data')").2. This is mostly useful for the maintainers of the OCI8 extension. "//localhost/XE"). // do not auto-commit ?> You get output like: OCI8 DEBUG: OCINlsEnvironmentVariableGet at (/tmp/php5.c:297) OCI8 DEBUG: OCIStmtExecute at (/tmp/php5.1/ext/oci8/oci8.c:1284) OCI8 DEBUG: OCIHandleAlloc at (/tmp/php5.1/ext/oci8/oci8. you can turn on debugging output. For a script that connects and does an insert: <?php oci_internal_debug(1). // turn on tracing $conn = oci_connect("hr".

c:1456) OCI8 DEBUG: OCIHandleFree at (/tmp/php-5.2.c:1452) OCI8 DEBUG: OCIServerDetach at (/tmp/php-5.1/ext/oci8/oci8. Otherwise. but some require a “round trip” to the database.c:1460) OCI8 DEBUG: OCIHandleFree at (/tmp/php-5.1/ext/oci8/oci8.2.1/ext/oci8/oci8. thus saving a roundtrip.c:601) OCI8 DEBUG: OCITransRollback at (/tmp/php-5. 170 . If a script only inserts one row it is fine to auto-commit.c:1400) OCI8 DEBUG: OCISessionEnd at (/tmp/php-5.2. do the transaction management yourself. the rollback was issued.1/ext/oci8/oci8.1/ext/oci8/oci8.1/ext/oci8/oci8_statement.2. As part of PHP’s end of HTTP request shutdown at the conclusion of the script.c:1448) OCI8 DEBUG: OCIHandleFree at (/tmp/php-5. The OCI_DEFAULT flag said not to auto-commit and there was no explicit oci_commit() call.2.2.c:1472) Many of these calls just allocate local resources (“handles”) and set local state (“attributes”).Tracing OCI8 Internals OCI8 DEBUG: OCIHandleFree at (/tmp/php5.c:1468) OCI8 DEBUG: OCIHandleFree at (/tmp/php-5.2. If you change to auto-commit mode you will not see a call to OCITransCommit() because the commit message is piggy-backed with the execution call.2.2.1/ext/oci8/oci8.c:1464) OCI8 DEBUG: OCIHandleFree at (/tmp/php-5.1/ext/oci8/oci8.1/ext/oci8/oci8. One of these is the OCITransRollback() call near the end of the script.

Consider contributing new tests to the PHP community. At the end of the of the details. types. 2. This specifies whether to test functionality that has the Oracle database reading files created directly by PHP. In older versions of PHP these variables are located in connect. The tests rely on being able to create tables. Edit php-5. 3. $password = "systempwd".inc and set the Oracle system user password for your database: $user = "system". You should run the tests after building PHP on Linux. 4. To run the OCI8 tests: 1. password and connect string for your database need to be configured.inc file. This gives load and real-life testing not possible with PHP’s command-line test suite.2/ext/oci8/tests verify the behavior of the OCI8 extension. stored procedures. This ensures PHP continues doing what you need.2.ini configuration may also be needed. Running OCI8 Tests The tests in php-5.CHAPTER 15 Testing PHP and the OCI8 Extension This section discusses installing and running the PHP source code tests for OCI8 on Linux. The PHP source code includes tests for all the core functionality and extensions. you may have to grant that database user extra privileges. It is also a good idea to proactively test your applications with PHP “release candidates” and report problems so they can be fixed before each final PHP release.inc. then also set: $oracle_on_localhost = TRUE. the username. Some php.2/ext/oci8/tests/details. For the tests to run successfully.2. If you change the $user variable. You should also verify your applications work correctly with your new PHP binary before putting it into production. set the connection string for the database: $dbase = "//localhost/XE". this is not possible and the variable should be left FALSE. If PHP is running on the same machine as the database. If the database and PHP are not using the same file system. 171 . Adding tests that are relevant to your application reduces the risks of PHP developers breaking PHP features important to you. and so on.

Set any necessary Oracle environment variables in your shell. the Oracle environment variables are not propagated through the test system and tests fail to connect.phpt] PASS oci_bind_array_by_name() and invalid values 2 [ext/oci8/tests/array_bind_002.ini More . for example: variables_order = "EGPCS" Without this flag.INIs : Extra dirs : ============================================================== Running selected tests..phpt] PASS oci_bind_array_by_name() and invalid values 3 [ext/oci8/tests/array_bind_003.2 make test If you want to run just the OCI8 tests use: make test TESTS=ext/oci8 Each test script is executed and its status reported. 6. Successful tests begin with PASS. or where portability of the test cannot be guaranteed. Tests that Fail Occasionally a few tests are known to fail.0.2 ZEND_VERSION : 2. 7.ini. $OH/bin/oracle_env. For example. A summary of the failing tests is given at the completion of the tests.9-42.2.2 PHP : /home/myhome/php-5.0/server . ============================================================== CWD : /home/myhome/php-5. for PHP linked with Oracle Database XE enter: export OH=/usr/lib/oracle/xe/app/oracle/product/10.10.0 PHP_OS : Linux . The output of failing tests is kept for your 172 . Check that variables_order has E in your php.Linux localhost 2.2. These might be for unfixed bugs.2/sapi/cli/php PHP_SAPI : cli PHP_VERSION : 5.1.2.0. Tests that are to be skipped in the current configuration are marked SKIP.sh Note the space after the full stop.6.. Run PHP’s test suite with: cd php-5. Failing tests are marked FAIL.2.EL INI actual : /usr/local/apache/conf/php.Testing PHP and the OCI8 Extension 5.2. PASS oci_bind_array_by_name() and invalid values 1 [ext/oci8/tests/array_bind_001.phpt] .2.

diff demotest.phpt --TEST— Demo to test the Test system --SKIPIF— <?php if (!extension_loaded('oci8')) die("skip no oci8 extension"). The FILE section is the PHP code to be executed. oci_execute($s). create demotest. if ext/oci8/tests/demotest.Creating a Test analysis.out demotest.exp demotest.2. 173 .phpt file Difference between actual and expected output Actual and expected output in a single file Creating a Test To add a new OCI8 test. For example. echo "Done\n". $s = oci_parse($c.2. $res). oci_fetch_all($s.phpt fails. ?> --FILE-<?php require dirname(__FILE__). the following files will be in php5. The SKIPIF section causes the test to be skipped when the OCI8 extension is not enabled in PHP.log File Contents Test framework script PHP file executed Test output Expected output as coded in the .phpt demotest. The EXPECTF section has the expected output.php demotest. var_dump($res).inc'.2/ext/oci8/tests: Table 15-1 Test files and their contents File name demotest.phpt: demotest.'/connect.2/ext/oci8/tests using the test file format. "select user from dual"). For example. ?> --EXPECTF-array(1) { ["USER"]=> array(1) { [0]=> string(6) "SYSTEM" } } Done The test begins with a comment that is displayed when the test is run.phpt file in php-5. create a .

ini More .1.0.0.inc drop_type.2.EL INI actual : /usr/local/apache/conf/php. to run the demotest.2. simple and selfdiagnosing requires fine judgment and tidy programming.2.php script directly and pass the test names as parameters. The test output is similar to the previous output: =================================================================== CWD : /home/myhome/php-5.inc Running a Single Test To run only one or two tests. PASS Demo to test the Test system [ext/oci8/tests/demotest.php script. Making a test portable. For example. call the run-tests.2/ext/oci8/tests/connect. including arguments and php.INIs : Extra dirs : =================================================================== Running selected tests.php for the other sections the test file can have.10. When you run make test the new file is automatically run.2 ZEND_VERSION : 2.inc create_type. accurate. but they could be different executables.phpt.php.6.inc drop_table.9-42. the same PHP binary is used to run the controlling runtests.phpt] =================================================================== Number of tests :1 1 174 .php \ ext/oci8/tests/demotest.phpt The TEST_PHP_EXECUTABLE variable contains the PHP binary with which to test demotest.0 PHP_OS : Linux . There are several PHP test frameworks with sophisticated features that might be more suited to your application test suites. There are several other scripts for creating and dropping basic tables and types: * * * * create_table.2.php.2.2/sapi/cli/php run-tests.2/sapi/cli/php /home/myhome/php-5.inc will connect to Oracle as $user and return the connection resource in $c.Testing PHP and the OCI8 Extension See Writing Tests at http://qa. OCI8 Test Helper Scripts The file php-5. This page also has generic examples and helpful information on writing tests.2.net.phpt script.ini settings.net/write-test.2 PHP : /home/myhome/php-5. They include PHPUnit and SimpleTest.2. do the following: export TEST_PHP_EXECUTABLE=/home/myhome/php-5.Linux localhost 2. In example 1-1. Application level testing brings even more challenges. Please send new tests or issues with PHP’s test suite to php-qa@lists. Writing good units tests is an art.2/sapi/cli/php PHP_SAPI : cli PHP_VERSION : 5.

for example: export OH=/usr/lib/oracle/xe/app/oracle/product/10.----------.sh 3. You may need to su as the oracle user so you have operating system privileges to start SQL*Plus: su –oracle Password: ****** 2. Use SQL*Plus to connect as a privileged database user: sqlplus / as sysdba 4.inc so scripts take an extra second and the database has time to clean up closed connections.0/server . This may be noticeable with Oracle Database XE.----------. $OH/bin/oracle_env.Configuring the Database For Testing Tests skipped :0 ( 0.0%) ------------------------------------------------------------------Time taken :0 seconds =================================================================== Configuring the Database For Testing Sometimes it is possible for rapidly executing OCI8 test scripts to flood the database with connections. 175 . Set the Oracle environment variables needed by SQL*Plus.0%) -------Tests warned :0 ( 0. the number of “processes” that Oracle can handle needs to be increased.0%) ( 0. processes integer 40 5. Check the current value of processes using the SHOW PARAMETER PROCESSES command: SQL> show parameter processes NAME TYPE VALUE ------------------------.0%) (100.0%) ( 0. To increase the number of processes in Oracle: 1.. System altered. For the errors above. to details.0%) Tests passed :1 (100. Increase the value to. Random tests fail with errors like the following: ORA-12516 TNS:listener could not find available handler with matching protocol stack ORA-12520: TNS:listener could not find available handler for requested type of server A quick solution is to add sleep(1).2. 100: SQL> alter system set processes=100 scope=spfile.0%) Tests failed :0 ( 0.. The preferred solution is to configure the database to suit the load. which has smaller defaults. say.

Use the SHOW PARAMETER PROCESSES command to confirm the new value is in effect: SQL> show parameter processes NAME TYPE VALUE ------------------------. SQL> startup ORACLE instance started. ORACLE instance shut down. processes integer 100 8. Database opened. followed by the STARTUP command: SQL> shutdown immediate Database closed.---------.----------... Total System Global Area 289406976 bytes Fixed Size 1258488 bytes Variable Size 96472072 bytes Database Buffers 188743680 bytes Redo Buffers2932736 bytes Database mounted. Restart the database using the SHUTDOWN IMMEDIATE. 7. Exit SQL*Plus using the EXIT command: SQL> exit 9. Now the tests can be run again: make test TESTS=ext/oci8 176 . Database dismounted.Testing PHP and the OCI8 Extension 6.

The refactored OCI8 extension in PHP 5. and so on. One side effect of renaming the function names is that user contributed comments in the PHP manual (http://www. you should replace the OCI8 code with the new version to get improved stability and performance optimizations.2 onwards builds and runs with PHP 4 too.php. PHP 4 functions like OCILogin() became oci_connect(). The comments are either on the page for the old syntax. Steps to do this are given in this book. or on the page for the new syntax.CHAPTER 16 OCI8 Function Names in PHP 4 and PHP 5 In PHP 5 several extensions including OCI8 underwent name standardization.ini parameters) oci_close() oci_new_cursor() oci_free_statement() Cursor Open cursor ocinewcursor() Close cursor ocifreecursor() 177 . OCIParse() became oci_parse(). Operation Connection Action PHP 4 Name PHP 5 Name oci_connect() oci_new_connect() oci_pconnect() Open connection ocilogon() Open new connection ocinlogon() Persistent connection ociplogon() Close connection ocilogoff() (and new php. Table 16-1 shows the OCI8 function names in PHP 4 and PHP 5 where names or functionality differ.net/oci8) are found in two different places. The old OCI8 names still exist as aliases.1. Table 16-1 Relationship between OCI8’s PHP 4 and PHP 5 function names. check both manual pages for user tips. Where a function has an alias. so PHP 4 scripts do not necessarily need to be changed. Function names in PHP are case insensitive and it is common to see the PHP 4 names written with a capitalized prefix. If you are using PHP 4 and cannot upgrade to PHP 5.

OCI8 Function Names in PHP 4 and PHP 5 Operation Action PHP 4 Name ocifreestatement() PHP 5 Name Parsing Binding Parse statement Bind variable ociparse() ocibindbyname() oci_parse() oci_bind_by_name() oci_bind_array_by_name() Bind array Not applicable Defining Define output variables Execute statement Fetch row ocidefinebyname() oci_define_by_name() Execution Fetching ociexecute() ocifetch() oci_execute() oci_fetch() oci_fetch_array() oci_fetch_row() oci_fetch_assoc() oci_fetch_object() oci_fetch_all() oci_result() Fetch row ocifetchinto() Fetch all rows Fetch column Is the column NULL? Cancel Fetch Transaction Management Commit Rollback Descriptors ocifetchstatement() ociresult() ocicolumnisnull() oci_field_is_null() ocicancel() ocicommit() ocirollback() ocinewdescriptor() ocifreedesc() oci_cancel() oci_commit() oci_rollback() oci_new_descriptor() oci_free_descriptor() oci_error() Error Handling Long Objects (LOBs) Note: Methods on a collection object ocierror() ocisavelob() oci_lob_save() 178 .

Configuring the Database For Testing Operation can be used in addition to these functions. Action PHP 4 Name PHP 5 Name ocisavelobfile() ociwritelobtofile() ociwritetemporarylob() ociloadlob() ocicloselob() oci_lob_import() oci_lob_export() OCI-Lob->writeTemporary() method oci_lob_load() OCI-Lob->close() method Collections Note: Methods on a collection object can be used in addition to these functions. ocinewcollection() oci_new_collection() ocifreecollection() ocicollappend() ocicollgetelem() ocicollassign() oci_free_collection() oci_collection_append() oci_collection_element_get() OCI-Collection->assign() method oci_collection_element_assig n() oci_collection_size() oci_collection_max() oci_collection_trim() oci_statement_type() ocicollassignelem() ocicollsize() ocicollmax() ocicolltrim() Metadata Statement type Name of result column Size of result ocistatementtype() ocicolumnname() oci_field_name() ocicolumnsize() oci_field_size() 179 .

OCI8 Function Names in PHP 4 and PHP 5 Operation Action column PHP 4 Name PHP 5 Name Datatype of result ocicolumntype() column Datatype of result ocicolumntyperaw() column Precision of result ocicolumnprecision() column Scale of result column oci_field_type() oci_field_type_raw() oci_field_precision() ocicolumnscale() oci_field_scale() Number of rows ocirowcount() effected Number of columns ocinumcols() returned Changing Password Tracing Server Version Tuning ocipasswordchange() ociinternaldebug() ociserverversion() oci_num_rows() oci_num_fields() oci_password_change() oci_internal_debug() oci_server_version() oci_set_prefetch() ocisetprefetch() (and new php.ini parameter) 180 .

Oracle and OCI8 Comparison Table 17-1 shows the general relationship between the obsolete and current extensions. This chapter gives a comparison of the obsoleted Oracle PHP extension and the current OCI8 extension. This extension is obsolete and is no longer included with PHP. Table 17-1 Relationship between current and obsolete Oracle extensions Operation Connection Action Open connection Open new connection Persistent connection Close connection Cursor Open cursor Close cursor Parsing Binding ORA function (obsolete) ora_logon() OCI8 function oci_connect() oci_new_connect() oci_pconnect() Not available ora_plogon() (and new php. and upgrading to the new OCI8 extension might be as simple as enabling the newer OCI8 extension in the PHP binary.ini parameters) oci_close() oci_new_cursor() oci_free_statement() oci_parse() oci_bind_by_name() oci_bind_array_by_name() ora_logoff() ora_open() ora_close() Parse statement ora_parse() Bind variable Bind array ora_bind() Not applicable 181 . The functionality it offered was limited.CHAPTER 17 The Obsolete Oracle Extension Very rarely you might come across PHP scripts that use the early Oracle extension. Paying some attention to transaction management and connection handling is wise to make sure all your data is committed when you expect it to be. and changing the ora_ function calls in your scripts.

execute ora_do() and fetch oci_fetch_all() oci_fetch_array() oci_fetch_assoc() oci_fetch_object() oci_fetch_row() oci_fetch() oci_fetch() oci_fetch_array() oci_fetch_row() oci_fetch_assoc() oci_fetch_object() oci_fetch_all() oci_result() oci_field_is_null() oci_cancel() oci_commit() Fetching Fetch row ora_fetch() Fetch row ora_fetch_into Fetch all rows Fetch column Is the column NULL? Cancel Fetch Transaction Commit Management Commit mode Rollback Error Handling Not applicable ora_getcolumn() Not applicable Not applicable ora_commit() ora_commiton() ora_commitoff() ora_rollback() ora_error() ora_errorcode() Pass OCI_DEFAULT flag to oci_execute() oci_rollback() oci_error() OCI-Lob->append OCI-Lob->close OCI-Lob->eof OCI-Lob->erase OCI-Lob->export OCI-Lob->flush OCI-Lob->free OCI-Lob->getBuffering Long Objects (LOBS) Not applicable 182 .The Obsolete Oracle Extension Operation Execution Action Execute statement ORA function (obsolete) ora_exec() OCI8 function oci_execute() oci_parse() oci_execute() Followed by one of: Prepare.

Oracle and OCI8 Comparison Operation Action ORA function (obsolete) OCI8 function OCI-Lob->import OCI-Lob->load OCI-Lob->read OCI-Lob->rewind OCI-Lob->save OCI-Lob->saveFile OCI-Lob->seek OCI-Lob->setBuffering OCI-Lob->size OCI-Lob->tell OCI-Lob->truncate OCI-Lob->write OCI-Lob->writeTemporary OCI-Lob->writeToFile OCI-Collection->append OCI-Collection->assign OCI-Collection->assignElem OCI-Collection->free OCI-Collection->getElem OCI-Collection->max OCI-Collection->size OCI-Collection->trim oci_statement_type() oci_field_name() oci_field_size() oci_field_type() oci_field_type_raw() oci_field_precision() oci_field_scale() oci_num_rows() Collections Not applicable Metadata Statement type Not applicable Name of result ora_columnname() column Size of result column Datatype of result column Precision of result column Scale of result column ora_columnsize() ora_columntype() Not applicable Not applicable Number of rows ora_numrows() effected Number of columns returned Changing Password ora_numcols() oci_num_fields() Not applicable oci_password_change() 183 .

The Obsolete Oracle Extension Operation Tracing Server Version Tuning Action ORA function (obsolete) Not applicable Not applicable OCI8 function oci_internal_debug() oci_server_version() oci_set_prefetch() Not applicable (and new php.ini parameters) 184 .

Each database consists of one or more data files. nested tables.Glossary Anonymous Block A PL/SQL block that appears in your application and is not named or stored in the database. BLOB The BLOB datatype stores unstructured binary data in the database. Data Dictionary A set of tables and views that are used as a read-only reference about the database. Because these blocks are not stored in the database. lists. typically a single Oracle 185 . all of the same type. A BFILE column or attribute stores a file locator that points to an external file containing the data. In many applications. Collection Type A collection is an ordered group of elements. and NCLOBs store Unicode national character set data. BFILE The BFILE datatype stores unstructured binary data in operating-system files outside the database. PL/SQL blocks can appear wherever SQL statements can appear. Although you may have more than one database per machine. CLOBs store database character set data. they are generally for one-time use. Connection String The string used to identify which database to connect to. Each element has a unique subscript that determines its position in the collection. Database A database stores and retrieves data. Binding A method of including data in SQL statements that allows SQL statements to be efficiently reused with different data. CHAR The CHAR datatype stores fixed-length character strings. A PL/SQL block groups related declarations and statements. sets and trees. CLOB and NCLOB The CLOB and NCLOB datatypes store up to 8 terabytes of character data in the database. PL/SQL datatypes TABLE and VARRAY enable collection types such as arrays. bags.

When an Oracle database is started. Datatype Each column value and constant in a SQL statement has a datatype. which is associated with a specific storage format. When you create a table. A database link connection allows local users to access data on a remote database. For example. and would usually have SYSDBA access to the database. Instance The Oracle Instance is the running component of an Oracle database server. INSERT. a system global area (SGA) is allocated and Oracle 186 . Multiple applications can use the same database without any conflict by using different schemas. you must specify a datatype for each of its columns. SQL statements that define the database structure or schema. this is the text used in oci_connect() calls. UPDATE and DELETE. The hr user has access to the Human Resources demonstration tables in the HR schema. Also see Easy Connect. or DATE DATE The DATE datatype stores point-in-time values (dates and times) in a table. and DROP. and a valid range of values. Database Link A pointer that defines a one-way communication path from an Oracle Database server to another database server.Glossary database contains multiple schemas. like SELECT. DML SQL’s Data Manipulation Language. A person who administers the Oracle database. This person is a specialist in Oracle databases. Indexes can be created to increase the performance of data retrieval. ALTER. HR The Human Resources user created by default with an Oracle seed database installation. DDL SQL’s Data Definition Language. In the PHP world. Index Indexes are optional structures associated with tables. A schema is often equated with a user. NUMBER. Database Name The name of the database. DBA Database Administrator. Easy Connect A simple hostname or database name string that is used to identify which database to connect to. like CREATE. SQL statements that define or manage the data in the database. constraints.

demonstration scripts and error message files for each component of Oracle. Unlike an ordinary view. ORACLE_HOME install An Oracle Client or Oracle Database install. Different object privileges are available for different types of schema objects. Instant Client The Oracle Instant Client is a small set of libraries. Instant Client is downloadable from OTN and is usable and distributable for free. LOB Locator A “pointer” to LOB data. stored in the database. utilities. NUMBER The NUMBER datatype stores fixed and floating-point numbers. Object Privilege A right to perform a particular action on a specific schema object. Any 187 . BLOB and BFILE. Procedures and Functions A PL/SQL procedure or function is a schema object that consists of a set of SQL statements and other PL/SQL constructs. A subset of the full Oracle Client. See CLOB. LOB A large object. The combination of the background processes and memory buffers is called an Oracle instance. Materialized View A materialized view provides access to table data by storing the results of a query in a separate schema object. Packages A package is a group of related procedures and functions. configuration scripts. stored together in the database for continued use as a unit. along with the cursors and variables they use. NCHAR and NVARCHAR2 NCHAR and NVARCHAR2 are Unicode datatypes that store Unicode character data. These installs contain all required software in a directory hierarchy. which does not take up any storage space or contain any data. LOBS may be persistent (stored in the database) or temporary. a materialized view contains the rows resulting from a query against one or more base tables or views.background processes are started. and run as a unit to solve a specific problem or perform a set of related tasks. An Oracle Instant Client install is not required to be in an Oracle Home. The privilege to delete rows from the departments table is an example of an object privilege. it requires minimal installation but has full functionality. which allow you to connect to an Oracle Database. grouped together. This set of directories includes binaries.

188 . In Oracle it is called parsing. stored procedures. It also hosts many discussion forums. and packages. The Oracle Net listener is a process that handles connection requests from clients and passes them to the target database. functions. Many (but not all) options that are set in php. PECL The PHP Extension Community Library (PECL) is a repository of PHP extensions that can be linked into the PHP binary. you can create and run PL/SQL program units such as procedures. and packages. PL/SQL Oracle’s procedural language extension to SQL. PL/SQL program units generally are categorized as anonymous blocks. interpreted scripting language commonly used for web applications. PHP A popular. PHP is a recursive acronym for “PHP: Hypertext Preprocessor”. and variables in packages can be called from other packages. stored functions. With PL/SQL. or functions. functions. This term is often used with non-Oracle databases. It is a server-side. Regular Expression A pattern used to match data. stored procedural language that enables you to mix SQL statements with procedural constructs.ini can also be set at runtime using ini_set(). Procedures. Oracle has several functions that accept regular expressions. procedures. including one on PHP. functions. PEAR The PHP Extension and Application Repository (PEAR) is a repository for reusable packages written in PHP. Php. Package A group of PL/SQL procedures.ini The configuration file used by PHP.Glossary program using Oracle typically requires the ORACLE_HOME environment variable to be set to the top level installation directory. Prepared Statement A pre-parsing step for SQL statements. OTN The Oracle Technology Network is Oracle’s free repository of articles on Oracle technologies. Oracle Net The networking component of Oracle that connects client tools such as PHP to local or remote databases. and variable definitions stored in the Oracle database.

sys has access to all base tables and views for the database data dictionary. Although recently superceded by GUI tools like Oracle’s free SQL Developer. view. function. 189 . type. procedure. Functions are different than procedures in that functions return a value when executed. but with a limited set of privileges that allows basic administrative tasks without having access to user data. sequence. It enables sys to perform high-level administrative tasks such as starting up and shutting down the database. and stores its parsed representation in the database.Schema A schema is a collection of database objects. the unique number assigned to each database user session when they connect to the database. user-defined object type. It is also convenient to show examples using SQL*Plus. by default. A schema is owned by a database user and has the same name as that user. Synonym A synonym is an alias for any table. package. SYSDBA A system privilege that. SQL*Plus remains hugely popular. and indexes. Sequence A sequence (a sequential series of numbers) of Oracle integers of up to 38 digits defined in the database. SYS An administrative user account name. When you create a stored procedure or function. views. SYSTEM An administrative user account name that is used to perform all administrative functions other than starting up and shutting down the database. or another synonym. SQL*Plus The traditional command line tool for executing SQL statements available with all Oracle databases. materialized view. Java class schema object. is assigned only to the sys user. Schema objects are the logical structures that directly refer to the database's data. SYSOPER Similar to sysdba. SID The system identifier is commonly used to mean the database name alias in the connection string. Schema objects include structures like tables. SID also stands for session identifier. Stored Procedures and Functions A PL/SQL block that Oracle stores in the database and can be called by name from an application. Oracle parses the procedure or function.

Each user connects to the database with a username and secret password. The trigger can be called after the event. The alias is used in the PHP connection string. The names are currently synonyms but VARCHAR2 is recommended to ensure maximum compatibility of applications in future. TNS stands for Transparent Network Substrate. to prevent erroneous operations or fix new data so that it conforms to business User A database user is often equated to a schema. View Views are customized presentations of data in one or more tables or other views. they derive their data from the tables on which they are based. or take some follow-up action. Rather. view. Tnsnames. A view can also be considered a stored query. to record it. Users are assigned a default tablespace that holds all the data the users creates. Tablespaces are often created for individual applications because tablespaces can be conveniently managed. Transaction A sequence of SQL statements whose changes are either all committed. VARCHAR and VARCHAR2 These datatypes store variable-length character strings. A database is made up of default and DBA-created tablespaces. The file maps an alias to a local or remote database and allows various configuration options for connections. and so on. Each table has columns and rows. and has access to tables. The trigger can be called before the event. Database tables hold all user-accessible data.Glossary System privilege The right to perform a particular action. or event. Table Tables are the basic unit of data storage. Temporary LOB See LOB. Tablespace Tablespaces are the logical units of data storage made up of one or more datafiles. For example. Trigger A stored procedure associated with a database table. the privileges to create tables and to delete the rows of any table in a database.ora The Oracle Net configuration file used for connecting to a database. or to perform an action on any schema objects of a particular type. 190 . or all rolled back. referred to as the base tables of the views. in the database. Views do not actually contain data.

191 .XMLType XMLType is a datatype that can be used to store XML data in table columns.

.

com/opal/ Blog: Alison Holloway on PHP http://blogs.html Blog: Christopher Jones on OPAL http://blogs.oracle.oracle.oracle.com/docs/cd/B25329_01/doc/appdev.htm Oracle Database Express Edition 10g Release 2 (10.102/b25317/toc.oracle. General Information and Forums * * * * * * * PHP Developer Center on Oracle Technology Network (OTN) http://www.php.php Oracle Database Express Edition 2 Day Plus PHP Developer Guide http://download.2) Documentation (Oracle Database XE) http://www.oracle.com/ Oracle Metalink – Oracle Support web site http://metalink.net/docs.net/oci8 PHP documentation http://www.oracle.htm Oracle Net Services Reference http://download.oracle.html OTN PHP Discussion Forum http://www.html Documentation * * * * PHP OCI8 documentation http://www.com/technology/forums/php. resources and articles discussed in this book.oracle.102/b14212/toc.com/docs/cd/B19306_01/network.com/alison/ AskTom – General Oracle language and application design help http://asktom.htm 193 * * * .102/b14213/toc.com/database/product_editions.com/technology/tech/php/index.oracle.php.com/ Oracle Database Editions http://www.com/ Oracle Net Services Administrator's Guide http://download.Resources This chapter gives links to documentation.com/docs/cd/B19306_01/network.oracle.com/pls/xe102/homepage Oracle Documentation Portal http://tahiti.oracle. and to other web sites of interest.oracle.

htm * PHP and Oracle Books * * Oracle Database 10g Express Edition PHP Web Programming.com/technology/tech/php/pdf/globalizing_oracle_php_applicatio ns.102/b14212/naming.oracle.com/technology/oramag/oracle/05-jul/o45php. Articles and Other References * * * Oracle PHP Troubleshooting FAQ http://www. Osbourne Oracle Press.php. by Wez Furlong http://www. Mladen Gogala.com/technology/pub/articles/php_experts/otn_pdo_oracle5. O’Reilly Press.oracle. Improving Performance Through Persistent Connections by John Coggeshall http://www.Resources * Oracle Database Net Services Administrator’s Guide 10g Release 2 (10.oracle. Currently in its 4th edition.html Oracle PL/SQL Programming by Steven Feuerstein.oracle.com/technology/oramag/oracle/05-jul/o45php.html Using PHP 5 with Oracle XML DB by Yuli Vasiliev http://www.com/technology/pub/articles/oracle_php_cookbook/coggeshall_p ersist.oracle. 2006 Easy Oracle PHP: Create Dynamic Web Pages with Oracle Data. Michael McLaughlin.pdf Using PHP5 with Oracle XML DB http://www.com/docs/cd/B19306_01/server.php 194 . * * * * * Source and Binaries * * Zend Core for Oracle http://www.html Autonomous transactions in Oracle http://asktom.htm# i498306 Oracle Database SQL Reference http://download.com/docs/cd/B19306_01/network.oracle.com/technology/tech/php/zendcore/ PHP versioned releases (source and Windows binaries) http://www.oracle.2) – Easy Connect Naming Method http://download.net/downloads.html The PHP 5 Data Object (PDO) Abstraction Layer and Oracle.oracle.html An Overview on Globalizing Oracle PHP Applications http://www. Rampant TechPress.html.com/technology/tech/php/htdocs/php_troubleshooting_faq. 2006 Other PHP and Oracle books are due to be published in 2007.oracle.oracle.com/tkyte/autonomous/index.102/b14200/toc.

oracle.php.net/ PECL OCI8 source snapshot http://pecl.net/search.html 195 .php.oracle.php.net/ext.php.org/ Utilities * PHP Extension for JDeveloper http://www.php.simpletest.net/viewcvs.dll PECL PDO_OCI source snapshot http://pecl.php.php.phpunit.de/ SimpleTest PHP unit tester http://www.com/technology/products/jdev/htdocs/partners/addins/exchange/ php/index.com/technology/tech/oci/instantclient/ PHP * * * * * PHP Home Page http://www.net/ PHP Quality Assurance Site http://qa.php/php_oci8.net/ext.php.php PHPUnit PHP unit tester http://www.dll Oracle Instant Client http://www.php/php_pdo_oci.net/ PHP Bug system http://bugs.net/package/oci8 Windows OCI8 DLLs matching PECL oci8 snapshots http://pecl4win.net/package/PDO_OCI Windows PDO_OCI DLLs matching PECL PDO_OCI snapshots http://pecl4win.* * * * * * * OCI8 source code in CVS http://cvs.cgi/php-src/ext/oci8/ Snapshots of PHP's source code and Windows binaries http://snaps.php.