7

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;
GDP
  • 8,109
  • 6
  • 45
  • 82

5 Answers5

13

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

lanzz
  • 42,060
  • 10
  • 89
  • 98
  • 1
    Ah, to have PHP 5.3 at my disposal, alas, I'm stuck with 5.2 for the duration, but THANK you for at least clarifying the "string thing"...was getting bruised while I was beating myself up trying every ^&^*(( possible setting!!! – GDP Jun 21 '12 at 16:26
0

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

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

You can see the reference.

Ricardo Alvaro Lohmann
  • 26,031
  • 7
  • 82
  • 82
0

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

Julien B.
  • 3,023
  • 2
  • 18
  • 33
0

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.

Rodrigo García
  • 1,357
  • 15
  • 26
-2

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.
Luke Madhanga
  • 6,871
  • 2
  • 43
  • 47
  • @YourCommonSense Not when you are building a system OOP style. BTW, this is just a snippet of what I use the 'tabledescriptions' table for. I also use it to determine what the insert fields are for tablex, etc. meaning that in the long run, the code is a lot more efficient and reliable – Luke Madhanga Mar 05 '14 at 17:26
  • Why to not just ask dbms about datatype? – vp_arth Apr 06 '16 at 11:28