简体   繁体   中英

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;

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).

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

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

You can see the reference .

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...

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.

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.

eg

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM