PDO Specification

Wez Furlong

Message Systems, Inc.

Wed Jan 23 10:27:20 EST 2008


Table of Contents

Preface
1. Overview
1.1. Design Principles
1.1.1. Connection Management
1.1.2. Data typing
1.1.3. Transaction Support
1.1.4. Error Handling
2. Driver Documentation
2.1. Driver Registration
2.2. Connection Establishment
2.2.1. Factory method inputs
2.2.2. Factory method outputs
2.2.3. Factory method return value
2.3. Database Handle Methods
2.3.1. Error handling protocol
2.3.2. SKEL_close_func
2.3.3. SKEL_prepare_func
2.3.4. SKEL_do_func
2.3.5. SKEL_quote_func
2.3.6. SKEL_begin_func
2.3.7. SKEL_commit_func
2.3.8. SKEL_rollback_func
2.3.9. SKEL_set_attr_func
2.3.10. SKEL_last_id_func
2.3.11. SKEL_fetch_error_func
2.3.12. SKEL_get_attr_func
2.3.13. SKEL_check_liveness_func
2.3.14. SKEL_get_driver_methods_func
2.3.15. SKEL_request_shutdown_func
2.4. Preparing Statements
2.4.1. pdo_parse_params
2.5. Parameter Binding
2.6. Statement Handle Methods
2.6.1. Error handling protocol
2.6.2. SKEL_stmt_dtor_func
2.6.3. SKEL_stmt_execute_func
2.6.4. SKEL_stmt_fetch_func
2.6.5. SKEL_stmt_describe_col_func
2.6.6. SKEL_stmt_get_col_data_func
2.6.7. SKEL_stmt_param_hook_func
3. User-space Documentation
Index

Preface

This document specifies the implementation of PDO, PHP Data Objects, both from the perspective of PHP script level APIs used by people developing PHP applications, and from the perspective of C level APIs in the PDO internals that will be used by people developing PDO drivers.

Briefly summarize the chapters here.

Acknowledgments

A number of people were involved in the development of PDO and its drivers; without them it wouldn't be what it is, and you wouldn't be reading this text. Those people are: Ilia Alshanetsky, Ard Biesheuvel, Marcus Börger, Sara Golemon, Sterling Hughes, Edin Kadribašić Frank Kroman and George Schlossnagle from the PHP community, Chris Jones from Oracle, Dan Scott, Bill Abt, Kellen Bombardier Rick McGuire and Krishna Raman from IBM.

Chapter 1. Overview

PDO is structured as depicted below; a core PDO module provides a framework for loading driver extensions and calling into them, similar in some ways to ODBC, although PDO is a very lightweight bridge when compared to ODBC. The core module is responsible for managing the user-space portions of the the PHP/Database interaction, delegating the database/vendor specific portions to the appropriate driver extension module. It is typical for a driver extension to delegate, in turn, to a pre-existing database client library to carry out its duties.

+---------------------------------------------+
|                  PDO Core                   |
+---------------------------------------------+
+--------------------+   +--------------------+
|PDO Driver Extension|   |PDO Driver Extension|
+--------------------+   +--------------------+
+--------------------+   +--------------------+
| DB Client Library  |   | DB Client Library  |
+--------------------+   +--------------------+

1.1. Design Principles

PDO was built around the ideal of being able to provide a common data access paradigm across a variety of data providers. The goal was to provide the lowest common denominator of features using a common API, while still being able to provide access to database/vendor specific features. There are some important behavior traits in PDO; most are general behaviors that most drivers exhibit; some deviation is allowed if it the net effect of the deviation is not a big problem (for instance, type juggling). There are a couple of hard rules that must be adhered to for conformance, however.

1.1.1. Connection Management

While an instance of the PDO class exists, it represents an open connection to the database.

1.1.2. Data typing

As a "typeless" environment, PHP doesn't mind whether data is returned as integer, floating point or string; it can convert to the appropriate type as needed. This conversion process may cause loss in data fidelity in some cases, in particular when it comes to floating point numbers. The type of choice for PDO when binding or requesting data is to use the string type, as this has the best data fidelity.

Note that some database client library implementations don't provide the application with a means to specify their preferred data type, returning it in their own perception of the best native data type. For those drivers it would typically be wasted effort to convert to a string in the PDO driver layer, so the native type is passed up and returned to the script in that form.

