Русское сообщество fluxbb

Быстрый лёгкий надёжный форумный движок

Вы не вошли.

Объявление

Вы можете внести свой вклад в содержание сайта. Жертвователи попадут в почетную группу "Спонсоры". Поддержать сайт.

#1 2011-06-19 09:29:58

artoodetoo
Admin by chance
Зарегистрирован: 2008-09-09
Сообщений: 887
Сайт

Минимальный ООП фреймворк для облегчения расширения FluxBB

Я сторонник оформления кода в объектном стиле. Ниже мой рецепт как ненавязчиво использовать ООП в своих расширениях движка FluxBB.

  1. Нам очень пригодится автозагрузчик классов. Это избавляет от необходимости include/require во множестве мест.

  2. Параметры приложения, которые в коде fluxbb традиционно передаются с помощью global, можно поместить в Реестр

  3. Доступ к данным оформляем через классы Модели. Конкретный текст SQL-запросов и кеширование будут скрыты внутри модели. Снаружи доступен простой интерфейс типа "получить свежие записи".

  4. Переводы тоже добываем через класс. Кроме прочего этот класс легко разрешает проблему переключения языка "на лету" при отправлении писем, например.

Реализация

Автозагрузка файлов по имени.
Все классы помещаем в подпапки /include/classes/. Автозагрузчик будет искать класс, разбивая его имя по символам "_". Например Model_Images находится в /include/classes/Model/Images.php
Процедуру автозагрузки я поместил в functions.php, а её регистрация происходит в common.php

Реестр.
Класс Registry имеет два статических метода: get($name) и set($name, $value). Очень просто! Вся его заслуга в том, что класс доступен отовсюду, что избавляет нас от необходимости global.

Модели.
Есть базовый класс Model_Cached, который умеет писать и читать из файлов кешируемые данные. Кеш имеет время жизни. Кроме того можно сбросить кеш принудительно, если в данных произошли изменения. Имя кеш-файла зависит от группы пользователя и набора параметров запроса.
Производные от Model_Cached классы доверяют всю работу с кешем своему родителю, а сами занимаются формированием правильного SQL-запроса .
Еще одна фишка Model_Cached - паттерн Мультитон. Чтобы создавать только один экземпляр объекта-модели можно сделать так:
$images = Model_Cached::instanceOf('Images');
$rows = $images->getRecent();

Переводы.
Задать текущий язык:
Translation::$language = 'Russian';
Получить массив строк-переводом можно так:
$lang_index = Translation::get('index');
Класс "кеширует" переводы внутри себя. Очевидно нам не придется тащить глобальные переменные через массу вложенных функций.


There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors.

Offline

#2 2011-09-26 17:46:09

Visman
Administrator
Из Сибирь
Зарегистрирован: 2009-06-08
Сообщений: 2,236
Сайт

Re: Минимальный ООП фреймворк для облегчения расширения FluxBB

Решил проверить класс переводов по аналогии с тем, что будет в 2.0
Наваял (но без кэша и языковые файлы по аналогии с PE)

<?php

class Tr
{
    private static
        $translationTable = array(),
        $langDir = 'lang',
        $defaultLang = 'English',
        $lang = 'English',
        $registry = array();

    /**
     * Устанавливаем директорию языковых файлов
     */
    public static function setLanguageDirectory($dir)
    {
        // Remove any trailing slashes
        self::$langDir = rtrim($dir, '/');
    }

    /**
     * Устанавливаем язык по умолчанию
     */
    public static function setDefaultLanguage($lang)
    {
        if (file_exists(self::$langDir.'/'.$lang))
            self::$defaultLang = $lang;
        else
            throw new Exception('It seems like default language pack "'.$lang.'" does not exist.');
    }

    /**
     * Устанавливаем используемый язык
     */
    public static function setLanguage($lang)
    {
        if (file_exists(self::$langDir.'/'.$lang))
            self::$lang = $lang;
        else
            throw new Exception('It seems like language pack "'.$lang.'" does not exist.');
    }

    /**
     * Возвращаем массив языковых соответствий из файла
     */
    private static function loadFile($file)
    {
        if (file_exists($file))
            return require($file);
        else
            return array();
    }
    
    /**
     * Загружаем языковой файл.
     * Сначала грузим язык по умолчанию, затем - выбранный язык, если они разные
     */
    public static function load($resource)
    {
        if (isset(self::$registry[$resource])) return;

        self::$registry[$resource] = true;
    
        $filename = self::$langDir.'/'.self::$defaultLang.'/'.$resource.'.php';
    $trans = self::loadFile($filename);
        self::$translationTable = array_merge(self::$translationTable, $trans);

        if (self::$defaultLang === self::$lang) return;
        
        $filename = self::$langDir.'/'.self::$lang.'/'.$resource.'.php';
    $trans = self::loadFile($filename);
        self::$translationTable = array_merge(self::$translationTable, $trans);
    }

    /**
     * Возвращаем перевод по ключу, если нет, то сам ключ
     */
    public static function t($str)
    {
        return isset(self::$translationTable[$str]) ? self::$translationTable[$str] : $str;
    }
}

В common.php

// Load the language system
require PUN_ROOT.'include/classes/translation.class.php';
Tr::setDefaultLanguage('English');
Tr::setLanguage($pun_user['language']);

// Attempt to load the common language file
Tr::load('common');

Все

$lang_common['***']

были заменены на

Tr::t('***')

Статистика генерации главной страницы форума
до -

[ Сгенерировано за 0.069 сек, 8 запросов выполнено - Использовано памяти: 1.55 Мбайт (Пик: 1.6 Мбайт) ]

после -

[ Сгенерировано за 0.070 сек, 8 запросов выполнено - Использовано памяти: 1.57 Мбайт (Пик: 1.98 Мбайт) ]

P.S. Не нравится мне, что использование памяти увеличивается sad

Offline

Подвал доски

Под управлением FluxBB. Хостинг Hostens