【问题标题】:dynamic class or function return query result PDO动态类或函数返回查询结果 PDO
【发布时间】:2012-05-14 14:59:48
【问题描述】:

我曾经在我的脚本中对任何选择查询都有一个函数,但由于它不安全,我需要了解如何在 php 中创建动态 PDO 类。

比如我以前用过这段代码。

function excute_query ($Query)
{

    if($Query_Run = mysql_query($Query))
    {
        while($DATA = mysql_fetch_array($Query_Run, MYSQL_ASSOC))
            {
                $data_array[] = $DATA;
            }
            return $data_array;
            close();

    }
    else{
            die(mysql_error());
        }

    mysql_close();

}

我可以在我的脚本中的任何地方使用它,它返回一个包含数据的数组。两行。

$sql = 'SELECT * FROM users';
$users = execute_query($sql);

现在我需要对 PDO 使用相同的功能。我一直在尝试,但是如何使用 PDO 使类或函数做同样的事情。

我想说什么。而不是写同样的 4 行来进行查询,有没有办法让函数或类接受查询并返回数据?

谢谢。

【问题讨论】:

    标签: php mysql pdo


    【解决方案1】:

    你的代码很糟糕。严重地。 close() 函数永远不会被调用,因为它在 return 语句之后。出于同样的原因,mysql_close() 也从未被调用过。

    也就是说,这是我要使用的函数:

    function execute_query( $con, $query, $statements ) {
        $q = $con->prepare( $query );
        foreach ( $statements as $statement ) {
            $q->bindParam( $statement[ 'string' ], $statement[ 'value' ], $statement[ 'type' ] );
        }
        $q->execute();
        return $q->fetchAll();
    }
    

    这是一个使用它的代码示例:

    $con = new PDO( /* ... */ );
    $query = "SELECT * FROM users WHERE id = :id";
    $statements = array();
    // Prepare a statement array
    $id = array(
        'string' => ':id',
        'value' => $_GET[ 'id' ],
        'type' => PDO::PARAM_INT
    );
    // Add the statement to the array
    $statements[] = $id;
    $results = execute_query( $con, $query, $statements );
    

    PDO 的冗长性伴随着可提供良好安全性的准备好的语句。准备好语句意味着您可以安全地使用 SQL 注入。

    【讨论】:

    • 是的,但我认为你的推理不合理。
    • The verbosity from PDO comes with the prepared statements that allow a good security. Preparing the statements means you are safe with the SQL injections.
    • 好吧,从你的 cmets 看来,你只是在嘲笑别人。希望您现在已经添加了答案。
    • @YourCommonSense 我仍然认为您不应该像在 cmets 中那样对他人进行人身攻击。关于有 10 个参数的情况,我还是更喜欢显式设置参数类型,因为它是 explicit。添加这种样板不会打扰我,也不会打扰维护我的代码的人,如果它当然不是难以理解的混乱,但代码样式有助于解决这个问题。但这只是使用的偏好/标准问题。要回答这个要求尽可能少的字符的问题,您的答案会更好。
    • 当你说(which still ugly though, as you do not know PDO)时,它被认为是人身攻击。我什至不是在谈论您对除了您的回答之外的两个答案的第一个评论,这是对回答的人的“非个人”攻击:-)。考虑到如此鼓励不切实际的答案,我只能同意人们只想要声誉。
    【解决方案2】:

    要让您的辅助函数与 PDO 一起使用,您有几个选择:

    • 将 PDO 对象与$query 一起传递
    • 使用某种形式的工厂类,在需要时实例化您的 PDO。

    第一个可能看起来像这样:

    function queryGetAll(PDO $pdo, $query)
    {
        return $pdo->query($query)->fetchAll(PDO::FETCH_ASSOC);
    }
    

    您可以通过添加对准备好的语句的支持使其更有用。

    function queryGetAll(PDO $pdo, $query, $params = array(), $style = PDO::FETCH_ASSOC)
    {
        $stmt = $pdo->prepare($query);
        $stmt->execute($params);
        return $stmt->fetchAll($style);
    }
    

    这样称呼:

    $results = queryGetAll($pdo, "SELECT * FROM users WHERE uid = ?", array($user_id));
    

    您可以编写的另一个包装器是queryGetOne(),它类似于queryGetAll(),但只返回第一个结果。您也可以考虑为插入语句编写一个包装器,返回最后插入的标识符。

    结论

    考虑到所有因素,我个人认为这些包装器并没有添加太多仅使用 PDO 无法提供的功能。

    顺便说一句,使用 PDO 时,请确保您允许 exceptions to be thrown from PDO;这有助于调试您的代码并避免笨拙的代码。

    【讨论】:

    【解决方案3】:

    一个快速而肮脏但不太冗长的解决方案就是这个

    function execute_query( $query, $params ) {
        global $pdo;
        $stmt = $pdo->prepare( $query );
        $stmt->execute($params);
        return $stmt->fetchAll();
    }
    $users = execute_query('SELECT * FROM users WHERE id=?',array($id));
    

    但我个人讨厌写array这个词,所以,我会用func_get_args()这样称呼

    function execute_query() {
       global $pdo;
       $args  = func_get_args();
       $query = array_shift($args);
       $stmt  = $pdo->prepare($query);
       $stmt->execute($args);
       return $stmt->fetchAll();
    }
    $sql   = 'SELECT * FROM users WHERE username=? AND password=?';
    $found = execute_query($sql,$username,$password);
    

    但是上课显然会更好。
    它会让你对不同的结果集有不同的功能,比如

    $username = db::getOne('SELECT name FROM users WHERE id=?',$id);
    

    而不是你现在的

    $user     = execute_query('SELECT name FROM users WHERE id=?',$id);
    $username = $user['name'];
    

    或者,更有用的

    $users = db::getIndexed('id','SELECT name FROM users);
    

    获取一个数组,其中的键填充了用户 ID 或

    $ids = db::getCol('SELECT id FROM users');
    $in  = implode(",",$ids);
    

    【讨论】:

    • 用2个参数定义函数时,函数如何接受3个参数?
    • 哦,是的,对于第二种方法,您根本不需要定义参数。
    • 哦,我喜欢。我现在要做的就是发送带有参数的 SQL 语句,然后砰!非常感谢。
    • 如果你使用LIMIT,这将不起作用,因为它需要一个整数(PDO::PARAM_INT)。或者我错过了什么?
    • 我可以这样用吗 SELECT * FROM your_table LIMIT ?, ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2015-01-29
    • 2017-05-18
    • 1970-01-01
    • 2016-09-03
    相关资源
    最近更新 更多