Strict Standards: Non-static method nggallery::get_option() should not be called statically in /home/mchedlishvili.com/mike/WWW/wp-content/plugins/nextgen-gallery/nggfunctions.php on line 10

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Strict Standards: Only variables should be assigned by reference in /home/mchedlishvili.com/mike/WWW/wp-includes/post.php on line 173

Источник: http://topright.livejournal.com/

  1. Боритесь с рутиной! Инкапсулируйте её (в ж…),
    абстрагируйтесь от неё (на х…). Пишите всё единожды, локализуйте
    решение повседневных задач. Настоящие сенсеи выше двух низменных
    вещей: суеты желаний и размножения методом copy-paste.

  2. В начале проектирования перечислите и назовите все сущности
    предметной области (в нашем случае это site, page, module, user,
    language, session, cookie и т.д.). Не обязательно все эти сущности
    отразятся в архитектуре вашей системы в виде классов или файлов. Но
    в вашем распоряжении окажется богатая лексика предметной области,
    что поможет раскованному проектированию системы. По мере локализации
    решения стандартных задач (см. предыдущий совет), раскидывайте эти
    решения по наиболее подходящим сущностям (классам или файлам).
    Пускай ваши сущности постепенно обрастают мясом, методами,
    способностями. Чем не RPG?

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

    • определение расширения файла

    • проверка допустимости данного
      расширения файла

    • загрузка файла в нужный каталог

    • масштабирование или кадрирование
      изображения

    • создание thumbnail нужного размера

    • наложение watermark

    Каждая из перечисленных подзадач вполне типична и может
    возникнуть вне контекста загрузки файла. Например, может
    потребоваться перемасштабирование уже загруженных изображений.
    Хороший дизайн системы позволит “выхватить” нужную
    функцию и использовать её в контексте другой задачи.

  4. Хотите создавать гибко расширяемые интерфейсы? Используйте
    ассоциативные массивы. Сделайте один из параметров функции
    ассоциативным массивом, который будет содержать всевозможные опции.
    Значительное удобство такого подхода в том, что вам не надо помнить
    порядок параметров функции - заполнять ассоциативный массив
    можно в любом порядке. Вы сможете легко добавлять и даже удалять
    поддержку опций, не меняя сигнатуру функции. Благодаря явному
    указанию в клиентском коде пар “название опции -
    значение”, он становится более понятным. Предусмотрите
    значения опций по умолчанию, и использование таких интерфейсов
    станет по-настоящему приятным.

  5. Минимизируйте количество точек входа на сайт. Если для
    каждого модуля сайта (главная страница, форум, новости, админка)
    добавлять точку входа, то скоро вы столкнетесь с большим
    нагромождением файлов, в которые неудобно вносить изменения. Обычный набор: index.php (обращение ко всем
    страницам сайта), admin.php (форма для авторизации админов),
    file.php (показ увеличенных изображений во всплывающих окнах),
    captcha.php (генерация captcha-кодов) и т.д.

  6. Запрещайте обращение извне к файлам, которые
    не являются точками входа. Это можно сделать, настроив
    соответствующим образом файл .htaccess. Другой способ состоит в том,
    чтобы в начале каждого файла - точки входа определять
    переменную:


    $GLOBALS
    [‘ENTRY_POINT’] = true


    а в остальных файлах проверять, определена ли она:


    if (!isset(
    $GLOBALS[‘ENTRY_POINT’])) 



        
    Header(‘Location:index.php); 

        die; 


    При этом PHP должен быть настроен с опцией register_globals OFF (по умолчанию в версиях >= 4.2.0).

  7. Предусмотрите единственную стандартную директорию, в которую
    админы смогут сохранять изображения, flash-ролики, текстовые
    документы и прочие файлы при редактировании контента сайта. Внутри
    неё может быть любое количество поддиректорий. Приятно, что они не
    захламлят главный каталог сайта. И главное: вы будете уверены, что
    существует единственная ветвь каталогов, которой нужно назначить
    права на запись файлов.

  8. Часто модули удобно делить дальше на подмодули. Отведите каждому модулю (подмодулю)
    свою директорию, чтобы логическая иерархия наглядно отразилась в
    иерархии папок (как это в Java).

  9. Существует два способа реализации админ-части: в виде
    отдельной точки входа или одного из модулей сайта. Первый случай
    самый распространенный, но он ничем не примечателен. Во втором
    случае вы выигрываете сразу в нескольких отношениях. Во-первых,
    структура сайта становится концептуально проще. Во-вторых, легче
    поддерживать единую систему прав доступа к разным модулям и
    подмодулям сайта. В-третьих, появляется выбор: встраивать ли
    админский интерфейс в стандартный шаблон страницы сайта или вынести
    его в качестве отдельной страницы (возможно, со своим особым
    дизайном). Интеграция удобна тем, что администратор сразу видит
    изменения, которые вносит, хотя смешение админского и внешнего
    интерфейсов может запутать некоторых “чайников”. Здесь
    желательно предоставить выбор пользователю - как ему самому
    удобнее.

  10. На этапе проектирования предусмотрите возможность создания
    мультиязычных сайтов. Один из способов - использование функции
    наподобие этой:


    function 
    lang($ru$en $de 



        global 
    $lang

        return $
    $lang






    lang(‘Русский’‘English’‘Deutch’); 

    Недостаток такого подхода состоит в том, что текстовые константы оказываются
    раскиданными по всем файлам сайта. Другой способ, популярный среди
    разработчиков, но тоже не самый правильный - собрать текстовые
    константы в файлах вроде constants.ru.php, constants.en.php,
    constants.de.php, и для каждой языковой версии сайта подключать
    нужный файл. В обоих описанных случаях при добавлении новой языковой
    версии придется давать переводчику исходные коды сайта. Нет никакой
    гарантии, что переводчик, внося изменения, сохранит правильный
    синтаксис PHP. Кроме того, для исправления опечаток корректоры будут
    обращаться к вам, отвлекая от насущных дел и играния в тетрис.
    Поэтому храните все текстовые константы пользовательского интерфейса
    в базе данных, а не в PHP-скриптах. Предоставьте контент-менеджерам
    и модераторам сайта удобный интерфейс, с помощью которого они смогут
    самостоятельно редактировать и настраивать текстовое оформление
    сайта.

  11. Организуйте базу данных таким образом, чтобы добавление
    нового языка не было болезненным. Однажды мне довелось увидеть
    таблицу с такой
    структурой:

    id
    title_ru
    title_lv
    content_ru
    content_lv
    weight
    is_active
    title_en
    content_en

    По
    структуре таблицы видно, что английская версия сайта была добавлена
    позже остальных. Красиво? Не очень. Использование таких полей
    сравнительно эффективно, но с точки зрения расширяемости сайта не
    удобно. Для каждого нового сайта вам придется менять запросы и
    структуру базы данных. Другие варианты состоят в том, чтобы хранить
    все текстовые строки на разных языках в отдельной таблице или в
    одном поле через специальный разделитель. Оба варианта требуют
    дополнительных вычислительных затрат. Второй удобнее первого, но
    затрудняет сортировку по строкам.

  12. Группируйте текстовые константы (”для форума”,
    “для формы контактов”, “для админки”) и
    загружайте группами по мере необходимости.

  13. Не “зашивайте” админские пароли в код. У админа
    должна быть возможность оперативно менять свой пароль. Храните
    пароли в зашифрованном виде в базе данных. Раз есть таблица админов,
    то можно разрешить создавать сколько угодно админов. Раз есть
    сколько угодно админов, то можно варьировать их уровни допуска.
    Система разделения прав - полезная штука. Раз есть уровни
    допуска, то для полного счастья можно ввести “уровень допуска
    разработчика” - это еще круче, чем у админов. Например,
    настройка меню админки, добавление и удаление текстовых констант -
    это функции, полезные для разработчиков, но не администраторов.
    Такой интерфейс сэкономит вам много времени.

  14. “Горячие клавиши” сделают навигацию в ваших
    сайтах на порядок удобнее. Моментально переноситесь на страницу
    авторизации или в админку при нажатии кнопки “a”!
    Телепортируйтесь на стартовую страницу при нажатии кнопки “s”!
    Только, пожалуйста, добавьте проверку, не нажат ли вместе с горячей
    клавишей Ctrl или Alt (например, Ctrl+A является стандартной
    комбинацией клавиш для выделения всей страницы). Запретите событию
    keypress всплывать (bubble), когда в фокусе какое-либо текстовое
    поле формы, и пользователь вводит в него текст, содержащий символы
    “a” или “s”.

  15. Сформируйте определенный стиль, в рамках которого пишите
    надежный код. PHP - небезопасный язык с шаманской системой
    типизации. Отсутствие строгой типизации облегчает и ускоряет
    корректный кодинг, но затрудняет поиск багов.
    Благодаря тому, что это интерпретируемый язык, вы можете куролесить
    напропалую и вообще ходить на голове - парсер стерпит всю
    акробатику, но и ответственности на вас больше. Проторите
    определенное русло, исследуйте в нем каждую кочку, и в этих рамках
    пишите надежные программы.

  16. ООП в PHP не поддерживает “дизайн по контракту”:
    любому объекту можно динамически “пристегнуть” новый
    атрибут или метод. По возможности следите за тем, чтобы контракты
    ваших классов соблюдались. Пускай объявления классов будут
    целостными и самодокументирующимися: будьте уверены, что где-нибудь
    на просторах вашего движка не используются незадокументированные
    атрибуты или методы.

  17. Чтобы писать читабельный и легко сопровождаемый код, наложите
    на язык собственные дополнительные правила, и следуйте им так, как
    если бы они были непреложной частью синтаксиса и лексики языка.
    Например, я всегда называю ассоциативные массивы: $employee_data,
    $file_data и т.д. Названия текстовых констант, полученных из базы
    данных, всегда начинаются со знака “_”. Такие правила
    помогают мне не задумываться каждый раз, какой выбрать
    идентификатор, и в результате получается понятный, стильный код.

  18. Сформируйте также собственные семантические правила, именуя
    таблицы в базе данных. Многие таблицы в моем движке имеют вид:
    m_modulename_tablename. Префикс m означает, что
    таблица относится к какому-либо модулю. Modulename - это
    название модуля, а tablename - собственно название таблицы.
    Остальные таблицы, которые относятся к ядру движка (конфигурация
    сайта, текстовые константы, администраторы) не имеют префиксов.
    Благодаря префиксам вы сможете легко находить нужные таблицы в коде.
    Поскольку PhpMyAdmin и другие СУБД обычно сортируют таблицы по их
    названиям, то благодаря префиксам таблицы будут сгруппированы в
    некие логические объединения. Этот простой, но приятный совет
    поможет вам быстро ориентироваться среди таблиц.

  19. Предусмотрите в своем движке стандартную поддержку
    тестирования и отладки скриптов. Создайте класс, который будет
    ведать уровнем выводимых сообщений об ошибках. Пускай все другие
    классы в случае возникновения ошибок посылают сообщения этому
    диагностическому классу, а тот уже решает, что с ними делать:
    вывести на страницу, сохранить в базу данных, отправить по e-почте
    разработчикам или побить баклуши. Для локализации жучков можно
    использовать библиотечную функцию debug_backtrace() и
    предопределенные константы (__LINE__, __FILE__, __FUNCTION__,
    __CLASS__, __METHOD__ и т.д.). Поскольку отладочная информация
    требуется редко, не скупитесь с её выводом: красочный темплейт на
    свой вкус, как можно более полная сводка информации.

  20. Используйте замечательный плагин Firebug для броузера
    Firefox. При ловле багов это как BFG 9000.

  21. Ограничивайте свои скрипты областью видимости функций или
    методов. Даже если на сервере включена опция register_globals ON, вы
    всё равно обезопасите скрипты от подмены переменных, потому что
    автоматически инициализированные переменные не будут видны внутри
    ваших функций или методов.

  22. Все переменные, включаемые в mysql-запросы, пропускайте через
    функцию наподобие этой:

    function nosql($field)

    {

        if (
    is_array($field))

        {

     foreach (
    $field as $key => $elem)

     $field[$key] = nosql($elem);

        }

        else

        {

     if (
    get_magic_quotes_gpc())

     
    $field stripslashes($field);

     $field mysql_real_escape_string($field);

        }

        return 
    $field;

    }

    В запросах заключайте переменные в кавычки:


    $field 
    nosql($field);

    mysql_query(“UPDATE table SET field=’$field’”);




    Так вы избежите атак под названием mysql injections.

  23. Проверяйте все небезопасные переменные (из массивов $_GET,
    $_POST, $_COOKIE и т.д.). Например, для получения переменной
    $_GET[’var’] можно использовать следующую запись:


    $var 
    getvar(‘var’1);

    где первый параметр - ключ в массиве
    $_GET, а второй - значение по умолчанию (если такого ключа в
    массиве нет). Значение по умолчанию используется также для валидации
    получаемого значения. Например:


    $var 
    getvar(‘var’0); // $_GET[’var’] должен быть числом

    $var getvar(‘var’, array() ); // $_GET[’var’] должен быть массивом

    $var getvar(‘var’); // значение по умолчанию равно null, проверка типа также не нужна

  24. Все переменные, включаемые в атрибут value тегов input,
    option и т.п., пропускайте через функцию htmlspecialchars(). (В PHP
    версиях ниже 5.2.0. существовал баг переполнения буфера в функциях
    htmlspecialchars() и htmlentities().). Проверяйте отсутствие
    подстроки ‘</textarea>’ в переменных, включаемых в область
    textarea. Экранируйте кавычки в строковых переменных, которые включаете в строки javascript.

  25. Помните, что переменные в cookies можно подделать. Переменные
    сессии нельзя подделать, но id сессии хранится в cookies…

  26. В документации написано о $_SERVER[’HTTP_REFERER’]: “The
    address of the page
    (if any) which referred the
    user agent to the current page.
    This is set by the user
    agent
    . Not all user agents will set this, and some
    provide the ability to modify HTTP_REFERER as a feature.
    In
    short, it cannot really be trusted
    .
    Тем
    не менее, проверять источник получаемой формы (отправлена ли она со
    страницы вашего сайта) - нелишняя мера.

  27. Когда пользователь отправляет форму на сервер, ваш скрипт её
    обрабатывает и возвращает в броузер новую страницу. После этого
    пользователь может нажать кнопку “Refresh page”. Это
    приведет к повторной отправке и обработке той же формы! Возрастает
    нагрузка на сервер, и если форма заносится в базу данных или
    отправляется на e-mail, скоро база данных и почтовые ящики будут
    забиты дублями, которые кому-то придется удалять. Поэтому после
    обработки формы обязательно переадресовывайте пользователя на другую
    страницу:

    function Redirect($url ‘index.php)

    {

        
    Header(‘Location:’.$url);

        die;

    }

  28. Разделяйте логику и представление (паттерн
    Model-View-Controller). Обрабатывайте пользовательские формы до
    отправки html-кода броузеру. В противном случае HTTP-заголовок
    переадресации (см. предыдущий совет) не будет отправлен броузеру.

  29. Создайте класс-фасад для работы с базой данных. Так вы
    локализуете использование mysql-функций. Методы класса-фасада могут
    инкапсулировать рутинную проверку результатов запросов и выводить
    диагностические сообщения.

  30. Внутри класса-фасада (см. предыдущий совет) используйте
    mysql_fetch_row() для получения кортежа длины 1, иначе применяйте
    mysql_fetch_assoc() или mysql_fetch_object(). $result[’field_name’]
    - читабельно, а $result[5] - нет.

  31. Следите за тем, чтобы один и тот же javascript-сценарий не
    был случайно добавлен на страницу несколько раз. Это можно
    контролировать на уровне PHP-скриптов. Для этих целей я “запаковал”
    все javascript-функции в PHP-функции (далее - PHPJS-функции).
    В PHPJS-функции проверяется, вызывалась ли она прежде. Некоторые
    PHPJS-функции вызывают другие PHPJS-функции. Если 10 из них
    нуждаются в предварительном определении javascript-функции
    get_mouse_coord(), то я знаю, что эта функция будет добавлена на
    страницу лишь один раз.

  32. При добавлении на страницу flash-роликов используйте скрипт
    RunActiveContent.js от Adobe. Этот скрипт загружает ActiveX объект,
    необходимый для полной интеграции flash-ролика в броузере IE.

  33. При добавлении на страницу прозрачных изображений в формате
    png применяйте стиль
    filter:progid:DXImageTransform.Microsoft.AlphaImageLoader,
    необходимый для адекватного показа png-файлов в IE
    версии 6 и ниже.

  34. Таблицы, к которым часто осуществляются запросы
    на чтение и запись, объявляйте как InnoDB. Этот тип таблиц
    поддерживает построчную блокировку записей. В простых случаях выносите часто редактируемые
    поля в отдельные таблицы. Например, счетчик количества просмотров
    новости обновляется гораздо чаще самой новости. Отделив ведение
    статистики от таблицы новостей, вы увеличите производительность базы
    данных.

  35. Если запрос SELECT занимает много времени,
    воспользуйтесь командой EXPLAIN, чтобы узнать, каким образом mysql
    выполняет данный запрос. Проверьте, какие индексы используются и не
    следует ли их создать. Для оптимизации INSERT можно использовать
    INSERT DELAYED.

  36. Предпочитайте заключать строки в одинарные кавычки, так как в
    них распознается меньше управляющих символов, чем в двойных,
    следовательно, они эффективнее обрабатываются синтаксическим
    анализатором.

  37. Используйте регулярные выражения только при необходимости. В
    большинстве случаев можно обойтись простыми строковыми функциями
    (str_replace, strpos и т.д.).

  38. Вы можете уменьшить нагрузку на сервер, используя компиляцию
    скриптов в opcode или кеширование страниц. Кеширование - это
    компромисс между динамичностью сайта и его производительностью. И
    наоборот, вы можете уменьшить нагрузку на сеть, используя
    буферизацию вывода с помощью функции ob_start() и выдавая html-код
    броузеру большими кусками. Возвращаемый код также можно сжать с
    помощью ob_gzhandler(). При этом нагрузка на сеть уменьшается за счет использования большего
    количества памяти и увеличения времени ожидания.

  39. Чтение файла функцией file() гораздо быстрее, чем функцией
    fopen(). Однако при чтении больших файлов функция file() может
    заполнить всю память, отведенную на сервере для работы скрипта,
    поэтому чтение файла маленькими порциями через fopen() / fgets()
    надежнее. Это справедливо также при парсинге больших xml-файлов
    (функциями типа xml_parse_into_struct() ). Вы можете следить за количеством используемой памяти, применяя memory_get_usage() и ini_get(’memory_limit’).

  40. В PHP массивы копируются в функцию “by demand”.
    Это значит, что если вы передали в функцию массив из 1000
    элементов, а реально использовали только один элемент, то и
    скопирован будет только один элемент. Несмотря на это, возьмите за
    правило передавать массивы в функцию по ссылке. Если позже
    понадобится использовать все 1000 элементов, вы точно не забудете
    поменять способ передачи массива, и производительность функции не
    упадет. При передаче строк и базовых типов использование ссылок не
    дает никакого преимущества. Начиная с PHP 5, объекты передаются по
    ссылке автоматически, без требования явно указывать &.

C этой записью сегодня также читали: