Analitycs

Показаны сообщения с ярлыком PHP. Показать все сообщения
Показаны сообщения с ярлыком PHP. Показать все сообщения

суббота, 6 апреля 2013 г.

Как добавить Product-Per-Page для WooCommerce?

Для создания виджета Product-Per-Page (выбор количества продуктов на странице) в WooCommerce нужно использовать вот такой сниппет

Добавлять в functions.php вашей темы

вторник, 20 ноября 2012 г.

nginx Connection reset by peer) while reading response header from upstream

Иногда некоторые скрипты, запущенные на PHP-FASTCGI или  PHP-FPM кидают в лог nginx странную ошибку

Connection reset by peer) while reading response header from upstream

Погуглив - нашел много танцев с конфигами nginx и бубнами, ни один из которых не помог, кроме одного... БЕЗУМНОГО совета, который как водится - сработал в моем случае ;-)

Вы не поверите... ;-)

/sbin/service php-fpm restart

Установка Wordfence Security на Wordpress - прошла успешно ;-)

суббота, 13 октября 2012 г.

Wordpress - Briefly unavailable for scheduled maintenance. Check back in a minute.

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

Briefly unavailable for scheduled maintenance. Check back in a minute.

То нужно пройти с ним в тихий уголок document_root и там ему надавать по сусалам удалить оставшийся файлик .maintenance - который и отвечает за обновление этого монстрика.

Взлетели. ;-)

понедельник, 1 октября 2012 г.

Как вывести массив из PHP в JSON без всяких UTF конвертаций?

Если нужно вывести кириллический массив в JSON для последующей обработки в Javascript, генерируя его посредством PHP, да еще и в Windows-1251 (без всяких UTF-8, encoding и прочего)  - да, да - "мсье знает толк в извращениях" (с) ;-) ,

то можно воспользоваться вот такой жуткой конструкцией.

function php2js($a=false)
{
  if (is_null($a)) return 'null';
  if ($a === false) return 'false';
  if ($a === true) return 'true';
  if (is_scalar($a))
  {
    if (is_float($a))
    {
      // Always use "." for floats.
      $a = str_replace(",", ".", strval($a));
    }

    // All scalars are converted to strings to avoid indeterminism.
    // PHP's "1" and 1 are equal for all PHP operators, but
    // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend,
    // we should get the same result in the JS frontend (string).
    // Character replacements for JSON.
    static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'),
    array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
    return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"';
  }
  $isList = true;
  for ($i = 0, reset($a); $i < count($a); $i++, next($a))
  {
    if (key($a) !== $i)
    {
      $isList = false;
      break;
    }
  }
  $result = array();
  if ($isList)
  {
    foreach ($a as $v) $result[] = php2js($v);
    return '[ ' . join(', ', $result) . ' ]';
  }
  else
  {
    foreach ($a as $k => $v) $result[] = php2js($k).': '.php2js($v);
    return '{ ' . join(', ', $result) . ' }';
  }
}

Страшно, да...  но работает ;-). "Костыли - это кошерно" (с)

Найдено в дебрях PHP.net

понедельник, 18 июня 2012 г.

Как скрыть версию nginx?

В конфиг nginx в раздел http добавляется строка

server_tokens off;

а в php.ini

expose_php = Off

воскресенье, 29 апреля 2012 г.

Востребованность Python Tornado/Twisted

Кстати - об асинхронных фреймворках и их востребованности.

Решил пробить количество вакансий на асинхронные фреймворки на Python - Twisted и Tornado.

Далее факты - и ничего кроме фактов.

Linkedin

  • python twisted - 10 вакансий против 1026 участников
  • python tornado - 14 вакансий  против 815 участников

HH

  • python tornado - 0
  • python twisted - 1 вакансия

Moikrug

  • python twisted - 2 вакансии
  • python tornado  - 1 вакансия

То есть в мире - на 1 открытую вакансию на асинхронный питон приходится 100 кандидатов для twsted и 59 - tornado.

Что интересней -  linkedin по запросу python django дает 208 вакансий 18469 участников - на 1 вакансию 71 потенциальный кандидат.

Что как-бы намекает...

Ну а php -  вообще полный ахтунг - 2060 вакансий и 634347 кандидатов -> 308 человек на одну позицию.

Кстати, хороший Python-dev с Торнадой/Twisted по прежнему - ищется.

среда, 25 апреля 2012 г.

MacOS X - использование mysql из Zend Server

Для использования MySQL клиента из Zend Server под MacOS вместо установленного из портов (зачем тащить еще один порт - если mysql уже есть в системе? ) нужно сделать следующее:

1) проверить есть ли /etc/zce.rc -

$ /usr/local/zend/mysql/bin/mysql
/etc/zce.rc doesn't exist!

2) создать/отредактировать его

ZCE_PREFIX=/usr/local/zend
if [ -z "$LIBPATH" ];then
   LIBPATH=/lib:/usr/lib:/usr/local/zend/lib
else
   LIBPATH=$LIBPATH:/usr/local/zend/lib
fi
export LIBPATH
APACHE_VER=2.2.11
WEB_USER=qtmhhttp
WEB_GROUP=nogroup
APACHE_PID_FILE=
PRODUCT_NAME=ZendServer
PRODUCT_VERSION=5.0.0
export INSTALLATION_UID=091708121207
DIST=pe
JB_EN=true
ZEND_TMPDIR=/tmp

3) Сделать симлинк на зендовский клиент

sudo ln -s /usr/local/zend/mysql/bin/mysql  /usr/bin/mysql

Теперь можно работать - ну или собираем из портов, либо ставим MAMP (не люблю).

суббота, 17 марта 2012 г.

MD5 проверка PHP, Python и MySQL

Несколько лет поймал одну особенность - md5 суммы посчитанные в PHP и MySQL отличались(!!!) - но хоть убей не помню на каких версиях.

Из-за этого, кстати были большие проблемы... Сейчас решил проверить на всякий случай - совпадают.

PHP

php -r "echo md5('domains.txt');"
aeae2f628c54f10054e5c70076e1237b

md5sum

# echo -n "domains.txt" | md5sum
aeae2f628c54f10054e5c70076e1237b 

Python

# echo "import md5;print md5.md5(\"domains.txt\").hexdigest()" | python
aeae2f628c54f10054e5c70076e1237b

MySQL

SELECT MD5('domains.txt');

aeae2f628c54f10054e5c70076e1237b

Уф, отпустило ;-) Приступ паранойи навеян вот этой заметкой.

вторник, 31 января 2012 г.

Python/PHP - запятая - казнить нельзя помиловать

Сегодня ловлю баг в сервисе - в JSON-результате вместо поля с integer  выдается список элементов-integer, то есть вместо

data : {
  'id' : 1
}

упорно получаю

data : {
  'id' : [1]
}

Перепроверяю код 20 раз - ничего не могу понять... вроде все правильно, должен быть идентификатор ОДИН, но хоть ты тресни - список. Подвисаю на несколько минут, иду попить кофе, снова смотрю в код...

Через несколько минут доходит - начинаю истерически хохотать

def bla-bla(self, args): 
    data = {
      'bla-bla' : bla_bla,
      'name' : name,
      'id' : temp_id,
    }
  return data


Правлю один символ - все работает. После хохота начинаю вспоминать хорошего PHP team-leader, с которым работал много-много лет назад.

Он был большим аккуратистом в плане чистоты форматирования кода и железнобетонно приучил меня расставлять меня запятые в ассоциативных массивах в КАЖДОМ элементе, включая последний.  Так как в случае необходимости быстро переставить элементы в коде - не пришлось бы искать потенциальную ошибку c пропущенной запятой.

А для Python - это собственно - сокращенный формат списка-последовательности.

