Ускоряем вордпресс

Standard

Для блога сделал очередное улучшение: теперь fancybox файлы вставляются в html, в том случае, если в посте есть изображения.
Зачем ? Чтобы, блог быстрее работал у конечного пользователя — уменьшая количество загрузок (особенно скриптов) мы ускоряем наш сайт.
Внутри header.php в head тегах вставьте следующий код:

<head>
<? if(!is_front_page()):?>
#SOME CODE
<? endif;?>
</head>

Там где, #SOME CODE можно расположить все стили и скрипты к-ые нужны только в посте, к примеру код комментариев ВКонтакте, fancybox, подсветку синтаксиса и тд.
Вот весь код, к-ый вставляет скрипты или стили, если есть картинки:

<?
$content = $post->post_content;
$searchimages = '~]* />~';
preg_match_all( $searchimages, $content, $pics );
$imgs_num = count($pics[0]);
// Если у нас есть картинки - грузим fancybox
if($imgs_num > 0): ?>
<!-- ВСТАВЛЯЕМ СЮДА СВОИ ФАЙЛЫ -->
<? endif; ?>

Как бороться с segmentation fault в simple_html_dom

Standard

Иногда бывает что ваш скрипт выдает ошибку segmentation fault (ошибка сегментации) и завершает свою работу. Скорей всего ошибка в комбинации ваших расширений к пхп, попробуйте оставить только те расширения, к-ые необходимы для скрипта. Если все ок — найдите расширение, к-ое глючит и попробуйте обновить либо само расширение, либо библиотеку, к-ую оно использует.

Но к сожалению у меня эта ошибка возникала на нескольких компьютерах с разными версиями php и комбинацией расширений. Причина была в библиотеке для парсинга simple_html_dom, пробовал Nokogiri, Zend_Dom — все равно, лучше simple_html_dom ничего нету. При больших объемах обрабатываемого html кода, например внутри цикла, возникает segmentation fault. Возможное решение — разместите следующий код в конце итерации (если парсинг идет в цикле):

$simple_html_object->clear();
unset($simple_html_object);

Строка выше помогает бороться с потреблением памяти, но полностью ошибку segfault не решает. Причина кроется на 143 строке (в классе simple_html_dom_node):
// clean up memory due to php5 circular references memory leak...
function clear()
{
$this->dom = null;
$this->nodes = null;
$this->parent = null;
$this->children = null;
}

Данная функция вызывается деструктором simple_html_dom_node класса, и когда подходит его очередь для garbage collector`a происходит segfault (в некоторых случаях).
Есть открытый bug на sourceforge, люди советуют сделать так:
// clean up memory due to php5 circular references memory leak...
function clear()
{
unset($this->dom);
unset($this->nodes);
unset($this->parent);
unset($this->children);
}

Но мне и это не помогло, решил сделать быстро и тупо => закомментировать все строки внутри clear функции. В итоге потребление памяти увеличилось, к примеру раньше было стабильно 20 мегабайт, теперь — при парсинге около 1000 страниц потребление где-то 1 гагабайт, зато без segfault`а :)!

Вышел php 5.5 alpha 3

Standard

Раз уж я начал освещать каждый новый выход php 5.5, тогда продолжу.

Итак предыдущие обзоры:

В третей альфе, сделаны следующие изменения (нововведения):

  1. Добавлен метод Generator::throw()
  2. Новые cURL функции и опции, например: curl_escape(), curl_multi_setopt(), curl_multi_strerror(), curl_pause(), curl_reset()
  3. Поддержка атрибута Max-Age в setcookie функции
  4. Исправлено пару багов в mysqlnd и ядре

Весь список изменений здесь. Я очень часто использую curl, поэтому добавление новых функций в расширение только приветствую, жду не дождусь set, get операций над cookies.

Вышел php 5.5 alpha 2

Standard

Вышла 2 альфа версия PHP 5.5. Качаем с этой страницы.

Из нового:

  1. Функция empty() теперь поддерживает выражения и вызов функции как аргументы.
    До этого момента был возможен вызов empty($somevar), но нельзя было сделать empty(some_function())
  2. Оптимизирован доступ к временным и скомпилированным VM переменным. На 8% меньше обращений к памяти.
  3. MySQL расширение теперь бросает E_DEPRECATED ошибку, вместо него используйте MySQLi, PDO или Mysqlnd
  4. Оптимизация VM стека

Все это не может не радовать, пхп становится лаконичней и быстрее.

Вышел php 5.5 alpha 1

Standard

Вот это новость! Наконец-то, вышла php 5.5 alpha 1 (update: уже доступна php 5.5 alpha 3,), из нового:

Новый способ хеширования паролей

Обсуждение

Ссылка на документацию

Поддержка finally в try/catch блоках

Обсуждение
Для меня самое удивительное было узнать, что finally исполнится, даже если в catch блоке выполнится return (либо break, либо continue).

try {
return 2;
} finally {
echo "Это будет вызванно\n";
} //Эхо никогда не выполнится
echo "Вы меня не увидите";

Поддержка генераторов (привет python :))

Обсуждение

Разыменование в массивах / строках

Обсуждение

echo array(1, 2, 3)[0]; //выведет 1
echo "foobar"[2]; //выведет o
echo "foobar"["foo"][0] //выведет f
echo [1,3,4][2]; //выведет 4

Улучшения в intl расширении

Очень много нововведений, см. полный список

Новый способ хеширования паролей

Обсуждение новвоведения

Поддержка list() в foreach цикле

