首頁  >  問答  >  主體

在其他類別中使用PDO連接的方法

<p>我覺得我在理解物件導向程式設計(OOP)的工作原理方面有問題。我已經改變了程式碼,使其能夠工作,但我認為這不是正確的方式。以下是一個場景(不,我不是自己創建用戶登錄,這只是為了更好地理解OOP):</p> <p>我有一個database.php檔:</p> <pre class="brush:php;toolbar:false;">class Database { /* 屬性 */ private $conn; private $dsn = 'mysql:dbname=test;host=127.0.0.1'; private $user = 'root'; private $password = ''; /* 建立資料庫連線 */ public function __construct() { try { $this->conn = new PDO($this->dsn, $this->user, $this->password); } catch (PDOException $e) { print "Error!: " . $e->getMessage() . ""; die(); } return $this->conn; } }</pre> <p>所以在這個類別中,我創建了一個資料庫連接,並返回連接(物件?)</p> <p>然後我有一個第二個類,著名的User類(實際上我沒有使用自動加載,但我知道它):</p> <pre class="brush:php;toolbar:false;">include "database.php"; class User { /* 屬性 */ private $conn; /* 取得資料庫存取 */ public function __construct() { $this->conn = new Database(); } /* 登入使用者 */ public function login() { $stmt = $this->conn->prepare("SELECT username, usermail FROM user"); if($stmt->execute()) { while($rows = $stmt->fetch()) { $fetch[] = $rows; } return $fetch; } else { return false; } } }</pre> <p>這就是我的兩個類別。如你所見,沒有什麼大不了的。現在,請不要對函數名稱<code>login</code>感到困惑 - 實際上,我只是嘗試從資料庫中選擇一些用戶名和用戶郵件,並將它們顯示出來。我嘗試透過以下方式實現:</p> <pre class="brush:php;toolbar:false;">$user = new User(); $list = $user->login(); foreach($list as $test) { echo $test["username"]; }</pre> <p>這裡出現了問題。當我執行這段程式碼時,我得到以下錯誤訊息:</p> <blockquote> <p>未捕獲的錯誤:呼叫未定義的方法Database::prepare()</p> </blockquote> <p>我不確定我真的理解這個錯誤的原因。</p> <p><strong>當我改變以下內容時,程式碼可以正常運作:</strong></p> <p>將database.php中的<code>$conn</code>從private改為public(我認為這是不好的...?但當它是private時,我只能在Database類內部執行查詢,對嗎?那麼我應該將所有這些查詢放在Database類別中嗎?我認為這是不好的,因為在一個大專案中,它將變得非常龐大...)</p> ; <p>第二個改變是:</p> <p>將user.php檔案中的<code>$this->conn->prepare</code>改為<code>$this->conn->conn->prepare< /code>。對此我真的沒有想法。 </p> <p>我的意思是,在<code>user.php</code>的建構子中,我有一個<code>$this->conn = new Database()</code>,由於new Database將傳回來自DB類別的連接對象,我真的不知道為什麼這裡必須有第二個<code>conn-></code></p>
P粉293550575P粉293550575422 天前450

全部回覆(1)我來回復

  • P粉451614834

    P粉4516148342023-08-25 11:13:39

    • 不要建立像Database這樣的類,因為它沒有什麼用。如果它能為PDO添加一些額外的功能,那麼建立一個資料庫封裝類別是有意義的。但是考慮到它目前的程式碼,最好使用原始的PDO。
    • 從原始的PDO或你的資料庫類別建立一個單一的 $db 實例。
    • 將它作為建構子參數傳遞給每個需要資料庫連接的類別。

    database.php:

    <?php
    $host = '127.0.0.1';
    $db   = 'test';
    $user = 'root';
    $pass = '';
    $charset = 'utf8';
    
    $dsn = "mysql:host=$host;dbname=$db;charset=$charset";
    $opt = [
        \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_EXCEPTION,
        \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
        \PDO::ATTR_EMULATE_PREPARES   => false,
    ];
    $pdo = new \PDO($dsn, $user, $pass, $opt);

    user.php

    <?php
    class User {
        /* Properties */
        private $conn;
    
        /* Get database access */
        public function __construct(\PDO $pdo) {
            $this->conn = $pdo;
        }
    
        /* List all users */
        public function getUsers() {
            return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
        }
    }

    app.php

    include 'database.php';
    $user = new User($pdo);
    $list = $user->getUsers();
    
    foreach($list as $test) {
        echo $test["username"],"\n";
    }

    output:

    username_foo
    username_bar
    username_baz

    查看我的(唯一正確的)PDO教程以獲取更多PDO的詳細資訊。

    回覆
    0
  • 取消回覆