Так что вот вам прекрасный пример того, что старые привычки часто вредят, а иногда - вредят ОЧЕНЬ сильно. "Казнить нельзя помиловать" (с)   ;-)

Ну и верный вариант - БЕЗ запятой ;-)

def bla-bla(self, args): 
    data = {
      'bla-bla' : bla_bla,
      'name' : name,
      'id' : temp_id
    }
  return data

понедельник, 30 января 2012 г.

Javascript+Flash мультизагрузчики картинок (SWFUpload, Uploadify) и Error #2038

Иногда мультизагрузчики изображений с использованием Flash (SWFUpload, Uploadify и т.д) дают ошибку #2038 при загрузке на случайных картинках без всяких видимых причин.

Как выяснилось - может быть целая куча разномастных серверных проблем - причем проблем преимущественно backend'овских.

TODO-list
  • обновляем Flash загрузчик до последней версии;
  • проверяем, что POST приходит на сервер в скрипт загрузки нормально - без всяких HTTP авторизаций, сессии нормально передаются, пользователь распознается залогиненным и т.д.;
  • и внимание - ЭПИЧНАЯ ОШИБКА: Размер разрешенных вложений должен быть <= размеру upload_max_filesize в php.ini;

И только потом лезем в настройки сервера - для nginx решение

Открываем nginx.conf и в http секцию добавляем директиву

client_max_body_size 500m;  

И удаляем из конфига директиву keepalive_timeout

Через некоторое время, когда у пользователей обновится кеш браузера - начинает все работать

пятница, 27 января 2012 г.

Python implode/join - TypeError: sequence item 0: expected string, int found

Одна из частых функций в PHP проектах - implode/explode.

На Python (по идее/по мануалу) это делается так

tmp = [1,2,3,4,5]
','.join( tmp )

Но в результате - получаем ошибку TypeError: sequence item 0: expected string, int found

Проблема - в том, что у нас числа, а не строки

 В итоге - нужно так

','.join( map( str, tmp ) )
'1,2,3,4,5'

Но вот пресловутое неявное приведение типов-то в PHP как помогает, а? ;-)

вторник, 17 января 2012 г.

Email от PHPBB падает в spam

Диагноз и причина

Оповещения от русской версии PHPBB падают в спам.

X-Amavis-Alert: BAD HEADER SECTION, Non-encoded 8-bit data (char D3 hex): 
   Subject: 323342345344356354353345355350345 356341 
   356[...] 
X-Spam-Flag: NO 
X-Spam-Score: 4.301 
X-Spam-Level: **** 
X-Spam-Status: No, score=4.301 tagged_above=-10 required=5 
   tests=[BAYES_50=0.8, RCVD_IN_DNSWL_NONE=-0.0001, 
   SUBJECT_NEEDS_ENCODING=0.049, SUBJ_ILLEGAL_CHARS=1.518, 
   TO_NO_BRKTS_MSFT=1.934] autolearn=no

subject уходит с сервера в iso-8859-1/quoted. В этой кодировке русских букв нет.

Subject: 
   =?iso-8859-1?Q?=D3=E2=E5=E4=EE=EC=EB=E5=ED=E8=E5_=EE=E1_=EE=F2=E2?= 
   =?iso-8859-1?Q?=E5=F2=E5_=E2_=F2=E5=EC=E5_-_=D7=F2=EE_=ED=E5_=ED=F0=E0=E2?= 
   =?iso-8859-1?Q?=E8=F2=F1=FF_=ED=E0_=F1=E0=E9=F2=E5?=

Хотя тело сообщения - нормально в Windows-1251

MIME-Version: 1.0
Content-type: text/plain; charset=windows-1251 
Content-transfer-encoding: 8bit 

Лечение


Нужно изменить кодировку Subject на необходимую с русскими буквами(win1251, utf8, koi8r).

файл

PHPBB_DIR/include/emailer.php

после строчки

$this->subject = (($this->subject != '') ? $this->subject : 'No Subject');

Добавляется