The net result of this is that data is usually, but not always, returned as strings unless otherwise specified by the PHP script.

1.1.3. Transaction Support

Many, but not all, database implementations support the notion of transactions. The transaction reflects a block of database operations that can be either committed or rolled back. Some database implementations support nesting transactions, or transactions across multiple connection handles. Most databases that support transactions start out in a mode known as "auto-commit", which emulates non-transactional behavior.

PDO, as an abstraction layer, is responsible for making sure that the behavior of two freshly opened connections to different databases don't exhibit drastically different behavior. The principle of least surprise is particularly important when it comes to transactions, so PDO requires that its driver extensions observe the following rules, since an application that assumes that transactions are available when they are not could proceed and cause damage to the data in the database when it attempts to rollback its changes.

Freshly created connections must start in auto-commit mode. This allows non-transactional scripts to operate without having to do anything special to get auto-commit enabled.

Attempting to use transactions when the underlying database doesn't support them must return an error to the PDO core layer. PDO itself will generate a runtime exception which will cause the script to terminate unless handled by the script. Note that PDO will not normally generate exceptions unless explicitly told to do so by the script. Forcing an exception in this case helps to reinforce that something is seriously wrong.

PDO only supports the notion of being in a transaction or not. It does not support nested transactions, it is an error to start a new transaction while a transaction is active.

Ad-hoc SQL executed by the script that affects the transactional state of the connection as seen by the database is allowed, but its effect on the PDO-core notion of the transactional state is undefined. A driver must not attempt to reconcile the effect of ad-hoc SQL with the PDO-core transactional state.

1.1.4. Error Handling

The behavior of PDO in the face of errors varies based on application preference. The default is to silently return error codes back to the script, but also allows the option of emitting a warning in addition to returning the error code, or to throw an exception object containing the error state.

In the interests of portability and fidelity of information, PDO requires its drivers to record the ANSI SQL 92 SQLSTATE error code along with their native and human readable error codes when an error is encountered. This allows portable scripts the ability to use vendor-independent error handling logic as well as the freedom to also use vendor-dependent logic if required.

Chapter 2. Driver Documentation

Any PHP extension that is linked against the PDO core module can elect to register a PDO driver. A PDO driver is represented by the pdo_driver_t type which describes the version of PDO against which the driver was built, the name of the driver and a factory method that can be used to instantiate a database connection handle. A connection handle is represented by the pdo_dbh_t type which describes, among other things, how to instantiate a prepared statement handle, represented by the pdo_stmt_t type.

These three types are the main interface between the PDO core and a PDO driver. In this chapter, we'll refer to an imaginary skeleton driver, and use SKEL as a placeholder for its various functions or types. In practice, a given database vendor will typically choose to use a short, lowercase, version of the name of their database or client library in place of SKEL.

2.1. Driver Registration

A driver extension will typically statically define an instance of pdo_driver_t and pass the address of it to php_pdo_register_driver during its module initialization callback (also known as MINIT, for module init), and again to php_pdo_unregister_driver during its module shutdown callback (also known as MSHUTDOWN).

php_pdo_driver.h defines pdo_driver_t, php_pdo_register_driver and php_pdo_unregister_driver as follows:

/* This structure is registered with PDO when a PDO driver extension is
 * initialized */
typedef struct {
    const char      *driver_name;
    unsigned long   driver_name_len;
    unsigned long   api_version; /* needs to be compatible with PDO */

#define PDO_DRIVER_HEADER(name) \
    #name, sizeof(#name)-1, \
    PDO_DRIVER_API

    /* create driver specific portion of the database handle and stash it into
     * the dbh.  dbh contains the data source string and flags for this
     * instance.  You MUST respect dbh->is_persistent and pass that flag to
     * pemalloc() for all allocations that are stored in the dbh or your instance
     * data in the db, otherwise you will crash PHP when persistent connections
     * are used.
     */
    int (*db_handle_factory)(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC);
} pdo_driver_t;

/* call this in MINIT to register your PDO driver */
PDO_API int php_pdo_register_driver(pdo_driver_t *driver);
/* call this in MSHUTDOWN to unregister your PDO driver */
PDO_API void php_pdo_unregister_driver(pdo_driver_t *driver);

A driver would typically use code like the following to register a driver:

