I'm having a strange issue with pdo_odbc and PDO::FETCH_OBJ (and PDO::FETCH_CLASS) that results in the following error message:
PHP Fatal error: Cannot access empty property
Here's the code:
$dbh = new PDO("odbc:FOO");
$sth = $dbh->query("
SELECT rolename
FROM dbc.allrolerights
WHERE databasename = 'BAR'
");
$result = $sth->fetch(PDO::FETCH_OBJ);
The FOO DSN, for reference, is a Teradata datasource using the tdata.so driver, provided by the tdodbc package.
I believe this is happening because the field name (as returned from the ODBC query) is blank when PDO calls zend_API.h:object_init_ex() to instantiate the stdClass object. If I switch to PDO::FETCH_LAZY and var_dump() the row, I get the following:
object(PDORow)#3 (2) {
["queryString"]=>
string(95) "
SELECT rolename
FROM dbc.allrolerights
WHERE databasename = 'BAR'
"
[""]=>
string(30) "FNAR "
}
Which seems to back it up. I've tried several different PDO attribute combinations and bunch of different angles to work around the problem. One solution is to fetch an associative array and pass it to the class constructor. However, this doesn't work for certain frameworks and ORMs that are using PDO::FETCH_CLASS directly, behind the scenes.
I want to add that other fetch methods seem to do the right thing, for example, PDO::FETCH_NAMED:
array(1) {
["RoleName"]=>
string(30) "FNAR "
}
I'm looking for something I can put in the PDO dbh or sth definition, or in the odbc.ini or odbcinst.ini for the datasource or driver, to resolve this issue. Thank you in advance.
Update: odbc_fetch_object() (i.e. not PDO) works great with the same exact everything. Just wanted to mention it. There clearly doesn't seem to be any serious issues with PHP, unixODBC, or the ODBC driver. It's something in the PDO code. Time to open a bug report... opened
$dbh = odbc_connect("FOO", NULL, NULL)
or die(odbc_error_msg());
$sth = odbc_exec($dbh, "
SELECT rolename
FROM dbc.allrolerights
WHERE databasename = 'BAR'
");
$result = odbc_fetch_object($sth);
var_dump($result);
And the output:
object(stdClass)#1 (1) {
["RoleName"]=>
string(30) "FNAR "
}
Update 2: The situation continues to grow more and more bizarre. I can do a PDO::FETCH_LAZY and see the blank column name as seen in the var_dump() above, but if I try to access the property by name (e.g. $result->RoleName), it works! What are these fetch methods doing so differently that some of them can sometimes access the field names, and others cannot?
Side-by-side comparisons of ODBC traces ("working" cf. "not working") shows no differences (other than different pointer addresses). PDO::FETCH_BOUND works with both numbered and named columns. PDO::FETCH_INTO an object with a RoleName property does not.
SELECT rolename
isn't case sensitive is it? PDO might get a bit funny about that. Also if you join onto a table with the same column the column might not come back at all unless you select dup as dup1 in the SQL. Also one final suggestion try backticking '`' the column name.. – Kevin Andrews