$this->subject = '=?'.trim($lang['ENCODING']).'?B?'.base64_encode($this->subject).'?=';

И после - вуаля

X-Spam-Flag: NO 
X-Spam-Score: 0.034 
X-Spam-Level: 
X-Spam-Status: No, score=0.034 tagged_above=-10 required=4 
   tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, 
   TO_NO_BRKTS_MSFT=1.934] autolearn=no

По материалам этой темы, спасибо коллеге BW4ever за баг-репорт

понедельник, 9 января 2012 г.

Как подключить Яндекс-Спеллер (Yandex-Speller) к PHPBB?

Есть у Яндекс одна хорошая штука, до которой у меня долго не доходили руки...  а именно - проверка орфографии в формочках ввода - Яндекс-Спеллер. Оказалось, что зря откладывал - не так сложно.

Как подключить к форуму PHPBB2 (как модуль на RunCMS)? По идее - в чистом PHPBB2/3 не должно сильно отличаться, разве что файлы  будут другие, скорей всего...

1) Разместить на сайте папку с самим спеллером в /class/xoopsform/yandex_speller/ Затем

2) файл include/viewtopic_quickreply.php
 
$addon_html = '
<script type="text/javascript" src="'.XOOPS_URL.'/class/xoopsform/yandex_speller/spell.js"></script>

// YandexSpeller 

var speller = 

new Speller({ url:"/class/xoopsform/yandex_speller", lang:"ru", options:Speller.IGNORE_URLS });
// Настройка параметров проверки http://api.yandex.ru/speller/doc/dg/reference/speller-js.xml  

<button name="cmdSpell_message" onclick="speller.check([document.getElementById(\'message\')])" type="button">'._CORE_CHECK_ORPHO.'</button>
';

$template->assign_vars(array(
  'U_POST_SQR_TOPIC' => 'javascript:sqr_show_hide();',
  'SQR_IMG' => $images['quickreply'],
  'L_POST_SQR_TOPIC' => $lang['Show_hide_quick_reply_form'],

  'L_EMPTY_MESSAGE' => $lang['Empty_message'],
  'L_QUICK_REPLY' => $lang['Quick_Reply'],
  'L_USERNAME' => $lang['Username'],
  'L_NO_TEXT_SELECTED' => $lang['Qreply_no_text_selected'],
  'L_SUBJECT' => $lang['Subject'],
  'L_MESSAGE_BODY' => $lang['Message_body'],
  'L_PREVIEW' => $lang['Preview'],
  'L_SUBMIT' => $lang['Submit'],
  'S_POST_ACTION' => append_sid("posting.php"),
  'S_HIDDEN_FORM_FIELDS' => $hidden_form_fields,
  'ADDON_HTML' => $addon_html,
  )
);

где _CORE_CHECK_ORPHO - наш новый языковой дефайн, 'ADDON_HTML' => $addon_html, - добавленная строчка в код и шаблон.

3) правим шаблон

Особо расписывать не вижу смысла - все просто как грабли.


Как подключить спеллер к формам - читать тут.
Полное API
Навеяно вот этим хаком

пятница, 6 января 2012 г.

Как оптимизировать RunCMS? или Оптимизация CMS для начинающих

Решил перевыложить свою старую статью - она местами уже потеряла актуальность, да и RunCMS практически уже умерла, к сожалению - оставив после себя несколько веток-форков -на одной из которых и работает ScaleModels.ru, но люди спрашивают. Увы - некоторые вещи, приведенные тут уже устарели за несколько лет, некоторые - спорны, но  пусть будет в этом блоге - до кучи. 

