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 »

Шаблонизаторы для PHP

Здесь я соберу известные мне шаблонизаторы для PHP. Они бывают двух типов: написанные на PHP и написанные на чём попало, но скомпиленные в виде модуля к самому PHP.  Теоретически, вторые должны быть в разы быстрее первых. Итак:

Модули PHP:

  1. CTPP. Если говорить коротко, то CTPP (CT++, Сити Плас Плас) - это инструмент, отделяющий процесс обработки данных (бизнес-логику) от их представления. Для проектов, в которых программист и HTML верстальщик - разные люди, CT++ - самый подходящий выбор.
    Библиотека CTPP действительно работает очень быстро, поскольку полностью написана на языке C++. В отличие от шаблонизаторов, разработанных на интерпретируемых языках, таких как PERL или PHP, CTPP не тратит время на интерпретацию исходного кода самой себя и не занимается подгрузкой среды исполнения.
    В тоже время, библиотека быстрее широкоизвестных проектов типа Xalan-C или libxslt потому, что не предоставляет излишнюю, зачастую ненужную, но снижающую производительность функциональность.
    Есть НЕПРОВЕРНЕННАЯ информация, что по “бенчмаркам” уступает всем из первого эшелона - blitz, php_templates, smarty, google ctemplate.
  2. Blitz. Blitz родился весьма неоригинально, for fun. Blitz поддерживает разделение и скрытие функционально различных частей шаблонов с помощью простого механизма: текст шаблона может содержать вызов методов объекта, который этим шаблоном управляет. Таким образом, достигается основная цель: шаблон не содержит большого количества блоков и контекстов, часто мешающих разобраться, что к чему. Напротив, даже в проекте со сложной логикой представления при правильном подходе шаблоны будут давать разработчику своеобразную «карту» всего проекта. Blitz также позволяет включать одни шаблоны в другие (аналог include) и поддерживает условный вывод переменных (аналог if).
    Начиная с версии 0.4 в Blitz добавлен функционал движка php_templates.
  3. php_templates.  В php_templates вы совершенно точно НЕ найдете какой-либо подвид скриптового языка в шаблоне. Как уже было сказано ранее, шаблоны предназначены для отделения кода от дизайна. Вот почему любой вид логики в шаблоне идет вразрез с идеологией шаблонов. Несмотря на это, почти в каждом сообществе веб-разработчиков продолжаются споры по вопросу использования программного кода в шаблонах. На самом деле, этот вопрос уже давно перерос в нечто религиозное. В конце концов, есть масса проектов со своим собственным скриптовым языком в шаблонах, на которые вы можете перейти. Однако, они не слишком-то и быстрые.

PHP-код:

  1. Smarty
  2. XTemplates
  3. Perl HTML::Template

 Немного бенчмарков:

  • С сайта автора Blitz

    lebowski-bench-small1.png

Стандарты кодирования для PHP

Ковыряясь в чужом коде, начинаешь понимать насколько всё-таки важны стандарты кодирования

Погуглив чуть-чуть на тему стандартов кодирования для PHP нашёл следующие источники:

стырено здесь

Популярные PHP frameworks

  1. Symfony
  2. CakePHP
  3. Solar 8
  4. Zend Framework
  5. phpOnRails
  6. CodeIgniter

Исходники Facebook просочились в Сеть

Вы давно хотели увидеть исходный код одного из самых успешных проектов Веб 2.0? Ну вот, сегодня как раз тот день, когда вы можете посмотреть на работу «лучших PHP-программистов мира».

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

Компания Facebook уже подтвердила утечку информации, так что это настоящий код, а не подделка.
 
Напомню так же, что ещё два хеджевых фонда из Нью-Йорка подключились к сделке Microsoft и Facebook. Они вложили в социальную сеть ещё $500 млн, то есть в два раза больше, чем Microsoft, и, что самое главное, инвестиции сделаны из расчёта той же самой рыночной оценки проекта в $15 млрд.

Дополнительные полмиллиарда инвестиций, которые сделаны без всяких дополнительных условий, доказывают, что реальная стоимость Facebook на сегодняшний день действительно составляет $15 млрд.

Read the rest of this entry »