static pdo_driver_t SKEL_driver = {
  PDO_DRIVER_HEADER(SKEL),
  SKEL_db_handle_factory
};

PHP_MINIT_FUNCTION(pdo_SKEL)
{
  return php_pdo_register_driver(&SKEL_driver);
}

PHP_MSHUTDOWN_FUNCTION(pdo_SKEL)
{
  php_pdo_unregister_driver(&SKEL_driver);
  return SUCCESS;
}

The SKEL_db_handle_factory is provided by the driver; its operation will be discussed in the next section.

2.2. Connection Establishment

When a database connection is to be established, the PDO core will create an instance of pdo_dbh_t and initialize it. The factory method will then be invoked, which is responsible for performing driver specific initialization, connecting to the underlying data source and communicating certain database characteristics back to the PDO core.

2.2.1. Factory method inputs

The PDO core initializes various pieces of a pdo_dbh_t (we'll refer to it as dbh from now on). The portions of the structure that are relevant as inputs to the factory method are:

struct _pdo_dbh_t {
/* credentials */
char *username, *password;
/* data source string used to open this handle */
const char *data_source;
unsigned long data_source_len;

/* if true, then data stored and pointed at by this handle must all be
 * persistently allocated */
unsigned is_persistent:1;

/* if true, driver should act as though a COMMIT were executed between
 * each executed statement; otherwise, COMMIT must be carried out manually
 * */
unsigned auto_commit:1;
};
username, password, data_source, data_source_len,

These fields describe the data source to which to connect, and the credentials that should be used. username and/or password may be NULL if they were not passed to the constructor. In this case, the driver may then take credentials from the data_source string.

The data_source is defined as a string prefixed by a driver name and a colon, but is otherwise left entirely to a driver to interpret. For instance, and ODBC driver could define the data source string as a prefixed version of the underlying ODBC data source name and pass data_source directly to the ODBC API calls needed for connection establishment.

If the underlying database client library doesn't have its own concept of encoding the connection parameters in a data source string, a driver may find it convenient to use php_pdo_parse_data_source to parse defined connection parameters out of the data_source string.

is_persistent

PHP has a memory manager that can be used for per-request memory or for memory that persists beyond the scope of a request. If creating a persistent connection, is_persistent will be set to 1 indicating that all state associated with the dbh must be allocated using a persistent allocator.

In practice, drivers will simply call pemalloc or pefree and pass in is_persistent, and be able to satisfy this requirement.

Failure to observe this requirement can lead to memory leaks or crashes. If a driver cannot operate correctly when is_persistent is set, then it should raise an error as described below.

auto_commit

When set to 1, the driver must act as though an implicit commit were executed after each successfully executed statement.

When set to 0, the driver should implicitly start a transaction.

If the underlying data source does not support transactions and auto-commit is disabled, the driver must raise an error, as described below.

In addition to the dbh, the factory method is also passed a PHP zval pointer that may be NULL. If it is not NULL, it will reference a PHP array type keyed by integer attribute identifiers. The driver should use pdo_attr_lval and/or pdo_attr_strval to determine if any parameters that affect how it will establish the connection are present.

The PDO core will iterate all the options and inform the driver of them immediately after the connection has been successfully established, so the factory method should only process those parameters that are needed to establish the connection.

2.2.2. Factory method outputs

The primary purpose of the factory method is to establish a connection to a data source. It must also set certain fields of the dbh so that the PDO core knows how best to interact with it.

The portions of the dbh that are relevant as outputs of the factory method are:

struct _pdo_dbh_t {
  /* driver specific methods */
  struct pdo_dbh_methods *methods;
  /* driver specific data */
  void *driver_data;
  /* if true, the driver requires that memory be allocated explicitly for
   * the columns that are returned */
  unsigned alloc_own_columns:1;
  /* max length a single character can become after correct quoting */
  unsigned max_escaped_char_length:3;
};
methods

This field must be set by the factory method before it returns, even if the connection attempt failed. This allows the core to correctly interrogate the connection handle if an error occurs.

driver_data

The driver_data field can be used by the driver to store an arbitrary pointer to some state. This is typically a structure that holds the connection context used by the underlying database client library and any other additional state needed by the driver.

alloc_own_columns

When set to 1, indicates the driver needs to pre-allocate memory to hold the data for a result set. In this case, the PDO core will trigger a describe immediately after executing a statement for the first time. Otherwise, the describe occurs just-in-time.

max_escaped_char_length

This is used by the query rewriter to size buffers when quoting parameters. If the driver supports parameter binding, then this field is unused. If left at its default value of 0, the query rewriter will assume 3 bytes per quoted character.

2.2.3. Factory method return value

On success, the methods and driver_data fields of dbh must be set to non-NULL values. The other fields described above should be set as appropriate. The factory method must return 1 to indicate success.

On failure, the methods field of dbh must be set to a non-NULL value, The other fields described above may have been modified by the driver. The PDO core will free all resources by calling the closer method provided by the driver. The driver must trigger an exception and return 0 to indicate failure.

The connection failure case might look something like this:

zend_throw_exception_ex(php_pdo_get_exception(), 0 TSRMLS_CC,
  "SQLSTATE[%s] connection failed", sqlstate);
return 0;

Note

Implementation bug: the intention was for the exception thrown during connection errors to behave identically to the way it behaves after a successful connect, in that it should have an errorInfo property as described elsewhere. However, there is no exported convenience API for this purpose, and so no drivers do this.

2.3. Database Handle Methods

The pdo_dbh_methods structure defines the methods for a given database connection handle. The methods are defined below; each one is subject to the following error handling protocol:

2.3.1. Error handling protocol

When a driver encounters an error, it must update the error_code field of the dbh to hold an appropriate SQLSTATE error code, and take some action to record the driver specific error code and human readable message, if necessary.

The method descriptions below describe how to indicate an error status. The PDO core may invoke the SKEL_fetch_error_func to obtain the driver specific error code and human readable message.

The driver should not unilaterally raise an exception in reponse to an error. Instead, it should be left to the PDO core to handle reporting the error to the script, based on the application preferences for error handling.

2.3.2. SKEL_close_func

int SKEL_close_func(pdo_dbh_t *dbh TSRMLS_DC);

This function is called by the PDO core when freeing resources associated with the dbh. It should release any resources allocated by the driver.

Returns 0. An implementation bug means that the return value is not checked.

2.3.3. SKEL_prepare_func

int SKEL_prepare_func(pdo_dbh_t *dbh, const char *sql,
      long sql_len, pdo_stmt_t *stmt, zval *driver_options TSRMLS_DC);

This function is called when creating a statement handle. It is described in more detail in Section 2.4, “Preparing Statements”.

Returns 1 on success, 0 on failure.

2.3.4. SKEL_do_func

int SKEL_do_func(pdo_dbh_t *dbh, const char *sql,
      long sql_len TSRMLS_DC);

Execute a statement that does not return a result set.

Returns -1 on failure, or the number of affected rows otherwise.

2.3.5. SKEL_quote_func

int SKEL_quote_func(pdo_dbh_t *dbh, const char *unquoted,
      int unquoted_len, char **quoted, int *quotedlen,
      enum pdo_param_type paramtype TSRMLS_DC);

Quote a parameter, escaping SQL meta-characters as appropriate and enclosing the parameter in appropriate quotation marks. This function will allocate an appropriately sized buffer using emalloc and return it to the caller by setting quoted and quotedlen to the buffer and its length.

The return value should be 1 if the function generated a quoted string, or 0 otherwise.

2.3.6. SKEL_begin_func

int SKEL_begin_func(pdo_dbh_t *dbh TSRMLS_DC);

This function begins a transaction on the connection. If the driver does not support transactions, it should not provide this method.

Returns 1 to indicate that a new transaction has begun, 0 to indicate error. The PDO core maintains its own idea of whether a transaction is in progress, so the driver should not maintain its own.

2.3.7. SKEL_commit_func

int SKEL_commit_func(pdo_dbh_t *dbh TSRMLS_DC);

This function commits a transaction on the connection. If the driver does not support transactions, it should not provide this method.

Returns 1 to indicate that the transaction was committed, 0 otherwise. Once committed, PDO assumes that a transaction is no longer active.

2.3.8. SKEL_rollback_func

int SKEL_rollback_func(pdo_dbh_t *dbh TSRMLS_DC);

This function rolls back a transaction on the connection. If the driver does not support transactions, it should not provide this method.

Returns 1 to indicate a successful rollback, 0 otherwise. Once rolled back, PDO assumes that a transaction is no longer active.

2.3.9. SKEL_set_attr_func

int SKEL_set_attr_func(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);

Sets an attribute on the database handle. Returns 1 if the attribute was set successfully, 0 otherwise. There are a number of attributes that can be set, and these are discussed in ???.

2.3.10. SKEL_last_id_func

char *SKEL_last_id_func(pdo_dbh_t *dbh, const char *name,
      unsigned int *len TSRMLS_DC);

Returns the last insert id. A NULL return value indicates an error condition, otherwise the return value must be a NUL terminated string allocated using emalloc.

2.3.11. SKEL_fetch_error_func

int SKEL_fetch_error_func(pdo_dbh_t *dbh, pdo_stmt *stmt,
      zval *info TSRMLS_DC);

Fetch error information. If stmt is not NULL, fetch information pertaining to the statement, otherwise fetch the connection level error information. The driver should add the following information to the array "info" in this order: a) the native error code and b) a string representation of the error code.

