如何mysqli_result::fetch_array with key [table.属性]



我正在尝试创建一个通用的方法来自动实例化对象从这样的查询:

SELECT town.*, content.*, user.*
FROM townhub.content
LEFT JOIN town ON content.townReceiver = town.id_town
LEFT JOIN user ON content.author = user.id_user

我想构建的方法应该返回3种类型的对象:Town, UserContent到一个数组中。我想过这样的事情:

protected function build_objects($result, Array $classes) {
    $data = array();
    $i = 0;
    while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
        foreach ($classes as $class) {
            $$class = new $class;
            $$class = $$class->fill_object($$class, $row);
            $data[$i][$class] = $$class;

        }
        $i++;
    }
    return $data;
}

然后,在每个类中,有一个这样的方法:

public function fill_object($object, Array $row) {
    $attributes = get_object_vars($object);
    foreach ($row as $attribute => $value) {
        foreach ($attributes as $objAtt => $emptyValue) {
            if ($attribute == $objAtt) {
                $object->$attribute = $value;
            }
        }
    }
    return $object;
}

实际上,这就是我想要的,下面的数组(在build_objects()中使用var_dump($data)打印):

array (size=4)
  0 => 
    array (size=3)
      'Content' => 
        object(Content)[4]
          protected 'id_content' => string '1' (length=1)
          public 'title' => string 'Hello World!' (length=10)
          public 'description' => string 'Hello world description' (length=43)
          public 'category' => string '1' (length=1)
          public 'date' => string '2015-01-01' (length=10)
          public 'townReceiver' => string '1' (length=1)
          public 'author' => string '1' (length=1)
          private 'dbHost' (Model) => string 'localhost' (length=9)
          private 'dbUser' (Model) => string 'root' (length=4)
          private 'dbPass' (Model) => string 'root' (length=4)
          private 'dbName' (Model) => string 'townhub' (length=7)
          private 'conn' (Model) => null
      'Town' => 
        object(Town)[5]
          protected 'id_town' => string '1' (length=1)
          public 'name' => string 'Isaac' (length=5)
          public 'population' => string '750' (length=3)
          private 'dbHost' (Model) => string 'localhost' (length=9)
          private 'dbUser' (Model) => string 'root' (length=4)
          private 'dbPass' (Model) => string 'root' (length=4)
          private 'dbName' (Model) => string 'townhub' (length=7)
          private 'conn' (Model) => null
      'User' => 
        object(User)[6]
          protected 'id_user' => string '1' (length=1)
          protected 'dni' => string '20011225' (length=9)
          private 'password' => string '1234' (length=4)
          public 'name' => string 'Isaac' (length=5)
          public 'firstSurname' => string 'Surname1' (length=5)
          public 'secondSurname' => string 'Surname2' (length=5)
          public 'birthdate' => string '0000-00-00' (length=10)
          public 'gender' => string 'H' (length=1)
          public 'email' => string 'isaac@mail.com' (length=19)
          public 'isAdmin' => string '1' (length=1)
          public 'id_town' => string '1' (length=1)
          private 'dbHost' (Model) => string 'localhost' (length=9)
          private 'dbUser' (Model) => string 'root' (length=4)
          private 'dbPass' (Model) => string 'root' (length=4)
          private 'dbName' (Model) => string 'townhub' (length=7)
          private 'conn' (Model) => null

问题是,当我fech_array(在fill_object()方法)镇的名字被用户的名字覆盖;所以我不知道这个小镇的名字。简单的解决方案是更改db和类上的属性名称;但我认为这将是一个糟糕的解决方案……请记住,属性的名称在db和类上应该是相等的,所以查询中的alias是不可能的。

有任何方法与fetch_array获得一个数组与键[表。Attribute]而不是[Attribute]?
我也想知道更好的方法来做到这一点,如果我想做的是不可能的。

 <?php
class DataCollectionHelper
{
    /**
     * $result var is the result of:
     * "SELECT *
     * FROM townhub.content".
     * 
     * As you left join your tables, it may appear that you haven't any towns and users
     * for particular content.
     *
     * @param $result
     * 
     * @return array
     */
    protected function build_objects($result)
    {
        $data = array();
        $i = 0;
        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            $contentObject = new Content();
            $contentObject->fill_object($row);
            $data[$i]['Content'] = $contentObject;
            $data[$i]['User'] = $this->getUserByContentAuthor($contentObject->getAuthor());
            $data[$i]['Town'] = $this->getTownByContentByTownReceiver($contentObject->getTownReceiver());
            $i++;
        }
        return $data;
    }
    /**
     * @param integer $townReceiver
     *
     * @return Town
     */
    private function getTownByContentByTownReceiver($townReceiver)
    {
        /**
         * Here you have to get town data by your $townReceiver - property
         *  and return the object of Town
         */
    }
    /**
     * @param integer $author
     *
     * @return User
     */
    private function getUserByContentAuthor($author)
    {
        /**
         * The same here for users
         */
    }
}
class Content
{
    /**
     * @var integer
     */
    protected $content_id;
    /**
     * @var string
     */
    public $title;
    /**
     * @var integer
     */
    public $townReceiver;
    /**
     * @var string
     */
    public $description;
    /**
     * @var integer
     */
    public $author;
    /* other vars */
    /**
     * @param array $row
     *
     * @return $this
     */
    public function fill_object(array $row)
    {
        /*
         * It's not the best approach, to do like that.
         * It's better to use setters or just set your properties
         * $this->title = $row['title']; etc
         *
         * Still you could use $this instead of your $object variable
         */
        $attributes = get_object_vars($this);
        foreach ($row as $attribute => $value) {
            foreach ($attributes as $objAtt => $emptyValue) {
                if ($attribute == $objAtt) {
                    $this->$attribute = $value;
                }
            }
        }
        return $this;
    }
    /**
     * @return int
     */
    public function getTownReceiver()
    {
        return $this->townReceiver;
    }
    /**
     * @return int
     */
    public function getAuthor()
    {
        return $this->author;
    }
}

相关内容

  • 没有找到相关文章

最新更新