<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Антон Шевчук</title>
	
	<link>http://anton.shevchuk.name</link>
	<description>Web-разработчик</description>
	<lastBuildDate>Wed, 01 Feb 2012 12:54:21 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AntonShevchuk" /><feedburner:info uri="antonshevchuk" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Technology/Tech News</media:category><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FAntonShevchuk" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAntonShevchuk" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAntonShevchuk" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FAntonShevchuk" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><item>
		<title>Определяем количество онлайн пользователей из Google Analytics</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/ljshCEb9Rr0/</link>
		<comments>http://anton.shevchuk.name/google/check-online-users-from-google-analytics/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 12:54:21 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=2029</guid>
		<description><![CDATA[Очень часто при обсуждении нагрузки на сайт упоминаются мистические &#171;онлайн-пользователи&#187;, кто это и как их считать? Я не буду вдаваться в детали, особенно коли в оных не силен, но термин &#171;онлайн-пользователи&#187; зачастую используют для измерения производительности системы которая, по идее, должна что-то говорить заказчику о потенциальных возможностях расширения системы. Для начала, стоит определиться со средним [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2010/02/tips_and_tricks.png" alt="" title="Заметки на полях" width="200" height="200" class="aligncenter size-full wp-image-1164" /></p>
<p>Очень часто при обсуждении нагрузки на сайт упоминаются мистические &laquo;онлайн-пользователи&raquo;, кто это и как их считать?</p>
<p><span id="more-2029"></span></p>
<p>Я не буду вдаваться в детали, особенно коли в оных не силен, но термин &laquo;онлайн-пользователи&raquo; зачастую используют для измерения производительности системы которая, по идее, должна что-то говорить заказчику о потенциальных возможностях расширения системы. Для начала, стоит определиться со средним пользователем системы, для этого нам потребуется залезть в Google Analytics и взять пару параметров:</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2012/02/average-user.png" alt="" title="Средне статистический" width="578" height="321" class="aligncenter size-full wp-image-2031" /></p>
<p>Таким образом, среднестатистический посетитель моего блога просматривает две страницы за две минуты, т.е. 1 обращение в минуту эмитирует одного пользователя. Идём дальше &mdash; очередь за контентом. Выбираем самый популярный &mdash; &laquo;Content&raquo; &rarr; &laquo;Site Content&raquo; &rarr; &laquo;Pages&raquo; &mdash; и чем больше охват тем лучше:</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2012/02/top-10-content.png" alt="" title="Top 10 Pages" width="559" height="453" class="aligncenter size-full wp-image-2035" /></p>
<p>Таким образом 10 страниц охватывает 60% посещений, лучше этот показатель довести до разумного максимума используя минимумом страниц &mdash; это будет наш список подопытных.</p>
<p>Ну на этом всё &mdash; мы теперь готовы настроить тестовое окружения для получения правдивых цифр, но что у нас сейчас?</p>
<p>Определить текущую нагрузку на сайт в данной единице измерения можно используя пункт &laquo;Audience&raquo; &rarr; &laquo;Overview&raquo; (кликаем и смотрим):</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2012/02/visitors-per-hour.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2012/02/visitors-per-hour-460x153.png" alt="" title="Visitors per hour" width="460" height="153" class="aligncenter size-medium wp-image-2037" /></a></p>
<p>Таким образом &laquo;онлайн&raquo; у меня составляет:</p>
<pre class="brush: xml; title: ; notranslate">
    пользователей в час              ~200
  -------------------------     =  ---------  =   6,66
 60 минут / время пребывания        60 / ~2
</pre>
<p>Предположим, что проведя нагрузочное тестирование, и получив точку отказа в 100 пользователей я могу сказать, что мой сервер выдержит нагрузку в 15 раз большую нынешней, вот только осталось собрать аудиторию в 45 000 :)</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li>No Related Post</li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=ljshCEb9Rr0:qyAnTYJKgJI:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=ljshCEb9Rr0:qyAnTYJKgJI:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=ljshCEb9Rr0:qyAnTYJKgJI:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/ljshCEb9Rr0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/google/check-online-users-from-google-analytics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/google/check-online-users-from-google-analytics/</feedburner:origLink></item>
		<item>
		<title>Поговорим о PHP</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/B_3bafhc4aM/</link>
		<comments>http://anton.shevchuk.name/php/about-php/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 10:59:50 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1987</guid>
		<description><![CDATA[Хотел было назвать статью &#171;профессиональное PHP программирование&#187;, но по факту &#8212; это лишь &#171;заметки бывалого&#187;, которые будут полезны начинающим разработчикам, хотя, возможно, привлеку внимание и &#171;старшего&#187; поколения ;) Инструментарий Хороший мастер работает лишь со своим инструментом, и сильно расстраивается когда оного нет под рукой, так и я &#8212; всё своё ношу с собой: IDE &#8212; [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/tools.jpg" alt="" title="tools" width="420" height="351" class="aligncenter size-full wp-image-2006" /><br />
Хотел было назвать статью &laquo;профессиональное PHP программирование&raquo;, но по факту &mdash; это лишь &laquo;заметки бывалого&raquo;, которые будут полезны начинающим разработчикам, хотя, возможно, привлеку внимание и &laquo;старшего&raquo; поколения ;)<br />
<span id="more-1987"></span></p>
<h2>Инструментарий</h2>
<p>Хороший мастер работает лишь со своим инструментом, и сильно расстраивается когда оного нет под рукой, так и я &mdash; всё своё ношу с собой:</p>
<ul>
<li>IDE &mdash; PHP Storm</li>
<li>Менеджер БД &mdash; SQLYog</li>
<li>Всяко-разно &mdash; notepad++, putty, winscp&#8230;</li>
</ul>
<h3>PHP Storm</h3>
<p>IDE решает многие задачи и проблемы, которые постоянно возникают перед разработчиком. Мой выбор остановился на <a href="http://www.jetbrains.com/phpstorm/">PHP Storm</a>, а до того я успел попробовать Zend Studio, Eclipse, Aptana, NetBeans и еще несколько о которых и не вспомню. Что же хорошего в данной IDE:</p>
<ul>
<li>java &mdash; т.е. нам практически любая платформа по плечу</li>
<li>автодополнение &mdash; очень адекватное, и приучает к документированию кода</li>
<li>автосохранение &mdash; забудьте про ctrl+s</li>
<li>автозаливка (FTP/SFTP)</li>
<li>автозаливка после комита</li>
<li>исправление ошибок</li>
<li>поддержка VCS</li>
<li>рефакторинг</li>
<li>поиск и замена по файлам &#8211; работает просто отлично, и частенько меня выручала</li>
<li>отличная поддержка HTML/CSS/JS</li>
<li><a href="http://code.google.com/p/zen-coding/">Zen coding</a> из коробки (советую таки узнать что это ;)</li>
</ul>
<p>Но без недостатков не бывает:</p>
<ul>
<li>java &mdash; т.е. любит память, и IDE приходится время от времени перезапускать &mdash; где-то раз в неделю</li>
<li>цена &mdash; сейчас, со скидкой, это <a href="http://www.jetbrains.com/phpstorm/buy/">$50 (до 27-го ноября)</a></li>
</ul>
<p>Отдельно оговорюсь насчет цены &mdash; у меня купленная версия, но так же есть Open Source лицензия, ее тоже можно получить, но только надо запастись терпением (как можно догадаться &mdash; у меня терпения не хватило). Насчет же NetBeans &mdash; задолбал он своей нестабильной работой и такими же обновлениями.</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/phpstorm.jpg" alt="" title="phpstorm" width="400" height="300" class="aligncenter size-full wp-image-2000" /></p>
<p>В качестве заключения: мои слова ничего не значат, верьте своим глазам &mdash; попробуйте триал, благо целого месяца хватит на распробовать ;)</p>
<p>Кстати, если кому нравится <a href="http://dl.dropbox.com/u/27453635/PHPStorm/screen-php.png">моя</a> <a href="http://dl.dropbox.com/u/27453635/PHPStorm/screen-js.png">тёмная</a> <a href="http://dl.dropbox.com/u/27453635/PHPStorm/screen-php.png">схема</a> для PHP Storm, то её можно забрать с <a href="http://dl.dropbox.com/u/27453635/PHPStorm/config.zip">dropbox&#8217;a</a></p>
<h2>SQLYog</h2>
<p>Для работы с MySQL использую <a href="http://www.webyog.com/en/downloads.php">SQLYog</a>, что же в нём такого хорошего:</p>
<ul>
<li>автодополнение</li>
<li>профайлер</li>
<li>автоформатирование запросов</li>
<li>синхронизация структуры БД и данных при необходимости</li>
<li>SSH туннель &mdash; если у вас есть SSH, то SQLYog в игре</li>
<li>HTTP туннель &mdash; хотя хватит доступа и к FTP</li>
<li>отлично работает под wine (по правде говоря есть огрехи, но совсем мелкие)</li>
</ul>
<p>Ну не без ложки дёгтя:</p>
<ul>
<li>цена &mdash; от <a href="http://www.webyog.com/en/buy.php">$69</a>, но есть триальная и урезанная фришная версия</li>
</ul>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/sqlyog.png" alt="" title="sqlyog" width="113" height="90" class="alignleft size-full wp-image-2001" /></p>
<p>Опять же, есть триал &mdash; пробуйте, и забудьте про phpMyAdmin как про страшный сон.</p>
<h2>Ещё чуть-чуть</h2>
<p>Ой, ну дальше дело вкуса:</p>
<ul>
<li><a href="http://notepad-plus-plus.org/">Notepad++</a> &mdash; всегда на подхвате, открывает большие файлы, понимает все кодировки, с плагином hex-редактор</li>
<li><a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTY</a> &mdash; без него никак, (<a href="http://the.earth.li/~sgtatham/putty/0.60/htmldoc/Chapter8.html#pubkey-puttygen">puttygen</a> рулит кстати)</li>
<li><a href="http://www.ghisler.com/">TotalCmd</a> &#8211; файловый менеджер + FTP клиентб недавно вышла 8-ая версия (beta), не купил, жмакаю раз в неделю кнопку с циферкой</li>
<li><a href="http://winscp.net/eng/index.php">WinScp</a> &#8211; SFTP клиент (файловый менеджер over SSH)</li>
</ul>
<p>Да, я работаю на винде, набор инструментов для Linux и Мас отличается лишь набором дополнительных тулзов&#8230;</p>
<h2>Фишки PHP и 5.3 в частности</h2>
<h3>phpDocumentor</h3>
<p>Я уже упоминал о крутом автодополнение в IDE, тук вот, чтобы этого добиться необходимо описывать классы, методы и функции используя doc comment&#8217;ы:</p>
<pre class="brush: php; title: ; notranslate">
/**
 * @property integer $id
 * @property string $login
 * ...
 */
class Row
{

}
</pre>
<p>В результате IDE будет подсказывать нам всё что нужно:</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/phpDocumentor-1.png" alt="" title="phpDocumentor" width="348" height="110" class="aligncenter size-full wp-image-1988" /></p>
<p>Еще примерчик:</p>
<pre class="brush: php; title: ; notranslate">
/**
 * @return Users\Row
 */
function getUser()
{
     return Registry::get(&quot;user&quot;);
}

/* @var Users\Row $user */
$user = Registry::get(&quot;user&quot;);
</pre>
<p>В IDE похожий результат:</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/phpDocumentor-2.png" alt="" title="phpDocumentor" width="348" height="88" class="aligncenter size-full wp-image-1989" /></p>
<p>Кроме бенефитов для IDE есть еще возможность сгенерировать техническую документацию используя PHPDocumentor:</p>
<pre class="brush: php; title: ; notranslate">
/**
 * &lt;code&gt;
 * $this-&gt;getByLoginOrPasswordAndEmail(
 *      'vasya', md5(123456), 'vasya@mail.ru'
 *  )
 * &lt;/code&gt;
 */
function getByColumnsFinder()
{
    /*...*/
}
</pre>
<p>Обернётся в:<br />
<img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/phpDocumentor-3.png" alt="" title="phpDocumentor-3" width="526" height="186" class="aligncenter size-full wp-image-1990" /></p>
<h3>Tips &#038; Tricks: Fixme Comment</h3>
<p><a href="http://c2.com/cgi/wiki?FixmeComment">Заметки</a> на будущее прям в коде:</p>
<pre class="brush: php; title: ; notranslate">
// TODO: do something with some function
// FIXME: hands
// XXX: may be broken
</pre>
<p>IDE нынче умные пошли, и все такие заметки соберут до кучи:</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/TODO.png" alt="" title="TODO" width="526" height="186" class="aligncenter size-full wp-image-1993" /></p>
<h3>Tips &#038; Tricks: о include и require</h3>
<p>А вы смотрели что возвращают функции include и require? А если в подключаемом файле используется return?</p>
<pre class="brush: php; title: ; notranslate">
$config = require 'config.php';

&lt;? // config.php
    return array(
        'DB' =&gt; array(...)
    );
</pre>
<p>Достаточно универсальный способ для подключения конфигурационных файлов.</p>
<h3>Tips &#038; Tricks: о фильтрации данных</h3>
<p>На дворе уже закат PHP 5.2, а фильтры не используем:</p>
<pre class="brush: php; title: ; notranslate">
// return string or false
filter_var('bob@example', FILTER_VALIDATE_EMAIL);
filter_var('bob@example.com', FILTER_VALIDATE_EMAIL);

// return string or false
filter_var('http://example.com', FILTER_VALIDATE_URL);
</pre>
<p>По теме:</p>
<ul>
<li><a href="http://www.php.net/manual/en/function.filter-var.php">http://www.php.net/manual/en/function.filter-var.php</a></li>
<li><a href="http://www.php.net/manual/en/filter.filters.validate.php">http://www.php.net/manual/en/filter.filters.validate.php</a></li>
<li><a href="http://www.php.net/manual/en/function.filter-var-array.php">http://www.php.net/manual/en/function.filter-var-array.php</a></li>
</ul>
<p>Иногда обработку массива превращают в что-то невообразимое, можно же проще:</p>
<pre class="brush: php; title: ; notranslate">
  // array of ids
$ids = $Request-&gt;getParam(&quot;ids&quot;);

  // to integer
$ids = array_map(&quot;intval&quot;, $ids);

  // without zero
$ids = array_filter($ids);

  // unique
$ids = array_unique($ids);

  // prepare for SQL
$idsStr = join(&quot;,&quot;, $ids);
</pre>
<p>А бывают ситуации, когда в форме есть несколько submit кнопок, и надо понимать что же было нажато (о да, это плохие формы)</p>
<pre class="brush: xml; title: ; notranslate">
&lt;form&gt;
    ...
    &lt;input type=&quot;submit&quot; name=&quot;disable&quot; value=&quot;Disable selected&quot; /&gt;
    &lt;input type=&quot;submit&quot; name=&quot;enable&quot; value=&quot;Enable selected&quot; /&gt;
&lt;/form&gt;
</pre>
<pre class="brush: php; title: ; notranslate">
&lt;?php  // gets current action
$action = current(array_intersect(array_keys(
    $_REQUEST), array('disable', 'enable')
));
</pre>
<h3>Tips &#038; Tricks: glob</h3>
<p>Уже везде упоминали функцию <a href="http://www.php.net/manual/en/function.glob.php">glob</a>, но мы всё так же её игнорируем, так что я решил её опять вспомнить:</p>
<pre class="brush: php; title: ; notranslate">
$controllers = glob('/modules/*/controllers/*.php');

$modules = glob('/modules/*', GLOB_ONLYDIR);
</pre>
<h3>Tips &#038; Tricks: mysqlnd</h3>
<p>Если у вас высокопроизводительное приложение, если вам знакомо понятие master и slave, если разруливаете это ручками, то вот оно &mdash; прозрение:</p>
<pre class="brush: php; title: ; notranslate">
// in config
[myapp]
master[]=localhost:/tmp/mysql.sock
slave[]=192.168.2.27:3306

// in sources
$mysqli = new mysqli(&quot;myapp&quot;, &quot;username&quot;, &quot;password&quot;, &quot;database&quot;);
$pdo = new PDO(&quot;mysql:host=myapp;dbname=database&quot;, &quot;username&quot;, &quot;password&quot;);
</pre>
<p>По теме:</p>
<ul>
<li><a href="http://www.php.net/manual/en/book.mysqlnd.php">http://www.php.net/manual/en/book.mysqlnd.php</a></li>
<li><a href="http://blog.ulf-wendel.de/?p=307">Replication and load balancing mysqlnd plugin for all PHP MySQL extensions released</a></li>
</ul>
<p>P.S. О, это уже было в &#8230; <a href="https://twitter.com/AntonShevchuk">твитере</a> ;)</p>
<h3>Reflection</h3>
<p>Посмотри на себя в <a href="http://php.net/manual/en/book.reflection.php">зеркало</a>, в нём ты увидишь и имена <a href="http://www.php.net/manual/en/reflectionclass.getmethods.php">методов</a>, и приватные <a href="http://www.php.net/manual/en/reflectionclass.getproperties.php">данные</a>, и даже <a href="http://www.php.net/manual/en/reflectionclass.getdoccomment.php">комментарии</a>. Знай и используй с умом!</p>
<h2>PHP 5.3</h2>
<p>Приведу краткие тезисы по теме новшеств в PHP 5.3 (да, да, жевано-пережевано, но повторить то стоит)</p>
<h3>Анонимные функции</h3>
<p>Используете jQuery, значит ничего нового тут не увидите:</p>
<pre class="brush: php; title: ; notranslate">
$ids = array_map(function($el){
    return intval($el);
}, $ids);
  // or
$toInt = function($el){
    return intval($el);
};
$ids = array_map($toInt, $ids);
  // or
$int = $toInt($el);
</pre>
<h3>Замыкания</h3>
<p>Смотреть в код до наступления понимания происходящего:</p>
<pre class="brush: php; title: ; notranslate">
function getTimeout() {
    $el = &quot;15 minutes&quot;;

    return function() use ($el){
        return intval($el);
    };
}

$timeOut = getTimeout();
echo $timeOut(); // &gt;&gt; 15
</pre>
<h3>Магический метод __invoke()</h3>
<p>Вместо слов, лишь код:</p>
<pre class="brush: php; title: ; notranslate">
class Row
{
    function __invoke()
    {
        return $this-&gt;login;
    }
}

$user = new Users\Row();
$var = $user(); // &gt;&gt; return user login
</pre>
<h3>Namespaces</h3>
<p>Про пространство имён не писал лишь ленивый, но я предлагаю простую ассоциацию c файловой системой (спасибо за бэкслеш, ассоциация будет с Windows):</p>
<pre class="brush: plain; title: ; notranslate">
\              &lt;&lt; Default namespace - root
\Exception
\StdClass
\Application   &lt;&lt; Our namespace - Application
            \Model
                  \User
                  \Group
            \Controller
                  \User
</pre>
<ul>
<li>объявляя namespace &mdash; мы добавляем новый класс в иерархию &laquo;папок&raquo; &mdash; cd &#038;&#038; mkdir</li>
<li>говоря use &mdash; используем директорию из иерархии (1 или более) &mdash; как команда cd</li>
<li>говоря use as &mdash; используем под определенным именем &mdash; ln</li>
<li>всегда можно обращаться идя от корня (абсолютный путь: \Application\Model\Group)</li>
</ul>
<h3>Позднее статическое связывание</h3>
<p>Эта непонятная фигня означает, что когда вы наследуете класс от статического, то у вас возникнут проблемы с доступом к статическим методам наследуемого класса, приведу наглядный (я надеюсь) пример:</p>
<pre class="brush: php; title: ; notranslate">
class Latin
{
     const CHARS = 'abc...';
     static function getChars() {
         return self::CHARS;
     }
}
class French extends Latin
{
    const CHARS = 'aàábc...';
}

echo French::getChars(); // &gt;&gt; abc...
</pre>
<p>В PHP 5.3 решается просто:</p>
<pre class="brush: php; title: ; notranslate">
class Latin
{
     const CHARS = 'abc...';
     static function getChars() {
         return static::CHARS; // &lt;&lt; static
     }
}
class French extends Latin
{
    const CHARS = 'aàábc...';
}

echo French::getChars(); // &gt;&gt; aàábc...
</pre>
<h3>Почти фреймворк</h3>
<p>Ой, велосипед, да на &laquo;новых&raquo; технологиях, нямочка, зацените-ка контроллер:</p>
<pre class="brush: php; title: ; notranslate">
namespace Bluz;
return
/**
 * @acl View User Profile
 * @cache 5 minutes
 * @param integer $id
 * @return closure
 */
function($id) use ($bootstrap, $app, $view) {
    /**
     * @var closure $bootstrap
     * @var Application $app
     * @var View $view
     */
     $view-&gt;user = $app-&gt;getDb()-&gt;getRow(&quot;...&quot;, array($id));
};
</pre>
<ul>
<li>Контроллер &mdash; анонимная функция возвращаемая при подключении файла</li>
<li>Может вернуть что угодно, лишь бы было callable</li>
<li>Принимает параметры с реквеста, уже отфильтрованнные (описали же в doccomment&#8217;e правила)</li>
<li>Кеширует результат выполнения на 5 минут (опять reflection)</li>
<li>Acl тут тоже не просто так ;)</li>
</ul>
<p>Возможно выложим на общее обозрение сие творение, ну когда отшлифуем его ;)</p>
<h3>Если что-то позабыл</h3>
<p>Позабыл я о небольшом изменении в поведении тернарного оператора &laquo;(statement)?(then):(else)&raquo;, у него появилось мини-сокращение:</p>
<pre class="brush: php; title: ; notranslate">
echo $var?$var:'nil';
// ? : improvements
echo $var?:'nil';
</pre>
<p>Что-то оно не очень, можно было сделать лучше (эти примеры не работают!):</p>
<pre class="brush: php; title: ; notranslate">
echo $var?;
// or
echo isset($var['elem'])?$var['elem'];
</pre>
<p>Еще &laquo;незаслужено&raquo; обошёл стороной метки:</p>
<pre class="brush: php; title: ; notranslate">
// labels
start: echo &quot;start&quot;; goto finish;

echo &quot;never&quot;;

finish: echo &quot;finish&quot;;
</pre>
<p>Но наверное вы в курсе:<br />
<a href="http://xkcd.com/292/"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/11/xkcd-goto.png" alt="" title="xkcd-goto" width="620" class="aligncenter size-full wp-image-1994" /></a></p>
<p>P.S. Всё это и еще немного больше я обычно рассказываю на лекциях в <a href="http://anton.shevchuk.name/php/team-life/" title="Жизнь в PHP отделе">своём отделе</a> ;)</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li>No Related Post</li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=B_3bafhc4aM:y4MjTYP9ETc:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=B_3bafhc4aM:y4MjTYP9ETc:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=B_3bafhc4aM:y4MjTYP9ETc:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/B_3bafhc4aM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/php/about-php/feed/</wfw:commentRss>
		<slash:comments>37</slash:comments>
		<media:content url="http://feedproxy.google.com/~r/AntonShevchuk/~5/pb_3Zs7d3t0/config.zip" fileSize="6390" type="application/zip" /><feedburner:origLink>http://anton.shevchuk.name/php/about-php/</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/AntonShevchuk/~5/pb_3Zs7d3t0/config.zip" length="6390" type="application/zip" /><feedburner:origEnclosureLink>http://dl.dropbox.com/u/27453635/PHPStorm/config.zip</feedburner:origEnclosureLink></item>
		<item>
		<title>Zend Framework Day</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/y9VOgk-cF28/</link>
		<comments>http://anton.shevchuk.name/php/zend-framework-day/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 15:20:11 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[announcement]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1982</guid>
		<description><![CDATA[12 ноября, в Киеве, пройдет конференция &#8220;Zend Framework Day&#8221;, посвященная популярному PHP фреймворку Zend Framework. Среди докладчиков &#8211; непосредственные разработчики компонент Zend Framework. Событие соберет лучших PHP и Zend Framework специалистов из Украины, России, Белоруссии и других стран СНГ. С текущим списком тем и докладчиков можно ознакомиться на странице. Событие будет интересно не только тем, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://frameworksdays.com/uploads/events/zend-framework-day.png" alt="Zend Framework Day" align="left" style="margin-right: 20px;" />12 ноября, в Киеве, пройдет конференция &#8220;Zend Framework Day&#8221;, посвященная популярному PHP фреймворку Zend Framework. <br/><br />
Среди докладчиков &#8211; непосредственные разработчики компонент Zend Framework. Событие соберет лучших PHP и Zend Framework специалистов из Украины, России, Белоруссии и других стран СНГ.</p>
<p><span id="more-1982"></span></p>
<p>С текущим списком тем и докладчиков можно ознакомиться на <a href="http://frameworksdays.com/event/zend-framework-day-2011/speakers">странице</a>.</p>
<p>Событие будет интересно не только тем, кто использует Zend Framework, но и всем веб-разработчикам и PHP программистам в частности.</p>
<p>Место проведения — отель &#8220;Казацкий&#8221;, г. Киев, ул. Михайловская 1/3 (Площадь Независимости).</p>
<p>Стоимость участия и другая необходимая информация доступна на <a href="http://frameworksdays.com/event/zend-framework-day-2011">странице</a>.</p>
<p>Для участия в конференции необходимо пройти регистрацию на <a href="http://frameworksdays.com/register">странице</a>, а затем произвести оплату из личного кабинета.</p>
<p>
Сайт конференции &#8211; <a href="http://frameworksdays.com/event/zend-framework-day-2011">http://frameworksdays.com/event/zend-framework-day-2011</a><br />
Наши новости в twitter &#8211; <a href="http://twitter.com/fwdays">http://twitter.com/fwdays</a><br />
Наша страница в facebook – <a href="http://facebook.com/fwdays">http://facebook.com/fwdays</a></p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/html-and-css/master-klass-yuriy-akella-artyukh/" title="Мастер-класс Юры Артюха">Мастер-класс Юры Артюха</a></li><li><a href="http://anton.shevchuk.name/internet/sphinx-master-class/" title="Мастер-класс по Sphinx">Мастер-класс по Sphinx</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-2011-piter/" title="Конференция ZFConf 2011">Конференция ZFConf 2011</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-ukraine/" title="ZFConf Ukraine">ZFConf Ukraine</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class-feedback/" title="Анонс мастер-классов по JavaScript&#8217;у">Анонс мастер-классов по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class/" title="Мастер-классы по JavaScript&#8217;у">Мастер-классы по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/internet/pdfeed-rss-to-pdf-generator/" title="PDFEED &#8211; или RSS2PDF в новом обличье">PDFEED &#8211; или RSS2PDF в новом обличье</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=y9VOgk-cF28:514ejhGyJ9s:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=y9VOgk-cF28:514ejhGyJ9s:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=y9VOgk-cF28:514ejhGyJ9s:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/y9VOgk-cF28" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/php/zend-framework-day/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/php/zend-framework-day/</feedburner:origLink></item>
		<item>
		<title>Мастер-класс Юры Артюха</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/g6vqnLPb2D4/</link>
		<comments>http://anton.shevchuk.name/html-and-css/master-klass-yuriy-akella-artyukh/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 11:51:59 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[HTML and CSS]]></category>
		<category><![CDATA[announcement]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1972</guid>
		<description><![CDATA[8-го октября (в Киеве) и 15-го октября (в Харькове) пройдет мастер-класс Юры Артюха &#171;Современные подходы в вёрстке 2&#187; Юрий Артюх — специалист по верстке с многолетним стажем. Принимал участие в разработке нескольких сотен проектов среди которых такие как kremlin.ru, groupon.ru, subscribe.ru, sports.ru, ukr.net, zn.ua, delo.ua, pravda.com.ua. Мастер-класс может быть интересен и полезен всем, кто работает [...]]]></description>
			<content:encoded><![CDATA[<p><strong>8-го октября (в Киеве)</strong> и <strong>15-го октября (в Харькове)</strong> пройдет мастер-класс Юры Артюха &laquo;<strong>Современные подходы в вёрстке 2</strong>&raquo;</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/10/yuriy-akella-artyukh.jpg" alt="" title="Юрий Артюх" width="285" height="200" class="aligncenter size-full wp-image-1975" /></p>
<p><strong>Юрий Артюх</strong> — специалист по верстке с многолетним стажем. Принимал участие в разработке нескольких сотен проектов среди которых такие как <a href="http://kremlin.ru" target="_blank">kremlin.ru</a>, <a href="http://groupon.ru" target="_blank">groupon.ru</a>, <a href="http://subscribe.ru" target="_blank">subscribe.ru</a>, <a href="http://sports.ru" target="_blank">sports.ru</a>, <a href="http://ukr.net" target="_blank">ukr.net</a>, <a href="http://zn.ua" target="_blank">zn.ua</a>, <a href="http://delo.ua" target="_blank">delo.ua</a>, <a href="http://pravda.com.ua" target="_blank">pravda.com.ua</a>.</p>
<p><span id="more-1972"></span><br />
Мастер-класс может быть интересен и полезен всем, кто работает с фронт-эндом.</p>
<p>Уже более 7 лет Юрий ведет популярный блог посвященный проблемам верстки <a href="http://cssing.org.ua" target="_blank">CSSing.org.ua</a>. Также является активным участником сообщества русского крыла веб-стандартистов, и организатором первой украинской конференции веб-разработчиков UA WEB.</p>
<p>В конце мастер-класса у нас будет возможность задать любые вопросы.</p>
<p>После занятий самые стойкие смогут продолжить общение в пабе.</p>
<p>Дополнительная информация и <a href="http://www.smartme.com.ua/master-klassy-o-verstke-v-xarkove-i-kieve/" target="_blank">подробный план мастер-класса можна посмотреть на сайте</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/php/zend-framework-day/" title="Zend Framework Day">Zend Framework Day</a></li><li><a href="http://anton.shevchuk.name/internet/sphinx-master-class/" title="Мастер-класс по Sphinx">Мастер-класс по Sphinx</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-2011-piter/" title="Конференция ZFConf 2011">Конференция ZFConf 2011</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-ukraine/" title="ZFConf Ukraine">ZFConf Ukraine</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class-feedback/" title="Анонс мастер-классов по JavaScript&#8217;у">Анонс мастер-классов по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class/" title="Мастер-классы по JavaScript&#8217;у">Мастер-классы по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/internet/pdfeed-rss-to-pdf-generator/" title="PDFEED &#8211; или RSS2PDF в новом обличье">PDFEED &#8211; или RSS2PDF в новом обличье</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=g6vqnLPb2D4:JuqSDIGrz3Y:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=g6vqnLPb2D4:JuqSDIGrz3Y:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=g6vqnLPb2D4:JuqSDIGrz3Y:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/g6vqnLPb2D4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/html-and-css/master-klass-yuriy-akella-artyukh/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/html-and-css/master-klass-yuriy-akella-artyukh/</feedburner:origLink></item>
		<item>
		<title>Обзор Boogie Board</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/1X2m6pHfJU0/</link>
		<comments>http://anton.shevchuk.name/my-life/review-boogie-board/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 13:57:54 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[My Life]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1946</guid>
		<description><![CDATA[Прикупил занятный девайс для рисования &#8211; Boogie Board. Небольшой horror-обзор далее (хотя картинка выше такая спойлерная)&#8230; Для начала о грустном &#8211; о цене &#8211; заказывал на Amazon Boogie Board Bundle за $44.95, пересылка через Shipito обошлась бы еще в $12.75, но объединение посылок съело эту сумму. В Bundle входит &#8211; собственно Boogie Board 8.5&#8243;, стилус, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie_board_anim.gif" alt="" title="Boogie Board" width="400" height="438" class="aligncenter size-full wp-image-1947" /></p>
<p>Прикупил занятный девайс для рисования &#8211; <a href="http://www.improvelectronics.com/us/en/boogie-board-LCD-writing-tablet/boogie-board-8-LCD-writing-tablet.html">Boogie Board</a>. Небольшой horror-обзор далее (хотя картинка выше такая спойлерная)&#8230;<br />
<span id="more-1946"></span></p>
<p>Для начала о грустном &#8211; о цене &#8211; заказывал на Amazon <a href="http://amzn.to/pHftC5">Boogie Board Bundle</a> за $44.95, пересылка через <a href="http://anton.shevchuk.name/internet/my-internet-shopping-and-shipping-with-shipito/" title="Мой опыт работы с Shipito">Shipito</a> обошлась бы еще в $12.75, но объединение посылок съело эту сумму. В Bundle входит &#8211; собственно Boogie Board 8.5&#8243;, стилус, чехол, клипса для стилуса, набор магнитов на скотче (которые я сразу и приклеял):</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie-board-bundle.jpg" alt="" title="Boogie Board Bundle" width="640" height="430" class="aligncenter size-full wp-image-1948" /><br />
<img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie-board-bundle-2.jpg" alt="" title="Boogie Board Bundle" width="640" height="494" class="aligncenter size-full wp-image-1949" /></p>
<h3>Описание</h3>
<p>Размером планшетик с лист формата А5 &mdash; 222х140 мм, LCD экран &mdash; 183х125 мм. Толщина от 3мм до 6мм, правда магниты и клипса еще добавляет габаритов, но не значительно. Стилус &laquo;дебелый&raquo;, так просто не сломать, в разложеном состоянии можно использовать как указку. Стилус можно закрепить либо на клипсе, либо положить в специальный кармашек чехла.</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie-board-4.jpg" alt="" title="Boogie Board" width="640" height="455" class="aligncenter size-full wp-image-1952" /></p>
<h3>Использование</h3>
<p>Держать удобно, рисовать не напряжно &mdash; чем-то напоминает рисование карандашом по бумаге (даже с характерным звуком). Можно повесить на холодильник или на доску в офисе &mdash; магнитные ножки держат надежно (хотя в таком положении рисовать не удобно). </p>
<p>Экран чувствителен к силе нажатия &mdash; под собственным весом стилус оставляет точку радиусом ~2-3мм; при усилии ~4-5мм. И да &mdash; он матовый!</p>
<p>На девайсе всего одна кнопка &mdash; очистить экран &mdash; выглядит это как перелистывание страниц на e-ink. Производитель же обещает 50 000 очисток на одной батарейке &mdash; а потом будем думать (через 6 лет, если стирать по 20 раз на дню).</p>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie-board-5.jpg" alt="" title="Boogie Board" width="640" height="444" class="aligncenter size-full wp-image-1953" /></p>
<p>Насчет внутренностей чудо-блокнота &mdash; походу, с заменой батарейки, проблем не возникнет (найдено на amazon):<br />
<img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie-board-inside.jpg" alt="" title="boogie-board-inside" width="500" height="200" class="aligncenter size-full wp-image-1955" /></p>
<h3>Выводы</h3>
<p>Девайс прикольный, конечно не хватает функции сохранения картинок на комп, да и режим ластика для стилуса &mdash; а то я его постоянно переворачиваю пытаясь стереть что-то. Покупал планшет, в первую очередь, для ребенка, но пока он он у бабушки стресс-тестирование еще не проводилось :)</p>
<p>Еще раз о грустном (ссылки реферальные, о ужас):</p>
<ul>
<li><a href="http://amzn.to/oHauRl">Boogie Board 8.5&#8243;</a> &mdash; чёрная версия &mdash; $29.95 </li>
<li><a href="http://amzn.to/pHftC5">Boogie Board 8.5&#8243; Bundle</a> &mdash; тот что на скринах выше &mdash; $44.95</li>
<li><a href="http://amzn.to/reVYaZ ">Boogie Board 10.5&#8243;</a> &mdash; новый и большой, пока чехла к нему не найти &mdash; $59.95</li>
</ul>
<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/07/boogie-board-6.jpg" alt="" title="Boogie Board Evil Win" width="640" height="319" class="aligncenter size-full wp-image-1950" /></p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/my-life/review-corsair-graphite-series-600t/" title="Обзор корпуса Corsair Graphite Series 600T">Обзор корпуса Corsair Graphite Series 600T</a></li><li><a href="http://anton.shevchuk.name/my-life/nook-barnes-noble-review/" title="Обзор Nook от Barnes &#038; Noble">Обзор Nook от Barnes &#038; Noble</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=1X2m6pHfJU0:JcuPTzS3JQA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=1X2m6pHfJU0:JcuPTzS3JQA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=1X2m6pHfJU0:JcuPTzS3JQA:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/1X2m6pHfJU0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/my-life/review-boogie-board/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/my-life/review-boogie-board/</feedburner:origLink></item>
		<item>
		<title>Интеграция форума Vanilla</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/mEjRnqgq1D4/</link>
		<comments>http://anton.shevchuk.name/php/embed-migration-integration-vanilla/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 06:57:18 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Vanilla]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1932</guid>
		<description><![CDATA[Если перед вами стоит задача подключения форума к готовой системе, то советую вам обратить внимание на Vanilla Forum. А дальше &#8212; скучноватый пошаговый мануал =\ Для начала нам потребуется скачать последнюю версию форума с официального сайта, а поскольку я тут успел наступить на одни грабли &#8212; то качаем последнюю бету &#8212; vanilla-core-2.0.18b2. Встраиваем По умолчанию, [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/vanilla_sticker-460x207.png" alt="" title="Vanilla Forum" width="460" height="207" class="aligncenter size-medium wp-image-1933" /><br />
Если перед вами стоит задача подключения форума к готовой системе, то советую вам обратить внимание на <a href="http://vanillaforums.org/">Vanilla Forum</a>. А дальше &mdash; скучноватый пошаговый мануал =\<br />
<span id="more-1932"></span></p>
<blockquote><p>Для начала нам потребуется скачать последнюю версию форума с официального сайта, а поскольку я тут успел наступить на одни грабли &mdash; то качаем последнюю бету &mdash; <a href="http://vanillaforums.org/addon/vanilla-core-2.0.18b2">vanilla-core-2.0.18b2</a>.</p></blockquote>
<h3>Встраиваем</h3>
<p>По умолчанию, Vanilla форум имеет прекрасную возможность &mdash; встраиваться в любую HTML страничку посредством JavaScript&#8217;a, для этого нам понадобится активировать плагин &lt;Embed&gt; Vanilla (идет в стандартной поставке) и получить код скрипта:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://forum.your-domain.com/plugins/embedvanilla/remote.js&quot;&gt;&lt;/script&gt;
</pre>
<p>Так же советую использовать дефолтную тему &laquo;Embed-Friendly&raquo; для встроенного форума &mdash; она достаточно простая и удобная для кастомизации. </p>
<p>Единственная проблема которая у меня возникла при подобном подключении форума &mdash; это ошибки JavaScript&#8217;a &mdash; разработчики форума не в курсе о методе <code>jQuery().delegate()</code> и используют <code>jQuery('a').live('click')</code>, чем вызывают не очень адекватное поведение ссылок на странице без атрибута href. </p>
<h3>Интеграция с использованием ProxyConnect</h3>
<p>Как понятно из подзаголовка, нам потребуется скачать плагин <a href="http://vanillaforums.org/addon/proxyconnect-plugin">Vanilla ProxyConnect</a>. Устанавливаем и идем настраивать (Users &gt; Authentication):</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/ProxyConnect.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/ProxyConnect-460x300.png" alt="" title="ProxyConnect" width="460" height="300" class="aligncenter size-medium wp-image-1936" /></a></p>
<p>Тут всё просто, по пунктам (пути в примере полные, могут быть относительные):</p>
<ol>
<li>Ваш сайт</li>
<li>Страничка для получения данных о вашем пользователе (о ней чуть далее)</li>
<li>Страница регистрации</li>
<li>Страница входа</li>
<li>Страница выхода</li>
</ol>
<p>Теперь займемся пунктом 2 &mdash; Authenticate URL. Это страничка, где у вас должны выводиться данные вашего текущего пользователя в простом формате:</p>
<blockquote><pre>
UniqueID=1279
Name=Bob
Email=bob@gmail.com
TransientKey=qwerty
DateOfBirth=1970-01-01
Gender=Male
Roles=Member,Admin
</pre>
</blockquote>
<ul>
<li><strong>UniqueID</strong> &mdash; обязательное поле, UID пользователя в вашей системе</li>
<li><strong>Name </strong> &mdash; обязательное поле, username, или как он у вас обзывается</li>
<li><strong>Email</strong> &mdash; обязательное поле, email вашего пользователя</li>
<li><strong>TransientKey</strong> &mdash; ключ, для предотвращения CSRF атак (вам скорей всего не понадобится, для wordpress обязательно)</li>
<li><strong>DateOfBirth</strong> &mdash; дата рождения</li>
<li><strong>Gender</strong> &mdash; мальчик/девочка, Male/Female</li>
<li><strong>Roles</strong> &mdash; роли пользователя на Vanilla форуме, через запятую, можно IDшниками</li>
</ul>
<p>Если у вас Zend Framework, то action будет выглядеть как-то так:</p>
<pre class="brush: php; title: ; notranslate">
// disable View
$this-&gt;_helper-&gt;layout()-&gt;disableLayout();
$this-&gt;_helper-&gt;viewRenderer-&gt;setNoRender(true);

// get current User
$user = Zend_Auth::getInstance()-&gt;getIdentity();
if ($user) {
echo &quot;UniqueID={$user-&gt;id}\n&quot;
     . &quot;Name={$user-&gt;username}\n&quot;
     . &quot;Email={$user-&gt;email}\n&quot;
     . &quot;Roles={$user-&gt;role}\n&quot;;
} else {
echo &quot;UniqueID=\n&quot;
     . &quot;Name=\n&quot;
     . &quot;Email=\n&quot;;
}
</pre>
<p>Как это работает &mdash; когда пользователь заходит на форум, то Vanilla незаметно так стучится на нашу страничку с текущей сессией пользователя, и пытается получить о нем информацию. Если это удалось, то движок пытается найти соответсвующую запись у себя в БД &mdash; если нашел, то мы авторизированы, если не нашел соответсвия &mdash; регистриует нового пользователя с указанными данными и так же авторизирует. Если наша страничка не вернула данных о пользователе, то он либо будет послан на страницу Sign In указанную в настройках ProxyConnect, либо отобразит страницу авторизации форума (зависит, от того, что разрешено пользователю guest).</p>
<p>Из замеченного: для разлогинивания на форуме следует чистить куки:</p>
<pre class="brush: php; title: ; notranslate">
// vanilla forum logout
setcookie('Vanilla', ' ', time() - 3600, '/', '.domain.com');
unset($_COOKIE['Vanilla']);
</pre>
<p>Если пользователь авторизирован в вашей системе, а при входе на форум требуется логинится (банально клацнуть на кнопку, для запуска процесса авторизации), то это тоже поправимо &mdash; следует в вашем методе логина добавить следующую очистку куков (я их еще и в логаут добавил, так на всяк случай):</p>
<pre class="brush: php; title: ; notranslate">
setcookie(&quot;Vanilla&quot;, &quot;deleted&quot;, time() - 1,'/', &quot;.domain.com&quot;, false);
setcookie(&quot;Vanilla-Volatile&quot;, &quot;deleted&quot;, time() - 1, '/', &quot;.domain.com&quot;, false);
</pre>
<p><a href="http://vanillaforums.org/page/ProxyConnect_SSO">Официальная документация по ProxyConnect</a></p>
<h3>Портирование с phpBB, vBulletin и т.д.</h3>
<p>На случай если вы решили сменить движок форума, то это тоже предусмотрено ;) Качаем <a href="http://vanillaforums.org/addon/porter-core">Vanilla Porter</a> и заливаем его в корень вашего текущего форума (phpBB или что там у вас). Далее следуем простой инструкции по переносу данных:</p>
<ol>
<li>Экспорт форума в TXT файл хитрого формата</li>
<li>Импорт этого самого файла</li>
</ol>
<p>Как просто-то :) Ну для наглядности приведу еще скриншот самой тулзы:<br />
<img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/VanillaPorter-356x460.png" alt="" title="VanillaPorter" width="356" height="460" class="aligncenter size-medium wp-image-1934" /></p>
<p>Но без нюансов тоже не обошлось &mdash; первое с чем столкнулся это непонимание формата файла в архиве, пришлось распаковывать и заливать. Второе &mdash; во время импорта все текущие пользователи Vanilla будут удалены, включая вашу учетную запись, так что в определенный момент вам надо будет указать email нового админа из портированных данных, после чего вы получите ошибку авторизации, без паники, логинимся заново под новым админом и продолжаем импорт данных (будет такая кнопочка). Следующий шаг &mdash; вам потребуется назначить права для всех ролей пользователей, которые были перенесены со старого движка. И напоследок, когда пользователи со старой системы попробуют зайти на новый форум им высветится следующий диалог (это верно для Vanilla + ProxyConnect):</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/linking.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/linking.png" alt="" title="Vanilla Linking Accounts" width="600" height="287" class="aligncenter size-full wp-image-1938" /></a></p>
<p>Подготовьте пользователей к правильным действиям заранее.</p>
<p>Еще такой момент, умные дядьки часто изменяют алгоритм хэшированя паролей, на этот случай прийдется выполнить следующие действия:</p>
<ol>
<li>Заменить имя метода хэширования на некоторый произвольный</li>
<li>Добавить его поддержку в файле <code>vanilla/library/core/class.passwordhash.php</code></li>
</ol>
<p>С первым всё совсем просто:</p>
<pre class="brush: sql; title: ; notranslate">
UPDATE GDN_User SET HashMethod = 'myHash' WHERE HashMethod = 'phpBB';
</pre>
<p>Второй пункт тоже не сложен &mdash; нам потребуется найти <code>switch</code> в методе <code>CheckPassword()</code> и добавить туда новый <code>case</code>:</p>
<pre class="brush: php; title: ; notranslate">
switch(strtolower($Method)) {
/* ... */
    case 'myhash':
        $Result = myMegaHashFunction($Password, $StoredHash);
        break;
/* ... */
}
</pre>
<p><a href="http://vanillaforums.com/blog/help/importing-data/">Документация по Vanilla Porter</a></p>
<h3>Вместо вывода</h3>
<p>Форум действительно стоит того, чтобы его установить и опробовать: много локализаций (включая русский и арабский) и полезных плагинов; простые для адаптации темы (хоть и Smarty используется); и таки удобная система интеграции.</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li>No Related Post</li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=mEjRnqgq1D4:jIuVbUlC4WA:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=mEjRnqgq1D4:jIuVbUlC4WA:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=mEjRnqgq1D4:jIuVbUlC4WA:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/mEjRnqgq1D4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/php/embed-migration-integration-vanilla/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/php/embed-migration-integration-vanilla/</feedburner:origLink></item>
		<item>
		<title>Обзор корпуса Corsair Graphite Series 600T</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/JStiQmP0xxw/</link>
		<comments>http://anton.shevchuk.name/my-life/review-corsair-graphite-series-600t/#comments</comments>
		<pubDate>Mon, 27 Jun 2011 08:46:43 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[My Life]]></category>
		<category><![CDATA[hardware]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1900</guid>
		<description><![CDATA[Вычеркнул из своего wishlist&#8217;а еще один пункт &#8212; я таки разорился на хороший корпус &#8212; Corsair Graphite Series 600T. Внешний вид Встречаем по одежке, и вот он во всей красе (кликабельно, с официального сайта): Комплектация: Скромная инструкция, в которой показано как можно снимать крышки Ключ для закрытия корпуса Три пакетика с крепежом &#8212; черные болтики [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t.jpg" alt="" title="Corsair Graphite 600T" width="195" height="300" class="aligncenter size-full wp-image-1970" /></p>
<p>Вычеркнул из своего <a href="http://anton.shevchuk.name/wishlist/">wishlist&#8217;а</a> еще один пункт &mdash; я таки разорился на хороший корпус &mdash; <a href="http://www.corsair.com/cases/graphite-series/graphite-series-600t.html">Corsair Graphite Series 600T</a>.</p>
<p><span id="more-1900"></span></p>
<h3>Внешний вид</h3>
<p>Встречаем по одежке, и вот он во всей красе (кликабельно, с официального сайта):<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-2.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-2-365x460.png" alt="" title="Corsair Graphite 600T Perspective" width="365" height="460" class="alignleft size-medium wp-image-1907" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-front.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-front-234x460.png" alt="" title="Corsair Graphite 600T Front" width="234" height="460" class="alignleft size-medium wp-image-1908" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-back.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-back-245x460.png" alt="" title="Corsair Graphite 600T Back" width="245" height="460" class="alignleft size-medium wp-image-1909" /></a></p>
<p><br class="clear"/></p>
<p>Комплектация:</p>
<ul>
<li>Скромная инструкция, в которой показано как можно снимать крышки</li>
<li>Ключ для закрытия корпуса</li>
<li>Три пакетика с крепежом &mdash; черные болтики для черного корпуса</li>
<li>Чёрные пластиковые стяжки</li>
<li>Круглые резиночки в количестве 8-ми штук, для чего они нужны я не понял</li>
</ul>
<h3>Преимущества</h3>
<p>Основной из главных причин смены корпуса послужил перегрев системы в старом корпусе. Старый корпус можно было подтюнить лишь 80мм вентиляторами, и получить жужжащую коробку под столом, и этим путем я решил не идти. Мой компьютер переселился в новую &laquo;квартиру&raquo; и теперь я могу сравнить результаты:</p>
<p><strong>Система</strong>: CPU Intel Core 2 Duo E6550 / Gigabyte GA-P35-DS3L / 4xDDR2-800 1Gb / MSI Cyclone GeForce GTS 450 / SAMSUNG HD400LJ +<br />
WDC WD20EVDS-63T3B0</p>
<p>Ну и показания датчиков (температура окружающей среды 27 градусов, данные снимались с помощью AIDA64):</p>
<table class="inline">
<tr>
<th>Датчик</th>
<th>Codegen</th>
<th>с нагрузкой</th>
<th>Corsair</th>
<th>с нагрузкой</th>
</tr>
<tr>
<td>Motherboard</td>
<td align="center">43</td>
<td align="center">54</td>
<td align="center">41</td>
<td align="center">45</td>
</tr>
<tr>
<td>CPU</td>
<td align="center">39</td>
<td align="center">58</td>
<td align="center">34</td>
<td align="center">49</td>
</tr>
<tr>
<td>GPU</td>
<td align="center">49</td>
<td align="center">64</td>
<td align="center">45</td>
<td align="center">57</td>
</tr>
<tr>
<td>SAMSUNG HD400LJ</td>
<td align="center">36</td>
<td align="center">52</td>
<td align="center">32</td>
<td align="center">32</td>
</tr>
<tr>
<td>WDC WD20EVDS-63T3B0</td>
<td align="center">37</td>
<td align="center">54</td>
<td align="center">35</td>
<td align="center">37</td>
</tr>
</table>
<p>Разница видна невооруженным взглядом :) Ну теперь подробнее о всяких вкусностях. Начну с верхней панели:<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-top.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-top-286x460.png" alt="" title="Corsair Graphite 600T Top" width="286" height="460" class="alignleft size-medium wp-image-1916" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-top-controls.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-top-controls-460x254.png" alt="" title="Corsair Graphite 600T Top Panel" width="460" height="254" class="alignleft size-medium wp-image-1917" /></a></p>
<p><br class="clear"/><br />
Кнопки включения и ресет должны быть сверху, не барское это дело &mdash; кланяться столу. Портов для подключения девайсов в изобилии &mdash; 4xUSB, Firewire и USB3 (последних у меня и нету). Ну и понятное дело выходы на микрофон и наушники. Опять же &mdash; все выходы направлены вверх, и нет риска случайно наступить на торчащую флешку.</p>
<p>Удобство доступа к внутренностям компьютер &mdash; две защелки и перед нами целый &laquo;аэропорт&raquo; для маневров:</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-openside.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-openside-460x391.png" alt="" title="Corsair Graphite 600T Openside" width="460" height="391" class="alignleft size-medium wp-image-1911" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-hdd-slots.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-hdd-slots-349x460.png" alt="" title="Corsair Graphite 600T HDD Slots" width="349" height="460" class="alignleft size-medium wp-image-1912" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-openside-back.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-openside-back-460x306.png" alt="" title="Corsair Graphite 600T Openside Back" width="460" height="306" class="alignleft size-medium wp-image-1913" /></a></p>
<p><br class="clear"/><br />
Можно достаточно легко навести порядок с проводами, вот что у меня получилось с моей скромной конфигурацией:</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-my-conf.jpg"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-my-conf-460x376.jpg" alt="" title="Corsair Graphite 600T My Configuration" width="460" height="376" class="alignleft size-medium wp-image-1921" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-my-conf-back.jpg"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-my-conf-back-460x377.jpg" alt="" title="Corsair Graphite 600T My Configuration Backside" width="460" height="377" class="alignleft size-medium wp-image-1922" /></a></p>
<p>Подсветка &mdash; белая и не раздражает:<br />
<a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-light.jpg"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-light-246x460.jpg" alt="" title="Corsair Graphite 600T Backlight" width="246" height="460" class="alignleft size-medium wp-image-1924" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-light-zoomin.jpg"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-light-zoomin-395x460.jpg" alt="" title="Corsair Graphite 600t Backlight ZoomIn" width="395" height="460" class="alignleft size-medium wp-image-1925" /></a></p>
<p><br class="clear"/><br />
Пылевые фильтры &#8211; мелочь, а приятно (для кулера на винчестерах, и для БП):</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-filter.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-filter-460x334.png" alt="" title="Corsair Graphite 600T Filter for HDD cooler" width="460" height="334" class="alignleft size-medium wp-image-1914" /></a><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-filter-power.png"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-filter-power-460x349.png" alt="" title="Corsair Graphite 600T Filter Power" width="460" height="349" class="alignleft size-medium wp-image-1915" /></a></p>
<p>Ну и напоследок фотография &laquo;Corsair VS Codegen&raquo;:</p>
<p><a href="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-vs-codegen.jpg"><img src="http://anton.shevchuk.name/wp-content/uploads/2011/06/corsair-graphite-600t-vs-codegen-460x399.jpg" alt="" title="Corsair Graphite 600T VS Codegen" width="460" height="399" class="aligncenter size-medium wp-image-1923" /></a></p>
<p><br class="clear"/><br />
Ну еще из спецификации и мной замеченного:</p>
<ul>
<li>Для материнок mATX и ATX</li>
<li>6 слотов для винчестеров (можно и 2.5&#8243; ставить)</li>
<li>4 слота для 5.25&#8243; устройств (я правда так ничего и не поставил)</li>
<li>Два 200мм вентилятора с подсветкой (800RPM, 24dB Max)</li>
<li>Один 120мм вентилятор</li>
<li>Прорезиненные ножки &mdash; корпус без значительных усилий по полу не поедет</li>
</ul>
<h3>Недостатки</h3>
<p>Самым главным недостатком данного корпуса считаю цену, если на Amazon цена еще приемлема, и составляет <a href="http://www.amazon.com/gp/product/B003Y0R1GO/ref=as_li_tf_tl?ie=UTF8&#038;tag=antoshev-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399377&#038;creativeASIN=B003Y0R1GO">$139.99</a>, то у нас эта цифра выростает до <a href="http://www.3ona51.com/ru/cases/corsair-graphite-600t/index.html">$232</a> (теперь у меня есть дисконт в 3%, если что &mdash; стучите в <a href="https://twitter.com/#!/AntonShevchuk">твиттер</a>).</p>
<p>Ну и еще по мелочи:</p>
<ul>
<li>Все же корпус не маленький, не у всех найдется место под столом (особенно это касается &laquo;компьютерных&raquo; столов)</li>
<li>Карманы для винчестеров не сидят плотно, и имеют значительный люфт, хотя под весом винтов не болтаются</li>
<li>Для верхней панели так и просится крышка, или хотя бы заглушки для портов &mdash; сборничек пыли обеспечен</li>
<li>Слишком близко расположены к друг другу слоты USB &mdash; если у вас флешка &laquo;толстовата&raquo;, то соседям она будет мешать</li>
<li>Регулятору скорости вращения вентиляторов не хватает режима ВЫКЛ</li>
<li>Инструкция для чайников &mdash; таковой не имеется, а очень бы хотелось, да с <a href="http://www.corsair.com/blog/how-to-identify-your-graphite-series-600t-fan-controller-cables/">наглядными иллюстрациями</a></li>
</ul>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/my-life/review-boogie-board/" title="Обзор Boogie Board">Обзор Boogie Board</a></li><li><a href="http://anton.shevchuk.name/my-life/nook-barnes-noble-review/" title="Обзор Nook от Barnes &#038; Noble">Обзор Nook от Barnes &#038; Noble</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=JStiQmP0xxw:hsWMqqgjhDw:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=JStiQmP0xxw:hsWMqqgjhDw:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=JStiQmP0xxw:hsWMqqgjhDw:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/JStiQmP0xxw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/my-life/review-corsair-graphite-series-600t/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/my-life/review-corsair-graphite-series-600t/</feedburner:origLink></item>
		<item>
		<title>Google Closure для начинающих. Компоненты</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/FEbUSpBJH2w/</link>
		<comments>http://anton.shevchuk.name/javascript/google-closure-for-beginners-components/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 10:06:19 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Closure]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1789</guid>
		<description><![CDATA[Продолжим изучение Google Closure Library. В данной статье я постараюсь отклонится от &#171;jQuery way&#187; и продемонстрировать как удобны в использовании и просты в создании компоненты фреймворка. Давненько я технических статей не писал, отвыкли небось, но отвлекать не буду, читайте на здоровье ;) Это все же, в большей степени, перевод статьи из официальной документации, но он [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/01/google-closure-logo.png" alt="" title="Google Closure" width="128" height="128" class="aligncenter size-full wp-image-1683" /></p>
<p>Продолжим изучение <a href="http://code.google.com/closure/library/">Google Closure Library</a>. В данной статье я постараюсь отклонится от &laquo;jQuery way&raquo; и продемонстрировать как удобны в использовании и просты в создании компоненты фреймворка.</p>
<blockquote><p>Давненько я технических статей не писал, отвыкли небось, но отвлекать не буду, читайте на здоровье ;)</p></blockquote>
<p><span id="more-1789"></span></p>
<blockquote><p>Это все же, в большей степени, перевод <a href="http://code.google.com/p/closure-library/wiki/IntroToComponents">статьи из официальной документации</a>, но он слегка сокращен и адаптирован</p></blockquote>
<p>Много вкусного несет в себе пакет goog.ui, я совсем чуть-чуть рассказывал о нем в <a href="http://anton.shevchuk.name/javascript/google-closure-for-beginners-with-examples/">предыдущей статье</a>, но напомню &mdash; этот пакет содержит в себе готовые компоненты для реализации интерфейсов: кнопки, меню, календари, и т.д.</p>
<p>Основой всех компонентов является класс goog.ui.Component, и для создания своих компонентов без него не обойтись. Он требует от нас определенную структуры класса состоящую из шести методов, которые описывают жизненный цикл компонента (в хронологическом порядке):</p>
<table class="inline">
<tr>
<th width="220px">Метод</th>
<th>Описание метода (жизненного цикла)</th>
</tr>
<tr>
<td>constructor</td>
<td>создание компонента</td>
</tr>
<tr>
<td>createDom()</td>
<td rowspan="2">создание DOM структуры компонента</td>
</tr>
<tr>
<td>decorateInternal() (optional)</td>
</tr>
<tr>
<td>enterDocument()</td>
<td>после создания DOM структуры будет запущен данный метод (обработчики событий вешаем тут)</td>
</tr>
<tr>
<td>exitDocument()</td>
<td>перед удалением DOM структуры (чистим обработчики событий)</td>
</tr>
<tr>
<td>dispose()</td>
<td>удаление компонента</td>
</tr>
</table>
<p>Отдельно особняком стоит метод <code>canDecorate(existingElement)</code> &mdash; он расскажет нам можно ли создать компонент основываясь на уже существующих элементах (existingElement). По умолчанию, суперкласс всегда возвращает true.</p>
<p>И так, перейдем к созданию своего компонента&#8230;</p>
<h2>Инициализация</h2>
<p>Начинается все с шага ноль &mdash; подключения <code>goog.ui.Component</code>, и объявления имени нашего компонента.</p>
<pre class="brush: jscript; title: ; notranslate">
goog.provide('tutorial.component');

goog.require('goog.ui.Component');
</pre>
<p>Теперь шаг первый &mdash; это создание конструктора компонента:</p>
<pre class="brush: jscript; title: ; notranslate">
tutorial.component = function(opt_label, opt_domHelper) {
    // вызов конструктора предка
    goog.ui.Component.call(this, opt_domHelper);

    /**
    * Заголовок виджета
    * @type String
    * @private
    */
    this.initialLabel_ = opt_label || 'Link';

    /**
    * Наш обработчик событий
    * @type goog.events.EventHandler
    * @private
    */
    this.eh_ = new goog.events.EventHandler(this);

    /**
    * Обработчик клавиатуры, у нас в компоненте не используется, но правила именования следует соблюдать
    *
    * @type {goog.events.KeyHandler?}
    * @private
    */
    this.kh_ = null;
};
// наследуем goog.ui.Component
goog.inherits(tutorial.component, goog.ui.Component);
</pre>
<h2>Создание DOM структуры</h2>
<p>После создания экземпляра компонента необходимо создать соответствующую DOM структуру, для этого потребуется реализовать метод <code>createDom()</code> и <code>decorateInternal()</code> (опционально):</p>
<table class="inline">
<tr>
<td>createDom()</td>
<td>создание DOM структуры компонента, и сохранение в <code>this.element_</code></td>
</tr>
<tr>
<td>decorateInternal() (optional)</td>
<td>создаем компонент используя уже существующую DOM структуру, и так же сохраняем в <code>this.element_</code></td>
</tr>
</table>
<p>Ну и пример кода:</p>
<pre class="brush: jscript; title: ; notranslate">

/**
 * создаём необходимую нам DOM структуру
 * в нашем примере необходим лишь один div
 */
tutorial.component.prototype.createDom = function() {
    // вызываем decorateInternal который внесет изменения в новосозданный элемент
    this.decorateInternal(this.dom_.createElement('div'));
};

/**
 * изменяем существующую структуру под наши нужды
 *
 * @param {HTMLElement} element DIV который мы изменяем
 */
tutorial.component.prototype.decorateInternal = function(element) {
    tutorial.component.superClass_.decorateInternal.call(this, element);

    var elem = this.getElement();
    goog.dom.classes.add(elem, 'tutorial-component');
    goog.dom.setTextContent(elem, this.initialLabel_);

};
</pre>
<h2>Еще один шаг &mdash; после того как построили DOM</h2>
<p>Зачастую, инициализация компонента требует уже заранее подготовленную структуру DOM. К примеру, вы создаете popup меню и вам необходимо повесить обработчик на div с id=&#8221;menu&#8221;, но этот элемент мы создаем лишь на этапе <code>createDom</code>, таким образом у нас получается неувязочка, но не стоит беспокоится, создатели фреймворка приберегли на этот случай метод <code>enterDocument()</code>:</p>
<table class="inline">
<tr>
<td>enterDocument()</td>
<td>в данном методе реализуют функционал, который требует наличие структуры компонента в DOM</td>
</tr>
</table>
<p>Реализуя метод <code>enterDocument()</code> необходимо всегда вызывать одноименный метод суперкласса, который вызовет все дочерние компоненты. Собственно, в методе <code>enterDocument()</code> лучше всего описывать методы, которые вешают обработчики событий на элементы DOM, и это тем более обязательно для элементов, которые не являются частью компонента (а лишь добавляют нам пачку зависимостей =).</p>
<p>Но вернемся к нашему примеру:</p>
<pre class="brush: jscript; title: ; notranslate">
tutorial.component.prototype.enterDocument = function() {
    // вызываем метод супер класса
    tutorial.component.superClass_.enterDocument.call(this);

    // простой обработчик на click
    this.eh_.listen(
        this.getElement(),
        goog.events.EventType.CLICK,
        this.onDivClicked_
    );
};
</pre>
<p>Резюмируя &mdash; не хочешь проблем с обработчиками &mdash; вешай их в enterDocument().</p>
<h2>Методы render() и decorate()</h2>
<p>Если мы все делали правильно, то можем попробовать инициализировать свой компонент используя метод <code>render()</code>:</p>
<pre class="brush: jscript; title: ; notranslate">
var comp1 = new tutorial.component(&quot;Button&quot;);
     comp1.render(goog.dom.$('button1'));
</pre>
<p>Метод <code>render()</code> вызывает <code>createDom()</code>, получившийся <code>element_</code> помещает в DOM и затем вызывает <code>enterDocument()</code>. Если метод <code>render()</code> дергать с параметром Element (в примере выше это &#8220;button1&#8243;), то <code>element_</code> будет помещен внутрь него, иначе станет потомком <code>body</code>.</p>
<p>В примере есть и второй способ вызова компонента:</p>
<pre class="brush: jscript; title: ; notranslate">
var comp2 = new tutorial.component(&quot;Button Two&quot;);
     comp2.decorate(goog.dom.$('button2'));
</pre>
<p>Метод <code>decorate()</code> получает уже готовый <code>element_</code> в качестве параметра, который и скармливает методу <code>decorateInternal()</code>, и затем точно так же вызывается <code>enterDocument()</code>. </p>
<blockquote><p>Внутри компонента вы не должны вызывать методы <code>render()</code> или <code>decorate()</code>. Хотя, если вы не используете методы <code>render()</code> или <code>decorate()</code>, следует вызывать <code>enterDocument()</code> после того как будут добавлены все необходимые элементы компонента в DOM</p></blockquote>
<h2>&laquo;Я тебя породил, я тебя и уничтожу&raquo;</h2>
<p>Создавая компонент не забИвайте описывать методы для подчистки DOM&#8217;а после его удаления, для этого следует подчистить все, что мы наворотили в методах <code>createDom()</code> и <code>enterDocument()</code>. В этом нам помогут следующие методы:</p>
<table class="inline">
<tr>
<td>exitDocument()</td>
<td>вызывается перед удалением DOM структуры &mdash; тут чистим обработчики событий</td>
</tr>
<tr>
<td>dispose()</td>
<td>удаление компонента и DOM элементов</td>
</tr>
</table>
<p>Ну и пример метода <code>exitDocument()</code>:</p>
<pre class="brush: jscript; title: ; notranslate">
tutorial.component.prototype.exitDocument = function() {
    tutorial.component.superClass_.exitDocument.call(this);

    this.eh_.unlisten(
        this.getElement(),
        goog.events.EventType.CLICK,
        this.onDivClicked_
    );

    this.eh_.unlisten(
        this.getElement(),
        [goog.events.EventType.MOUSEOVER, goog.events.EventType.MOUSEOUT],
        this.onDivHover_
    );
};
</pre>
<blockquote><p>Обратите внимание на вызов метода <code>exitDocument()</code> нашего суперкласса &mdash; данная махинация необходима для вызова методов <code>exitDocument()</code> у всех дочерних компонентов (если таковые имеются). Этот вызов обязателен!</p></blockquote>
<p>Теперь <code>dispose()</code>:</p>
<pre class="brush: jscript; title: ; notranslate">
tutorial.component.prototype.dispose = function() {
    if (!this.isDisposed()) {
        tutorial.component.superClass_.dispose.call(this);
        this.eh_.dispose();
        if (this.kh_) {
          this.kh_.dispose();
        }
    }
};
</pre>
<p>Опять же &mdash; дергаем супер класс, затем подчищаем обработчики событий.</p>
<h2>В заключение</h2>
<p>Как видите &mdash; в создании компонента нет ничего сложного, стоит лишь следовать простым правилам, которые диктует на фреймворк, и вы не запутаетесь и все будет работать.</p>
<p>И да, пощупать пример можно на страничке <a href="http://anton.shevchuk.name/wp-demo/closure-tutorials/component.html">closure-tutorials/component.html</a>.</p>
<h2>Читаем еще</h2>
<ul>
<li><a href="http://code.google.com/p/closure-library/wiki/IntroToComponents">Introduces goog.ui.Component</a> &mdash; первоисточник статьи</li>
<li><a href="http://anton.shevchuk.name/javascript/google-closure-for-beginners-with-examples/">Google Closure для начинающих</a></li>
</ul>
<h2>Offtopic</h2>
<p>Я тут еще в <a href="https://twitter.com/#!/AntonShevchuk">твиттер</a> на досуге пишу, так что следите и не пропустите ;)</p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/javascript/google-closure-for-beginners-with-examples/" title="Google Closure руководство для начинающих">Google Closure руководство для начинающих</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=FEbUSpBJH2w:vetNF1Qr6l4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=FEbUSpBJH2w:vetNF1Qr6l4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=FEbUSpBJH2w:vetNF1Qr6l4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/FEbUSpBJH2w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/javascript/google-closure-for-beginners-components/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/javascript/google-closure-for-beginners-components/</feedburner:origLink></item>
		<item>
		<title>Мастер-класс по Sphinx</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/u9fYG9s0Dco/</link>
		<comments>http://anton.shevchuk.name/internet/sphinx-master-class/#comments</comments>
		<pubDate>Tue, 31 May 2011 08:59:08 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[Sphinx]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1883</guid>
		<description><![CDATA[В субботу, 18-го июня в Киеве пройдет мастер-класс создателя движка полнотекстового поиска Sphinx Андрея Аксенова &#171;Как готовить Sphinx&#187;. Мастер-класс будет интересен разработчикам, руководителям и владельцам проектов, которые сталкиваются с проблемой поиска при высоких загрузках. Sphinx используют такие монстры, как CraigsList, DailyMotion, Meetup, HupPages, HabraHabr и еще десятки высоконагруженных сайтов. Андрей Аксенов выступал на многочисленных конференциях [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://anton.shevchuk.name/wp-content/uploads/2011/05/sphinx.jpg" alt="" title="sphinx" width="200" height="51" class="aligncenter size-full wp-image-1884" /></p>
<p>В субботу, 18-го июня в Киеве пройдет мастер-класс создателя  движка полнотекстового поиска Sphinx Андрея Аксенова &laquo;Как готовить Sphinx&raquo;. </p>
<p>Мастер-класс будет интересен разработчикам, руководителям и владельцам проектов, которые сталкиваются с проблемой поиска при высоких загрузках.</p>
<p>Sphinx используют такие монстры, как CraigsList, DailyMotion, Meetup, HupPages, HabraHabr и еще десятки высоконагруженных сайтов. Андрей Аксенов  выступал на многочисленных конференциях в России: &laquo;DevPoint 1-2&raquo;, &laquo;РИТ&raquo;, &laquo;DevConf 2011&raquo;, &laquo;HighLoad ++&raquo;. Организатор конференции пользователей Sphinx в Москве. Автор нашумевшего доклада &laquo;Как прекратить писать&raquo;.</p>
<p>Дополнительная информация и подробный план мастер-класса можна посмотреть на сайте <a href="http://www.smartme.com.ua/sphinx-workshop/">http://www.smartme.com.ua/sphinx-workshop/</a></p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/php/zend-framework-day/" title="Zend Framework Day">Zend Framework Day</a></li><li><a href="http://anton.shevchuk.name/html-and-css/master-klass-yuriy-akella-artyukh/" title="Мастер-класс Юры Артюха">Мастер-класс Юры Артюха</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-2011-piter/" title="Конференция ZFConf 2011">Конференция ZFConf 2011</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-ukraine/" title="ZFConf Ukraine">ZFConf Ukraine</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class-feedback/" title="Анонс мастер-классов по JavaScript&#8217;у">Анонс мастер-классов по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class/" title="Мастер-классы по JavaScript&#8217;у">Мастер-классы по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/php/sphinx-for-not-full-text-search/" title="Sphinx для НЕ полнотекстового поиска">Sphinx для НЕ полнотекстового поиска</a></li><li><a href="http://anton.shevchuk.name/internet/pdfeed-rss-to-pdf-generator/" title="PDFEED &#8211; или RSS2PDF в новом обличье">PDFEED &#8211; или RSS2PDF в новом обличье</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=u9fYG9s0Dco:3e6Mn7TT9Cs:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=u9fYG9s0Dco:3e6Mn7TT9Cs:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=u9fYG9s0Dco:3e6Mn7TT9Cs:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/u9fYG9s0Dco" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/internet/sphinx-master-class/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/internet/sphinx-master-class/</feedburner:origLink></item>
		<item>
		<title>Конференция ZFConf 2011</title>
		<link>http://feedproxy.google.com/~r/AntonShevchuk/~3/S8iS3Ze4VrY/</link>
		<comments>http://anton.shevchuk.name/php/zfconf-2011-piter/#comments</comments>
		<pubDate>Tue, 10 May 2011 14:24:38 +0000</pubDate>
		<dc:creator>Anton Shevchuk</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[announcement]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://anton.shevchuk.name/?p=1865</guid>
		<description><![CDATA[Если вы не понаслышке знакомы с Zend Framework&#8217;ом, то вам стоит посетить ZFConf. Сейчас уже открыта финальная регистрация на ZFConf 2011 — вторую российскую конференцию по Zend Framework. Основные подготовительные работы по конференции закончены. Доклады сформированы. Среди спикеров представители KnpLabs, Magento, JetBrains, Sphinx и других известных компаний. Если Вы проходили предварительную регистрацию, то для прохождения [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.zfconf.ru/" target="_blank"><img src="http://cs9981.vkontakte.ru/g14951507/a_78058dc0.jpg" width="192" height="139" class="aligncenter"></a><br />
Если вы не понаслышке знакомы с Zend Framework&#8217;ом, то вам стоит посетить ZFConf. Сейчас уже открыта <a href="http://www.zfconf.ru/registration/" target="_blank">финальная регистрация</a> на ZFConf 2011 — вторую российскую конференцию по Zend Framework.</p>
<p>Основные подготовительные работы по конференции закончены. Доклады сформированы. Среди спикеров представители KnpLabs, Magento, JetBrains, Sphinx и других известных компаний.</p>
<p><span id="more-1865"></span></p>
<p>Если Вы проходили предварительную регистрацию, то для прохождения финальной регистрации Вам нужно перейти по специальной ссылке, отправленной на e-mail. Введенную ранее информацию нужно будет только подтвердить. Если ссылка не приходила Вам, ее можно запросить через <a href="http://www.zfconf.ru/get-registration-path/" target="_blank">специальную форму</a>.</p>
<p>Пожалуйста, обратите внимание на то, что <strong>изменилось <a href="http://www.zfconf.ru/2011/location/" target="_blank">место проведения</a></strong>! Мероприятие будет проходить на прошлогодней площадке — в актовом зале ЛГТЦ (Ленгипротранс-Центр), по адресу: Московский пр., 143, ст. м. «Электросила». Кофе-брейки и обсуждения на флипчартах будут проходить в фойе.</p>
<h2>Cписок докладов</h2>
<ul>
<li><strong><a href="http://www.zfconf.ru/2011/topics/flexible-architecture-using-dependency-injection/" target="_blank">Гибкая архитектура Zend Framework приложений с использованием Dependency Injection</a></strong> &mdash; Алексей Качаев (<a href="http://cogniance.com/" target="_blank">Сogniance</a>, Senior PHP Developer)</li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/performance-increasing-with-phpdaemon-varnish-esi/" target="_blank">Воюем за ресурсы: Повышение производительности Zend Framework приложения с помощью phpDaemon, Varnish и ESI</a></strong>  &mdash; Алексей Качаев (<a href="http://cogniance.com/" target="_blank">Сogniance</a>, Senior PHP Developer)</li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/behavior-driven-development/" target="_blank">Behavior Driven Development в PHP и Zend Framework</a></strong>  &mdash; Константин Кудряшов (<a href="http://www.knplabs.com/" target="_blank">KnpLabs</a>, Senior Web Developer)</li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/multitasking-distributed-system-with-job-queue/" target="_blank">Разделение труда: Организация многозадачной, распределенной системы в Zend Framework с помощью Job Queue</a></strong>  &mdash; Александр Готгельф (<a href="http://www.magentocommerce.com/" target="_blank">Magento</a>, PHP-разработчик) </li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/how-can-help-development-environment/" target="_blank">Как может помочь среда разработки при написании приложения на Zend Framework?</a></strong>  &mdash; Николай Матвеев (<a href="http://www.jetbrains.com/" target="_blank">JetBrains</a>, разработчик) </li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/creating-rest-api-for-third-party-developers-and-mobile-devices-with-oauth/" target="_blank">Создание REST-API для сторонних разработчиков и мобильных устройств с авторизацией по протоколу OAuth 1.0</a></strong>  &mdash; Дмитрий Чижевский (<a href="http://zenmoney.ru/" target="_blank">Дзен-мани</a>, разработчик) </li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/fat-model-through-orm-development-history/" target="_blank">Толстая модель: История разработки собственного ORM</a></strong>  &mdash; Михаил Шамин (<a href="http://geometria.ru/" target="_blank">Геометрия</a>, ведущий разработчик) </li>
<li><strong><a href="http://www.zfconf.ru/2011/topics/what-is-sphinx-and-how-use-it-with-php/" target="_blank">Что такое Sphinx, зачем он вообще нужен и как его использовать с PHP (от простого индекса до поискового кластера)</a></strong>  &mdash; Владимир Федорков (<a href="http://sphinxsearch.com/" target="_blank">Sphinx</a>, Director of Professional Services)</li>
</ul>
<p>Стоимость участия в мероприятии составит 1500 руб. В данную сумму входит: участие в самой конференции, кофе-брейки (от внешней кейтеринг-компании), пакет материалов участника и доступ к профессиональным видеозаписям докладов (после мероприятия). Доступно <a href="http://www.zfconf.ru/payment-types/" target="_blank">множество способов оплаты</a>.</p>
<p>Торопитесь, <strong>количество мест ограничено</strong>!</p>
<p>Обязательно следите за последними новостями:</p>
<ul>
<li><strong>RSS-канал:</strong> <a href="http://feeds.feedburner.com/zfconf" target="_blank">feeds.feedburner.com/zfconf</a></li>
<li><strong>Twitter:</strong> <a href="http://twitter.com/zfconf" target="_blank">@zfconf</a></li>
<li><strong>Группа ВКонтакте:</strong> <a href="http://vkontakte.ru/club14951507" target="_blank">vkontakte.ru/club14951507</a></li>
</ul>
<p><strong>Организатор:</strong> <a href="http://www.wizartech.ru/" target="_blank">компания Wizartech</a><br />
<strong>Партнеры:</strong> <a href="http://zendframework.ru/" target="_blank">сообщество zendframework.ru</a> и <a href="http://zfconf.org.ua/" target="_blank">конференция ZFConf Ukraine</a></p>
<h3  class="related_post_title">Другие посты на эту тему</h3><ul class="related_post"><li><a href="http://anton.shevchuk.name/php/zend-framework-day/" title="Zend Framework Day">Zend Framework Day</a></li><li><a href="http://anton.shevchuk.name/html-and-css/master-klass-yuriy-akella-artyukh/" title="Мастер-класс Юры Артюха">Мастер-класс Юры Артюха</a></li><li><a href="http://anton.shevchuk.name/internet/sphinx-master-class/" title="Мастер-класс по Sphinx">Мастер-класс по Sphinx</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-ukraine/" title="ZFConf Ukraine">ZFConf Ukraine</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class-feedback/" title="Анонс мастер-классов по JavaScript&#8217;у">Анонс мастер-классов по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/php/facing-refucktoring/" title="Facing refucktoring">Facing refucktoring</a></li><li><a href="http://anton.shevchuk.name/javascript/javascript-master-class/" title="Мастер-классы по JavaScript&#8217;у">Мастер-классы по JavaScript&#8217;у</a></li><li><a href="http://anton.shevchuk.name/php/zfconf-feedback/" title="Под впечатлением от ZFConf">Под впечатлением от ZFConf</a></li></ul><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=S8iS3Ze4VrY:mJI90LCk9L4:D7DqB2pKExk"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?i=S8iS3Ze4VrY:mJI90LCk9L4:D7DqB2pKExk" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/AntonShevchuk?a=S8iS3Ze4VrY:mJI90LCk9L4:I9og5sOYxJI"><img src="http://feeds.feedburner.com/~ff/AntonShevchuk?d=I9og5sOYxJI" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/AntonShevchuk/~4/S8iS3Ze4VrY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://anton.shevchuk.name/php/zfconf-2011-piter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://anton.shevchuk.name/php/zfconf-2011-piter/</feedburner:origLink></item>
	<media:rating>nonadult</media:rating></channel>
</rss>

