PHP5 data Object (PDO) abstraction Layer and oracle_php

Source: Internet
Author: User
Keywords abstraction object data pdo php use database one we
Tags dsn emit odbc connection php database php error php source code
The original developer of a new PHP data object (PDO) Data abstraction Layer gives you a brief introduction to the abstraction layer, highlighting how it works with Oracle.

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

About PDO

PHP is primarily a volunteer project; Although there are a handful of fixed "core" developers, none of us is developing PHP on a full-time payroll. In addition to this, we are located in different parts of the world, and you can imagine how difficult it is to develop long-term coordination efforts. Therefore, PHP is mainly based on the whim of personal short-term needs to develop, the reasons are various, some experiments, and some are because "tomorrow is a job to pay." Although this usually improves PHP every step of the way, it lacks integrity in the long run-a database extension 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 are doing the same kind of tasks with different code that is closely tied to the underlying database API. And because we (PHP core developers and extension developers) are very limited in staffing, this makes the code more difficult to maintain, which poses a big problem for PHP.

As PHP became more and more popular and successful, the major PHP database extension maintainers attended the LinuxTag 2003 conference in Germany, where we exchanged views on the future of PHP. In discussing the randomness of PHP's development, we identified some of the goals of database access in PHP:

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

We proposed this concept of PHP data Objects (PDO) because we wanted to get some of the better performance of the API by using 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; query "PHP database Abstraction" in Google to find about 83,200 matches. It's almost a dream for many PHP developers, and its production is partly due to our incomplete API. If you've ever tried to use a third-party abstraction layer to do any really important work, you'll often find that these layers of abstraction are too powerful for the job at hand-or that you need to do a lot of learning before using it, or that the interface is slow, Parameters need to be called through a multi-level scripting function to reach the database's own API, usually with the above two representations.

Why are these layers of abstraction problematic? These layers of abstraction are always trying to accomplish too many tasks, possibly even impossible. We decided to use utility as the basis for only some of the most common database API features, and to enable the PDO driver to expose their product-specific features as regular extension functions.

Why use PDO?

Heard about database abstraction extensions Most people will immediately wonder about the expansion of PDO-are we going to parse SQL and convert it to the appropriate back-end dialect? How we handle attribute X or attribute Y, and so on. So, when you hear that we don't have to worry about it at all in PDO, we don't want to be completely unified, because to make this unification possible, we can only limit ourselves to the lowest common standards.

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

Performance PDO has learned from the outset the successes and failures of existing database extensions. Because PDO's code is brand new, we have the opportunity to start designing performance again to take advantage of the latest features of PHP 5.
Ability PDO is designed to provide the basis for common database functionality while providing easy access to the unique features of the RDBMS.
Simple PDO is designed to make it easy to use your database. The API does not force you into your code, and it clearly shows the process of each function call.
• Expandable at runtime. The PDO extension is modular, allowing you to load drivers at run time for your database backend without having to recompile or reinstall the entire PHP program. For example, the Pdo_oci extension implements the Oracle database API instead of the PDO extension. There are also drivers for MySQL, PostgreSQL, ODBC, and Firebird, and more drivers are still being developed.

You may want to understand the comparison of PDO with other commonly used abstraction layers, such as PEAR DB or ADODB. PDO is lighter than other common abstraction layers, both in terms of API and performance, but involves providing uniformity between the various database backend, rather than the abstraction layer, 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, follow the instructions below to set it up, and later install the details on Windows.

Note that the PDO and its drivers are currently in the "Alpha" state, which means we can reasonably guarantee that there are no major flaws, but that the package is not perfect-we also have a lot of features to add. 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 work, and you may encounter many difficulties installing PDO. Get PHP 5 and compile and install it. Ensure that 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

You can now use the Pear tool to get and install the PDO and the Oracle driver for PDO. Because PDO is currently labeled 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 will look for the php.ini file in/usr/local/php5/lib/php.ini. Add the following line to the file:

Now you need to get a database-specific driver, and 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 line that was previously added:

Now check to make sure it runs:

% php-m

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

Firewall in the way?

If you are behind a firewall, you may experience some problems when you use the Pear Installer to obtain the package. If this happens, 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 call "pear Install" (followed by the real package that you downloaded); The version number in the example above is up-to-date at the time of writing, but will change as development progresses.

Windows Installation

If you are running Windows, follow these instructions:

• Get PHP 5 from HTTP://WWW.PHP.NET/DOWNLOADS.PHP#V5 and unzip it to C:\PHP5.
• Get PDO and Http:// separately from Http:// and Pdo_oci, put it into C:\php5\ext. Alternatively, you can find all of these PDO drivers, as well as all Windows versions of all PECL packages, from the PECL module collection for PHP 5.0.0 zip file listed on the PHP 5 download page.
• 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 drivers, otherwise it will not initialize correctly (in which case an error occurs).

If you have a PHP 4 global php.ini file in your Windows directory, you may experience problems. The best solution is to move the php.ini file so that it is located 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. Please note that not all of the documents in the PHP 5 program are up-to-date; The recommended installation process 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 C:\PHP5 is added to PATH. Also, note that the CGI version of PHP 5 is now named Php-cgi.exe.

Connect PDO

You first create an instance of the PDO class and use it as a database handle. It is not important to use which base driver, 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 the 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 additional information is specified, so the default database is used. For other drivers, such as ODBC drivers, everything after the first colon is used as an ODBC DSN. The MySQL driver will also interpret its DSN in a different way.

If the driver cannot be loaded, or if 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, the second is the character set, and the parameters correspond to the optional third and fourth arguments, and the latter two parameters you may have used in the oci8 extension function ociconnect () or Ociplogon (). To connect to a specific 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: The catch control structure has no benefit. If exception handling is not defined at the 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 each "new PDO" call will establish 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 the connection caching capability for PDO in the near future; In the case of current OCI8 extensions, connections to existing servers are reused, and idle logins are reused in these connections. When running in cached connection mode, releasing $DBH as shown in the preceding code snippet marks the login as being reusable by other connections.

If you use the ODBC driver to access Oracle, you may be pleased to note that the PDO_ODBC driver supports ODBC connection pooling 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 make a batch update (code below).

Create a PDO database handle object
The ' OCI: ' string Specifies that the OCI driver should is used
You 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 the 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 emit a CREATE TABLE query.

To make the example more natural, I extracted the extension and its 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 take advantage of Oracle's preprocessing statements and binding parameters to get 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 is in an implicit transaction, and the changes are not fully effective 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 after submission. This speeds up the execution of the code. Oracle is really good at this point.

Unfortunately, not every database vendor supports transactional processing, and because PDO is designed to support these transactions in a relatively portable way, it runs in autocommit mode by default. When auto-commit mode is enabled, the database driver implicitly submits each successful update. When you call $dbh->begintransaction (), you are asked to turn off autocommit until the call $DBH->commit () or $DBH->rollback () is re-enabled, 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 possibility of committing data that may not be defined or corrupted to the database, which is the standard semantics for handling discarded transactions.

Preprocessing statements, stored procedures

PDO supports the use of Oracle style-named placeholder syntax to help fix a variable to a preprocessing statement in SQL (similar to Ocibindbyname () in the oci8 extension). PDO also provides named placeholder simulations for other databases, such as ODBC, and can even emulate preprocessing statements and binding parameters for databases that are not supported by this 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 having to pay particular attention to the capabilities of the database platform.

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

$stmt = $dbh->prepare ("INSERT into CREDITS (extension, name) VALUES (: extension,: Name)");

