Really Useful Classes And Libraries For PHP Developers

Today millions of websites and servers across the Internet are powered by PHP. Originally created by Rasmus Lerdorf in 1995 so that anyone can easily create a Personal Home Page; PHP has come a long way and is now widely used as general purpose scripting language that is suitable for majority of web development projects.

Numerous PHP Frameworks have evolved to enable rapid web development with PHP. However even greater number of standalone PHP libraries and classes are available which provide similar benefits. W3Avenue has compiled a list of some really useful classes and libraries that every PHP developers should be familiar with. Whether you like to use a PHP Framework or prefer to work without one, your productivity can multiply with the help of these libraries and classes.

Read the rest of this entry »

Really Useful Tools For PHP Developers

Whether you are a PHP novice or an experienced developer; tools that you use have direct impact on your productivity. W3Avenue has compiled a list of really useful extensions & tools for PHP developers that will help you speed up development and significantly improve overall quality of your code.

Read the rest of this entry »

Zend Studio 7: how to automatically save before run script

Everytime I run a script, the dialog box ask for saving appear. How can I configure Zend Studio(v 7.0) automatically save before running?

Open Window -> Preferences
Open Run/Debug -> Launching
Find the option “Save required dirty editors before launching” (top of screen) and set it to “Always” instead of “Prompt”.

Конвертация php-скриптов в статику

Предположим, у Вас есть сайт, созданный при помощи php-скриптов и базы данных MySQL. В определенное время сервер перестает нормально работать, так как перегружен посетителями – слишком много запросов.
Как быть? Искусственно ограничить запросы – это значит отбросить посетителей. Наращивать мощности сервера накладно. Оптимизировать скрипты нет времени.
Именно в таком случае поможет тотальная конвертация всего сайта в статический HTML код и отдача его при помощи nginx.

Прежде всего необходимо определить дискретность, с которой происходит обновление информации (допустим, раз в час) и выполнять зеркалирование сайта при помощи команды wget:

wget -m -q -k http://мой.домен/

После этого полученное зеркало синхронизируем с директорией, откуда файлы обрабатывает nginx (предположим, что это /usr/local/html):

rsync -tgu –delete –force мой.домен /usr/local/html

После чего осталось синхронизировать те файлы, которые wget не отзеркалит, например, *.js – java скрипты:

rsync -a –include ‘*/’ –include ‘*.js’ –exclude ‘*’ /путь/к/файлам/сайта/ /usr/local/html/

Это все. Теперь осталось запускать этот код каждый час (или реже) и всю нагрузку возьмет на себя nginx.
Для того, чтобы сохранить доступ к админке CMS, необходимо повесить какой-то поддомен сайта на реальный IP и обращаться к нему.

Pinba – демон для сбора статистики о PHP-скриптах

Документация, исходники и всё остальное доступно на pinba.org.

Кратко о том, что это и для чего это:
Это демон для сбора статистики о выполнении PHP-скриптов. Статистика есть двух видов – общая (скрипт, время, rusage, объем вывода и др.) и данные по таймерам. Таймеры тут один из ключевых моментов, поэтому они достойны отдельного упоминания, см. ниже.
В то же время, это не standalone-демон, данные собираются отдельным тредом в MySQL. При этом функционал MySQL используется для доступа к данным (которые видны пользователю как обычные таблицы, только read only), т.е. для выборок можно использовать обычный SQL.
Статистика не хранится вечно, это просто невозможно, хранится только актуальная статистика (это понятие для всех разное и конечно это настраивается), так что возьмем для примера 1 000 000 последних запросов или 15 минут – т.е. хранятся все запросы за последние 15 минут, но не более миллиона записей. В зависимости от количества таймеров, эти данные могут занимать от 500Mb до нескольких Gb памяти. На диск, конечно, ничего не пишется.

