. Fix iterator based access
. Add new attribute ATTR_DEFAULT_FETCH_MODE: $bdh->setAttribute()
. Add new fetch mode: FETCH_PROPS_LATE, this fills object member
variables after calling the constructor (fixes#36428).
NULLs into empty strings as well as the other way around. It still doesn't
help a great deal in the long run, but at least the option is there.
Make sure hash tables are nulled out to avoid double freeing them.
proto bool PDOStatement::closeCursor()
Closes the cursor, leaving the statement ready for re-execution.
The purpose of the function is to free up the connection to the server so that
other queries may be issued, but leaving the statement in a state that it can
be re-executed.
This is implemented either as an optional driver specific method (allowing for
maximum efficiency), or as the generic PDO fallback if no driver specific
function is installed.
The PDO generic fallback is semantically the same as writing the following code
in your PHP script:
do {
while ($stmt->fetch())
;
if (!$stmt->nextRowset())
break;
} while (true);
These are effectively named statements with strong constraints on the naming
format. We cater for this in a fairly generic way: allow a driver to replace
the format string we use to generate names from positional parameters. In
addition, if that format is set, we always force a rewrite from regular names
to the strongly enforced names.
floating point values into strings during fetch. This is a compatibility hack
for drivers that return native types rather than string representations.
We use this flag in the test suite to persuade postgres tests to pass.
by name, even when multiple columns have the same name:
$sql = "SELECT 1 a, 2 a, 3 b, 4 c, 5 d, 6 c, 7 a";
echo "$sql\n";
print_r($db->query($sql)->fetchAll(PDO_FETCH_NAMED));
Array
(
[0] => Array
(
[a] => Array
(
[0] => 1
[1] => 2
[2] => 7
)
[b] => 3
[c] => Array
(
[0] => 4
[1] => 6
)
[d] => 5
)
)
Also added two new attributes for use at prepare time;
PDO_ATTR_FETCH_TABLE_NAMES and PDO_ATTR_FETCH_CATALOG_NAMES instruct the driver
that the names of the columns that they return to PDO should include the table
and catalog names respectively. Both attributes may be used together or
independently. The catalog, table and column name components should be
separated by a . character.
new one each time.
Add a hook for persistent connections: it is called when the object goes out of
scope, and offers the driver an opportunity to release per-request scoped data
at the right time.
This hook is used by pdo_sqlite to unregister UDFs, which are dangerous to keep
registered between requests.
Changed PDO::lastInsertId() to have following proto:
string PDO::lastInsertId([string name])
this allows arbitrary unique identitifers to be returned from the driver.
The optional name parameter is for databases that require additional contextual
information to be able to return the correct identifier. None currently use
it, but pgsql will be on the list of drivers that do.
old: proto object PDO::prepare(string statment [, array driver_options [, string classname ]])
now: proto object PDO::prepare(string statment [, array options])
param 'classname' and and 'ctor_args' are now set through options
using index PDO_ATTR_STATEMENT_CLASS
- Change all deriver_options parameters to 'options' to reflect the fact
that they may contain statement as well as driver specific flags
- Verify fetch modes
- Add last fetch mode PDO_FETCH_FUNC (only valid inside fetchAll()) that
allows to completley customize the way data is treated on the fly
placeholders.
The current restriction is that you may not use the same named parameter
more than one in a given query, as there is a danger of scary things happen
with the zval if it gets bound multiple times.
Allow drivers to add methods to dbh and stmt objects
(note that we can't use a class, because the use only sees the PDO class).
Clarify the api slightly:
PDO::exec() is used for one-shot queries that don't return rows
PDO::query() is a convenience function for returning a rowset without
having to go through the steps of preparing and executing.
PDOStatement::setFetchMode()
reset default fetch() mode for a statement to PDO_FETCH_BOTH
PDOStatement::setFetchMode(PDO_FETCH_NUM)
PDOStatement::setFetchMode(PDO_FETCH_ASSOC)
PDOStatement::setFetchMode(PDO_FETCH_BOTH)
PDOStatement::setFetchMode(PDO_FETCH_OBJ)
set default fetch() mode for a statement.
PDOStatement::setFetchMode(PDO_FETCH_COLUMN, int colno)
set default fetch() mode to retrieve colno-th column on each fetch() call.
PDOStatement::setFetchMode(PDO_FETCH_CLASS, string classname [, array ctor args])
set default fetch() mode to create an instance of classname,
calling it's ctor, passing the optional ctor args.
The names of the columns in the result set will be used as property names on
the object instance. PPP rules apply.
[NOTE: calling ctor is not yet implemented]
[TODO: this might crash PHP for persistent PDO handles]
PDOStatement::setFetchMode(PDO_FETCH_INTO, object obj)
Similar to PDO_FETCH_CLASS, except that each iteration will update the
supplied object properties.
[TODO: this might crash PHP for persistent PDO handles]
The default fetch() mode is used when no parameters are passed to
PDOStatement::fetch(). When using a statement in an iterator context,
PDOStatement::fetch() is called implicitly on each iteration.
object PDO::queryAndIterate(string sql, <PDOStatement::setFetchMode args>)
This is semantically equivalent to:
$stmt = $pdo->prepare($sql);
$stmt->execute();
$stmt->setFetchMode($args);
return $stmt;
Example/Intended usage:
/* fetch an array with numeric and string keys */
foreach ($pdo->queryAndIterate("select NAME, VALUE from test") as $row) {
debug_zval_dump($row);
}
/* fetch the value of column 1 into $row on each iteration */
foreach ($pdo->queryAndIterate("select NAME, VALUE from test",
PDO_FETCH_COLUMN, 1) as $row) {
debug_zval_dump($row); // string(3) "foo"
}
/* create a new instance of class Foo on each iteration */
foreach ($pdo->queryAndIterate("select NAME, VALUE from test",
PDO_FETCH_CLASS, 'Foo') as $row) {
debug_zval_dump($row);
/*
Object(Foo)#4 (2) refcount(2){
["NAME"]=>
string(12) "foo220051429" refcount(2)
["VALUE"]=>
string(12) "bar789825748" refcount(2)
}
*/
}
etc.