Массив с объектами php
Массивы или Объекты? Хочу коллекции в пхп!
Чего уж скрывать, мне нравятся объекты, и не нравятся ассоциативные массивы. И когда выбираю из базы некий набор данных, хочется получать набор объектов а не массив массивов. Причем не просто набор объектов, а нужный мне набор и именно так как я этого хочу. Раньше происходила выборка из базы в 3 этапа:
1. получить массив данных из бд
2. пройтись по результату
3. на каждой итерации создать объект и сунуть в другой массив
Ну и собственно вернуть данные наружу. Это не то чтобы напрягало сильно, но чувствовал что должен быть способ проще и удобней. И я его нашел — Коллекции.
Очень нравятся коллекции. Всегда хотелось иметь массив однотипных данных, в частности объектов. Особенно в связке с бд.
Самая банальная ситуация — хочу получить массив объектов User из бд:
Метод Db_users::getAll()
1. считываем данные из бд
2. проходимся по массиву результатов и загоняем каждую строку в объект User
3. сохраняем полученный объект User в другой массив который отдаем наружу
Как-то так это происходит:
Вот такой простенький и стандартный метод у нас получился, который берет всех пользователей из базы и возвращает массив сущностей.
И как-то так это выводится в шаблоне:
И так постоянно. Все вроде хорошо и работает, но что-то не так. Первое что бросается в глаза — два цикла. Первый при создании массива сущностей, и второй при выводе. Два цикла по (грубо говоря) одному и тому же массиву — зачем? Первая мысль — PDO!
Да у него ведь есть волшебный метод fetchObj. Он многим подойдет, но мне не нравится одна его особенность:
(Добрые люди подсказывают о PDO::FETCH_PROPS_LATE, это решает проблему установки свойств до вызова конструктора.)
Если вам это не принципиально, то на этом можно остановиться, меня же не устраивало что конструктор вызывается после установки свойств (у меня в конструкторе создавался фильтр отдельным классом, не хочется вставлять костыли с проверками на пустые переменные), да и все поля устанавливались как свойства, так что едем дальше.
Есть великолепное встроенное решение — ArrayIterator. Хороший такой себе объект, с геттерами и сеттерами как у массива и возможностью перебора в foreach. Как раз то что надо.
Немножечко меняем метод getAll:
Уже лучше, но какая же это коллекция? Мы просто банально скопированный массив. Так не очень интересно. Хочется получать объект, причем полноценный.
Смотрим на методы ArrayIterator::offsetGet (доступ по ключу как в массиве) и ArrayIterator::current (доступ при переборе в foreach и получение элемента функцией current) этои методы возвращают значение по ключу и текущий элемент по внутреннему указателю соответственно, то что нужно, переопределяем:
В итоге шаблон стал таким как и хотелось:
Отлично, вроде бы все ок, избавились от лишних циклов, заменили массив объектом
Как последний штрих, можно добавлять возвращаемый класс динамически.
Массивы в PHP
Что такое массив
Например, так можно объявить массив с тремя значениями:
Массивы также отлично подходят для объединения нескольких связанных между собой значений, например характеристик товара:
Создание массива
Для создания пустого массива просто укажите квадратные скобки вместо значения:
Результат в браузере:
PHP сообщает нам, что в переменной лежит массив (англ. array), в котором находится 0 значений.
Чтобы объявить массив с данными, просто перечислите значения в квадратных скобках:
Создание массивов с помощью квадратных скобок работает начиная с версии PHP 5.4. До этого использовался более громоздкий синтаксис:
Ключи и значения массива
Массив состоит из ключей (индексов) и соответствующих им значений. Это можно представить как таблицу:
| Ключ | Значение |
|---|---|
| 0 | Samsung |
| 1 | Apple |
| 2 | Nokia |
У каждого значения есть свой ключ. В массиве не может быть несколько одинаковых ключей.
Вернёмся к предыдущему примеру и посмотрим, что лежит в массиве:
Результат в браузере:
Когда мы создаём массив без указания ключей, PHP генерирует их автоматически в виде чисел, начиная с 0.
Указание ключей происходит с помощью конструкции => :
Простые и ассоциативные массивы
Когда мы создаём массив с числовыми ключами, такой массив называется простым или числовым.
Вывод массива
Вывод элементов массива выглядит следующим образом:
Однако обе функции выводят информацию на одной строке, что в случае с массивами превращается в кашу. Чтобы этого не происходило, используйте тег ‘;
Результат в браузере:
Также вывести содержимое массива можно с помощью цикла foreach:
Подробней работу цикла foreach мы разберём в отдельном уроке.
Добавление и удаление элементов
Добавление новых элементов в массив выглядит следующим образом:
Но если название ключа не играет роли, его можно опустить:
Удалить элемент массива можно с помощью функции unset() :
Двумерные и многомерные массивы
В качестве значения массива мы можем передать ещё один массив:
Обратиться к элементу многомерного массива можно так:
Теперь мы можем хранить в одном массиве целую базу товаров:
Или альтернативный вариант:
Задача 1
Задача 2
2. Создайте подмассив streets с любыми случайными улицами. Каждая улица должна иметь имя (name) и количество домов (buildings_count), а также подмассив из номеров домов (old_buildings), подлежащих сносу.
Как создать список или массив объектов в PHP?
что я пробовал.
Продукты, являющиеся собственностью для коллекции orderitems :
3 ответов
на [] нотации добавляет элемент в конец массива.
индекс первого элемента в вашем примере кода равен 1 (разве это не стандартный случай для VB?). php обычно начинается с 0-хотя это возможно (потому что php-массивы не являются реальными массивами), чтобы начать с произвольных индексов, я бы рекомендовал придерживаться нуля.
mysql_fetch_array это древние способ работы с для MySQL. в настоящее время вы лучше с mysqli или (еще лучше) PDO.
списки, массивы, стеки, что угодно: в php everthing-это упорядоченная карта (ошибочно называемая массивом):
PHP: Arrays: массив в PHP на самом деле является упорядоченной картой. Карта-это тип, который связывает значения с ключами. Этот тип оптимизирован для нескольких различных применений; его можно рассматривать как массив, список (вектор), хэш-таблица (реализация карты), словарь, коллекция, стек, очередь и, вероятно, многое другое. Так как значением массива может быть другой массив PHP, можно также создавать деревья и многомерные массивы.
обновление:
извините, у меня сейчас нет времени, чтобы объяснить более тонкие нюансы pdo/ mysqli над в MySQL.
Итак, вот только основы:
ООП: pdo и mysqli являются объектно-ориентированными (жесткие mysqli получили функциональные псевдонимы)
подготовить отчетность: самое главное: pdo/mysqli получил подготовленные заявления. это означает, что сначала вы подготовите запрос с заполнителями один раз, а затем заполните значения позже (без необходимости подготовки запроса во второй раз). этот подход имеет 3 очевидно преимущества:
производительность: это быстрее, потому что база данных должна анализировать, компилировать и оптимизировать запрос только один раз (по крайней мере со сложными запросами)
безопасность: нет необходимости в кавычках (происходит автоматически!), делая SQL-инъекции атаки сложнее
ремонтопригодность: логическая и информационная части запроса разделены, таким образом легче читать, и вам не нужно делать много конкенации строк
Делаем из массивов объекты

