Early Bird Registration for DrupalCon Portland 2024 is open! Register by 23:59 PST on 31 March 2024, to get $100 off your ticket.
I just found an interesting quirk in PDO. If you do something like
$stmt->execute(PDO::FETCH_CLASS, 'className');
it populates the attributes from the result row before it calls __construct() on the class className. If you want __construct() called first you need to do something like
$stmt->execute(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'className');
PDO::FETCH_PROPS_LATE and this case don't seem to be very well documented.
This situation doesn't seem to be accounted for in DatabaseStatement::execute. It only allows for the first code case above.
Comment | File | Size | Author |
---|---|---|---|
#7 | pdo-FETCH_PROPS_LATE-298309-7.patch | 872 bytes | mfer |
#6 | pdo-FETCH_PROPS_LATE-298309-6.patch | 1.08 KB | mfer |
#4 | pdo-FETCH_PROPS_LATE-298309-4.patch | 818 bytes | mfer |
Comments
Comment #1
Crell CreditAttribution: Crell commentedInteresting. When would you want to do one or the other? Should we be defaulting to one or the other, or is there value to allowing both?
Comment #2
mfer CreditAttribution: mfer commentedHere's an example, hopefully this clarifies
You have an object:
If you call
and have a resulting field called id the value on the object would be set to null. First $this->id would be set to the field result from the row. Then __construct() would be called setting it to NULL.
Calling
the resulting $this->id would be the value from the id field in the row. First __construct would be called setting it to null and then the attributes from the result row would be applied.
You'd want the second case if your __construct() function did any kind of setup that might override the attributes placed on the object from the database. The second case will follow the same flow to create an object as if you did
Personally, I prefer the second method. I'm a fan of having the object built in the same order everywhere. You have to account for less in your testing and less odd circumstances happen.
Just as PDO allows for the flexibility of both ways it might be good for us to as well. But, if we choose one I'd like to see PDO::FETCH_PROPS_LATE be used.
I know that we can write our __construct() functions to take the first situation into account. I found this issue when I was creating objects from an external library that had __construct() statements causing issues. In order to support using the external library in an unmodified way I needed to use PDO::FETCH_PROPS_LATE.
Comment #3
Crell CreditAttribution: Crell commentedHm. Makes sense. I'm not sure off hand how we'd allow both in the current setup, except adding yet another field to the options array. It seems it would cause fewer issues to just make it always do a late fetch. That's also easier to implement.
Can anyone see a reason we'd want an early fetch in this case? If not, let's just roll a patch to use late fetch.
Comment #4
mfer CreditAttribution: mfer commentedThis patch adds PDO::FETCH_PROPS_LATE in with PDO::FETCH_CLASS and adds a comment into why we use FETCH_PROPS_LATE.
Comment #6
mfer CreditAttribution: mfer commentedFixed patch for drupalTestbedBot.
Comment #7
mfer CreditAttribution: mfer commentedRough night. Removed accidental change to another part of the file.
Comment #8
Dries CreditAttribution: Dries commentedI think this makes a ton of sense. I've committed it to CVS HEAD. Thanks.
Comment #9
c960657 CreditAttribution: c960657 commentedIt looks like this caused a regression: #310904: Use early fetch and document why
Comment #10
Anonymous (not verified) CreditAttribution: Anonymous commentedAutomatically closed -- issue fixed for two weeks with no activity.