Спотыкашки

Материал из PHPShop CMS

Перейти к: навигация, поиск

Полезные советы для разработчиков от разработчика.
Общение с пользователями системы и попадание их на одни и те же "грабли" сподвигло меня написать этот раздел, берегите лбы, друзья.

Содержание

Шаблонизатор

Полезные советы по использованию функций шаблонизации.

Хитрости с set()

Метод set() назначает переменную шаблонизатора для использования в шаблонах в виде @var@, пример:

$var = "Мы любим Россию";
$this->set('my_var',$var);

и вставка ее вида @my_var@ в файл tpl шаблона позволит вывести фразу "Мы любим Россию" на сайте. Часто в модулях, таких как formgenerator или comment используется перехват и изменение переменных. Если мы в функции хука используем модель $this->set('my_var',$var), то мы полностью переписываем значение переменной, в нашем примере переписываем содержание страницы. Все бы хорошо, но это правило работает, если у нас включен только один модуль, который перехватывает содержание страницы, а если у нас их больше, то каждый новый модуль будет затирать результат работы вывода другого модуля. В таких случаях на помощь приходит третий аргумент метода $this->set, принимающий значение true. Использование этого аргумента позволит не переписать переменную, а ее дополнить, те позволит поочередно вывести результат работы модулей - вывод формы и комментариев.

Решение:

$this->set('my_var',$var,true);

ParseTemplateReturn() в модулях

Если в модуле используется шаблон этого модуля, описанный в config.ini модуля, то запись вида:

$comment=ParseTemplateReturn($GLOBALS['SysValue']['templates']['comment']['comment_content']);

выведет пустой результат. Для использования глобальной функции шаблонизации ParseTemplateReturn() в модулях необходимо указать второй аргумент true, переводящий функции в режим чтения файлов шаблонов из папки модулей, а не из общей phpshop/templates/.

Решение:

ParseTemplateReturn($GLOBALS['SysValue']['templates']['comment']['comment_content'],true);


Использование php в шаблонах

Шаблонизатор позволяет использовать php-функции. Формат вставки:

@php
...
php@

Во избежании ошибок в php компиляторе используются двойные кавычки ", вместо одинарных ', пример:

@php
echo "Мы любим Россию!";
php@


Работа с БД

Полезные советы по использованию функций доступа к данным БД.

Быстрая выборка настроек модуля

Есть очень хороший и короткий способ получить настройки модуля, которые хранятся в базе modulename_systems:

// Настройки модуля
PHPShopObj::loadClass("array");
class PHPShopCommentArray extends PHPShopArray {
    function PHPShopCommentArray() {
        $this->objType=3;
        $this->objBase=$GLOBALS['SysValue']['base']['comment']['comment_system'];
        parent::PHPShopArray("enabled","flag","other");
    }
}

В этой записи нам нужно указать имя БД, из которой мы хотим получить данные, например

$this->objBase=$GLOBALS['SysValue']['base']['comment']['comment_system'];

и перечислить через запятую имена полей, которые нам нужны

parent::PHPShopArray("enabled","flag","other");

Для доступа к этим данным используется:

$PHPShopCommentArray = new PHPShopCommentArray();
$enabled = $PHPShopCommentArray->getParam('enabled');

Сложные запросы в ORM

Для работа с MySQL используется PHPShopOrm. Пример обычной выборки имеет вид:

$data=$PHPShopOrm->select(array('id','name'),array('id'=>'=10'),array('order'=>'id DESC'),array('limit'=>1000));
if(is_array($data))
   foreach($data as $row){ .... }

Это все упрощает и стандартизирует запросы, но если нужно выполнить сложные выборки с совмещением таблиц? В таких случаях используются метод $PHPShopOrm->query(), например:

$result = $PHPShopOrm->query('SELECT a.*, b.login FROM '.$GLOBALS['SysValue']['base']['comment']['comment_log'].' AS a
            JOIN '.$GLOBALS['SysValue']['base']['users']['users_base'].' AS b ON a.user_id = b.id
            WHERE a.page="'.$page.'" order by a.id desc');
while($row = mysql_fetch_array($result)) { ..... }

Мешанина с многомерностью результат выборки select()

Частый "бок" встает на пути у разработчика, когда при выборке $PHPShopOrm->select() и условии, что в БД 1 запись выводится одномерный массив, а если больше, то многомерный. Для обхода такой неопределенности используется аргумент array('limit'=>1), при котором всегда массив будет одномерный и работать с ним через запись вида:

$data=$PHPShopOrm->select(array('id','name'),array('id'=>'=10'),array('order'=>'id DESC'),array('limit'=>1000));
if(is_array($data))
   { .... }

в случаях явной предрасположенности результата к множественным полям используется формат записи с явным указанием лимита array('limit'=>1000):

$data=$PHPShopOrm->select(array('id','name'),array('id'=>'=10'),array('order'=>'id DESC'),array('limit'=>1000));
if(is_array($data))
   foreach($data as $row){ .... }


GUI интерфейсы

Волшебный Framework и тонкие моменты в его использовании.

Назначение первичного загрузчика формы

Часто разработчики для создания интерфейсов административной части создают файлы методом копирования уже существующих и не понимают почему, указав в качестве управления экшенами скопированный кусок кода из файла adm_news_new.php, они не могут вывести простую форму параметров модуля.

// Вывод формы при старте
$PHPShopGUI->setAction($_GET['id'],'actionStart','none');
 
// Обработка событий 
$PHPShopGUI->getAction();

Фокус в том, что метод $PHPShopGUI->setAction($_GET['id'],'actionStart','none') используется в случаи, если в форму при загрузке передается параметр $_GET['id']. Если в форме нет параметров, то используется метод setLoader() форма записи:

// Вывод формы при старте
$PHPShopGUI->setLoader($_POST['editID'],'actionStart');
 
// Обработка событий 
$PHPShopGUI->getAction();

setLoader() имеет в качестве первого аргумента $_POST['editID'], который служит маркером зависимости, что указанная вторым аргументом функция actionStart будет выполнена при условии, что $_POST['editID'] не определено.

А если $_POST['editID'] будет задано, то будет выполнять функция actionInsert(), которая должна находится в этом же файле. Объявление экшена actionInsert происходит в функции actionStart() включением в форму строки:

$ContentFooter=$PHPShopGUI->setInput("submit","editID","ОК","right",70,"","but","actionInsert");
$PHPShopGUI->setFooter($ContentFooter);

Данная вставка выведет графически кнопку ОК, при нажатии на которую выполнится функция actionInsert().


Отладка

Для отладки используется отладочная панель PHPShopDebug, куда выводится полезная информация. Рекомендуется использовать браузеры, отличные от IE, т.к. данный браузер иногда прячет панель внизу, наперики всем правилам разметки в некоторых шаблонах.

Отлов данных навигации

Что бы понять, какие данные за что отвечают и как их можно использовать существует меню Requet в панели отладки. Нажав на нее и раскрыв полный вывод, мы получим полезные данные и имена переменных для использования, пример:

GLOBALS['SysValue']['nav']: Array
(
    [truepath] => /price/
    [path] => price
    [nav] => 
    [name] => 
    [id] => 
    [page] => 
    [querystring] => debug=request
    [query] => Array
        (
            [debug] => request
        )
 
    [longname] => /price/
    [url] => /price/
)

Например, переменная $GLOBALS['SysValue']['nav'][path] содержит адрес раздела price и т.д.


Прячем Notice (отладочные уведомления)

Зачастую локальные сервера и хостинги балуются опцией вывода всех отладочных сообщений для php. Это очень не удобно, а новичков сражает на повал кол-во ошибок, но это не ошибки, а отладочные сообщения для разработчиков. Простому смертному они как козе пятая нога. Можно коненчно вообще убрать все ошибки в файле .htaccess, но тогда отладка будет затрудняться.

Для решения этой проблемы есть модуль Error Log, позволяющий управлять ошибками php и назначать свои обработчики для них. Все ошибки пишутся в БД модуля и доступны для анализа. Для записи определенных событий в БД модуля используется запись:

trigger_error("Текст отладки", E_USER_NOTICE);

Error Log входит в комплект поставки PHPShop CMS Free. Оптимальная настойка для уровня вывода ошибок в модуле - Блокировать вывод всех ошибок, при этом все ошибки и отладки будут писаться в вашу БД и не пугать пользователей сайта.