【问题标题】:How would I use a protected variable instead of a 'global' in this class?我将如何在此类中使用受保护的变量而不是“全局”?
【发布时间】:2013-07-26 19:37:03
【问题描述】:

我有以下数据库查询,它工作正常,但在前面的另一个问题中,我注意到我正在使用全局,但它不是必需的。原因是我试图使用受保护的变量,但作为 OOP 的新手,无法使其工作。

也许有人可以告诉我应该怎么做?

<?
class DB {

  public function __construct() {

    global $dbh;

    try {
      $dbh  = new PDO('mysql:host=localhost;dbname=main_db', 'my_user', 'my_pass');
      $dbh  ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
    }
    catch(PDOException $e) {
      echo $e->getMessage();
    }
  }

  public function getFAQCats2Array() {

    global $dbh;

    try {
      $q = '
            SELECT
                `id`        AS ci,
                `name`      AS n
            FROM
                `faqcat`;
      ';

      $s = $dbh->query($q);

      // initialise an array for the results
      $A = array();

      while ($r = $s->fetch(PDO::FETCH_ASSOC)) {
          $A[] = $r;
      }

      $s = null;
      return $A;
    }

    catch(PDOException $e) {
      echo  "Something went wrong fetching the list of FAQ categories from the database.\n";
      file_put_contents(
          $_SERVER['DOCUMENT_ROOT']."/PDOErrors.txt",
          "\n\n\n\n".$e->__toString(), FILE_APPEND);
    }
  }

  public function getFAQ($i, $f) {

      global $dbh;

       try {
        $q = '
            SELECT
                '.$f.'
            FROM
                faq
            WHERE
                id = ?
        ';

        $s = $dbh->prepare($q);
        $s->execute(array($i));
        //$s->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
        $r = $s->fetch();

        return $r[$f];

      }

      catch(PDOException $e) {
        echo  "Something went wrong fetching the FAQ answer from the database.\n";
        file_put_contents(
            $_SERVER['DOCUMENT_ROOT']."/PDOErrors.txt",
            "\n\n\n\n".$e->__toString(), FILE_APPEND);

      }

  }

}

(类中还有其他函数在$dbh 中使用相同的连接字符串,但为了简单起见,我已将其删除)

【问题讨论】:

    标签: php oop global-variables


    【解决方案1】:

    您可以直接点击global $dbh! 全局变量通常是一个非常糟糕的主意,会使您的代码更难维护。

    在这种情况下,我建议使用类属性(有点全局,但仅在此类中):

    class DB
    {
        protected $dbh;
    
        public function __construct()
        {
            $this->dbh = new PDO();
        }
    
        public function query()
        {
            return $this->dbh->query();
        }
    }
    

    我已经剥离并简化了很多代码,但这应该让您了解类属性的一般工作原理。您还可以在 PHP.net 手册上阅读更多相关信息。

    【讨论】:

    • 成功了。我当然已经在 php.net 上阅读了很多关于它的内容,但不幸的是,我无法充分理解那里的概念,以便我实现它。感谢您的帮助。
    • 我刚刚发现$this-&gt;dbh-&gt;query($q); 工作正常,但在另一个使用$this-&gt;dbh-&gt;prepare($q); 的查询中,它给出了错误“调用非对象上的成员函数prepare()”。请问我做错了什么?
    • 如何调用prepare() 方法。如果没有任何代码,我将无法提供帮助。
    • 谢谢。我已将受影响的函数添加到问题中(它是getFAQ())。有错误的行是$s = $dbh-&gt;prepare($q);。当我成功时,$s = $this-&gt;dbh-&gt;prepare($q); 就像 query 我得到了错误。不过query 的那些方法都可以。
    • var_dump($this->dbh) 的结果是什么; ?
    【解决方案2】:

    不要使用global $dbh

    只需向您的 DB 类添加一个属性,例如 protected $db,然后将您的 PDO 实例放入 $this-&gt;db 中,因为您只能在对象内使用 $db var。这是使用某种“数据库模型”的基本方法,您可以通过网络找到大量教程:)

    例如:

    public __construct($db_type = 'mysql', $host = 'my_server', $database = 'db_name', $user = 'my_user', $pwd = 'password') {
        $pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
    
        $dsn = $db_type.':host=' . $host . ';dbname=' . $database . '';
    
        try {
            $this->db = new PDO($dsn, $user, $pwd, $pdo_options);
        } catch (Exception $e) {
            'Unable to connect to database';
        }
    }
    

    然后在全局范围内创建您的对象的实例,您的脚本将在其中使用它:

    $db_manager = new DB('mysql','localhost','my_db','root','password');
    

    然后您的$db_manager 将能够使用您的DB 类的公共方法

    【讨论】:

      【解决方案3】:

      你去吧..

      class DB {
      
        protected $dbh;
      
        public function __construct() {   
      
          try {
            $this->dbh  = new PDO('mysql:host=localhost;dbname=main_db', 'my_user', 'my_pass');
            $this->dbh  ->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
          }
          catch(PDOException $e) {
            echo $e->getMessage();
          }
        }
      
        public function getFAQCats2Array() {  
      
          try {
            $q = '
                  SELECT
                      `id`        AS ci,
                      `name`      AS n
                  FROM
                      `faqcat`;
            ';
      
            $s = $this->dbh->query($q);
      
            // initialise an array for the results
            $A = array();
      
            while ($r = $s->fetch(PDO::FETCH_ASSOC)) {
                $A[] = $r;
            }
      
            $s = null;
            return $A;
          }
      
          catch(PDOException $e) {
            echo  "Something went wrong fetching the list of FAQ categories from the database.\n";
            file_put_contents(
                $_SERVER['DOCUMENT_ROOT']."/PDOErrors.txt",
                "\n\n\n\n".$e->__toString(), FILE_APPEND);
          }
        }
      }
      

      【讨论】:

      • 您忘记在查询方法中添加$this->dbh。
      猜你喜欢
      • 2013-02-07
      • 1970-01-01
      • 2019-06-21
      • 2021-12-27
      • 2013-09-26
      • 2018-01-20
      • 2022-11-09
      • 2021-11-16
      • 2023-02-02
      相关资源
      最近更新 更多