A driver may optionally append any other arbitrary, useful, information to the info array.

Returns 1 to indicate that it populated info, 0 otherwise.

2.3.12. SKEL_get_attr_func

int SKEL_get_attr_func(pdo_dbh_t *dbh, long attr, zval *val TSRMLS_DC);

Retrieves an attribute from a database handle. Returns 0 if the driver doesn't support the attribute. Returns -1 if the driver encountered an error. Returns 1 on success. There are a number of attributes that can be fetched, and these are discussed in ???.

2.3.13. SKEL_check_liveness_func

int SKEL_check_liveness_func(pdo_dbh_t *dbh TSRMLS_DC);

Performs some driver dependent action to determine if a connection is still valid for use, typically a low overhead ping. Returns SUCCESS if the connection is still alive and ready to be used, FAILURE if the connection is no longer alive (perhaps it timed out). If this function is not provided, it is equivalent to defining a function that always returns SUCCESS.

2.3.14. SKEL_get_driver_methods_func

zend_function_entry *SKEL_get_driver_methods_func(
      pdo_dbh_t *dbh, int kind TSRMLS_DC);

When a PHP script attempts to call a method on a PDO or PDOStatement object that is not covered by either this specification or by a user defined class that extends either PDO or a PDOStatement, then SKEL_get_driver_methods_func is called to determine the driver extension methods that are present.

