将数据库结果作为对象或数组?
将数据库结果作为对象或数组?
这个问题类似于 使用PHP处理MySQL结果-数组或对象?,不过我的问题更加广泛。
我正在试图决定使用什么格式更适合处理数据库结果:对象还是数组。我不关心性能(从我的了解来看,两者的差别不大)。我的重点也更多地放在显示结果上,而不是创建、更新或删除它们。
到目前为止,我一直使用对象,通过诸如 mysqli_fetch_object
或 PDO 的 fetchObject
等函数。这通常很好用,直到我开始使用联接。联接会导致奇怪的对象,它们是来自两个或更多个表的字段的混合体。我的代码很快变得混乱不堪。
值得注意的是,我正在指定特定的类名,而不是使用默认的 stdClass
。我这样做是为了可以访问我在自己的类中创建的任何辅助方法。例如:
foreach ($members as $member) { echo $member->full_name(); echo $member->age(); }
为了清晰起见,我正在考虑将所有的数据库结果转换成数组。从我读到的东西中,其他人也这么做。然而,这让我没有办法轻松地访问我的辅助方法。
使用以上的示例,我想我只能输出名字和姓氏,而不是使用 full_name()
方法,这并不是什么大问题。至于 age()
方法,我想我可以创建一个通用的实用类并将其放在其中。
我的问题:
- 如果你使用(模型)对象,你如何处理联接?
- 如果你使用数组,你如何处理辅助方法?
这取决于个人偏好。个人更喜欢使用对象。尽管 CakePHP 使用数组作为结果,但会使用“对象”名称作为数组键。然而,当您在 CakePHP 中获取相关记录时,事情开始变得有趣。
对于您的问题,您可以在对象内部简单地使用对象。例如:
stdClass Object ( [id] => 1 [title] => Article Title [published] => 2013-03-04 16:30:00 [category] => stdClass Object ( [id] => 1 [name] => Category Name ) )
然后在视图中显示关联数据如下:
category->name; ?>
或者,如果使用 getter 和 setter:
getCategory()->getName(); ?>
没有对错之分。正如我所说,这是个人喜好。
我一直使用对象——但我不直接从查询中放置数据。使用“ set”函数,我创建布局,从而避免连接和命名冲突问题。在您的“ full_name”示例中,我可能会使用“ as”获取名称部件,将每个设置在对象中,并提供“ get_full_name”作为成员函数。
如果您感到雄心勃勃,可能会将各种东西添加到“ get_age”中。设置出生日期仅一次,然后疯狂发挥。
编辑:
有多种方法可以将数据制作成对象。您可以预定义类并创建对象,也可以“即时创建”它们。
-->一些非常简化的示例——如果这还不足够,我可以添加更多。
即时创建:
$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并输出邮寄标签:
foreach( $ret as $location ) { echo $location->getMailing(); }