After preprocessing the statements, we use the Bindparam () method to associate these named arguments with the PHP variable name "$extension" and "$name" (which 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 are 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 the 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 perform the insert. This approach is both convenient and fast-there are only two rows per iteration loop during transaction processing. When we reach the end of the file, we can immediately use the commit () method of the database handle to commit the changes.

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 input/output parameters for stored procedures; The syntax is exactly the same, except that the query is different. The following code shows how to invoke a stored procedure named "Sp_add_item", which is designed to $item _name for input, and then the stored procedure updates $error _code on return.

$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

Fetching data using PDO is similar to inserting or updating, except that after you execute the query, the fetch () method will be called repeatedly to get the next row of the result set. The simplest case for getting is as follows, and it's worth noting that you can also bind parameters to a query to control content such as WHERE clauses; 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 vary in terms of convenience and performance; You can change the return value to suit your syntax by specifying one of the following options as a parameter to the fetch () method:

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

while ($row = $stmt->fetch (pdo_fetch_num)) {
printf ("Extension%s, by%s
", $row [0], $row [1]);

· PDO_FETCH_ASSOC-Each row fetch returns an array indexed by column name, based on the column name in the rowset.

while ($row = $stmt->fetch (PDO_FETCH_ASSOC)) {
echo "Extension $row [Extension] by $row [NAME]

· Pdo_fetch_both-Each row fetch returns an array that is indexed both by column position and by column name. This is the direct combination of the two cases. If no crawl mode is specified, the mode is the default mode.
· Pdo_fetch_obj-Each row fetch 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}

· Pdo_fetch_lazy-Each row fetches an overloaded object that returns a reference statement object. This "look" seems to be a combination of pdo_fetch_obj and pdo_fetch_both, but only when you access PHP variables in your script, you create those variables.
· Pdo_fetch_bound-Fetches each line and returns TRUE. This is useful when using bound output columns, which avoids creating any arrays or objects that you do not need. (see the example below).

Whichever crawl strategy you use, the Fetch () method returns FALSE when there are no other rows to crawl.

Now I'm going to tell you a few tricks that might help you if you need to finally tweak the script performance. But let me give you a piece of advice: avoid immature optimizations like escaping the plague. You should always prefer the clearest, most maintainable solution possible. Keep in mind that in a typical WEB application, you can't measure the difference between the various crawl modes, unless the script handles many rows. I repeat: the performance difference between crawl modes is very small-use the pattern that best suits your code.

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

Many database drivers will pre-fetch and cache a certain number of rows on your behalf. Every time PHP accesses a column in one of these rows, it needs to copy it into its own private memory area. If your query involves many rows, and you only need to access a particular column of a given row based on some complex logic, you will find that Pdo_fetch_lazy is a useful way to avoid using a lot of memory because it only replicates the column when you access the given column. When using this approach, it is important to note that the "lazy object" crawled from a given statement for each fetch () is the same object that is used for each iteration (to reduce the cost of creating/destroying it each time). This implies that you cannot simply store the object for a later comparison, because it still references the current line of the statement-you need to copy the required parts manually.

The last pattern is Pdo_fetch_bound, which tells PDO that you have bound all the columns to the PHP variable and that it does not need to do anything other than to notify you when it reaches 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 updates it every time that you call execute (). This technique can be used to shave off some virtual machine opcode (which is slower than the native code) for each column and row in the result set. The disadvantage of this technique is that it may make your code difficult to track (also known as a higher WTF coefficient), and you need to be careful when you use variable names. The following code illustrates the use of bound output columns. Note that you do not have to specify pdo_fetch_bound to use $stmt->bindcolumn (); Pdo_fetch_bound is just an optimization for situations where you know you can only use bound values.

$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 work well and portable. All of the queries mentioned in this article (except for calling stored procedures) should perform the same performance when using any PDO driver-including all bound input variables and bound output columns.

But there is a conversion problem-when you use PDO_FETCH_ASSOC to crawl data, different drivers return column names in different ways-some convert the column names to uppercase, some to lowercase, and some to the styles 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 Pdo_fetch_bound example above, because the SetAttribute () method call instructs PDO to convert all the column names returned by the fetch 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 is pdo_case_lower (which converts column names to lowercase) and pdo_case_natural (which is the default option: Keep columns in the form returned by the database driver).

Error and error handling

Another challenge for portable scripting is to handle the different kinds of error messages returned from various database handlers, some of which have poor support for programmatic processing errors, and others that have very rich error codes. As long as it works, PDO will provide a uniform 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 the driver with a native error code and error message, in case you need it for diagnostics, or the error code mapping is incomplete.

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

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

if (! $DBH->exec ($sql)) {
echo $DBH->errorcode (). "
$info = $dbh->errorinfo ();
$info [0] = = $DBH->errorcode () uniform error code
$info [1] is a driver-specific error code
$info [2] is a driver-specific error string

In addition to setting the error code, PDO emits a PHP warning that you can use to catch the warning using a regular PHP error handler, and to centrally apply any error handling/logging policies you have prepared for your application, or simply to make the error visible in the browser (useful during internal testing).
In addition to setting the error code, PDO throws a pdoexception and sets its properties to include the error code and information. You can then catch the exception at a higher level in the code, catch the exception by using a global exception handler, or terminate the script without processing it (this will roll back any pending transactions).

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 the silent mode uses the least amount of resources for run-time errors compared to warnings or exceptions, but to get that speed, you sacrifice some simplicity and become a bit more complex.

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 meanings represented by these constants are literally inferred, except for the 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 returns the driver-specific code to get more information.

Data type

PDO is somewhat type agnostic, so it prefers to represent data as a string, rather than converting it to an integer or double type. You may be confused about this at this point, but the reason is very simple: string types are the most accurate types, and the widest range of applications in PHP is that prematurely converting data to integers or double types can result in truncation or rounding errors. By extracting data as a string, PDO gives you some scripting controls that you can use to control how and when to convert using common 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 an empty string to NULL when returning data to PDO, but any other database supported by PHP does not handle this, leading to portability issues. 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 in any statement that $DBH open from this
Empty strings will be converted to null

The status and future of POD

PDO is still quite immature, but it can grow up quickly. At the time of writing this article, anything I mentioned in this article could be used by the PDO_OCI driver for Oracle 8 or later (tested on Oracle 8.0 and 9.2).

It is planned to add the following key features, which will soon be available:

1. LOB support using PHP streaming. 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 the LOB. Similarly, output parameters of type LOB will behave as PHP streams, so you can use Fread (), fwrite (), fseek (), and other stream functions to access these parameters. At this point, there is no LOB support at all in PDO.
2. Persistent connections and cached preprocessing statements. Persistent connections enable you to avoid opening and closing database server connections when each page hits. The cached preprocessing statement goes one step further, allowing you to persist the preprocessed version of the query and the database handle.
3. Cursors. Currently, PDO only provides forward-only read-only cursors, but will provide scrollable cursors in the future (requiring the underlying driver support), Ref-cursor, positioning updates using cursors, and updatable scrolling cursors.

We wanted to enable PHP extensions by default in PHP 5.1 (far from this target), but before that, we wanted to have the PDO run stably when PHP 5.0 was released, but the pressure on our daily work was a little bit delayed. At the same time, the release of PDO via PECL enables us to respond when a problem report is received and to release a fix based on a schedule different from the PHP 5.0 release schedule, so you can use PDO before PHP 5.1 is released.

We need your feedback.

If you try PDO and you find a problem, be sure to report it to us using our error tracking software. If you are using an Oracle driver, use this page:


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

If you're having trouble using PDO, or have questions about some features, or have an attribute request, please contact If you prefer, you can also contact me directly (, but please note that I receive a lot of emails about PHP every day, and you may find that you get a quicker response if you first contact the previous mailing list.

About the author
Wez Furlong is the technical director of Brain, a company that uses PHP not only for WEB development, but also as an embedded scripting engine for Linux and Windows applications and systems. Wez is a core developer of PHP, often contributing to SQLite, Com/.net, activephp, Mailparse, and Streams APIs, and he is the "Chief" of the PECL-PHP Extended Community Library. The homepage of his consulting firm is Http://

  • 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.