简体   繁体   中英

PHP MySQLI Select multi columns returning null

I'm attempting to retrieve 2 columns from my database with the following prepared statement:

$statement = $conn->prepare("SELECT script, work_instruction FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'");

Whenever I use this query, the PHP is returning null to my webpage, even though the data is present in the DB. However, the following statement does work (Same for work_instruction):

$statement = $conn->prepare("SELECT script FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'");

Once I prepare the statement I execute and loop through my results, before returning them. I think the problem may lie here, but am not sure.

$statement->execute();
$statement->bind_result($results);

while($statement->fetch()){
    array_push($myArr, $results);
}

$statement->free_result();
echo json_encode($myArr);


Here is an example of what my table looks like: 在此处输入图片说明


Here is the entire function, just in case you need to see more:

 // Responsible for generating queries to the database // and returning the data collected function query($conn, $column) { $myArr = array(); $table = $_POST['table']; $category = $_POST['category']; $sub_category = $_POST['sub_category']; $issue = $_POST['issue']; switch ($column) { case 'category': $statement = $conn->prepare("SELECT DISTINCT category FROM ".$table); break; case 'sub_category': $statement = $conn->prepare("SELECT DISTINCT sub_category FROM ".$table." WHERE category='".$category."'"); break; case 'issue': $statement = $conn->prepare("SELECT DISTINCT issue FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."'"); break; //This does not work case 'script': $statement = $conn->prepare("SELECT script, work_instruction FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'"); break; //This does work case 'work_instruction': $statement = $conn->prepare("SELECT work_instruction FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'"); break; case 'doc_link': //$statement = $conn->prepare($query); break; default: break; } $statement->execute(); $statement->bind_result($results); while($statement->fetch()){ array_push($myArr, $results); } $statement->free_result(); echo json_encode($myArr); } 

I don't see a problem in your code in terms of syntax. But you might want to change the way you are passing the parameters to your prepared statements. The current approach you are using is insecure and you don't actually get the benefits of using prepared statements at all.

Try the following code and see If your problem is resolved. I think this should work unless there is a problem with a values you are passing. In here I have assumed that all of your parameters are string. If it's integer you can change the 's' in bind_param to 'i'.

<?php
$statement = $conn->prepare("SELECT script, work_instruction FROM {$table} WHERE category = ? AND sub_category = ? AND issue= ?");
$statement->bind_param('sss', $category, $sub_category, $issue); // s = string
$statement->execute();

$results = $statement->get_result();
while($row = $results->fetch_array(MYSQLI_ASSOC)) {
    array_push($myArr, $row);
}

echo json_encode($myArr);

There are multiple issues with your code

  1. It is wide open to SQL injections
  2. It lacks proper error reporting.
  3. Minor syntax issue (that should have been reported, if you paid any attention to the option 2).

As you imagine that first two aren't important at all, here goes solution for the third: with bind_result() you have to bind variables for all the fields selected.

As a side note, if you have to change the table name dynamically, it's a BIG RED SIGN flashing "Bad database design".

In an attempt to simplify your query function and add in error reporting.

function query($conn, $column) {    
    $myArr = array();
    $table = '`' . trim($_POST['table']) . '`';
    $category = $_POST['category'];
    $sub_category = $_POST['sub_category'];
    $issue = $_POST['issue'];
    $selects = array(
       'category' => 'SELECT DISTINCT `category` FROM ' . $table,
       'sub_category' => 'SELECT DISTINCT `sub_category` FROM ' . $table . ' WHERE category = ?',
       'issue' => 'SELECT DISTINCT `issue` FROM ' . $table . ' WHERE category = ? AND sub_category = ?',
       'script' => 'SELECT `script`, `work_instruction` FROM ' . $table . ' WHERE category = ? AND sub_category = ? AND issue = ?',
       'work_instruction' => 'SELECT `work_instruction` FROM ' . $table . ' WHERE category = ? AND sub_category = ? AND issue = ?'
    );
    if (true === isset($selects[$column])) {
       $statement = $conn->prepare($selects[$column]);
       switch ($column) {
          case 'sub_category':
             $statement->bind_param('s', $category);
             break;
          case 'issue':
             $statement->bind_param('ss', $category, $sub_category);
             break;
          case 'work_instruction':
          case 'script':
             $statement->bind_param('sss', $category, $sub_category, $issue);
             break;
       }
       if (!$statement->execute()) {
           trigger_error('Error executing MySQL query: ' . $statement->error);
       }
       $results = $statement->get_result();
       while ($row = $results->fetch_array(MYSQLI_ASSOC)) {
           $myArr[] = $row;
       }
       $results->free();
       $statement->close();
   } else {
       trigger_error('Unknown column specified. Expected one of: "' . implode('", "', array_keys($selects)) . '" received "' . $column . '"');
   }
   echo json_encode($myArr);
}

Outside of your using bind_result Testing the query I return data fine, so if you are still having issues after changing this, I believe it would be something to do with the variable values. http://sqlfiddle.com/#!9/0bfb79/2

In order to identify the issue we would need an example of your table structure (columns and values) as close to actual values as possible, like in the SQL fiddle I linked.

Along with the variable values being sent to the query to fill in table, category, sub_category, and issue. Again like the SQL fiddle I linked.

Unless you use $statement->store_result() you don't need to call $statement->free_result() http://php.net/manual/en/mysqli-stmt.free-result.php As opposed to freeing the memory allocated by $statement->get_result http://php.net/manual/en/mysqli-result.free.php

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