When kind is PDO_DBH_DRIVER_METHOD_KIND_DBH, the driver extension method table for the connection handle must be returned. When kind is PDO_DBH_DRIVER_METHOD_KIND_STMT, the driver extension method table for the statement handle must be returned.

The return value is either a zend_function_entry pointer referencing a table of methods, or NULL to indicate that there are no extension methods available.

Driver extension methods must be prefixed with the driver name used to register the driver so that they are less likely to collide with either future PDO methods or user defined functions in derived classes.

2.3.15. SKEL_request_shutdown_func

void SKEL_request_shutdown_func(pdo_dbh_t *dbh TSRMLS_DC);

Called when a script terminates (request shutdown) for a persistent connection handle. This provides the opportunity to safely releases resources that only have per-request scope.

2.4. Preparing Statements

When building a prepared statement, the PDO core will allocate and initialize an instance of the pdo_stmt_t type and pass it to the SKEL_prepare_func function.

The stmt passed to the preparer will have query_string and query_stringlen initialized, along with some other state that is not relevant to a driver implementation.

The preparer is responsible for setting up the driver specific portion of the prepared statement state. This typically involves invoking the PDO query rewriter and then passing the resultant query string to a database client library API that sets up the prepared statement handle.

The stmt has the following fields that can be set by the preparer function:

struct _pdo_stmt_t {
  /* driver specific methods */
  struct pdo_stmt_methods *methods;
  /* driver specific data */
  void *driver_data;

  unsigned supports_placeholders:2;

  const char *named_rewrite_template;
};
methods

This field must be set by the preparer before it returns, even if the prepare failed. This allows the core to correctly interrogate the statement handle if an error occurs.

driver_data

The driver_data field can be used by the driver to store an arbitrary pointer to some state. This is typically a structure that holds the statement context used by the underlying database client library and any other additional state needed by the driver.

supports_placeholders

