【问题标题】:Unable to use PDO inside class无法在课堂内使用 PDO
【发布时间】:2015-01-12 21:40:41
【问题描述】:

我有一个简单的类,用户需要访问数据库。我还需要在其他几个类中访问数据库,所以我的 class.user.php 看起来像这样:

include "config.php"

class User {

    public $db;

    public function __construct(PDO $db){
        $this->db = $db;
        global $db;
    }

    function LastLogin(){
        // global $db; // if I uncomment this, it works for this function. 
        $pdo = $db->prepare("SELECT last_login FROM users WHERE username = ?");
        $pdo->execute(array($username));
        while($r = $pdo->fetchObject()){
            echo $r->last_login;
        }
    }
}

Config.php 看起来像这样:

$dsn = "mysql:host=localhost;dbname=db;charset=utf8";
$opt = array(
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$db = new PDO($dsn,'user','pass', $opt);

假设我有一个名为 userdetails.php 的页面,我想知道用户上次登录的时间。

$user = new User($db);
$user->LastLogin();

这会导致如下错误消息:

Notice: Undefined variable: db in /home/www/class.user.php on line 12 
Fatal error: Call to a member function prepare() on a non-object in/home/www/class.user.php on line 12

所以我在课堂上使用 pdo 时遇到了问题。对每个函数都输入“global $db”是没有意义的,那我做错了什么?

【问题讨论】:

  • @RiggsFolly 做到了,没有明显变化。
  • 你真的需要停止使用全局。它破坏了封装,这是使用 OOP 的原因之一。
  • @KevinM1 是的,我试过不使用它,但这是我让它工作的唯一方法。

标签: php mysql class pdo


【解决方案1】:

如 cmets 中所述,删除该行:

global $db;

另外,您也不需要传递PDO

而不是试图将其引用为

$db->prepare(....)

您想将其引用为:

$this->db->prepare(....)

因为您将其实例化为可在类中访问的变量。

【讨论】:

    【解决方案2】:

    试试这个

    include "config.php"
    
    class User {
    
        public $db;
    
        public function __construct($db){
            $this->db = $db;
          }
    
        function LastLogin(){
            $pdo = $this->db->prepare("SELECT last_login FROM users WHERE username = ?");
            $pdo->execute(array($username));
            while($r = $pdo->fetchObject()){
                echo $r->last_login;
            }
        }
    }
    

    global $db 绝对不是必需的,而且是不好的做法,因为它破坏了类的封装。

    据我所知,__construct(PDO $db) 中的类型提示 PDO 实际上也不合法。

    虽然你有一个$db 的属性并用正确的句柄加载它,但要使用它来改变它

    $pdo = $db->prepare("SELECT last_login FROM users WHERE username = ?");
    

    $pdo = $this->db->prepare("SELECT last_login FROM users WHERE username = ?");
    

    所以你正确地使用/解决了它。

    【讨论】:

    • 解决了。有没有办法使用 $db 而不是 $this->db?
    • 你为什么要这样做?
    • 只有一个原因:更容易记住和更快地输入。也许这是两个原因。但如果这不可能,我可以忍受。
    • 这就是语言结构。使用它是自我记录,当您回来添加新内容或修复错误时,您会发现它很有用
    【解决方案3】:

    global $db 是问题所在。松开它,一切都会正常。

    【讨论】:

      【解决方案4】:

      从您的构造函数中删除 global $db

      function LastLogin 中使用$this->db 而不是$db

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-30
        • 2021-11-05
        • 2016-04-24
        相关资源
        最近更新 更多