RunCMS - достаточно неплохая система, дружественная для новичка в Web, которая позволяет худо-бедно, но решить большинство типовых задач для небольшого сайта одним приемом - «из коробки». Однако сайты имеют свойство либо умирать, либо развиваться, и в случае когда ваш ресурс выходит из категории «homepage про меня и моего хомячка Вову» (c) - начинаются проблемы с производительностью. Ситуация осложняется тем, что большие и серьезные CMS (такие как Drupal или Joomla) давно прошли этот этап «детских болезней» и способы решения подобных проблем для них давно известны и доступны. К сожалению, крупных проектов на RunCMS встречается не много, и информации о ней очень мало. На правах бывшего coreteam разработчика RunCMS я хочу рассказать о способах увеличения ее производительности.

Данная статья не предназначена для полных новичков - подразумевается, что вы в состоянии отличить PHP от Perl, способны разбираться в чужом коде, и примерно представляете архитектуру RunCMS (или XOOPS-like систем). Желательно, чтобы вы знали что такое my.cnf и где его искать ;-)

Есть два варианта хостинга - обычный и VPS/VDS.

Обычный хостинг

В плане оптимизаций - это жопа (если вкратце). Особенно если у вас провайдер, который не хочет ставить дополнительный софт и его настраивать. Начиная этак от 500 уников в день - готовьтесь к прессингу с его стороны - «давайте-ка переедем на выделенный сервер» (с) Один мой прошлый хостер на просьбу установить поддержку mbstring на свой шаред-хостинг спросил - «А зачем он вам нужен?» Но в принципе, мигрировать на свой сервер - это логичный вариант.

Что можно сделать для оптимизации RunCMS непосредственно в ней самой на SHARED хостинге?

MySQL таблицы для сессий

Находим MySQL таблицу sessions и конвертируем ее в тип MEMORY (если стоит PHPBB - то такая судьба должна постигнуть и phpbb_session) Этим мы выиграем небольшое количество скорости - но на КАЖДОЙ страницы сайта. Единственный минус - после перезагрузки сервера всем пользователям прийдется перелогиниваться, но результат того стоит.

Кэш страниц для гостей-анонимусов

Включаем кэширование страниц для гостей на как можно большее время - однако учитывайте, что для этого нужно хотя бы 50-100 мб свободного места на диске?

Включаем кэширование MySQL средствами класса DB

class/database/mysql.php

<?php

    var $file_cache = true;

?>


Это то, что можно было сделать нормальными ШТАТНЫМИ способами RunCMS, а теперь начинаем экспериментировать

Файл-кэш SELECT запросов

Изучаем код сайта и модулей, добавляя для тяжелых запросов кэширование через метод

<?php

$db->query($sql, false, false, ‘имя_файла’,  время_кэширования)

?>


ставя подходящие значения. Учитывайте только то, что кэш отрабатает только в том случае если результат запроса будет прогнан через fetch_row или fetch_array , а вот fetch_object в текущей версии не кэшируется?

Скомпилированное ядро

Включаем экспериментальное компилированное ядро (класс RCCoreApi) файл class/core.php

<?php

var $compiling = true;

?>

Данное «ядро» была введено мной в версии 1.6.1 - оно позволяет сэкономить примерно 6 SQL запросов на каждой странице, но несколько повысит нагрузку на PHP.

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

Вообще если вы любознательны и способны экспериментировать и разбираться с чужим кодом - внимательно изучайте стандартные классы RunCMS 1.6.1 и 1.6.2.

Немного яда и кидания какашек

Несмотря на то, что netshark просто вышвырнул меня из разработки RunCMS и вычеркнул из списка живых team, а впоследствии - передал код в лапы Farsus, который ее успешно и угробил :-) - в коде осталось много экспериментальных неофициальных настроек для увеличения производительности сайта

Например -

Кэш деревьев

Установить в классе xoopstree.php

<?php

define('RC_TREE_CACHE', 1); 

?>

это сильно поможет при работе с большими деревьями категорий - в таких модулях, как news, например

Кэширование блоков

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

RCCache и RCCachedPage

Использование классов RCCache и RCCachedPage, написанных совместно с Shurik2k5. В репозитории RunLiveCMS можно найти версии этих классов не только для файлового кэша (как в RunCMS), так и в базу MySQL и Memcache - что предпочтительней, с (или без) serializing данных

