1

I'm trying to perform a SELECT from my database, but I'm getting an error and I don't understand why. All I can tell is that it seems to be failing at the prepare() statement. Any help would be appreciated.

$sQuery =  "SELECT * FROM ? WHERE `email` = ? AND `password` = ?";
$sTypes = "sss";
$aParams = array("user", "john.doe@missing.com", "password");

Above is the query and bind_param values.

function conn($sQuery, $sTypes=null, $aParams=null){
    $sMessage = '';
    $db = new mysqli('localhost','root','','myvyn') or die('unable to connect!');
    if($db->connect_errno){
        $message = $db->connect_error;
    } else{
        $stmt = $db->stmt_init();
        if (!($stmt->prepare($sQuery))) {
             var_dump("Prepare failed: (" . $stmt->errno . ") " . $stmt->error);
        }   
        if($sTypes&&$aParams){
            $bindParams[] = $sTypes;
            foreach($aParams as $param){
                $bindParams[] = $param;
            }
            call_user_func_array(array($stmt, 'bind_param'), $bindParams);
        }
        $stmt->execute();
        $oResult = $stmt->get_result();
        while($rows = $oResult->fetch_assoc()){
            $aRows[] = $rows;
        }
        $oResult->free();
        $db->close();
        return $aRows;
    }
}
halfer
  • 19,824
  • 17
  • 99
  • 186
user2812097
  • 92
  • 2
  • 14

1 Answers1

1

You cannot use parameters for a table name, as per here (my bold):

The markers are legal only in certain places in SQL statements. For example, they are allowed in the VALUES() list of an INSERT statement (to specify column values for a row), or in a comparison with a column in a WHERE clause to specify a comparison value.

However, they are not allowed for identifiers (such as table or column names), in the select list that names the columns to be returned by a SELECT statement, or to specify both operands of a binary operator such as the = equal sign. The latter restriction is necessary because it would be impossible to determine the parameter type. It's not allowed to compare marker with NULL by ? IS NULL too. In general, parameters are legal only in Data Manipulation Language (DML) statements, and not in Data Definition Language (DDL) statements.

Assuming you control the table name (so SQL injection is impossible), you could use something like:

$sQuery =  "SELECT * FROM $tblname WHERE `email` = ? AND `password` = ?";

and then only bind the email address and password.

Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • If it comes from user input, `$tblName` should be checked against a whitelist before being injected into the query. – halfer Feb 06 '15 at 01:33