The driver should set this to either PDO_PLACEHOLDER_NONE or one or both of PDO_PLACEHOLDER_NAMED or PDO_PLACEHOLDER_POSITIONAL bitwise OR'd together. This indicates to the query rewriter what level of parameter subsitution is supported natively by the driver. “named” style placeholders are Oracle style named parameters whereas “positional” style parameters are ODBC style question mark parameter placeholders.

named_rewrite_template

Some drivers may only support alternative named parameter syntax that is not recognized by PDO. Those drivers may set named_rewrite_template to a printf style format string that can be used by the query rewriter to map the ordinal position of a parameter to a name that is recognized by the driver.

snprintf will be invoked using this string as the format specifier, and will be passed a single integer parameter representing the ordinal position of the parameter.

The PostgreSQL driver sets named_rewrite_template to $%d, which allows PDO to rewrite Oracle style named parameters to position style, and from there, uses the rewrite template to map them to the PostgreSQL named format.

A driver must set supports_placeholders to PDO_PLACEHOLDER_NAMED to make use of this feature.

If the driver natively supports both placeholder styles, it can pass query_string through to its native prepare API. Otherwise, it must set supports_placeholders appropriately and then invoke pdo_parse_params to analyze and possibly rewrite the query string.

If an error is encountered, the preparer function should record error state in the dbh rather than the stmt as a failed prepare will result in the stmt being freed and it will thus not be available for interrogation. The state recorded in the dbh must be compatible with the error handling protocol described in Section 2.3.1, “Error handling protocol”.

Returns 1 on success, 0 on failure.

2.4.1. pdo_parse_params

PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery,
      int inquery_len, char **outquery, int *outquery_len TSRMLS_DC);

Given an input inquery and its length, inquery_len, analyzes the SQL and potentially rewrites it to an appropriate native form based on the supports_placeholders field in stmt.

Returns 0 if the input query is in a suitable native form that the driver understands.

Returns 1 if the query was rewritten; outquery and outquery_len will be updated to reference the rewritten query string and its length. If outquery is not NULL, the caller is responsible for freeing it via efree when it is no longer required.

Returns -1 if an error ocurred. The error_code field of stmt will have been set to an appropriate SQLSTATE error code. A driver will usually copy this code into the equivalent field of the dbh.

2.5. Parameter Binding

This section describes the parameter (and column) binding interface in PDO.

2.6. Statement Handle Methods

The pdo_stmt_methods structure defines the methods for a given prepared statement handle. The methods are defined below; each one is subject to the error handling protocol below.

Note that the dbh of the stmt handle references the connection handle associated with the statement.

2.6.1. Error handling protocol

When a driver encounters an error on a prepared statement handle, it must update the error_code field of the stmt to hold an appropriate SQLSTATE error code, and take some action to record the driver specific error code and human readable message, if necessary.

The method descriptions below describe how to indicate an error status. The PDO core may invoke the SKEL_fetch_error_func to obtain the driver specific error code and human readable message.

The driver should not unilaterally raise an exception in reponse to an error. Instead, it should be left to the PDO core to handle reporting the error to the script, based on the application preferences for error handling.

2.6.2. SKEL_stmt_dtor_func

int SKEL_stmt_dtor_func(pdo_stmt_t *stmt TSRMLS_DC);

This function is called by the PDO core when freeing resources associated with the stmt. It should release any resources allocated by the driver.

Returns 0. An implementation bug means that the return value is not checked.

2.6.3. SKEL_stmt_execute_func

int SKEL_stmt_execute_func(pdo_stmt_t *stmt TSRMLS_DC);

Starts the query. This is typically implemented as a call to the database specific prepared statement execute function. Prior to calling this function, the PDO core will trigger a PDO_PARAM_EVT_EXEC_PRE event for each parameter, offering the driver an opportunity to perform some final binding or allocation actions prior to executing the statement.

active_query_string and active_query_stringlen will be set by the PDO core to reflect the query being executed. This is largely for the convenience of drivers that don't natively support parameterized queries; the query rewriter will have synthesized a query string with the parameters expanded, if the supports_placeholders indicates that it should have. For drivers that do support parameterized queries, it is anticipated that they will have already prepared their statement handles and associated the parameters with it during the PDO_PARAM_EVT_EXEC_PRE notification.