Подробнее о таймерах:
Таймеры нужны для замеров конкретных частей кода. У таймеров есть “таги” для описания и группировки.
Например, есть у вас коннект к базам – оборачиваете его в таймер с тагами “operation”=>”connect”, “db”=>$dbase. В результате мы получаем статистику по одному тагу – “сколько раз в секунду у нас выполняется операция connect и сколько времени она занимает” и по двум – “сколько раз в секунду у нас выполняется операция connect к конкретному серверу и сколько она занимает”.
Тагов и таймеров может быть произвольное количество (но про разум не стоит забывать тоже, всё это доп. нагрузка на сервер).

Несколько примеров использования от Фишера: http://pinba.org/wiki/Manual:Usage_examples
Вся документация: http://pinba.org/wiki/Manual

Если вам интересно и/или есть вопросы/предложения – welcome.

Валидация данных в PHP при помощи filter_var

Основой безопасности любого приложения является простое правило: «пришедшим от пользователя данным доверять нельзя». Для этой цели пишется довольно большое количество кода, хотя типичные задачи можно решить стандартными средствами PHP ничего не изобретая.

Например, таким образом можно проверить адрес e-mail при помощи filter_var:

if (filter_var($user_email, FILTER_VALIDATE_EMAIL)) {
// правильный
}

также можно убрать лишнее, например, из URL:

$sanitized_url = filter_var($url, FILTER_SANITIZE_URL);

Хотя filter_var() есть в стандартном PHP начиная с версии 5.2.0, документация на него, особенно русская, хромает.

Нормальная документация и примеры:
Руководство w3schools.
Input Validation: Using filter_var() Over Regular Expressions.
Data Filtering Using PHP’s Filter Functions

CodeIgniter vs. CakePHP

Ниже находится перевод статьи Джонатана Снука (Jonathan Snook) о преимуществах и недостатках двух популярный PHP фреймворков CakePHP и CodeIgniter.

Прежде чем публиковать такого рода публикации, я обычно опасаюсь за всякого рода фанатиков, которые неадекватно реагируют на подобные сравнения. Поэтому стараюсь максимально объективно подойти к повествованию. Все выводы в статье сделаны только на основании фактов.

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

Зачем сравнивать?

CakePHP и CodeIgniter во многом очень похожи между собой, включая то, что оба поддерживают PHP4. Говоря о преимуществах одной платформы, мы тут же можем сослаться на сильные стороны другой.

Они обе дают возможность работать в парадигме MVC архитектуры, что просто означает их способность разделять Модель (данные), Контроллер (который направляет данные из модели, чтобы получить представление) и Вид (то, что видит пользователь).

Они обе используют роутинг, который дает возможность привязывать URL к определенной функции внутри контроллера (в CakePHP это называется actions). CodeIgniter поддерживает регулярные выражения для роутинга, в то время как нужно дожидаться релиза CakePHP версии 1.2 для поддержки этой функции. Поправка: CakePHP 1.1 уже поддерживает регулярные выражения для роутинга, но это не отражено в документации.

Они обе поддерживают scaffolding, который помогает автоматически сгенерировать Вид на основании Модели. В CodeIgniter scaffolding упрощен и позволяет получить доступ к подобному функционалу путем добавления ключевого слова в URL. Считаю это недостатком, т.к. часто разрабатываю персональные проекты не для публичного использования, и это ключевое слово надоедает.

Приступим…

Read the rest of this entry »

Tricky Tricky Refcounts…

Occasionally a PHP engineer reports this prolem:

Example Code:

$my_arr = array(1,2,3);
foreach ($my_arr as &$val) {
    var_dump($val);
}
foreach ($my_arr as $val) {
    var_dump($val);
}

Expected Output:

int(1)
int(2)
int(3)
int(1)
int(2)
int(3)

Actual Output:

int(1)
int(2)
int(3)
int(1)
int(2)
int(2)

The confusion comes from the expectation that the second loop will print the last element of the array as int(3) rather than int(2).  The initial reaction is usally “this is a PHP bug”, but it really isn’t.  There are two key aspects to this code to watch out for; 1) The scope of foreach variables is not limited to the foreach block. 2) Foreach loops do not unset foreach variables at the start of the block.

