jonmrich
jonmrich

Reputation: 4323

No data returned with PDO

Here's the relevant piece of my PHP code:

$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? "{$_GET['cat_code']}" : '';
$sortvalue = isset($_GET['sortvalue'])? "{$_GET['sortvalue']}" : '';
$sortorder = isset($_GET['sortorder'])? "{$_GET['sortorder']}" : '';

$sql = "select * from  {$table} where cat_code = ':cat_code' order by ':sortvalue' ':sortorder';";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$stmt2->execute(array(':cat_code' => $whereCategory,':sortvalue' => $sortvalue, ':sortorder' => $sortorder));
$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
header('Content-type: application/json');
echo json_encode($result);

If I var_dump the variables $where_category,$sortorder, and $sortvalue, they are all what I expect and the correct data that would need to be passed in the query. I've tried the query directly without PDO just substituting in the correct variables and I get back what I want, but apparently I'm not sending the variables correctly with my PDO methods (such as they are).

I'm getting no errors back, but no data returned either.

Any suggestions?

Upvotes: 2

Views: 225

Answers (5)

Rex U
Rex U

Reputation: 11

Use Like this

$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);

Upvotes: -1

Kevin
Kevin

Reputation: 41885

First off, named placeholders doesn't need to be quoted, so ditch those.

Secondly, you cannot bind identifiers (table/columns/DESC/ASC) You could only whitelist those.

Third, don't mix ->query() and ->execute(). Use ->execute() alone:

header('Content-type: application/json');
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

//get values from AJAX
if(isset($_GET['cat_code'], $_GET['sortvalue'], $_GET['sortorder'])) {

    $whereCategory = $_GET['cat_code'];
    $sortvalue = $_GET['sortvalue'];
    $sortorder = $_GET['sortorder'];

    // super simple filtering
    $default_tables = array('table1', 'table2', 'table3');
    $default_columns = array('column1', 'column2', 'column3');
    in_array(needle, haystack)
    if(
        in_array($table, $default_tables) &&
        in_array($sortvalue, $default_columns) &&
        in_array($sortorder, array('ASC', 'DESC'))
    ) {
        // good to go

        $sql = "SELECT * FROM $table where cat_code = :cat_code ORDER BY $sortvalue $sortorder";
        $stmt2 = $dbh->prepare($sql);
        $stmt2->execute(array(':cat_code' => $whereCategory));
        echo json_encode($stmt2->fetchAll(PDO::FETCH_ASSOC));

    } else {
        // did not satisfy condition
    }

}

Sidenote: Those default tables and columns are just examples, you'll need to populate and correspond it into yours. You could create your own method/function which creates a map with tables with their corresponding columns if you really want to be sure of it.

Upvotes: 3

Jonathan
Jonathan

Reputation: 2877

The query you are running is against a prepared statement which is incorrect, removing the query and assigning the result from the execute statement will work. There's also quite a few other problems in your php. Also using the input directly from the user such as the table (which appears to be undefined in this code snippet), sort order and sort value leaves you open to sql injection.

$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

//get values from AJAX
$whereCategory = isset($_GET['cat_code'])? $_GET['cat_code'] : '';
$sortvalue = isset($_GET['sortvalue'])? $_GET['sortvalue'] : '';
$sortorder = isset($_GET['sortorder'])? $_GET['sortorder'] : '';

/** you cannot use prepared statements for doing the order by */
$sql = "select * from $table where cat_code = :cat_code order by $sortvalue $sortorder;";
$stmt2 = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY) );
$query = $stmt2->execute(['cat_code' => $whereCategory]);
/** below line isn't needed because above on deals with it */
//$dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$result = $query->fetchAll();
header('Content-type: application/json');
echo json_encode($result);

Upvotes: 1

Alex
Alex

Reputation: 17289

try without quotes:

$sql = "select * from  {$table} where cat_code = :cat_code order by :sortvalue :sortorder;";

Upvotes: 0

Jay Blanchard
Jay Blanchard

Reputation: 34406

Change this -

$result = $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);

to this -

$result = $stmt2->fetchAll(PDO::FETCH_ASSOC);

You're trying to run the query again when all you need to do is grab the results.

Upvotes: 1

Related Questions