PHP 5 Data Object (PDO) abstraction Layer and Oracle

Source: Internet
Author: User
Tags empty error code error handling exception handling connect odbc naming convention stmt
Oracle| Object | data

The original developer of a new PHP data object (PDO) Data abstraction Layer gives you a brief introduction to the abstraction layer, focusing on running with Oracle.

Need php:5.0
Need other: Oracle 8 or later client library
Download PDO for Oracle (Windows): Php_pdo.dll, Php_pdo_oci.dll
Download PDO (Unix) for Oracle: PDO, Pdo_oci

PDO Introduction

PHP is primarily done by volunteers, although there are a few fixed "core" developers, but none of us are developing PHP on a full-time payroll. In addition, we are located in different parts of the world, you can imagine the long-term development of the coordination work is how difficult. Therefore, PHP is mainly based on the whim of the individual short-term needs to develop, the reasons are varied, some experiments, and some is because "tomorrow has a job to pay." Although this usually improves PHP at every step, it is a lack of integrity in the long run-database expansion is an important example.

There is no real consistency between the various data extensions (OCI, MySQL, PostgreSQL, MSSQL, etc.), and even in some cases there is no real consistency within those extensions. Almost all of these extensions perform the same kind of tasks using different code that is tightly linked to the underlying database APIs. And because we have very limited staff (PHP core developers and extension developers), this makes the code more difficult to maintain, which poses a big problem for PHP.

As PHP became increasingly popular and successful, defenders of the major PHP database extensions attended the LINUXTAG 2003 conference in Germany, where we exchanged views on the future of PHP. When discussing the randomness of PHP development, we identified some of the goals of database access in PHP:

• Provides a lightweight, clear, and convenient API
• Unify the common features of various RDBMS libraries, but do not exclude more advanced features.
• Provide an optional degree of abstraction/compatibility through PHP scripts.

The concept of this PHP data object (PDO) is proposed because we want to get some of the better performance of the API by using the advanced object-oriented features of Zend Engine 2 (The core of PHP 5).

The concept of the data abstraction layer in PHP is not new at all; querying PHP database abstraction in Google will find about 83,200 matches. It's almost the dream of many PHP developers, and its generation is partly due to our incomplete APIs. If you've ever tried to do anything really important with a Third-party abstraction layer, you'll often find that the abstraction layers are too powerful for the job at hand--either as a significant amount of learning before use, or as a slow interface, Parameters require multiple script function calls to reach the database's own API; there are usually two of these appearances.

Why do these layers of abstraction have this problem? These layers of abstraction are always trying to accomplish too many tasks, possibly even impossible tasks. We decided to target practicality, using only some of the most common database API features as our foundation, and enabling PDO drivers to expose their product-specific features to regular extension functions.

Why use PDO?

Most people who have heard rumors about database abstraction extensions are immediately puzzled by the expansion of PDO-do we want to parse SQL and convert it to the corresponding back-end dialect? How we deal with feature X or attribute Y, and so on. So it may be a surprise to hear that we don't have to worry about it at all in the PDO, we don't want everything to be completely unified, because to make it possible is to limit ourselves to the lowest common standards.

If PDO is not a monolithic abstraction layer, is there any other reason why you should consider using it?

Performance From the outset, PDO learned from the successes and failures of existing database extensions. Because PDO's code is brand new, we have the opportunity to restart design performance to take advantage of the latest features of PHP 5.
Ability PDO is designed to provide common database functionality as a foundation, while providing easy access to the unique features of the RDBMS.
Simple PDO is designed to make your database easy to use. The API does not force you into your code, and it clearly indicates the procedure for each function call.
• The runtime can be extended. The PDO extension is modular, enabling you to load drivers for your database backend at run time without having to recompile or reinstall the entire PHP program. For example, the PDO_OCI extension implements Oracle database APIs instead of PDO extensions. There are also a number of drivers for MySQL, PostgreSQL, ODBC, and Firebird, and more drivers are still in the process of development.

You might want to see how PDO compares with other common abstraction layers, such as PEAR DB or ADODB. PDO is lighter than other common abstraction layers, both in terms of APIs and performance, but it involves providing uniformity across the backend of each database, rather than those layers of abstraction, such as the PEAR MDB 2 abstraction layer for handling a large number of portability issues.

Where can I get PDO?

PDO is provided through PECL (pronounced "pee-kle", European language Style), or PHP extension library. If you are running a Linux computer, set it up as described in the following instructions, and later install details on Windows.

Note that the PDO and its drivers are currently in Alpha State; This means that we can reasonably guarantee that there are no major flaws, but the package is not functional-we also need to add a lot of functionality. Although we encourage you to test the package, it is not recommended for production at this stage.

Unix/linux Installation

If you haven't tried PHP 5 before, take a moment to read through the news and various announcements. On UNIX computers, you may want to install or upgrade LIBXML2, and if you do not have libxml2, the Pear Package management tool will not run and you may encounter many difficulties when you install PDO. Get PHP 5 and compile and install it. Make sure the specified prefix is not/usr/local/so that it does not conflict with the PHP 4 installation:

%./configure--PREFIX=/USR/LOCAL/PHP5--with-zlib [Specify other options here]
% make Install
Now you can use the Pear tool to get and install PDO and Oracle drivers for PDO. Because PDO is currently marked with alpha, the Pear tool does not download the package by default. Add the suffix "-alpha" after the package name to notify the Pear tool to install the Alpha version:% path= "/usr/local/php5/bin: $PATH"
% Pear Install Pdo-alpha

You need to tell PHP to load the PDO driver from a php.ini file dedicated to PHP 5. If you use the same prefix as I used, PHP looks for php.ini files in/usr/local/php5/lib/php.ini. Add the following line to the file:

Now you need to get the database-specific driver; For Oracle, this particular program is called PDO_OCI. In the shell, type:

% Pear Install Pdo_oci-alpha

This driver also needs to be loaded from the php.ini file, and the following lines are added to the previously added line:

Now check to make sure it works:

% php-m

In the list of modules, you should see PDO and Pdo_oci.

Is the firewall interfering?

If you are behind a firewall, you may experience problems when you use the Pear Setup program to get the package. If this occurs, you can manually download and install the packages by following these instructions:

% wget Http://

% Pear Install pdo-0.1.1.tgz

[Add to PHP.ini]

% wget Http://
% Pear Install pdo_oci-0.1.tgz

[Add to PHP.ini]

In both cases, you need to first invoke "pear Install" (followed by the actual package being downloaded); The version number in the example above is current at the time of writing, but will change as development continues.

Windows Installation

If you are running Windows, follow these instructions:

• Get PHP 5 from and unzip it to C:\PHP5.
• From Http:// and

Http:// get PDO separately

And Pdo_oci, put it into C:\php5\ext. Alternatively, you can list from the PHP 5 download page

All of these PDO drivers are found in the "PECL module collection for PHP 5.0.0" zip file.

And all versions of Windows for all PECL packages.
• Edit the C:\php5\php.ini file and add the following:


When editing a php.ini file, it is important to load the PDO extension before any other PDO driver, or you will not initialize correctly (in this case, an error).

If you have a global php.ini file for PHP 4 in the Windows directory, you may experience problems. The best solution is to move the php.ini file so that it is in the same folder as PHP 4 SAPI to isolate the PHP 4 installation; For example, move it to the same folder as Php4apache.dll. Note that not all documents are up to date in the PHP 5 program, and the recommended installation process is as described above-do not copy any DLLs to the Windows folder or the System folder, as stated in the Install.txt file-any content is self-contained. If you are running Apache and you encounter an error that cannot load the DLL, check to see if the C:\PHP5 is added to the PATH. Also note that the CGI version of PHP 5 is now named Php-cgi.exe.

Connect PDO

