Я разрабатываю легкий ORM, который использует базовую модель для извлечения всех строк из таблицы базы данных. У меня есть несколько моделей (Вопрос, Ответ, Комментарии), которые расширяют базовую модель защищенной $table
свойство объявлено в каждой модели. Это мой метод для выборки строк таблицы в базовой модели:
public function all() {
$query = "SELECT * FROM {$this->table}";
$statement = $this->database->getConnected($this->connection)->prepare($query);
$statement->setFetchMode(PDO::FETCH_CLASS, 'Core\Database\Collection');
$statement->execute();
return $statement->fetchAll();
}
Когда я получаю результаты, я получаю что-то похожее на это:
array(5) {
[0]=>
object(Core\Database\Collection)#31 (4) {
["id"]=>
string(1) "1"["title"]=>
string(34) "What is your favourite video game?"}
[1]=>
object(Core\Database\Collection)#244 (4) {
["id"]=>
string(1) "2"["title"]=>
string(28) "What is your favourite food?"}
}
Мне было интересно, возможно ли, чтобы вместо того, чтобы быть возвращенным как массив или отдельные объекты, каждый объект коллекции мог бы быть сгруппирован как один большой объект коллекции?
Я знаю, что все еще могу получить результаты, используя foreach
но я просто хотел сделать его настоящей коллекцией, а не массивом.
Один большой объект коллекции
object(Core\Database\Collection) {
all: {
Namespace\Question {
["id"]=>
string(1) "1"["title"]=>
string(34) "What is your favourite video game?"},
Namespace\Question {
["id"]=>
string(1) "2"["title"]=>
string(28) "What is your favourite food?"}
}
}
Мое мнение таково, что вам, вероятно, лучше использовать ваш текущий массив объектов. Тем не менее, вы можете принести в существующий объект и магия __set()
метод для добавления значений в именованный массив:
class Collection {
public function __set($name, $value) {
$this->$name[] = $value
}
}
PDO::FETCH_INTO
не будет работать с fetchAll
насколько я знаю, так что вам нужно while
:
$collection = new Core\Database\Collection;
$statement->setFetchMode(PDO::FETCH_INTO, $collection);
$statement->execute();
while($statement->fetch()){}
return $collection;
Должен вернуть что-то вроде:
object(Core\Database\Collection)#1 (2) {
["id"]=>
array(2) {
[0]=>string(1) "1",
[1]=>string(1) "2"}
["title"]=>
array(2) {
[0]=>string(34) "What is your favourite video game?",
[1]=>string(28) "What is your favourite food?"}
}
На самом деле единственная другая возможность — это иметь объект, как показано в отредактированном примере, со свойством, которое является массивом объектов. Вы бы сделали это похоже на то, что у вас есть. Просто получите массив объектов класса someNamespace\Question
и назначить его свойству другого объекта класса Core\Database\Collection
:
$collection = new Core\Database\Collection;
$statement->setFetchMode(PDO::FETCH_CLASS, 'someNamespace\Question');
$statement->execute();
$collection->all = $statement->fetchAll();
return $collection;
Должен вернуть что-то вроде:
object(Core\Database\Collection)#1 (1) {
["all"]=> array(2) {
[0]=>
object(someNamespace\Question)#1 (2) {
["id"]=>
string(1) "1"["title"]=>
string(34) "What is your favourite video game?"}
[1]=>
object(someNamespace\Question)#2 (2) {
["id"]=>
string(1) "2"["title"]=>
string(28) "What is your favourite food?"}
}
}
Я не знаю Laravel, и синтаксис объекта / массива в видео кажется доморощенным, поэтому его сложно расшифровать.
Других решений пока нет …