PHP содержит очень мощный инструмент — массивы. Половина функций в PHP возвращает результат как ассоциативные массивы. При работе с такими функциями легко допустить ошибки в именовании ключей массива. Понятно что для опытного разработчика это не составляет проблем, но для начинающих это частенько может стать головной болью, особенно если мы получаем огромный json или просто правим legasylegacy код, ну а для не программистов… (таких как я) может послужить генератором говнострашного кода.
Тут приведу некий трюк, который позволяет использовать массив как объект/коллекцию. Возможно кому то это покажется глупым, а кому то даст идеи для применения.
Сразу оговорюсь что реализация рабочая для PHPStorm, в других IDE нужно вам проверять.
Часть примеров будет взята с потолка, часть будет взята из Instagram api.
Примеры
Пример 1. Работаем с данными формы.
Ну и результат использования такого «класса»
Сразу видно с чем имеем дело.
Пример 2. Работаем с сессиями.
Нам нужно работать с сессиями максимально просто.
Наш класс:
Класс для сессий (код ArrayClass будет в конце):
Это нам позволяет спокойно работать так:
$s = new MySession();
$s->var1 = 10;
Всё просто и прозрачно.
Пример 3. Instagram, json и сложные массивы
Нам нужно вызвать API. Делаем это примерно так:
Как это выглядит в IDE:
В 2х словах. Мы получаем json от Instagram и заворачиваем его в наши классы. На выходе получаем структуру классов и помощь от нашей IDE.
Ну а теперь сам ArrayClass:
Вот что получаем на выходе:
Если у кого нибудь есть дополнения по использованию памяти и производительности прошу отписаться в комментариях. Спасибо.
Объекты и классы в PHP
Объекты
Объекты в PHP — это просто ещё один тип данных. Объект позволяет хранить в переменной набор из свойств и их значений, а также встроенные функции. Это делает объекты похожими по своей структуре на ассоциативные массивы. Но отличие от массивов всё-таки есть, и при этом достаточно важное — объекты могут иметь внутреннее состояние.
Особенности объектов и их отличия от массивов
Давайте разберёмся, что такое PHP-объект. Как сказано выше, объекты похожи на массивы, но со своими особенностями. Объекты могут содержать отдельные значения, каждое под своим ключом. Эти значения называются свойствами объекта.
Также объекты могут иметь внутри себя функции — их называют методами объекта. Методы могут обращаться к любым свойствам объекта, читать и записывать туда данные.
Значение свойства объекта может быть любого типа: число, строка, массив, другой объект. Но, в отличие от массива, объекты не позволяют добавлять в себя новые значения. То есть объект всегда имеет конечное число своих свойств и методов. Менять значения существующих свойств можно, а удалять и заменять их — нельзя. Что в корне отличается от поведения массива, ведь там добавлять и удалять значения можно в любое время.
Но самая большая особенность объектов — это то, как они создаются. Если массив создается либо пустым, либо сразу с набором значений, то объекты устроены иначе. Дело в том, что объекты не существуют сами по себе. Чтобы создать новый объект, вам придётся вначале создать его описание — класс.
Класс — это как бы чертёж объекта. Класс описывает то, из чего состоит объект. Мы разберёмся с классами чуть позже.
Анатомия объекта
Как же устроен объект изнутри? Его содержимое можно поделить на две группы: свойства и методы.
Свойства могут быть двух видов: публичные и скрытые. К публичным свойствам можно обращаться за пределами объекта, точно так же, как вы обращаетесь к элементам массива по его ключам.
Скрытые свойства не имеют аналогов в массиве. Они доступны для чтения и изменения только внутри самого объекта — и это могут делать его методы.
Вторая группа — это методы объекта.
Набор методов также называется поведением объекта. Как и свойства, методы бывают публичными и скрытыми. Публичные методы объекта можно вызывать из внешнего кода, а скрытые только из самого объекта. Методы способны обращаться к свойствам объекта также просто, как если бы это были их внутренние переменные или аргументы.
Классы
Класс — это шаблон, по которому создаются объекты.
Напомню, что классы — это описания объектов. Мы не можем создать объект «на лету», как это происходит с массивами. Объект может быть создан только на основе своего описания — класса. Этим, кстати, реализация объектов в PHP отличается от JavaScript. В JS объектам не нужны никакие классы, и они могут быть созданы и модифицированы когда угодно и как угодно.
Класс как чертёж
Зачем же нужны классы, и почему объекты не могут существовать без них?
Здесь аналогия очень простая: класс – это чертёж, максимально подробное описание того, как должно выглядеть изделие. Сам по себе класс не является чем-то физическим и осязаемым, то есть мы не можем использовать его в коде непосредственно. Вместо этого класс является схемой, структурой, на основе которой будет создан объект.
Жизненный цикл объекта
Любая работа с объектами в PHP состоит из следующих этапов.
Начинается всё с создания класса. В классе мы фиксируем из каких свойств и методов будет состоять каждый его экземпляр. Также в классе можно задать начальные значения для каждого свойства.
Имея класс, возможно создать его экземпляр — объект.
Классы в PHP принято сохранять в отдельных файлах, поэтому вначале вы подключаете этот сценарий там, где он необходим. Затем вызываете процедуру создания нового объекта на основе этого класса.
Чтобы использовать объект в дальнейшем, его следует, как всегда, назначить переменной. Затем вы будете работать с объектом через переменную: вызывать методы и обращаться к свойствам.
Пример создания объекта на основе класса
Создание объекта на основе класса:
Разбор примера
Разберёмся с тем, что здесь происходит.
Начнём с целей создания данного класса. Его задача — хранить в объекте данные о погоде за конкретный день, а также предоставлять сводку за этот день в текстовом виде.
В классе определено четыре скрытых свойства. Это значит, что к ним не будет доступа за пределами объекта. Читать и записывать эти свойства могут только внутренние методы объекта. Сами свойства хранят температурные параметры (температуру, осадки), дату и дополнительный комментарий к записи. Некоторым свойствам задано значение по умолчанию.
Что такое конструктор объекта
Методы объекта вызываются из внешнего кода, при явном обращении к ним с указанием имени. Но если назвать один метод __construct то он будет вызываться автоматически в момент создания объекта на основе класса.
Конструкторы объектов используются для инициализации каких-либо значений и выполнении других подготовительных операций. В нашем примере конструктор устанавливает содержимое скрытых свойств.
Обращение к свойствам и методам объекта
Посмотрим, как внутри метода происходит обращение к его свойствам.
Во-первых, для этого используется специальная переменная this, которая всегда присутствует внутри объекта и ссылается на него самого.
Во-вторых, для обращения к методам и свойствам объекта нужен специальный синтаксис: «стрелочка». Такая стрелочка отделяет имя свойства или метода от имени объекта. Это аналог квадратных скобок при работе с массивами.
Метод с именем isCold() нужен, чтобы узнать было ли холодно в тот день, основываясь на показаниях температуры в градусах.
Метод setRainStatus() устанавливает логическое значение, которое показывает статус осадков в день наблюдения.
Метод getDayDescription() формирует текстовое описание погоды на заданную дату.
Создание объекта на основе класса
В коде мы передаём в конструктор почти все параметры погодных наблюдений. Затем для созданного объекта вызываются его методы: первый устанавливает значения осадков, а второй возвращает текстовое описание погоды.