Результаты базы данных как объекты или массивы?
Этот вопрос похож на 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
, из которого могут быть связаны его данные.