【问题标题】:Issue using Mysqli in PHP class在 PHP 类中使用 Mysqli 的问题
【发布时间】:2013-09-02 17:40:28
【问题描述】:

我是面向对象的 PHP 新手,遇到以下代码问题。使用 Mysqli 进行的数据库查询在课堂内不起作用,但在课堂外可以正常工作。所以我的问题是,我做错了什么?

class webFile {

    private $sql, $query;

    function __construct() {
        $sql = new mysqli('host','user','pass','dbname');
    }

    function doQuery() {
        $queryText = "SELECT * FROM blog_posts WHERE number = '2'";
        if($query = $this->sql->query($queryText)) {
            $results = $query->fetch_array();
            return $results['post_id'];
        } else {
            return "Error";
        }
    }
}

$object = new webFile();
echo $object->doQuery();

服务器错误日志显示“PHP 致命错误:在非对象上调用成员函数 query()”...我是否又犯了一个愚蠢的错误?我在网上四处查看,但找不到与此问题相关的任何内容。任何帮助将不胜感激。

【问题讨论】:

    标签: php oop mysqli


    【解决方案1】:

    在您的构造函数中,您将 mysqli 设置为局部变量 $sql

    将您的构造函数更改为

     function __construct() {
            $this->sql = new mysqli('host','user','pass','dbname');
        }
    

    【讨论】:

      【解决方案2】:

      正如 Miguelo 所说,问题在于您在构造函数中编写了 $sql 而不是 $this->sql

      但还有另一个问题。

      如您所见,在您的代码中

      private $sql, $query
      

      我不认为你想在类中的函数之间使用 $query,所以我会删除它并离开:

      private $sql;
      

      但是如果你想在函数之间使用它 function doQuery() 应该是这样的:

      function doQuery() {
          $queryText = "SELECT * FROM blog_posts WHERE number = '2'";
          if($this->query = $this->sql->query($queryText)) {
              $results = $this->query->fetch_array();
              return $results['post_id'];
          } else {
              return "Error";
          }
      }
      

      【讨论】:

        【解决方案3】:

        这是一个 PHP 问题。从这篇文章开始,PHP 不支持嵌套类。 7.0 版中可能会发生变化,但据我所知,它还没有在准备中。

        我认为您最好的选择是简单地使用您的类来扩展 MySQLi 类,如下所示:

         class webFile extends mysqli {
        

        您可能希望将其锁定一些。说到这里,请注意 MySQLi 的构造不会被您自己的 __construct() 方法自动调用,因此您可能需要解决这个问题。

        您还可以使用 MySQLi 的程序功能来实现所需的结果,而无需扩展 MySQLi 的类,当我发现这篇文章目前有超过 2600 次浏览并且对您的问题没有明确的正确答案时,我正在研究该类。

        p>

        PHP 的面向对象不如某些强大,希望这种情况在未来几年会有所改变。 PHP 7.0 支持匿名类实例化,这表明它可能很快就会支持嵌套类。

        编辑:我在 PHP.net 上找到了一个涵盖覆盖构造的链接。显然您自己的构造不会覆盖 MySQLi,但您必须手动调用它,如下所示:

         parent::__construct($host,$user,$pass,$db);
        

        http://php.net/manual/en/mysqli.construct.php

        【讨论】:

          【解决方案4】:

          在 php 5.3 中,在类构造函数中初始化 mysqli 对象会破坏代码。我必须将 mysqli 对象作为参数传递给类才能使其工作。 这是无效的:

          function __construct() {
               $this->sql = new mysqli('host','user','pass','dbname');
           }
          

          但这会起作用:

          function __construct($mysqli) {
               $this->sql = new mysqli('host','user','pass','dbname');
           }
          

          $mysqli 参数可以在哪里

          new mysqli('host','user','pass','dbname');
          

          从执行的 php 脚本传递。 mysqli 类似乎有一个问题,我希望他们能在 php 7 中解决这个问题。 另一种解决方法是将其扩展为 php 手册页中的大纲。

          【讨论】:

            【解决方案5】:

            由于某种原因,您的 $SQL 变量似乎没有设置为 MySQLi 对象的实例。

            我个人并不经常使用 MySQLi;因为我更喜欢 mysql_connect。

            我建议如下:

            $this->sql = mysql_connect($host,$user,$pass) or die( mysql_error());
            $this->db = mysql_select_db($db) or die( mysql_error());
            

            或者,如果您设置在 MySQLi 对象上 -

            try
            {
                $this->sql = new mysqli('host','user','pass','dbname');
            } 
            catch(Exception $e)
            {
                // throw another exception or something
            }
            

            假设连接抛出错误 - 这将让您知道它已失败并允许您进行更正。

            【讨论】:

            • 所有 mysql_* 函数都已弃用
            • 很抱歉没有更新 PHP 文档 - 我不知道这意味着它不是一个有效的解决方案。谢谢你的意见。
            • 答案是有效的,但是你把他送到了一条封闭的道路上
            • 我自己评估为一条崎岖不平的路,不是很封闭……但我也给他绕了个弯。无论哪种方式,都要欣赏声誉。谢谢老兄。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-07-13
            • 2010-11-30
            • 1970-01-01
            • 2017-09-22
            • 1970-01-01
            相关资源
            最近更新 更多