Immediately after executing, the PDO core will trigger a PDO_PARAM_EVT_EXEC_POST event for each parameter, offering the driver an opportunity to take some action, for example, with parameters bound as OUT parameters.

Returns 1 on success, 0 on failure.

2.6.4. SKEL_stmt_fetch_func

int SKEL_stmt_fetch_func(pdo_stmt_t *stmt,
      enum pdo_fetch_orientation ori, long offset TSRMLS_DC);

Requests that the driver fetch the next row into driver storage. Prior to calling this function the PDO core will trigger a PDO_PARAM_EVT_FETCH_PRE event for each column, offering the driver an opportunity to perform per-column allocations or binding.

After calling this function, the PDO core will trigger a describe of the columns if they haven't already been queried, and will then trigger a PDO_PARAM_EVT_FETCH_POST event.

The orientation and offset parameters allow scrolling cursor operation.

Returns 1 if data was returned, 0 otherwise.

2.6.5. SKEL_stmt_describe_col_func

int SKEL_stmt_describe_col_func(pdo_stmt_t *stmt,
      int colno TSRMLS_DC);

Requests that the driver populate the columns field of stmt with information about a given column. Columns are numbered zero-based in this function.

Returns 1 if successful, 0 otherwise.

2.6.6. SKEL_stmt_get_col_data_func

int SKEL_stmt_get_col_data_func(pdo_stmt_t *stmt,
      int colno, char **ptr, unsigned long *len, int *caller_frees TSRMLS_DC);

Requests that the driver return a pointer and size of the data for a particular column. PDO prefers that the driver manage the lifetime of this data (it can often reuse the same memory block for repeated fetches). The PDO core will translate this memory, copying it if necessary. If the driver must allocate transient memory for a column, then it should do so using emalloc() and set caller_frees to a non-zero value. This informs PDO that it is responsible for freeing the column data when it is no longer required.

The type of pointer is specified by the column description prepared by SKEL_stmt_describe_col_func.

Returns 1 if successful, 0 otherwise.

2.6.7. SKEL_stmt_param_hook_func

int SKEL_stmt_param_hook_func(pdo_stmt_t *stmt,
      struct pdo_bound_param_data *param, enum pdo_param_event event_type
      TSRMLS_DC);

The param hook function is called by the PDO core at certain key points in the setup of a statement handle, per parameter or column, to notify the driver, so that it can perform some driver specific function.

The PDO core has no expectations for the hook function, except that it should return 0 if there was an error, 1 otherwise.

The events that are possible are:

PDO_PARAM_EVT_NORMALIZE

Triggered before PDO_PARAM_EVT_ALLOC to normalize the parameter name. This is not typically used by most drivers. The pgsql driver uses this opportunity to fixup the parameter name and ordinal position before the core registers its parameter state.

PDO_PARAM_EVT_ALLOC

Triggered in response to binding a parameter or column. This is the drivers opportunity to allocate its driver-specific state for the parameter.

Some drivers will take this opportunity to set up bind descriptors if enough information is present in the param data. Note that this stage is too early to be sure of the value (it may change between the bind call and statement execution), so drivers must not snapshot the value of the parameter at this point.

PDO_PARAM_EVT_FREE

Triggered when the core is done with a parameter, typically at statement handle tear-down time. The driver must release any resources it may have allocated for the parameter.

PDO_PARAM_EVT_EXEC_PRE

Triggered for each parameter immediately before invoking the SKEL_stmt_execute_func. This is the correct time to capture or reference the parameter value and finalize the binding of the parameter.

PDO_PARAM_EVT_EXEC_POST

Triggered for each parameter immediately after invoking the SKEL_stmt_execute_func. This allows a driver to fixup or reconcile state, in particular for OUT parameters that have been bound to a zval.

PDO_PARAM_EVT_FETCH_PRE

Triggered for each bound column immediately before invoking the SKEL_stmt_fetch_func. This has similar semantics to PDO_PARAM_EVT_EXEC_PRE, except that it applies to binding columns in a result set to zvals rather than parameters in a prepared statement.

PDO_PARAM_EVT_FETCH_POST

Triggered for each bound column immediately after invoking the SKEL_stmt_fetch_func. This has similar semantics to PDO_PARAM_EVT_EXEC_POST, except that it applies to binding columns in a result set to zvals rather than parameters in a prepared statement.

Chapter 3. User-space Documentation

bar

Index