Результаты базы данных как объекты или массивы?

Этот вопрос похож на Mysql приводит к PHP-массивам или объектам? Однако мой вопрос расширяет то, что обсуждалось там.

Я пытаюсь решить, какой формат лучше подходит для работы с результатами базы данных: объекты или массивы. Меня не интересует производительность (из того, что я понимаю, это мало что влияет). Мое внимание также уделяется отображению результатов, а не созданию, обновлению или удалению.

На сегодняшний день я всегда использовал объекты с помощью таких функций, как mysqli_fetch_object или PDO fetchObject. Это нормально работает, пока я не начну присоединяться. Соединения приводят к странным объектам, которые представляют собой смесь полей из двух или более таблиц. Мой код быстро начинает запутываться.

Следует отметить, что я назначаю определенные имена классов и не придерживаюсь стандартного stdClass. Я делаю это, чтобы получить доступ к любым вспомогательным методам, которые я создал в своих классах. Например:

foreach ($members as $member)
{
    echo $member->full_name();
    echo $member->age();
}

Для ясности я рассматриваю возможность перехода к массивам для всех результатов моей базы данных. Из того, что я читал, другие делают это тоже. Однако это оставляет мне простой способ получить доступ к моим вспомогательным методам.

Используя приведенный выше пример, я думаю, я мог бы просто выводить как первое, так и последнее имя вместо использования метода full_name(), а не большое дело. Что касается метода age(), я думаю, я мог бы создать общий класс утилиты и поместить его туда.

Мои вопросы:

  • Если вы используете (модельные) объекты, как вы относитесь к объединениям?
  • Если вы используете массивы, как вы относитесь к вспомогательным методам?

Ответ 1

Я всегда использовал объекты - но я не помещаю данные непосредственно из запроса. Используя функции "set", я создаю макет и избегаю проблем с объединениями и именованием коллизий. В случае вашего примера "full_name" я, вероятно, использовал бы "как", чтобы получить части имени, установить каждый в объекте и предложить "get_full_name" как член fn.

Если вы были амбициозны, вы могли бы добавить всевозможные вещи в get_age. Установите дату рождения один раз и идите оттуда.

EDIT: Существует несколько способов сделать объекты из ваших данных. Вы можете предопределить класс и создать объекты, или вы можете создать их "на лету".

- > Некоторые v упрощенные примеры - если этого недостаточно, я могу добавить больше.

на лету:

$conn = DBConnection::_getSubjectsDB();  
$query = "select * from studies where Status = 1";  
$st = $conn->prepare( $query );  

$st->execute();  
$rows = $st->fetchAll();  
foreach ( $rows as $row )  
{  
    $study = (object)array();  
    $study->StudyId = $row[ 'StudyId' ];  
    $study->Name = $row[ 'StudyName' ];  
    $study->Investigator = $row[ 'Investigator' ];  
    $study->StartDate = $row[ 'StartDate' ];  
    $study->EndDate = $row[ 'EndDate' ];  
    $study->IRB = $row[ 'IRB' ];  

    array_push( $ret, $study );  
} 

предопределено:

/** Single location info
*/
class Location  
{  
    /** Name  
    * @var string  
    */  
    public $Name;  

    /** Address  
    * @var string  
    */  
    public $Address;  

    /** City  
    * @var string  
    */  
    public $City;

    /** State
    * @var string
    */
    public $State;

    /** Zip
    * @var string
    */
    public $Zip;

    /** getMailing
    * Get a 'mailing label' style output
    */
    function getMailing()
    {  
         return $Name . "\n" . $Address . "\n" . $City . "," . $State . "  " . $Zip;
    }
}

использование:

$conn = DBConnection::_getLocationsDB();  
$query = "select * from Locations where Status = 1";  
$st = $conn->prepare( $query );  

$st->execute();  
$rows = $st->fetchAll();  
foreach ( $rows as $row )  
{  
    $location = new Location();  
    $location->Name= $row[ 'Name' ];  
    $location->Address = $row[ 'Address ' ];  
    $location->City = $row[ 'City' ];  
    $location->State = $row[ 'State ' ];  
    $location->Zip = $row[ 'Zip ' ];  

    array_push( $ret, $location );  
} 

Затем вы можете перебрать метки $ret и output mailing:

foreach( $ret as $location )
{ 
    echo $location->getMailing();
}

Ответ 2

Его предпочтение в конце дня. Лично я предпочитаю объекты. Хотя CakePHP использует массивы для результатов, используя имя "object" в качестве ключа массива. Однако при загрузке связанных записей в CakePHP все становится забавным.

С вашей проблемой вы можете просто иметь объекты внутри объектов. Например:

stdClass Object
(
    [id] => 1
    [title] => Article Title
    [published] => 2013-03-04 16:30:00
    [category] => stdClass Object
        (
            [id] => 1
            [name] => Category Name
        )

)

Затем вы можете отображать связанные данные в своих представлениях следующим образом:

<?php echo $article->category->name; ?>

Или, если вы используете геттеры и сеттеры:

<?php echo $article->getCategory()->getName(); ?>

Нет правильного или неправильного ответа. Как я уже сказал, все его личные предпочтения.

Ответ 3

Я думаю, вы говорите о странных объектах, которые появляются с помощью SELECT на двух или более таблицах.

Я решаю это, используя AS в моем sql, чтобы дать ему более простое имя.

SELECT IFNULL(SUM(table2.big_name),0) AS sumBig

...


$result=$PDO->fetchObject();
$sum=$result->sumBig;

Ответ 4

Я думаю, что лучше представить все ваши данные и их тип в форме модели. Для объединенных и особых объектов. Это всегда будет опускать вашу проблему.

class Member_Details {
    public $id;    
    public $first_name;
    public $last_name;

    public function FullName() {
         return $this -> first_name." ".$this -> last_name;
    }
}

class Member_Address {
    public $id;
    public $address;
    public $city;
}

class MemberJoins {
     public $objects = array();
}

После создания таких классов вы можете настроить JOIN следующим образом.

$obj_details = new Member_Details();
$obj_address = new Member_Address();
//Add data to the objects and then

//Then create the join object
$obj_address_details = new MemberJoins();
$obj_address_details -> objects = array($obj_details, $obj_address);

Оба они имеют общее свойство id, из которого могут быть связаны его данные.