Документация InstantCMS

для администраторов и разработчиков

Инструменты пользователя

Инструменты сайта


dev:models:get

Чтение записей

В данном разделе описаны методы класса cmsModel, позволяющие извлекать записи из базы данных.

Все примеры кода подразумевают, что действие происходит в контексте модели (т.е. внутри класса вашей модели, унаследованного от cmsModel).

Вы должны иметь представление о работе SQL-запросов для полного понимания описанных здесь методов.

Одна строка

Получить одну строку из таблицы в базе можно несколькими методами, в зависимости от условий, по которым будет происходить поиск строки.

Все методы возвращают массив, содержащий в себе поля полученной записи, либо false, если запись не найдена.

Получение строки по id

getItemById($table_name, $id, $item_callback=false)
$table_nameНазвание таблицы, без префикса
$idЗначение поля id искомой строки
$item_callbackАнонимная функция для обработки результата (см. раздел «Обработка строк» ниже)

Пример:

$comment = $this->getItemById('comments', $comment_id);

Получение строки по значению поля

getItemByField($table_name, $field_name, $field_value, $item_callback=false)
$table_nameНазвание таблицы, без префикса
$field_nameНазвание поля, по которому происходит поиск строки
$field_valueЗначение поля в искомой строке
$item_callbackАнонимная функция для обработки результата (см. раздел «Обработка строк» ниже)

Пример:

$comment = $this->getItemByField('comments', 'is_deleted', 1);

Получение строки по условиям фильтров

getItem($table_name, $item_callback=false)
$table_nameНазвание таблицы, без префикса
$item_callbackАнонимная функция для обработки результата (см. раздел «Обработка строк» ниже)

Условия задаются с помощью фильтров (см. раздел Фильтрация).

Пример:

$comment = $this->
                filterEqual('is_deleted', 0)->
                filterLike('content', '%текст%')->
                getItem('comments');

Набор строк

Получение нескольких строк

Для извлечения нескольких строк из таблицы (или нескольких связанных таблиц) используется метод:

get($table_name, $item_callback=false, $key_field='id')
$table_nameНазвание таблицы, без префикса
$item_callbackАнонимная функция для обработки результата (см. раздел «Обработка строк» ниже)
$key_fieldПоле, значения которого будут использовать как ключи для массива с результатами. Если указать false, то массив будет пронумерован простым способом, от нуля

Пример:

$all_comments = $this->get('comments');

При таком вызове массив $all_comments будет содержать в себе все строки из таблицы comments. Вы можете ограничить результаты по условиям и количеству. См. ниже.


Получение количества строк

Чтобы узнать сколько строк вернет метод get() перед его вызовом можно вызвать метод:

getCount($table_name, $by_field='id')
$table_nameНазвание таблицы, без префикса
$by_fieldПо какому полю считать количество строк

Метод возвращает число.

Пример:

$comments_count = $this->getCount('comments');

При подсчете учитываются все фильтры, установленные ранее (см. раздел Фильтрация).


Обработка строк

Строки, полученные из базы при помощи любого из методов getItem() и get() могут быть обработаны перед возвратом. Обработчик определяется с помощью анонимной функции, передаваемой как параметр $item_callback:

function($item, $model) { }

На вход функция получает два параметра:

$itemМассив с данными текущей строки
$modelЭкземпляр текущей модели

Функция может обработать поля в массиве $item или добавить новые. Затем она должна вернуть массив обратно:

$items = $this->get('my_table', function($item, $model){
 
    $item['date'] = date('d.m.Y', strtotime($item['date']));
 
    return $item;
 
});

В этом примере обработчик используется чтобы привести поле date в каждой записи к нужному формату. В реальности, конечно, так делать не нужно, поскольку форматирование даты – задача шаблона.

Чаще всего такой обработчик используется для парсинга сложных полей. Например, если при сохранении записи в базу (об этом в разделе ниже) одно из полей записи будет содержать массив, то он будет автоматически преобразован в формат YAML и сохранен как текст. При извлечении такой записи нужно вручную сделать обратное преобразование.

Пример. Допустим, у нас есть таблица my_table с полями id (int), title (varchar), options (text). Мы добавляем запись в эту таблицу так, чтобы поле options хранило в себе сразу несколько значений:

$new_item = array(
    'title' => 'Новая запись',
    'options' => array(
        'first' => 1,
        'second' => 2
    )
);
 
$new_item_id = $this->insert('my_table', $new_item);

Затем мы извлекаем эту запись обратно:

$loaded_item = $this->getItemById('my_table', $new_item_id);

В этом случае можно ожидать что массивы $new_item и $loaded_item будут одинаковыми. Однако, это не так. В массиве $loaded_item поле options будет уже текстовым, а не вложенным подмассивом. Поэтому, мы должны преобразовать его обратно в массив. Сделать это можно с помощью обработчика:

$loaded_item = $this->getItemById('my_table', $new_item_id, function($item, $model){
    $item['options'] = cmsModel::yamlToArray($item['options']);
    return $item;
});

Метод yamlToArray() преобразует текст в формате YAML обратно в массив. И в этом примере мы получим на выходе точно такой же массив, как и на входе.

Для метода get() обработчик работает точно так же, с той лишь разницей, что обрабатывается не одна строка, а все полученные по-очереди.


Отдельные поля

Поле из строки с известным ID

Для получения значения определенного поля конкретной строки в таблице можно использовать метод:

getField($table_name, $row_id, $field_name)
$table_nameНазвание таблицы, без префикса
$row_idЗначение поля id искомой строки
$field_nameНазвание поля, значение которого нужно получить

Пример – получим дату создания комментария с ID=35:

$pub_date = $this->getField('comments', 35, 'pub_date');

Поле из строки по условию

Вместо указания конкретного ID строки можно использовать набор из одного или нескольких фильтров. Для получения значения поля из строки, отобранной фильтрами, используется метод:

getFieldFiltered($table_name, $field_name)

Если примененные фильтры возвращают больше одной строки, то будет возвращено указанное поле из первой строки в наборе результатов.

Пример – получим ID комментария созданного администратором в указанный день:

$id = $this->
    filterEqual('user_id', 1)->
    filterEqual('pub_date', '2014-12-03')->
    getFieldFiltered('comments', 'id');

Фильтрация

При чтении записей модель может применять различные фильтры, подробно описанные здесь.


Сортировка

Перед извлечением строк с помощью метода get() модель может установить порядок их сортировки.

По одному полю

orderBy($field, $direction)
$fieldНазвание поля, по которому сортировать результат
$directionНаправление сортировки – asc (по возрастанию) или desc (по убыванию)

Пример – получим список всех пользователей, отсортировав их по убыванию даты регистрации (от новых к старым):

$users = $this->orderBy('date_reg', 'desc')->get('{users}');

Как видно из примера, метод orderBy поддерживает «цепочки вызовов», т.е. сразу после него мы можем вызвать любой другой метод объекта $this.

По нескольким полям

orderByList($list)
$listМассив условий сортировки. Каждое условие также задается массивом, с полями by (поле) и to (направление)

Пример – получим все комментарии, отсортировав их по рейтингу и дате:

$ordering = array(
    array('by' => 'rating', 'to' => 'desc'),
    array('by' => 'pub_date', 'to' => 'desc'),
);
 
$comments = $this->orderByList($ordering)->get('comments');

Лимиты

Перед извлечением строк с помощью метода get() модель может ограничить количество желаемых результатов.

limit($from, $howmany=15)
$fromНомер строки в результатах запроса, начиная с которой будут отобраны строки попавшие в финальный результат
$howmanyМаксимальное количество строк в финальном результате

Данный метод работает аналогично условию LIMIT в SQL-запросах. Рассмотрим на примере. Допустим, мы создаем запрос, в результате которого из базы возвращается 100 строк. Если перед запросом мы укажем лимит:

$this->limit(5, 10);

то в результатах мы будем иметь не все 100 строк, а только 10 (с 5-й по 15-ю).

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

limitPage($page, $perpage=15);
$pageНомер текущей страницы
$perpageМаксимальное количество строк на одной странице

Например, такой лимит:

$this->limitPage(3, 10);

вернет строки с 21-й по 30-ю включительно.

Пример – получим последние 10 комментариев (по дате):

$latest_comments = $this->orderBy('pub_date', 'desc')->limit(10)->get('comments');

Присоединения

При извлечении записей с помощью метода get() модель может обращаться к нескольким таблицам в базе данных одновременно, соединяя их. Это происходит аналогично тому, как работают JOIN-условия в SQL-запросах.

Доступно несколько методов:

join($table_name, $as, $on)
joinLeft($table_name, $as, $on)
joinLeftInner($table_name, $as, $on)
joinLeftOuter($table_name, $as, $on)
joinRight($table_name, $as, $on)
joinRightInner($table_name, $as, $on)
joinRightOuter($table_name, $as, $on)
joinInner($table_name, $as, $on)
joinOuter($table_name, $as, $on)
$table_nameНазвание таблицы, без префикса
$asПсевдоним (alias) присоединяемой таблицы
$onУсловие присоединения

Каждый из методов добавляет соответствующий JOIN в генерируемый SQL-запрос. Вызываться эти методы должны перед непосредственным получением результатов, т.е. до вызова метода get().

Параметр $as задает псевдоним (альяс, алиас) присоединяемой таблицы, обычно это просто первая буква (или несколько букв) названия.

Параметр $on описывает условие присоединения (связь таблиц) в SQL-формате. При этом считается, что исходная таблица имеет альяс i.

После того, как связь таблиц определена, необходимо указать какие поля из присоединенной таблицы вы хотите видеть в результатах запроса. Для этого используется метод:

select($field, $as)
$fieldНазвание поля в присоединяемой таблице. Указывается вместе с альясом, в формате: альяс.поле
$asНазвание поля в результатах запроса

Рассмотрим пример. В базе есть таблица menu, содержащая список доступных на сайте меню (главное, боковое, нижнее и т.п.). В таблице menu_items хранятся пункты этих меню. У каждого пункта в таблице menu_items есть поле menu_id, содержащее id меню, которому этот пункт принадлежит.

Предположим, мы хотим получить список всех пунктов меню и для каждого пункта нам нужно название меню:

// присоединяем таблицу menu
// задаем для нее альяс "m"
// исходная таблица имеет альяс "i"
$this->join('menu', 'm', 'm.id = i.menu_id');
 
// мы хотим добавить поле title (название меню) из таблицы menu в результаты
// но, поскольку в таблице menu_items тоже есть поле title (название пункта),
// мы будем использовать другое имя - menu_title
$this->select('m.title', 'menu_title');
 
// получаем результат - пункты из menu_items
$menu_items = $this->get('menu_items');
 
// теперь мы можем перебрать все пункты меню
foreach($menu_items as $item){
    // и у каждого из них будет доступно поле menu_title
    // полученное из присоединенной таблицы
    echo $item['menu_title'];
}

Дальше, к разделу Изменение записей


Дальше, к разделу Фильтрация


Назад, к оглавлению раздела "Модели"


Назад, к оглавлению документации для разработчиков

dev/models/get.txt · Последнее изменение: 03.09.2015 23:42 — аquarius

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki