GDP
GDP

Reputation: 8178

How to properly format PDO results? - numeric results returned as string?

With relative newness to AJAX, and now just starting to learn PDO, the added level of ReSTler has me completely boggled. Modeling the below code from Restler samples, I don't know how to change the output format from what PDO is returning to what Restler and Highcharts is expecting.

How do I change this code to get from the current format to the required format? (The results will generally be 5K-10K records, if that's a factor in handling the MySQL result.)

ReSTler API Code Snippet:

$sql = "SELECT ....."
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
    $stmt = $this->db->query($sql);
    return $stmt->fetchAll();
} catch (PDOException $e) {
    throw new RestException(502, 'Listing History: ' . $e->getMessage());
}

Current Output Format (includes unwanted column names):

[
  {
    "chart_date": "1118966400000",
    "bandwidth": "10.01",
    "views": "101"
  },
  {
    "chart_date": "1119225600000",
    "bandwidth": "20.02",
    "views": "101"
  },

Desired Output Format (numeric and without column names):

[
  [
    1118966400000,
    10.01,
    101
  ],
  [
    1119225600000,
    20.02,
    202
  ],

Edit using suggested fetch(PDO::FETCH_NUM):

Per the answer from @Ricardo Lohmann, I tried fetch(PDO::FETCH_NUM), which DID remove the column names, but all columns returned seem to be string, not numeric, as the data actually is, so try this, giving me the right data type - is this part of PDO to unilaterally return string?

while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
    $array[$x][0] = intval( $row[0] );
    $array[$x][1] = intval( $row[1] );
    $array[$x][2] = intval( $row[2] );
    $x++;
}
return $array;

Upvotes: 7

Views: 5715

Answers (5)

Rodrigo García
Rodrigo García

Reputation: 1417

You can set the next attributes as follows:

$pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

The attribute ATTR_STRINGIFY_FETCHES let you convert numeric values to strings when fetching.

Upvotes: 0

Julien B.
Julien B.

Reputation: 3344

The only way I found to bypass this problem (using SQLSRV driver), is to have SQL to send all datatypes as a string in an OUTPUT param. And then converting all values using the correct datatype. That might be heavy for big dataset.

Even though PDO developpers says it's a driver issue (not their mistake), I never had this problem using the SQLSRV driver without PDO...

Upvotes: 0

Luke Madhanga
Luke Madhanga

Reputation: 7487

I had hoped that there was a built in way to do this, thus why I performed the Google Search :v.

I'm building my own custom CMS application that I believe is 'Drupal-like' (I've never used Drupal but I use a custom system that is based off of Drupal). By this I mean I have a table in my DB that basically describes all of the fields in other tables, and when I retrieve fields from these other tables, I load up the descriptions and data type my data.

e.g.

tablex Fields: Name, Age, Old Enough

tabledescriptions:

fieldname  |  datatype  |  minlength  |  parent
___________|____________|_____________|________
Name       |  String    |  5          |  tablex
Age        |  Int       |  1          |  tablex
Old Enough |  Boolean   |  1          |  tablex

So when I load data from tablex, I look in tabledescription for things where parent = 'tablex' and use a switch statement to datatype the data

foreach ( ... ) {
    switch ($desc->datatype) {
       case 'int': (int) $tablex->data;
            break;
    }
}
etc.

Upvotes: -2

lanzz
lanzz

Reputation: 43208

PDO::FETCH_NUM is the way to go, though it does not mean numeric columns will remain numeric, it only means you will get an indexed array instead of an associative array (thus, it only accomplishes the omission of the column names).

The MySQL PDO driver always returns strings for numeric columns, which is a known bug, but unfortunately, one of the many bugs that PHP devs blatantly disregard as "thank you but this is not a bug".

You can force json_encode to use actual numbers for values that look like numbers: json_encode($data, JSON_NUMERIC_CHECK) (since PHP 5.3.3).

Upvotes: 13

Ricardo Lohmann
Ricardo Lohmann

Reputation: 26320

Try to set fetch mode instead of fetchall, like the following:

return $stmt->fetch(PDO::FETCH_COLUMN);

You can see the reference.

Upvotes: 0

Related Questions