First, you create an instance of the PDO class as a database handle. It doesn't matter which underlying driver you use, you always use the PDO class name. The first parameter of the constructor is the data source name (DSN), the second parameter is the user name, and the third parameter is the password for that user name. The PDO naming convention for DSN is the name of the PDO driver, followed by a colon, followed by optional driver-specific information. In our example, the OCI driver is loaded but no other information is specified, which uses the default database. For other drivers, such as the ODBC driver, all content after the first colon will be used as an ODBC DSN. The MySQL driver will also interpret its DSN in a different way.

If the driver cannot be loaded, or a connection failure occurs, a pdoexception is thrown so that you can decide how best to handle the failure.

try {
$DBH = new PDO ("OCI:", "Scott", "Tiger");
catch (Pdoexception $e) {
echo "Failed to obtain database handle". $e->getmessage ();
In the connection string, you can specify two optional parameters, the first is the database name, and the second is the character set, which corresponds to the optional third and fourth parameters, which you might have used in the oci8 extension function ociconnect () or Ociplogon (). To connect a particular database using a specific character set, you can do the following:

try {
$DBH = new PDO ("Oci:dbname=accounts;charset=utf-8", "Scott", "Tiger");
catch (Pdoexception $e) {
echo "Failed to obtain database handle". $e->getmessage ();
Omit Try ... Catch control structures are not beneficial. If exception handling is not defined at a higher level of the application, the script terminates if the database connection cannot be established.

Connection Management

Currently, PDO does not perform any of its own connection management at all, so every new PDO call creates a new database connection. The connection is freed when the $DBH variable is out of bounds, or when you specify a NULL value for it.

try {
$DBH = new PDO ("Oci:dbname=accounts;charset=utf-8", "Scott", "Tiger");
catch (Pdoexception $e) {
echo "Failed to obtain database handle". $e->getmessage ();
Perform some operations on the database here
// ...

Now complete, release the connection
$DBH = null;

It is planned to increase connection caching for PDO in the near future, and for the current OCI8 extension, connections to existing servers are reused and idle logins are reused in those connections. When running in cached connection mode, when the $DBH is released as shown in the preceding code snippet, the login is marked as reusable by another connection.

If you use an ODBC driver to access Oracle, you may be pleased to note that the PDO_ODBC driver supports the ODBC connection pool by default.

Using PDO

The best way to learn about a programming API is to use it, so let's take a look at the accompanying demo to learn how to do the batch update (code below).

Create a PDO database handle object
The ' OCI: ' string Specifies that the OCI driver should to be used
You are could use ' oci:dbname=name ' to specify the database name.
The second and third parameters are the username and password respectively
$DBH = new PDO (' OCI: ', ' Scott ', ' Tiger ');
Create a test table to hold the data from Credits.csv
$DBH->exec ("
Extension varchar (255),
Name varchar (255)
Start a transaction
$DBH->begintransaction ();
Prepare to insert a large quantitiy of data
$stmt = $dbh->prepare ("INSERT into credits (extension, name) VALUES (: extension,: Name)");
Bind the inputs to PHP variables; Specify that the data would be strings
With a maximum length of characters
$stmt->bindparam (': extension ', $extension, PDO_PARAM_STR, 64);
$stmt->bindparam (': Name ', $name, PDO_PARAM_STR, 64);
Open the. csv file for import
$fp = fopen (' credits.csv ', ' R ');
while (!feof ($fp)) {
List ($extension, $name) = Fgetcsv ($fp, 1024);
$stmt->execute ();
Fclose ($FP);
Commit the changes
$DBH->commit ();
Now that we have successfully connected to Oracle, we can create a table to hold some data. For this example, we use some PHP extensions and their authors and enter them into a database. The exec () method of a database handle object can be used to emit a quick one-time query that does not return a result set, so we use this method here to issue a CREATE TABLE query.

To make the example more natural, I extracted the extension and the author's information from the PHP source code and stored it in a CSV file (see "Related attachments: Credits.csv"). This represents a common scenario: importing data from a CSV file batch. In our example, we took advantage of Oracle's preprocessing statements and binding parameters to obtain an efficient data import script. Before you tell the example, it's important to understand how PDO handles transactions.

Transaction processing in PDO

Oracle has a sensitive default mode of operation: When you make a connection, it will be in an implicit transaction, and the changes will not take effect until the transaction is committed. In addition to the standard benefits of transactional processing (atomicity, consistency, isolation, durability-ACID), the database server does not need to rebuild indexes and other internal structures after each update, and it can be deferred until commit. This will speed up the execution of the code. Oracle is really good at this point.

Unfortunately, not every database vendor supports transaction processing, and because PDO is designed to support these transactions in a relatively portable way, it runs by default in autocommit mode. When Autocommit mode is enabled, the database driver implicitly commits each successful update. When you call $dbh->begintransaction (), you will request that autocommit be turned off until you call $DBH->commit () or $DBH->rollback (), depending on how your code is written. If the underlying driver does not support transaction processing, a pdoexception is thrown.

If a problem occurs and PHP fails, your script exits and the transaction is pending, or when you close the database handle, PDO automatically calls $DBH->rollback () for any pending transactions. This behavior reduces the likelihood of committing to a database that may not be defined or corrupted data, which is the standard semantics for handling abandoned transactions.

Preprocessing statements, stored procedures

PDO supports using the Oracle style-named placeholder syntax to fix a variable to a preprocessing statement in SQL (similar to the Ocibindbyname () in the oci8 extension). PDO also provides named placeholder simulations for other databases, such as ODBC, and can even simulate preprocessing statements and binding parameters for databases that are inherently unsupported by the concept, such as MySQL. This is a positive step forward for PHP because it allows developers to write "Enterprise-class" database applications in PHP without paying special attention to the capabilities of the database platform.

Using the PDO preprocessing statement is very simple, the prepare () method that invokes the database handle. It returns a statement handle object that you can then use to bind parameters and execute statements. In this example, we will define two named placeholders, ": extension" and ": Name", which are respectively associated with the. The PHP extension name in the CSV file corresponds to the name of one of the authors.

$stmt = $dbh->prepare ("INSERT into credits (extension, name) VALUES (: extension,: Name)");
After the statements have been preprocessed, we use the Bindparam () method to associate these named parameters with the PHP variable name "$extension" and "$name" (this is similar to Ocibindbyname ()). We will also notify Oracle that the data will be formatted as a string with a maximum length of 64 characters.

$stmt->bindparam (': extension ', $extension, PDO_PARAM_STR, 64);
$stmt->bindparam (': Name ', $name, PDO_PARAM_STR, 64);
We're ready to insert the data now-we just need to open the CSV file and get the data from it. This can be done fairly simply by using the fopen () and Fgetcsv () functions. We can then use the PHP list () constructor to assign a CSV column directly to the variable "$extension" and "$name". Because these variables are already bound to the statement, all we have to do now is invoke the Execute () method of the statement object to make it insert. This approach is both convenient and quick-there are only two rows for each iteration loop at transaction time. At the end of the file, we can immediately commit these changes using the commit () method of the database handle.

If you are simply passing input parameters, and there are many such parameters to pass, you will find the shortcut syntax shown below very helpful; This syntax allows you to omit calls to $stmt->bindparam ().

$stmt = $dbh->prepare ("INSERT into credits (extension, name) VALUES (: extension,: Name)");
$stmt->execute Array (': extension ' => $extension, ': Name ' => $name));
You can also use Bindparam to set up input/output parameters for stored procedures; The syntax is exactly the same, except that the query is different. The following code shows how to call a stored procedure named "Sp_add_item", which is intended to $item _name for input settings, and then the stored procedure updates $error _code when it is returned.

$stmt = $DBH->prepare ("Begin Sp_add_item (: Item_name, Error_code);" End ");
$stmt->bindparam (': Item_name ', $item _name, Pdo_param_str, 12);
$stmt->bindparam (': Error_code ', $error _code, Pdo_param_str, 12);
$stmt->execute ();
Fetching data
Using PDO to crawl data is similar to inserting or updating, except that after you execute the query, you will repeatedly call the fetch () method to get the next row of the result set. The easiest way to get it is as follows, and it's worth noting that you can also bind parameters to a query to control content such as WHERE clause; The syntax for doing this is exactly the same as the Bindparam () code we've seen.

$stmt = $dbh->prepare ("Select extension, name from credits");
if ($stmt->execute ()) {
while ($row = Stmt->fetch ()) {
Print_r ($row);
PDO supports a number of different crawl strategies that differ in ease and performance; by specifying one of the following options as the parameters of the fetch () method, you can change its return value to suit your syntax:

· Pdo_fetch_num-Each row crawl returns an array indexed by the column position, with a base of 0 (the first column is the No. 0 element).

while ($row = $stmt->fetch (pdo_fetch_num)) {
printf ("Extension%s, by%s<br>", $row [0], $row [1]);
· PDO_FETCH_ASSOC-Each row grab returns an array indexed by column names based on the column names in the rowset.

while ($row = $stmt->fetch (PDO_FETCH_ASSOC)) {
echo "Extension $row [Extension] by $row [name]<br>";
· Pdo_fetch_both-Each row crawl returns an array that is indexed both by column position and by column name. This is the direct combination of these two situations. If no crawl mode is specified, the mode is the default mode. · Pdo_fetch_obj-Each row crawl returns an anonymous object whose property name corresponds to the column name.
while ($row = $stmt->fetch (PDO_FETCH_ASSOC)) {
echo "Extension {$row->extension} by {$row->name}<br>";
· Pdo_fetch_lazy-Each row crawl returns an overloaded object that refers to a statement object. This "looks" like a combination of pdo_fetch_obj and pdo_fetch_both, only creating these variables when you access the PHP variable in a script.
· Pdo_fetch_bound-crawls each row, returns TRUE. This is useful when you use a bound output column to avoid creating any arrays or objects that you do not need. (see the following example).

Regardless of which crawl strategy you use, the Fetch () method returns FALSE when no other row is available to crawl.

Now I'm going to tell you some tips that might help you if you need to finally tweak your scripting performance. But let me give you a piece of advice: avoid an immature optimization, just like avoiding the plague. You should always be the best choice for the clearest and most maintainable solution. Keep in mind that in a typical WEB application, you can't measure the difference between various crawl modes, unless the script handles a lot of rows. I repeat: the performance difference between crawl modes is very small-please use the pattern that best suits your code.

Keep in mind that the cost of using Pdo_fetch_num is minimal because accessing the column data is just a simple numeric query. Pdo_fetch_obj enables you to use OO syntax to access the dataset's columns as properties of the object, but each property access involves an additional hash query that makes the cost of using it basically the same as PDO_FETCH_ASSOC. Each of these patterns replicates the entire row, which consumes slightly more memory.

Many database drivers will crawl and cache a certain number of rows on your behalf. Each time PHP accesses a column in one of these rows, it needs to copy it into its own dedicated memory area. If your query involves a number of rows, and you only need to access specific columns of a given row based on some complex logic, you'll find pdo_fetch_lazy a useful way to avoid using a lot of memory because it only replicates the column when you access the given column. When you use this approach, be aware that a "lazy object" crawled from a given statement for each fetch () is the same object that is used for each iteration (to reduce the overhead of creating/destroying it every time). This implies that you cannot simply store the object for future comparisons because it still references the current line of the statement-you need to manually copy the part you need.

The last pattern is Pdo_fetch_bound, which tells PDO that you have bound all the columns to the PHP variable, and that you do not need it to do anything other than to notify you when it arrives at the end of the rowset. The bound output column is conceptually similar to the binding input parameter, except that the bound output column can be used for all database drivers. You can bind a PHP variable to a named column, and PDO will update it each time you call execute (). This technique can be used to shave the virtual machine opcode for each column and row in the result set, which is slower than the native code. The disadvantage of this technique is that it may make your code difficult to track (also known as the WTF factor), and you need to be careful when you use variable names. The following code illustrates the use of a bound output column. Note that you do not have to specify pdo_fetch_bound to use the $stmt->bindcolumn (); Pdo_fetch_bound is only an optimization for situations where you understand that only bound values can be used.

$stmt = $dbh->prepare ("Select extension, name from credits");
if ($stmt->execute ()) {
$stmt->bindcolumn (' EXTENSION ', $extension);
$stmt->bindcolumn (' NAME ', $name);
while ($stmt->fetch (pdo_fetch_bound)) {
echo "Extension: $extension, Author: $name \ n";
Case-sensitive columns

PDO is designed to make scripts that use portable SQL run well and portable. All of the queries mentioned in this article (except the calling stored procedures) should run at the same performance when using any PDO driver-including all bound input variables and bound output columns.

But there is a conversion issue-when you use PDO_FETCH_ASSOC to crawl data, different drivers return column names differently-some convert the column names to uppercase, some to lowercase, and some to the style specified in the query. This is a potential problem for PHP scripts because the array keys are case-sensitive. PDO provides a compatibility property to help standardize the results of a script. The following small snippet is a portable version of the above Pdo_fetch_bound example, because the setattribute () method call instructs PDO to convert all of the column names returned by the crawl to uppercase:

$DBH = new PDO (' OCI: ', ' Scott ', ' Tiger ');
$DBH->setattribute (Pdo_attr_case, Pdo_case_upper);
stmt = $dbh->prepare ("Select extension, name from credits");
if ($stmt->execute ()) {
$stmt->bindcolumn (' EXTENSION ', $extension);
$stmt->bindcolumn (' NAME ', $name);
while ($stmt->fetch (pdo_fetch_bound)) {
echo "Extension: $extension, Author: $name \ n";

In addition to Pdo_case_upper, there are pdo_case_lower (which converts column names to lowercase) and pdo_case_natural (which is the default option: To keep the columns in the form that the database driver returns).

Error and error handling

Another challenge for portable scripts is to handle the various error messages that are returned from various database handlers; some databases have poor support for procedural errors, while others have very rich error codes. As long as it works, PDO will provide you with a unified error code for your script, so you don't have to be tired of dealing with this aspect of portability. Of course, PDO also provides a native error code and error message for the driver, in case you need to use it for diagnostics, or if the error code mapping is incomplete.

Another consistency problem that bothers PHP database extensions is the consistency of error-handling policies: Some extensions will return an error code that requires you to manually crawl the error string, while others simply issue a PHP warning. PDO allows you to choose one of the following three different error-handling strategies:

· Pdo_errmode_silent
This is the default mode; it simply uses the ErrorCode () and ErrorInfo () methods of the statement and database handle objects to set the error code you want to check.

if (! $DBH->exec ($sql)) {
echo $DBH->errorcode (). <BR> ";
$info = $dbh->errorinfo ();
$info [0] = = $DBH->errorcode () Unified error code
$info [1] is a driver-specific error code
$info [2] is a driver-specific error string
· Pdo_errmode_warning
In addition to setting the error code, PDO also emits a PHP warning that you can use a regular PHP error handler to catch the warning and centralize any error-handling/logging policies that you are prepared to use for your application, or just make the error appear in the browser (useful in the internal testing process).
· Pdo_errmode_exception
In addition to setting the error code, PDO throws a pdoexception and sets its properties to contain the error code and information. You can then catch the exception at a higher level of code, catch the exception using a global exception handler, or terminate the script without processing it (any pending transactions are rolled back at this point).

try {
$DBH->exec ($sql);
catch (Pdoexception $e) {
Display a warning message
Print $e->getmessage ();
$info = $e->errorinfo;
$info [0] = = $e->code; Unified error Code
$info [1] is a driver-specific error code
$info [2] is a driver-specific error string
Note that silent mode uses the least resources for run-time errors, compared to warnings or exceptions, but to get at that speed, you sacrifice some simplicity and become a bit more complicated.

The Unified Error code table currently includes the following constants: Pdo_err_none, Pdo_err_cant_map, Pdo_err_syntax, Pdo_err_constraint, Pdo_err_not_found, PDO_ERR_ Already_exists, pdo_err_not_implemented, Pdo_err_mismatch, pdo_err_truncated, pdo_err_disconnected.

The literal meaning of these constants is inferred, except Pdo_err_cant_map code; This is a PDO-specific code, which means that it cannot map driver-specific code to a unified error code, so you should query ErrorInfo () method to get more information from the driver-specific code returned by the

Data type

PDO is unknown to some extent, so it prefers to represent data as a string instead of converting it to an integer or a double type. You may be confused about this at this point, but the reason is simple: string types are the most accurate type, with the broadest range of applications in PHP, and prematurely converting data to integers or double types can result in truncation or rounding errors. By extracting the data as strings, PDO gives you some scripting controls, which you can use to control how transformations are made and when to convert using ordinary PHP type conversion tools such as transformations and implicit in mathematical operations.


If a column in the result set contains a null value, PDO maps it to a PHP null value. Oracle converts the empty string to NULL when returning data to PDO, but no other database supported by PHP will do so, causing portability problems. PDO provides a driver-level property pdo_attr_oracle_nulls that simulates this behavior for other data drivers:

$DBH = new PDO (' OCI: ', ' Scott ', ' Tiger '); $DBH->setattribute (Pdo_attr_oracle_nulls, true); Now the empty string in any statement opened from this $DBH will be converted to null POD status and future

PDO is still quite immature, but it will mature quickly. At the time this article was written, anything I mentioned in this article could be applied to Oracle 8 or later (tested on Oracle 8.0 and 9.2) through the Pdo_oci driver.

The following key features have been planned to be added in the near future:

1. LOB support using the PHP stream. With binding parameters, you can pass any stream resource (such as a file, socket, HTTP resource, compressed/filtered stream) as an input or output parameter to a query that runs on a LOB. Similarly, output parameters of type LOB are represented as PHP flows, so you can access these parameters using Fread (), fwrite (), fseek (), and other flow functions. At this point, there is no LOB support in the PDO.

2. Persistent connection and cache preprocessing statements. Persistent connections enable you to avoid opening and shutting down database server connections on each page hit. The cached preprocessing statement goes a step further, allowing you to persist the preprocessed version of the query and the database handle.

3. Cursors. Currently, PDO provides only forward read-only cursors, but in the future it will provide scrollable cursors (requiring underlying driver support), Ref-cursor, positioned updates with cursors, and updatable scrolling cursors.

We want PHP extensions to be enabled by default in PHP 5.1 (far from this target), but before that, we wanted to make PDO work stably when PHP 5.0 was released, but the stress of our daily work delayed them a little bit. At the same time, the release of PDO through PECL allows us to respond when we receive the problem report and release the repaired version based on a schedule different from the PHP 5.0 release schedule, so you can use PDO before the release of PHP 5.1.

We need your feedback.

If you have tried PDO and found the problem, be sure to use our Bug tracking software to report it to us. If you are using an Oracle driver, use this page:


If you are using a different driver, replace the PDO_OCI in the URL with its name.

If you have problems with PDO, or if you have questions about certain features, or if you have an attribute request, please contact If you want to, of course, you can contact me directly (, but please note that I get a lot of emails about PHP every day; you may find that if you first contact the previous mailing list you will get a quicker response.

About the author

Wez Furlong is the technical director of Brain Room Ltd., which uses PHP not only for WEB development, but also as an embedded scripting engine for Linux and Windows applications and systems. Wez, the core developer of PHP, often contributes to SQLite, Com/.net, activephp, Mailparse, and Streams APIs, and he is the "boss" of the PECL-PHP extension Community Library. His consulting firm's homepage is


1. More information about the PDO package
2. Report new errors? -Please provide any information that may help fix the error.
3. PHP Extensions for Oracle JDeveloper-this PHP extension simplifies the creation, editing, and running of PHP scripts in Oracle JDeveloper 10g
4.PHP Rover Guide-Learn everything about PHP, how the future will be from starting your first application to this language.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.