With this in mind we can see that at the end of the first loop, $val is a reference to the last element of $my_arr.  Each iteration over the foreach loop can be thought of as an assignment operation, in this case by reference:

$val = &$my_arr[0]
$val = &$my_arr[1]
$val = &$my_arr[2]
// last iteration $val is a reference to $my_arr[2]

As we step through each iteration of the second foreach loop we see the assignments of $val to each element of the $my_arr (assigned by value this time).

$val = $my_arr[0]
$val = $my_arr[1]
$val = $my_arr[2]

But if we you recall $val is really a reference to the last element of $my_arr because it carries over from the first foreach loop, so the actual assignment looks more like:

$my_arr[2] = $my_arr[0]
$my_arr[2] = $my_arr[1]
$my_arr[2] = $my_arr[2]

Thus we end up with $my_array being set as such on each iteration:

// (array(1,2,1))  first element is set to value of last
$my_arr[2] = $my_arr[0]

// (array(1,2,2))  second element is set to value of last
$my_arr[2] = $my_arr[1]

// (array(1,2,2))  last element is set to value of itself
$my_arr[2] = $my_arr[2]

Note that the last assignment is really assigning the last element to itself!

Because PHP5 handles variables with a copy on write algorithm, it’s typically not necessary to do any assignmnents by reference with performance gains in mind (as was the case with a lot of PHP4 code).  The above code can be made to function as the expected case by placing an unset($var) between the foreach loops, or not iterating over references and instead assigning the values of $my_arr explicitly by index or key values.  References should be used by care  and only when necessary.  When code like this is present in global scope or large functions it may affect future code in seemingly unpredictable ways.

О вечном: деревья… (db_tree)

Ссылки:

http://forum.dklab.ru/sql/php/IerarhicheskieStrukturiVBd.html
http://www.livejournal.com/users/demiurg/53125.html
http://e-taller.net/dev/dbtree/
http://sdm.viptop.ru/articles/sqltrees.html
http://www.webscript.ru/stories/04/09/01/8197045
http://www.webscript.ru/stories/05/01/24/6319028
http://phpclub.ru/talk/showthread.php?threadid=70821
http://phpclub.ru/faq/wakka.php?wakka=chpu&v=gls
http://phpclub.ru/faq/wakka.php?wakka=Tree&v=uof
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

Кропотливая оптимизация PHP-приложений (рассматриваю PHP5, но большинство справедливо и для 4-й ветки)

Не то чтобы “очень классная статья”, но начинающим будет полезна (взято здесь http://www.habrahabr.ru/blog/webdev/19129.html)

Когда во сне снится “ой а если сервера не хватит…”

Для начала, Доброй Ночи. Пишу что-то полезное вроде впервые (если не считать разного рода полу-тестов в моём блоге). Человек я допытливый до жути, неожиданно в голову пришло, что могу помочь сэкономить кому-то много времени ;) .

В общем когда на PHP создаются достаточно большие проекты (>100000 строк кода) желание сделать “правильно” то, что было сделано давно грозит повергнуть всё в хаос. По крайней мере для новых программистов, которые могут прийти в компанию через неделю, месяц, год… Решение – четкая систематизация с самого начала и установление жестких архитектурных правил. Для себя я решил – не используя фреймворки писать буду только “Hello World”-сайты. Не мудрствуя лукаво когда подумал о фреймворках полистал, почитал, но решил отдаться-таки зенду с его ZendFramework. Добротный он, хотя и изменений я в нём для себя сделал огромное количество.

В таком решении на ряду со всеми возможными плюсами и удобством неожиданно встаёт вопрос-стена: теперь у меня бизнес логика занимает, наверное, где-то вовсе 1-2% от времени исполнения всей программы. Плата за удобство и ООП (или “удобство ООП”? Наверное даже просто “удобство” или просто “ООП” – это почти одно и то же ;) ) – огромное количество сопутствующего и управляющего кода.
Read the rest of this entry »