Overriding fetch () for PDO when fetching using foreach

I expanded PDOStatementand modified fetch()to get values ​​of type timestamp and type arrays in a PostgreSQL, DateTime, and native array. This works as intended, but I cannot override the behavior when using the instruction in foreach.

I solved this by returning strings to an object that implements ArrayAccess, IteratorAggregate, and Countable. However, I am not satisfied with this decision and just want to return a clean array.

Example:

class ExtendedStatement extends PDOStatement {
    protected function __construct () {
        $ this-> setFetchMode (PDO :: FETCH_ASSOC);
    }
    public function fetch (
        $ fetch_style = PDO :: FETCH_ASSOC,
        $ cursor_orientation = PDO :: FETCH_ORI_NEXT,
        $ cursor_offset = 0)
    {
        $ r = parent :: fetch ($ fetch_style, $ cursor_orientation, $ cursor_offset);
        if (is_array ($ r)) {
            $ r ["extradata"] = TRUE;
        }
        return $ r;
    }
}
$ db = new PDO ("sqlite :: memory:");
$ db-> setAttribute (
    PDO :: ATTR_STATEMENT_CLASS, array ("ExtendedStatement", array ($ db)));
$ db-> exec ("CREATE TABLE example (id INTEGER PRIMARY KEY, name VARCHAR)");
$ db-> exec ("INSERT INTO example (name) VALUES ('test')");

// This is what is does
$ s = $ db-> prepare ("SELECT * FROM example");
$ s-> execute ();
foreach ($ s as $ r) {
    var_dump ($ r);
}
$ s-> closeCursor ();

// This is how I want it to be
$ s = $ db-> prepare ("SELECT * FROM example");
$ s-> execute ();
while ($ r = $ s-> fetch ()) {
    var_dump ($ r);
}
$ s-> closeCursor ();

// This is how I want it to be
$ s = $ db-> prepare ("SELECT * FROM example");
$ s-> execute ();
var_dump ($ s-> fetch ());
$ s-> closeCursor ();

Conclusion:

array (2) {
  ["id"] =>
  string (1) "1"
  ["name"] =>
  string(4) "test"
}
array(3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(4) "test"
  ["extradata"]=>
  bool(true)
}
array(3) {
  ["id"]=>
  string(1) "1"
  ["name"]=>
  string(4) "test"
  ["extradata"]=>
  bool(true)
}
+3
2

PDOStatement Traversable. , , PDOStatement::fetch().

+3

- :

$db->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
$sql = 'select * from table';
$stmt = $db->prepare($sql);
$stmt->execute();

while($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT))
{
    // do stuff
}

, :)

-1

Source: https://habr.com/ru/post/1756526/


All Articles