【问题标题】:How to use mysqli::fetch_object()?如何使用 mysqli::fetch_object()?
【发布时间】:2013-06-26 01:40:07
【问题描述】:

人们通常如何将mysqli结果转化为对象?

在使用自定义类时,我找不到任何带有 fetch_object() 的示例。假设以下设置

class Test1 {
    function __construct(array $data) { ... }
}

class Test2 {
    function __construct(array $data) { ... }
}

假设我有多个具有相同构造函数的类,如何动态实例化这些类?

我会想象这样的事情:

function customQuery($query, $class) {

    // Get some data by mysqli query, assume we get the data as $result object
    ...

    // Now I would like to store the data in an array with instances of $class
    $array = array();
    while ($obj = $result->fetch_object($class, ???) {
        $array[] = $obj;
    }

    // Return the array with instances of $class
    return $array;

}

我用什么作为我的问号的参数?我只知道 Test1 和 Test2 的两个类构造函数都想要一个关联数组作为输入(可能长度不一样!)。

最后我只是想做一些类似的事情

$arr1 = customQuery('SELECT id, product FROM test1 LIMIT 10', 'Test1');
$arr2 = customQuery('SELECT id, name, address FROM test2 LIMIT 10', 'Test2');

当然,如果您有更好的想法来实现我的目标,我将不胜感激。

【问题讨论】:

    标签: php object mysqli fetch


    【解决方案1】:

    看看“fetch_object”

    你有一个参数 $class_name

    来自文档: 要实例化、设置属性和返回的类的名称。如果未指定,则返回 stdClass 对象。

    它将自动创建给定类的实例并设置属性。所以不需要传递一个数组 http://www.php.net/manual/en/mysqli-result.fetch-object.php

    多一点解释,

    fetch_object 只是填充私有属性等(PHP Magic...我不喜欢它)。

    如果您的对象在构造函数中具有必需的参数,但您想从数据库中获取它,则 fetch_object 允许您为构造函数定义参数,以便可以构造它而不是引发警告/错误。

    class Test {
       private $title;
       public function __construct($required) { 
    
       }
    }
    
    $mysql->fetch_object('Test'); //will trigger errors/warnings
    $mysql->fetch_object('Test', array(null)); //won't 
    

    你可以做的是简单地获取一个数组并构造对象

    function query($query, $class) {
       $data = $query->fetch_assoc();
       $instance = new $class($data);
       return $instance;
    } 
    

    【讨论】:

    • 是的,我看到了,但我不明白 $params 用于构造函数。基本上所有通过 MySQLi 接收的数据都应该是我想要实例化的对象的参数。
    • 您不能以这种方式在构造函数中使用查询中的数据。您可以做的是创建一个接口 IFetchable 或其他东西并创建一个方法 finalizeFetch();它使用已设置的属性。
    【解决方案2】:

    fetch_object() 方法将返回 stdClass 的一个实例。但是,如果您指定类名,它将返回该类的实例并根据返回的数据填充属性。除非您想更改它们的可见性(即受保护或私有),否则您不需要指定类中的所有列。否则它们将默认为公开。

    此外,最好在要实例化的类中使用静态方法来巧妙地分离关注点。见:

    class Class_Name
    {
        public static function customQuery($query) 
        {
            $return = array();
            if ($result = $mysqli->query($query)) {
                // not passing a class name to fetch_object() 
                // will return an instance of stdClass
                while ($obj = $result->fetch_object('Class_Name')) { 
                    // add the fetched object (as an instance of the 
                    // 'Class_Name' class in this case) to the return array.
                    $return[] = $result;
                }
                return $return;
            }
            // return false if no results found
            return false;
        }
    }
    

    这样调用静态方法,你会得到一个'Class_Name'对象数组:

    $results = Class_Name::customQuery($query);
    

    如果您只查询 1 个结果,上面将是这样的:

    class Class_Name
    {
        public static function customQuery($query) 
        {
            $return = array();
            if ($result = $mysqli->query($query)) {
                return $result->fetch_object('Class_name');
            }
            // return false if no results found
            return false;
        }
    }
    

    这样您将获得一个“Class_Name”对象。

    注意,如果您使用的是命名空间类,请应用完全限定的命名空间类名称。

    【讨论】:

      【解决方案3】:

      这个功能用处不大。

      最好让你的对象的构造函数接受一个带有设置的数组并像这样使用

      while ($row = $result->fetch_assoc($res) {
          $array[] = new Foo($row);
      }
      

      还要注意 fetch_assoc/fetch_object 并不总是可用于准备好的语句。

      【讨论】:

      • 是的,直到现在我都是这样做的,但我认为可能有更清洁的方法
      【解决方案4】:

      您在结果上使用fetch_object。你做while ($obj = $result->fetch_query()) { ... }

      function customQuery($query) {
          if ($result = $mysqli->query($query)) {
              while ($obj = $result->fetch_object()) {
                  # do stuff.
              }
          } else {
              # raise some error, query did not make it.
          }
      }
      

      如果您指定param,这是一个将被实例化以处理结果的类。

      # $result->fetch_object('MyClass');
      
      MyClass {
          private $id;
      
          public function __construct($id/* fields */) {
              $this->id = $id; # say `id` is the only field
          }
      }
      

      【讨论】:

        【解决方案5】:

        以下是正确的使用方法:

        <?php
        
        $res = $mysqli->query($q);
        
        while($params = $res->fetch_assoc()):
        
        endwhile;
        
        $res->free();
        $res = $mysqli->query($q);
        
        while ($obj = $res->fetch_object('ClassName', array($params)):
        
            $obj_list[] = $obj;
        
        endwhile;
        
        ?>
        

        mysqli::fetch_object() 不会将字段名称和值发送给构造函数,它只是创建一个具有属性的对象,而不通过设置器传递。如果你想通过构造函数传递,你必须先将结果恢复并在参数中以数组的形式提供给他。

        如果你想通过构造函数会发生什么?首先,fetch_object() 将创建属性,然后通过构造函数覆盖它们。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-11-02
          • 1970-01-01
          • 2015-08-10
          • 1970-01-01
          • 1970-01-01
          • 2014-03-03
          相关资源
          最近更新 更多