Обсуждение новвоведения.
Что можно будет делать:

$users = [ ['Павел', 'Дуров'], ['Андрей', 'Рогозов']];
// До новвоведения
foreach($users as $user){
list($firstName, $lastName) = $user;
echo "$firstName по фамилии $lastName участвовал в разработке ВКонтакте";
}
// После новвоведения
foreach($users as list($firstName, $lastName)){
echo "$firstName по фамилии $lastName участвовал в разработке ВКонтакте";
}

С помощью этой фичи избавляемся от лишних переменный — в примере выше — это $user. Не скажу, что это часто требуется, но на мой взгляд писать на пхп становится более лаконичней, хотя python синтаксис в этом плане намного ясней и понятнее.

Стоит ли делать flush в PHP

Standard

По мотивам этой статьи. В ней советуют использовать flush ф-цию из PHP чтобы отдать клиенту данные из output буффера, таким образом что клиент увидит страницу раньше, чем если бы мы flush не воспользовались. Но к этой технике есть пара замечаний:

  1. Время PHP скрипта между началом и концом выполнения мало по сравнению со временем передачи данных, это уменьшит время приблизительно на 0.5 секунд, в зависимости от кода. Убедитесь что это вам необходимо.
  2. Это техника не работает с gzip output buffering
  3. Если вы флашите очень часто вы будете отсылать почти пустые пакеты при флаше, что возможно вызовет увеличение времени загрузки (на медленных соединениях)
  4. После того как буфер сброшен, вы больше не сможете отослать доп. заголовки
  5. Ответ сервера будет в виде chunked encoding, что означает клиент не будет знать размер данных (из-за этого не отобразится «x% готово» при скачивании файла)

С другой стороны и у этой техники есть плюсы, если ваш скрипт долго работает — flush поможет клиенту увидеть данные как можно раньше.

Как ускорить IPBoard форум

Standard

Недавно чинил форум на движке IPBoard (версия не самая новая была), было необходимо ускорить сайт — он открывался секунд за 40, после моих стараний он открывается за 1 сек. Итак, как ускорить форум:

  1. Установить NGINX + всю статику отдавать от него. (У заказчика стояли хитрые правила в apache пришлось не статический трафик отправлять через него, как reverse proxy).
  2. Обновите PHP, MySQL если у вас не стоит свежая стабильная версия.
  3. Установите правильные настройки в MySQL (про это сделаю отдельную статью).
  4. Установите настройку «Обновление просмотров темы немедленно» (Update Topic Views Immediately) на нет (в админке -> настройки -> CPU)
  5. Можно сделать и такое с таблицой сессий (мне не помогло):   alter table ibf_sessions Engine = ‘heap’;
  6. Установите memcached, в файле conf_global.php установите следующие настройки:

    $INFO['use_memcache'] = 1;
    $INFO['memcache_server_1'] = "nameofserver";
    $INFO['memcache_port_1'] = "11211";

    На самом деле все вышеописанное придало не очень ощутимый прирост (порядка 1-5 сек.), пришлось использовать XHProf расширение для PHP чтобы профилировать код и выяснить, в чем же собственно проблема! Про XHProf сделаю отдельную статью.

Динамические свойства объекта в PHP и StdClass

Standard

PHP позволяет создавать необъявленные переменные на ходу:
$someClass->nonExistenVar = 'someValue';
в итоге создастся переменная класса nonExistenVar. Если логика класса не такая простая — можно использовать магические методы __get и __set, но они как правило медленнее раз в 30 обычного присваивания.

Разница между empty(), isset() и is_null() в PHP

Standard

Лично я путаюсь в ответе на вопрос «В чем между ними разница». Поэтому приклепляю табличку на память.
Примечания:

  • $undefined — необъявленная переменная
  • NULL — переменная объявленна, но ей не присвоено никакого значения (что она означает в пхп)
  • 0 — ноль
  • false — одноименная булевая переменная
  • 353 — любое цифровое значение (int, float)
  • «» — пустая строка
  • В столбце «Функция» == и === означают, что значение сравнивается с false те для столбца 353 выполняется следующая операция: false == 353
Функция $undefined NULL 0 false 353 «»
isset() false false true true true true
empty() true true true true false true
is_null() true true false false false false
== true true true true false true
=== false false false true false false

Лично мое мнение: в javascript с этим все логичней как-то, есть специальный тип undefined, есть тип null к-ые друг от друга все же отличаются. В php другая история, тут надо использовать isset чтобы проверить объявленна ли эта переменная в коде выше.

Вышел Netbeans 7.3 beta

Standard

Наконец-то, netbeans 7.3 вышел в свет (пока бета, но candidate release не за горами). Скачать можно отсюда.

Подробно о том, что в нем нового (php версия):

PHP:

  • Парсеры аннотаций для namespace`ов (Symfony 2, Doctrine 2, etc.)
  • Базовая интеграция с composer (менеджер зависимостей)
  • Twig дополнение кода (с документацией)
  • Ошибки smarty парсера при незакрытых тегах

HTML5:

  • HTML5 проект с поддержкой javascript
  • Значительно улучшен javascript редактор
  • page inspector и визуальный css редактор
  • javascript debuger
  • встроенный webkit браузер, глубокая интеграция с chrome

Я уже работаю с ним дня 2 и бросается в глаза: breadcrumbs из html тегов при редактировании страницы, кстати теперь работает и для кода (показывает какой класс, какой метод и тд.), слева появилась полурамка показывающая где начинается и заканчивается функция, к-ую ты редактируешь.