【问题标题】:retrieve data from db using function pdo使用函数 pdo 从 db 检索数据
【发布时间】:2013-05-12 13:42:52
【问题描述】:

这是实现函数之前的代码,

try {
    $conn = new PDO('mysql:host=localhost;dbname=dbname', 'usr', 'pass');
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   
    $stmt = $conn->prepare('SELECT * FROM posts WHERE status= :published ORDER BY id DESC LIMIT 5');
    $stmt->execute(array(':published' => 'published'));
    while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $contents = $result['content'];
    $title = $result['title']; 
.... 

这很好用。然后我将 db 连接命令移动到单独的 php 文件(functions.php)。并创建了这个函数,

function run_db($sqlcom,$exe){
    $conn = new PDO('mysql:host=localhost;dbname=dbname', 'usr', 'pass');
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->prepare($sqlcom);
    $stmt->execute($exe);
    $data_db = $stmt->fetch(PDO::FETCH_ASSOC) ;
    return $data_db;
}

然后我像这样更改了第一个提到的代码,

try {
    $data_db=run_db('SELECT * FROM posts WHERE status= :published ORDER BY id DESC LIMIT 5',array(':published' => 'published'));   
    while ($result = $data_db) {
    $contents = $result['content'];
    $title = $result['title']; 

然后我得到的只是一篇无限重复的帖子。谁能告诉我如何纠正这个问题?

【问题讨论】:

  • 你不应该每次调用函数时都连接。你会杀死你的数据库服务器。

标签: php function pdo


【解决方案1】:

把函数改成这样:

function run_db($sqlcom,$exe){
    $conn = new PDO('mysql:host=localhost;dbname=dbname', 'usr', 'pass');
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->prepare($sqlcom);
    $stmt->execute($exe);
    return $stmt;
}

以及对该函数的调用:

try {
    $stmt = run_db('SELECT * FROM posts WHERE status= :published ORDER BY id DESC LIMIT 5',array(':published' => 'published'));   
    while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $contents = $result['content'];
        $title = $result['title'];

编辑:更好的解决方案是 jeroen 建议的解决方案 - 一次返回所有获取的对象

function run_db($sqlcom,$exe){
    $conn = new PDO('mysql:host=localhost;dbname=dbname', 'usr', 'pass');
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->prepare($sqlcom);
    $stmt->execute($exe);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

然后这样调用:

try {
    $data = run_db('SELECT * FROM posts WHERE status= :published ORDER BY id DESC LIMIT 5',array(':published' => 'published'));   
    foreach($data as $result) {
        $contents = $result['content'];
        $title = $result['title'];

编辑 2: 无论如何 - 将这样的逻辑包装到一个函数中并不是一个好主意。现在您只能执行 SELECT 查询,并且结果数组始终只包含记录的关联数组。如果您想(出于任何原因)检索对象的数组,甚至只有一个值,该怎么办?如果您想执行INSERTUPDATEDELETE 查询怎么办???

如果您确定要这样做,那么我想创建一个具有以下功能的类:

class MyPDO {
    private $connection;

    static $instance;

    function __construct() {
        $this->connection = new PDO('mysql:host=localhost;dbname=dbname', 'usr', 'pass');
        $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }

    static function getInstance() {
        return self::$instance ?  : self::$instance = new MyPDO;
    }

    // retrieves array of associative arrays
    function getAssoc($sqlcom, $exe) {
        $stmt = $this->connection->prepare($sqlcom);
        $stmt->execute($exe);

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    // retrieves array of objects
    function getObj($sqlcom, $exe) {
        $stmt = $conn->prepare($sqlcom);
        $stmt->execute($exe);

        return $stmt->fetchAll(PDO::FETCH_OBJ);
    }

    // retireves one single value, like for SELECT 1 FROM table WHERE column = true
    function getOne($sqlcom, $exe) {
        $stmt = $conn->prepare($sqlcom);
        $stmt->execute($exe);

        return $stmt->fetchColumn();
    }

    // just executes the query, for INSERT, UPDATE, DELETE, CREATE ...
    function exec($sqlcom, $exe){
        $stmt = $conn->prepare($sqlcom);

        return $stmt->execute($exe);
    }
}

那么你可以这样称呼它:

try {
    $pdo = MyPDO::getInstance();
    foreach($pdo->getAssoc('MySQL QUERY'), array($param, $param)) as $result) {
        print_r($result);
    }
} catch(\Exception $e) {
    // ...
}

【讨论】:

  • 是的,我实施了您使用类的建议。谢谢你的努力。
【解决方案2】:

只需返回语句:

function run_db($sqlcom,$exe){
    static $conn;
    if ($conn == NULL)
    {
        $conn = new PDO('mysql:host=localhost;dbname=dbname', 'usr', 'pass');
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }
    $stmt = $conn->prepare($sqlcom);
    $stmt->execute($exe);
    return $stmt;
}


try {
    $stmt=run_db('SELECT * FROM posts WHERE status= :published ORDER BY id DESC LIMIT 5',array(':published' => 'published'));   
    while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $contents = $result['content'];
    $title = $result['title']; 

您还可以在连接上设置默认的 fecth 模式。

【讨论】:

    【解决方案3】:

    从函数返回 $stmt 的正确答案的替代方法是在函数中使用 fetch all rows 并在主代码中使用 foreach

    在函数中:

    ...
    $data_db = $stmt->fetchAll(PDO::FETCH_ASSOC) ;
    return $data_db;
    

    函数外:

    $data_db=run_db('SELECT * FROM posts WHERE status= :published ORDER BY id DESC LIMIT 5',array(':published' => 'published'));   
    foreach ($data_db as $result) {
      $contents = $result['content'];
      $title = $result['title']; 
      ...
    

    【讨论】:

      【解决方案4】:

      您的代码存在两个基本问题。

      1. 每次运行查询时都会连接。
      2. 它只返回一种格式的数据,而 PDO 可以返回几十种不同格式的结果。

      接受的答案是错误的,因为它只是试图重新发明 PDO 功能,但方式非常肮脏,有很多重复的代码,但仍然无法使其与普通 PDO 一样好。

      正如 xdazz 的回答中所说,您必须返回声明。然后使用 PDO 的原生 fetch 模式获取所需格式的结果,使用 method chaining

      此外,您不应将try 添加到您的代码中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-12
        • 1970-01-01
        • 2021-09-02
        • 2014-05-08
        • 2021-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多