PHP/PDO函数从数据库varriabele参数返回值

PHP/PDO函数从数据库varriabele参数返回值,php,mysql,sql,pdo,Php,Mysql,Sql,Pdo,我试图编写这个基本函数来从表中获取一个值 <?php function getvalue($value, $from, $id){ //Returns the value of a table require('includes/connect.php'); $db = new PDO('mysql:host=localhost;dbname='.$database, $username, $password);

我试图编写这个基本函数来从表中获取一个值

<?php 
    function getvalue($value, $from, $id){
        //Returns the value of a table

        require('includes/connect.php');
        $db = new PDO('mysql:host=localhost;dbname='.$database, $username, $password); 
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

        $sql = "SELECT :value AS value
            FROM :from
            WHERE id = :id
            LIMIT 1";

        $stmt = $db->prepare($sql); 
        $stmt->bindParam(':value', $value, PDO::PARAM_STR); 
        $stmt->bindParam(':from', $from, PDO::PARAM_STR); 
        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        $stmt->execute(); 
        $data = $stmt->fetch();
        $return = $data['value'];

        return $return;
    }//function
?>
它给出了以下致命错误:

未捕获异常“PDOException”,消息为“SQLSTATE[42000]:语法错误或访问冲突:1064您的SQL语法有错误;在/functions/getvalue.php:26 Stack trace:0/functions/getvalue.php26:PDOStatement->execute 1中,查看与MySQL服务器版本对应的手册,以了解在项目“WHERE id='1 at line 2”附近使用的正确语法/ test.php24:getvalue'tarief','project','1'2{main}在第26行的/functions/getvalue.php中抛出


尝试此操作,确保转义$value和$from变量值:

<?php 
    function getvalue($value, $from, $id){
        //Returns the value of a table

        require('includes/connect.php');
        $db = new PDO('mysql:host=localhost;dbname='.$database, $username, $password); 
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

        $sql = "SELECT " . $value . " AS value
            FROM " . $from . "
            WHERE id = :id
            LIMIT 1";

        $stmt = $db->prepare($sql);  
        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        $stmt->execute(); 
        $data = $stmt->fetch();
        $return = $data['value'];

        return $return;
    }//function
?>

尽管您拥有这样一个功能的想法非常好,但实现起来却非常糟糕。一些基本缺点是:

每次调用此函数时,您都连接到数据库 此代码易于SQL注入 然而,它是非常不灵活的,让您运行的查询与愚蠢的选择不同。。。WHERE id.最终您将了解其他查询并发现此函数不可用。 它应该是一个接受SQL查询和带有要绑定的参数的数组的函数:

<?php 
//Returns the value of a query
function getvalue($sql, $params = array())
{
    global $pdo;
    $stmt = $db->prepare($sql); 
    $stmt->execute($params); 
    return $stmt->fetchColumn();
}

require('includes/connect.php');
$name = getValue("SELECT name FROM users WHERE id =?",array($_GET['id']))    

不能将表名或列名作为绑定参数。是否有其他方法可以编写此函数,或者根本不可能?唯一的方法是将变量直接包含在字符串中,这为SQL注入打开了大门。但是,您可以做的是从数据库中生成一个表及其列的白名单,并根据该名单验证您要查找的值。为什么是全局$pdo?为什么不把它作为函数参数发送呢?虽然我同意它有点不灵活,但getValue函数选择单个字段的目的不是吗?一开始,我想知道为什么我需要在一个不太灵活的任务中有更多的灵活性,但是当你每次使用这个函数时,你都无法发现在向它发送四个或五个参数时编写查询有什么坏处??他/她想解决问题,但问题确实解决了。没有考虑过更好的方法,我想有些人反对你十年前在$sql中插入任意字符串。原则上,如果您不向这些参数传递任何用户输入,您是安全的,但是如果像这样的函数在代码库中放置了一段时间,可能会有人向它提供$\u POST['from']或其他内容,您可能会遇到很多麻烦。
$dsn = "mysql:host=localhost;dbname=$database;charset=utf8";
$opt = array(
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$pdo = new PDO($dsn, $username, $password, $opt);