Настройка выделенного сервера (VPS/VDS)

Если же вы понимаете, что сайт будет расти дальше - то предстоит часть вторая - настройка выделенного сервера.

Ниже только ОБЩИЕ рекомендации, куда стоит смотреть
  • Имеет смысл поставить PHP акселератор - на моем сервере стоит Zend Optimizer + eAccelerator. 
  • Тщательно настроить сервер MySQL - не забывайте про кэш запросов самого сервера и ограничение по времени медленных запросов
  • После настройки Apache - отключите access логи на картинках, оставив для них только error
  • Имеет смысл избавиться от .htaccess файлов, снеся все редиректы и настройки непосредственно в httpd.conf
  • Повесить на front-end (перед Apache) nginx и настройте его на отдачу статических файлов (таких как картинки, CSS, JS) - либо вообще отказаться в пользу Nginx + PHP-FASTCGI.
  • Используйте RAM-диск для критичных файловых кэшей - в моем случае туда сохраняется файловый кэш класса DB, compiled_kernel, блоки и кэши некоторых страниц
  • Обязательно используйте программы top, mtop и apachetop для мониторинга своей системы - ведь лучше вас ее не знает никто

По настройке выделенных серверов написано достаточно много, в частности тут - про Nginx, PHP, Memcache и тут про MySQL и насморки.


В моем случае - самый сильный выигрыш был от введения (по порядку важности)
  • Гостевое кэширование
  • Nginx
  • настройка MySQL
  • RAM диски на кэши кусков страниц, блоков и темплейтов форума /modules/forum(ну или phpBB2)/cache (всего около 200МБ RAM) - у меня форум, статьи и главная страница - основная нагрузка
  • eAccelerator
  • Таблицы сессии в MySQL MEMORY

Все остальное, честно говоря - из разряда "экономить на спичках" - не помешает, но без этого можно обойтись

Возможно, кому-то эти советы покажутся детским садом и «мурзилкой», но кому-то - сэкономят несколько минут «гугления» и чесания в затылке.

Изначально было опубликовано тут.

воскресенье, 25 декабря 2011 г.

Как оптимизировать сервер? - реальные данные - теория без практики мертва

Это судьба - вслед за вчерашней заметкой про оптимизацию выделенного сервера на сайте были опубликованы весьма интересные материалы, которые привели к росту просмотров страниц на 54 тысячи - это составляет рост примерно 140%.

Итак, график LI

Скачок достаточно большой, но давайте посмотрим, как машина, настроенная по описанным ранее методикам с этим справилась - на графиках Munin еще видны вчерашние значения, так что можно сравнить с ними (хотя бы на глаз).


Трафик, прокачанный через firewall - разумеется, вырос, причем - значительно



Процессы и потоки - увеличились



MySQL немного изменился в пределах погрешности; коннекты - не изменились.





Memcache немного подрос, но незначительно


А самое главное - ЦПУ и Load Average практически не изменились

Вывод

nginx с кешом HTML страниц сильно спасает от резких скачков нагрузки от незарегестрированных пользователей.

Рискну предположить, что создатели многих супер-пупер-мега-стартапов, постоянно падающих от пресловутого великого и ужасного Хабраэффекта, об этом не знают ;-)

З.Ы. Люблю, когда теоретические выкладки подтверждаются практическими данными.


суббота, 24 декабря 2011 г.

Как настроить сервер? или оптимизация сайтов на PHP (Nginx, PHP, MySQL, Memcache)

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

Если же вы еще и не профессиональный HighLoad Linux-админ, а, например, разработчик (как я), то в процессе настройки прийдется ловить много-много граблей...  ;-)

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

Ниже рассматривается достаточно часто встречаемая комбинация для сайтов: nginx + php (nginx+apache c php немного отличается - вместо fastcgi_xxx будет proxy_xxx).

Да, и считаем, что сейчас все компоненты вашей системы (nginx, php, mysql, memcache) крутятся на одной машине - как оно обычно и бывает на частных ресурсах.

PHP


  • Пускаем как fastcgi через сокет
  • Pconnect к базе - спорно
  • Не забываем акселератор (моя юзает eAccelerator) - хотя тоже есть спорные моменты

eAccelerator


Только для production машин можно отключить проверку Modified time - это абсолютно не подходит, если на сервере идет отладка скриптов - иначе будете ловить постоянные глюки и проблемы - включать только после того как сайт стал стабилен.

eaccelerator.enable="1"
eaccelerator.optimizer="1"
eaccelerator.check_mtime="0"
eaccelerator.shm_only="1"

Временые диски

tmpfs для /tmp и сессий PHP - все это сносится в память, если ее достаточно. В /etc/fstab добавляем

tmpfs                   /tmp                    tmpfs   defaults        0 0
tmpfs /var/lib/php tmpfs size=200M,nr_inodes=1m,nosuid 0 0

MySQL

  • Проверяем, включен ли query кэш
  • Также используем сокет
  • Если в вашей CMS используется таблица сессий - ставим для них тип MEMORY (если нет текстовых полей) - это приведет к сбросу всех залогиненных пользователей при перезагрузке сервера, но добавит немного скорости. Ну или если это неприемлемо - то надеюсь, она уже переведена в InnoDB? ;-)
  • Определяем оптимальное количество коннектов - статистика хотя бы за месяц (я юзаю munin). Ставим в 1.5-2 раза больше среднего.
Более подробно про оптимизацию MySQL можно прочитать тут.

Memcache

Если вся солянка крутится на одной машине - то также используем коннект через сокеты (по умолчанию не используется - стоит ip адрес). В таком варианте работы memcache возможны проблемы с некоторыми средствами мониторинга memcache (которые работают также по IP).

Не забываем в PHP использовать сжатие при работе с MEMCACHE.

Nginx

Ограничиваем число коннектов и запросов, особенно на ресурсоемкие скрипты
http {
...
    limit_req_zone $binary_remote_addr zone=one:10m rate=5r/s;
    limit_zone three $binary_remote_addr 10m;

Включаем кэширование для неавторизованных гостей

http {
...
fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=wholepage:50m inactive=15d max_size=5000m;
        location ~ .*\.php$ {
            limit_conn three 20;
            include         /etc/nginx/fastcgi.conf;
            fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass    unix:/var/run/php-fastcgi/php.socket;
            #access_log  /var/log/nginx/domain.access.log  my_combined;
            fastcgi_cache wholepage_guest;
            fastcgi_cache_valid 301 302 304 10m;
            fastcgi_cache_valid 200 360m;
            fastcgi_cache_valid 404 5s;
            fastcgi_cache_key "$request_method|$host|$request_uri";
            fastcgi_pass_header "Set-Cookie";
            fastcgi_ignore_headers "Cache-Control" "Expires";
            fastcgi_cache_bypass $cookie_phpbb_session $arg_nocache $arg_PHPSESSID;
            fastcgi_no_cache $cookie_phpbb_session $arg_nocache $arg_PHPSESSID;
    }
Где phpbb_session - имя куки по которой идет авторизация

Все запросы с ?nocache=1 и PHPSESSID попадают на PHP-бэкенд сразу без кэша не забываем открыть скрипт, по которому идет авторизация (в том числе и всякие капчи - их можно переписать на ?nocache=1) - тут возможно прийдется немного поковыряться и в коде CMS тоже.

        location /register.php {
                limit_conn three 20;
                include         /etc/nginx/fastcgi.conf;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_pass    unix:/var/run/php-fastcgi/php.socket;
        }

Nginx - общие рекомендации

Очень нежелательно использовать location с регекспами - только простые префиксы вида
location /mymodule {}
Если от регекспов никак не избавится - то лучше их обрамлять простым location (Причина - сложноуловимые перехлесты в логике парсинга URL - кто за кем будет следовать)
location /mymodule {
  location ~ \/mymodule\/(.*)\.php$ {
    чего-то
  }

}

Отрубаем access лог для картинок

Разумеется - это только основные моменты оптимизации, на самом деле их гораздо больше. А какие трюки для уменьшения нагрузки на сервер знаете вы? Пишите в комментах.

суббота, 3 декабря 2011 г.

Как сделать sharding картинок в PHP между несколькими серверами?

Сегодня небольшой хак - боюсь, что скоро их будет тут больше, чем методически грамотных решений. ;-(

Когда вам нужно разшардить картинки/статические ресурсы по разным поддоменам для ускорения загрузки - можно использовать очень-очень грязный хак.

Дано

4 поддомена:
  • http://st1.xxx.ru
  • http://st2.xxx.ru
  • http://st3.xxx.ru
  • http://s4.xxx.ru
По ним и нужно раскидывать превьюшки - особенно это актуально, когда их много на страницах.

Функция получения url для превьюшки картинки после небольшой доработки выглядит так

 public function thumb_url($file = false) {
  $path = $this->path_by_file($file);
  $url = CMS_URL.'/'.$path.'/thumbs/'.$file;
  
  $key = md5($url) & 3;
  
  $static_url = 'http://st'.($key+1).'.xxx.ru/'.$path.'/thumbs/'.$file;
  
  return $static_url;
 }

Чем плох этот вариант?

В случае если добавится еще сервер, то из-за изменения функции распределения - пропадут все кеши у пользователей - и все картинки будет грузиться заново. Неприятно, но несмертельно.

А вот если так делать под большой нагрузкой для ключей сложных данных (которые рассчитываются сложно) - будет совсем плохо-плохо - полный пересчет кеша.

Короче - не делайте так.

А как правильно?

А как в том случае сделать подобное распределение методически грамотно  - это тема для отдельного поста. Может  быть и напишу, но позже.

вторник, 29 ноября 2011 г.

Как включить показ ошибок PHP в браузере?

Классический вопрос всех похапешников - "как показать ошибки PHP скрипта в окне браузера"

error_reporting(E_ALL);
ini_set("display_errors", 1);

P.S. Причем сам постоянно забываю, как точно пишется эта конструкция - особенно после переключения с языка на язык. Ненавижу переключать контекст мозга ;-)

среда, 23 ноября 2011 г.

PHP - хак быстрого логгирования в файл


Если вам в зубы выдали какой-то очередной супер-мега-пупер проект на PHP, в дебрях которого нет возможности и желания разбираться, однако нужно что-то быстро пофиксить с отладкой, (причем доступа к php error_log нету) - то можно быстро воткнуть небольшой полезный хак.

Это дополнительный метод в класс (или просто - функция) с минимальным количеством кода.

   function log($msg) {
       file_put_contents(SUPER_CMS_ROOT_PATH.'/cache/php-debug.log',"\n".$msg, FILE_APPEND);
   }

Соотвественно, после отладки ее можно либо убить, либо оставить, закомментировав содержимое.

P.S. И да -про некошерность данного метода и недопустимости этого при учете всех методик программирования - я в курсе, не нужно возбуждаться. ;-)
Просто нужно пофиксить и отладить - БЫСТРО.

среда, 9 ноября 2011 г.

PHP header("HTTP/1.0 404 Not Found") показывает пустую страницу

При отправке из PHP скрипта HTTP ошибки 404 - показывается белая страница, хотя в настройках вашего веб сервера явно задана собственная красивая страничка для этой ошибки.

Как лечить?

Просто считать содержимое файла с красивой 404 ошибкой и вывести его HTML в поток - примерно так
if ($is404) {
 $html = file_get_contents(YOUR_ROOT_PATH.'/404.htm');
 header("HTTP/1.0 404 Not Found");
 echo $html;
 exit();
}

В этом гаджете обнаружена ошибка