tag:blogger.com,1999:blog-22186344060375834862024-03-05T08:16:10.583+03:00Будни веб-разработчикаTo PHP or not to PHP?Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-2218634406037583486.post-72164876807473159092012-09-01T22:21:00.001+04:002012-09-01T22:21:19.164+04:00Создание базы данных и пользователя СУБД MySQL<div dir="ltr" style="text-align: left;" trbidi="on">
Давно меня здесь не было. Вряд ли я поделюсь с читателем сегодня чем-то новым. Это просто короткая заметка, как создать пользователя в БД MySQL из консоли.<br />
Создание новой БД (в данном случае amarok) с кодировкой UTF-8, создание нового пользователя и выдача ему новых прав на базу данных делается всего в 4 команды:<br /><br />
<script src="https://gist.github.com/3582191.js"></script><br />
Надеюсь, что благодаря этой заметке у вас не возникнет больше проблем с развертыванием новых проектов из консоли. Приятного кодинга!</div>
Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-65248951905093794332011-12-29T20:54:00.000+04:002011-12-31T10:51:57.896+04:00В преддверии 2012<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqT7cZb1zdOdaA6AbiHx-M5mHmbXpWKMAtPuuWbdje3Zi48WHROiZgm6JGULizA3T5cCUmPWe-cIS3cfryztRoBeFRS9lk6vECOl4de1SFc_LRE4YaTf8RYtMchW1P9GcgqARZ5Ep8gOI/s1600/578c5f431860.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqT7cZb1zdOdaA6AbiHx-M5mHmbXpWKMAtPuuWbdje3Zi48WHROiZgm6JGULizA3T5cCUmPWe-cIS3cfryztRoBeFRS9lk6vECOl4de1SFc_LRE4YaTf8RYtMchW1P9GcgqARZ5Ep8gOI/s1600/578c5f431860.png" /></a>Итак, подходит к концу 2011 год. Не хотелось бы просто брать и закрывать молча эту страницу. Уже весьма скоро мы все соберемся за столами семьями, поднимем бокалы шампанского, выслушаем нашего гаранта конституции и начнется новая итерация. Хочется взглянуть на итоги того, что же принес этот год. Во-первых, лично мне он принес огромное количество опыта и хорошую работу. Благодаря опыту, ко многим вещам при разработке я стал относиться куда более серьезнее и осмысленнее. Скорость изучения новых технологий подскочила на новый уровень. В следующем году буду стремиться продолжать расширять свои познания.<br />
<div class="" style="clear: both; text-align: center;">
</div>
<br />
<br />
В этом году я освоил следующие программные / серверные / девелоперские вещи: PhpStorm, Membase, MongoDB, Gearman, nginx, реализовал свой первый RESTful API, начал использовать различные веб-сервисы Amazon (чудные облачные технологии, должен признаться), попробовал разработку под Android... Что ж, перечислять можно долго, но это уже весьма малозначимые вещи.<br />
<br />
<b>Что же случилось с миром веба в 2011 году?</b> Постараюсь бегло взглянуть на события уходящего года.<br />
<br />
<br />
<a href="http://www.blogger.com/goog_1830095628" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRnp3gaqPGpytP1dqRxc2zeWi-q0lP72TzuyMi2owMLQmL5vjDt_H4ucpi5jv_KT1w593J58hV5MgRe1gG7E2KiGWlqPCxVLTmOdt_erMWaxbouHy5c5_jRL5kMiKTeXRCLl42yIgHoAY/s1600/1894964446781802922.png" /></a>Вспоминается начало 2011. Не знаю, кто как, но я почему-то ждал тогда IE9. Надежда умирает последней? Да, оказалось так. Да, он стал лучше, да, он стал чертовски быстрым, но некоторые проблемы как были, так и остались. Ныне ходят слухи, да и не только слухи про IE10. Любой желающий уже может <a href="http://ie.microsoft.com/testdrive/info/downloads/">взглянуть на превью версию</a>. Но как-то верится в него с трудом, если честно.<br />
<br />
<a href="http://www.blogger.com/goog_1830095628" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgl65aJuzzeFwf0ccBVoIJAfqWZRhSRVTIw0522IWeqPU3pIYaZyM1rPh-2SdVgJVbccTGd7qLu2VNnqdMTEsHbhm7tAo5y6LkmjZmAxP-bnKlCJlTlQIMLs3xERhCeQP06EWwOCseCb2Y/s1600/One_Mozilla-Logo-_white_.png" /></a>Mozilla перевела свои продукты Firefox и Thunderbird на крайне короткие итерации разработки (как я понял, чуть больше месяца), последовав примеру Google. Теперь как у Firefox, так и у Thunderbird версии обновляются синхронно. К тому же Firefox теперь обновляется довольно тихо и обыватель этого даже и не замечает. Считаю этот шаг для Mozilla крайне правильным. Так браузер будет развиваться динамичнее и различные новые фишки будут доходить до пользователя куда быстрее, пусть и маленькими порциями. Хочется также отметить, что Mozilla, как бы то ни было парадоксально, продолжает жить за счет своего главного конкурента на браузерном рынке Google. Не так давно был продлен весьма дорогостоящий контракт на то, что в Firefox поиском по умолчанию будет оставаться Google.<br />
<br />
<a href="http://www.blogger.com/goog_1830095628" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip9dwLhceR8FMdJh-gOwrEkuR3EoL4CU_SyjDkMtC6hJXPW_3i1sBA3aEzF_Nn29-avrtoEPqrgn2aeauG9jt2Rg-t3NaImOOJSxP2zB7rRQPjgAyN7g4oTNhge3dxMfW1dw1VZ2CqwIo/s1600/Opera_O.png" /></a>Opera Labs продолжают экспериментировать с различными новейшими технологиями, которые позволяет стандарт HTML5. Если мне не изменяет память, то недавно они выпустили первую 64-битную версию браузера. Хочется пожелать команде Opera великих свершений в их ожиданиях с экспериментами.<br />
<br />
<a href="http://www.blogger.com/goog_1830095628" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxLrXiVYMR9jCpJRBGMt3W4J0t60TsFW-1IGyMb1WFdd0dspHULm33aam_TbfhYdPgFbbt2p2XT3zJz0GAHNvDZtVaNp37eZ3KZJ8hTcm7SjEY9fGq1oFU3qAopNI6HprLbSY4HPAMrtM/s1600/Chrome.png" /></a>Chrome. Не могу говорить не предвзято об этом браузере лишь потому, что я его недолюбливаю. Но попробую. В 2011 этот браузер как всегда продолжает радовать своих пользователей скоростью. Ближе к концу года он даже обогнал Firefox по популярности. Теперь это самый популярный браузер в мире. Что в нем стало серьезно лучше? Хм, навскидку и не скажешь. Хотя да, в нем появились приложения (так называемые <a href="http://code.google.com/chrome/apps/docs/developers_guide.html">hosted apps</a>). Но пожалуй это все.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3CLoNtYhJNqGinW8t2moFkBQimcBs7dbJB4DjGXhtMjwdGEMqDlG6eLgaSx5EJXoqIqj2TMp1Iuk0lJH41FmYAd-5X8jutm6kQQZW6AqDeD-_TRQbqLULvdWBCRyLXJM5t4TXW1GweIA/s1600/safari1.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3CLoNtYhJNqGinW8t2moFkBQimcBs7dbJB4DjGXhtMjwdGEMqDlG6eLgaSx5EJXoqIqj2TMp1Iuk0lJH41FmYAd-5X8jutm6kQQZW6AqDeD-_TRQbqLULvdWBCRyLXJM5t4TXW1GweIA/s1600/safari1.png" /></a>А что Safari? Наверное, это один из самых консервативных браузеров в этом году. Честно говоря, Safari обновляю на своем десктопе регулярно, но каких-либо серьезных изменений я не заметил. Хотя наверняка Apple продолжает обновлять внутренний движок Webkit до последней версии перед каждым релизом Safari. И это не может не радовать. <br />
<br />
<a href="http://www.blogger.com/goog_1830095628" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih2luqxGDdjZEoHU2xNgXv8iaiwIpFvYFX_mr7as_POGamP_OABhylpaB7gsc-Sbu_KUd7yYmhCfs3uZfWAGzlUzU1Ozb95ZJDgRpBQs2PENJytKAMuC4KiQjiNDFn-nJG06DAa9y51pQ/s1600/php.png" /></a>PHP 5.4? Пожалуй вторая вещь которую я очень ждал и которую так и не дождался. Будем надеяться. В конце концов, 25 декабря уже вышла RC4, так что ждать осталось совсем недолго. Нам обещают еще больше производительности, mb_string вшитый по умолчанию, <a href="http://dron.by/post/vvedenie-v-traits/">traits</a> (aka <a href="http://rubydev.ru/2010/08/ruby_module/">mixins</a>) и много других здоровских мелочей.<br />
<br />
Очень многое еще хочется написать, но уже день 31-го числа и просто физически не остается времени на это. На этом все.<br />
<br />
Желаю всем счастливого Нового Года!</div>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-6936629999671931052011-05-23T08:48:00.000+04:002011-05-23T11:04:57.954+04:00Standard PHP Library (SPL) Exceptions<div dir="ltr" style="text-align: left;" trbidi="on">Как известно, в PHP помимо стандартного класса Exception имеются также и унаследованные от них (собственно SPL-исключения). Иерархию наследования на официальном мануале любезно <a href="http://www.php.net/manual/en/spl.exceptions.php#102226">предоставил <b class="user">Dawid Krysiak</b></a>. Всем PHP-кодерам советую с ней ознакомиться:<br />
<ul style="text-align: left;"><li>Exception</li>
<ul><li>LogicException</li>
<ul><li>BadFunctionCallException</li>
<ul><li>BadMethodCallException</li>
</ul><li>DomainException</li>
<li>InvalidArgumentException</li>
<li>LengthException</li>
<li>OutOfRangeException</li>
</ul><li>RuntimeException</li>
<ul><li>OutOfBoundsException</li>
<li>OverflowException</li>
<li>RangeException</li>
<li>UnderflowException</li>
<li>UnexpectedValueException</li>
</ul></ul></ul>Кидайте SPL-исключения, наиболее подходящие по контексту причины потенциальной ошибки или неверных входных данных. Этим вы помогаете людям, которые будут в будущем разбираться в вашем коде или использовать его.</div>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-90479230625145553382011-05-15T16:36:00.000+04:002011-05-15T16:36:16.842+04:00Проблема времени Windows / Ubuntu на одном компьютере<div dir="ltr" style="text-align: left;" trbidi="on"><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7TlM5WK_BY2aszgE9yRxr1kYm5m0i1TjEP8Vn_Eeze18C3xfOJmxKoxH7DrrwDvLVh3AN2Xpt7zq3Md2Qce80nAnV-WEqTXqqYcmu2Wqrn1Mjz5iDE6I1T0DDGEEO9zPsDetzDAMgSRo/s1600/clock_red.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7TlM5WK_BY2aszgE9yRxr1kYm5m0i1TjEP8Vn_Eeze18C3xfOJmxKoxH7DrrwDvLVh3AN2Xpt7zq3Md2Qce80nAnV-WEqTXqqYcmu2Wqrn1Mjz5iDE6I1T0DDGEEO9zPsDetzDAMgSRo/s1600/clock_red.png" /></a></div><br />
Я думаю, если у вас на разных [разделах] жесткого диска установлены <b>Windows </b>и <b>Ubuntu</b>, вы сталкивались с проблемой, что <b>Ubuntu </b>интерпретирует время BIOS как <b>UTC </b>и учитывает ваш часовой пояс, тем самым выставляя в <b>BIOS </b>время как <b>UTC </b>и отображая его правильно (+7 часов для Новосибирска). <b>Windows</b>, в свою очередь интерпретирует время <b>BIOS'а</b> как локальное и не "мучается" со всякими UTC.<br />
<br />
Проблема возникает в случае, когда вы загружаете <b>Windows </b>после <b>Ubuntu</b>. Время получается смещенным на 7 часов назад. Это очень раздражает, не так ли? Очень долго я жил с этим.<br />
Но, оказалось, от этого естественно есть лекарство. Лезем в <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">/etc/default/rcS</span> и меняем опцию <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">UTC</span><span class="Apple-style-span" style="font-family: inherit;"> </span>на <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">no</span>. Это решает все проблемы, описанные выше.<br />
<br />
Приятного всем кодинга на выходных дома! :)</div>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-57437700253563217922011-03-04T20:36:00.000+03:002011-03-04T20:36:23.854+03:00Форматирование JSON<div dir="ltr" style="text-align: left;" trbidi="on"><br />
<div dir="ltr" style="text-align: left;" trbidi="on">Сейчас работаю над проектом, в котором клиентские JavaScripts получают много JSON ответов от сервера. Я же занимаюсь разработкой back-end PHP скриптов и чтобы упростить жизнь своим коллегам по разбору JSON в браузерных консолях (будь то хоть Firebug, хоть Chrome), мне захотелось отдавать в debug режиме отформатированный читабельные JSON данные. Погуглив на эту тему, я сразу же <a href="http://recursive-design.com/blog/2008/03/11/format-json-with-php/">натолкнулся на необходимую функцию</a>, которой и хочу с вами сегодня поделиться:</div><br />
<pre class="prettyprint">/**
* Indents a flat JSON string to make it more human-readable.
* @param string $json The original JSON string to process.
* @return string Indented version of the original JSON string.
*/
function indent($json) {
$result = '';
$pos = 0;
$strLen = strlen($json);
$indentStr = ' ';
$newLine = "\n";
$prevChar = '';
$outOfQuotes = true;
for ($i = 0; $i <= $strLen; $i++) {
// Grab the next character in the string.
$char = substr($json, $i, 1);
// Are we inside a quoted string?
if ($char == '"' && $prevChar != '\\') {
$outOfQuotes = !$outOfQuotes;
// If this character is the end of an element,
// output a new line and indent the next line.
} else if (($char == '}' || $char == ']') && $outOfQuotes) {
$result .= $newLine;
$pos--;
for ($j = 0; $j < $pos; $j++) {
$result .= $indentStr;
}
}
// Add the character to the result string.
$result .= $char;
// If the last character was the beginning of an element,
// output a new line and indent the next line.
if (($char == ',' || $char == '{' || $char == '[') && $outOfQuotes) {
$result .= $newLine;
if ($char == '{' || $char == '[') {
$pos++;
}
for ($j = 0; $j < $pos; $j++) {
$result .= $indentStr;
}
}
$prevChar = $char;
}
return $result;
}</pre><div dir="ltr" style="text-align: left;" trbidi="on"><br />
Эта функция сразу же была внедрена в проект и теперь коллегам разбирать JSON куда более удобно. :)</div></div>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com3tag:blogger.com,1999:blog-2218634406037583486.post-46616357829446185082011-02-20T11:35:00.000+03:002011-02-20T11:35:39.593+03:00Как работают сервисы типа "shorten URL"?<div dir="ltr" style="text-align: left;" trbidi="on">Не так давно мне понадобилось реализовать свою генерацию коротких URL. Существует масса сервисов по укорачиванию URL: bit.ly, is.gd... Продолжать можно очень долго.<br />
Возник вопрос, а как же работает этот алгоритм? В коротком URL, как правило, могут присутствовать символы a-z, A-Z, 0-9, возможно, еще какие-то спецсимволы.<br />
<br />
Таким образом, попытаемся представить, что на выходе у нас получается 62-ричное число. На вход же подается очень большая строка, которую также можно представить в виде N-ричного числа, где N, очевидно, заведомо больше 62.<br />
<br />
Тут точного ответа по поводу, как именно работают эти сервисы, дать невозможно. Но можно предположить, что у них есть глобальный счетчик 10-ричных чисел, его числа они и переводят в 62-ричную систему счисления. И существует таблица, ставящая в соответствие URL - short URL. Таким образом, до 3 символов включительно могут соответствовать количеству URL:<br />
<br />
62 * 62 * 62 = 238328<br />
<br />
Применительно к практике, не всегда можно использовать столь небольшие числа. Например, при переводе MD5 хеша в 62-ричное число, разрядность числа превосходит разрядность регистров процессора и обычными инструкциями оперировать уже не получается. Поэтому на помощь приходит так называемая <a href="http://ru.wikipedia.org/wiki/%D0%94%D0%BB%D0%B8%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B0%D1%80%D0%B8%D1%84%D0%BC%D0%B5%D1%82%D0%B8%D0%BA%D0%B0">Длинная арифметика</a> и модуль для PHP <a href="http://php.net/manual/en/book.bc.php">BC Math</a>.<br />
<br />
Немного погуглив, я <a href="http://www.technischedaten.de/pmwiki2/pmwiki.php?n=Php.BaseConvert">натолкнулся на такую функцию</a>, которая и выполняет всю работу (жаль, автор был немец и пришлось рефакторить названия переменных):<br />
<br />
<pre class="prettyprint">function bc_base_convert($value, $frombase, $tobase)
{
$stock = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
if (max($frombase, $tobase) > strlen($stock)) {
trigger_error('Bad Format max: ' . strlen($stock), E_USER_ERROR);
}
if (min($frombase, $tobase) < 2) {
trigger_error('Bad Format min: 2', E_USER_ERROR);
}
$decimal = '0';
$level = 0;
$result = '';
$value = trim((string) $value, "\r\n\t +");
$sign = '-' === $value[0] ? '-' : '';
$value = ltrim($value, "-0");
$len = strlen($value);
for ($i = 0; $i < $len; $i++) {
$temp = strpos($stock, $value[$len - 1 - $i]);
if (false === $temp) {
trigger_error('Bad Char in input 1', E_USER_ERROR);
}
if ($temp >= $frombase) {
trigger_error('Bad Char in input 2', E_USER_ERROR);
}
$decimal = bcadd($decimal, bcmul(bcpow($frombase, $i), $temp));
}
if (10 == $tobase) {
return $sign . $decimal;
}
while (1 !== bccomp(bcpow($tobase, $level++), $decimal)) {
}
for ($i = $level - 2; $i >= 0; $i--) {
$factor = bcpow($tobase, $i);
$number = bcdiv($decimal, $factor, 0);
$decimal = bcmod($decimal, $factor);
$result .= $stock[$number];
}
$result = empty($result) ? '0' : $result;
return $sign . $result;
}
</pre><br />
Первым параметром подается число (может быть и строка с MD5, например). Второй и третий параметры используются для указания из какой в какую систему счисления переводить число.<br />
Массив $stock может быть модифицирован, например, если вы хотите использовать 63 или более -ричную систему счисления. Эта функция по умолчанию поддерживает переводы чисел в систему счисления до 62-ричных включительно.<br />
<br />
Надеюсь, что смог помочь ищущим истину людям. :)</div>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-12808101677526700232011-02-19T13:27:00.000+03:002011-02-19T13:27:02.969+03:00Сравнение последних сборок браузеров в SunSpider<div dir="ltr" style="text-align: left;" trbidi="on">Сегодня решил снова провести тестирование браузеров в, наверное, всеми известном бенчмарке <a href="http://www.webkit.org/perf/sunspider/sunspider.html">SunSpider</a>. Были взяты следующие подопытные:<br />
<ul style="text-align: left;"><li>Mozilla Firefox 4.0 beta 12 pre (2011-02-18)</li>
<li>Google Chrome 11.0.672.2 beta</li>
<li>Opera 11.10 build 2005 alpha</li>
<li>Internet Explorer 9.0.8080.16413 RC</li>
</ul><div style="text-align: left;">Safari в этот раз не вошел в результаты тестирования. Но я его также протестировал с целью нормализации последствий разгона своего процессора и памяти.<br />
Тесты проводились в наиболее нейтральном и одинаковом рабочем окружении. Тестовая кофигурация:<br />
<ul style="text-align: left;"><li>Intel Core 2 Quad Q6600 @ 3.10GHz</li>
<li>DDR2 @ 516MHz (5-5-5-18)</li>
</ul>Результаты тестирования:</div><div style="text-align: left;"> </div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifAk-ve0tl4GCVXXP0EcfREqQT2vciOrNUxRCTd8S97lwLpkjX_DCTvmztWqeANMf3jpz2j0-NEQj3lhWYRU6Ka68SRmzzTl3cFmOza7LVKIdFvpdIC5ZqZEY5O_TJEPu1ZlaGsJ4XqX4/s1600/2011-02-19+Browsers+comparsion.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifAk-ve0tl4GCVXXP0EcfREqQT2vciOrNUxRCTd8S97lwLpkjX_DCTvmztWqeANMf3jpz2j0-NEQj3lhWYRU6Ka68SRmzzTl3cFmOza7LVKIdFvpdIC5ZqZEY5O_TJEPu1ZlaGsJ4XqX4/s320/2011-02-19+Browsers+comparsion.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Результаты тестирования браузеров в SunSpider 0.9.1</td><td class="tr-caption" style="text-align: center;"><br />
</td></tr>
</tbody></table><div style="text-align: left;"> В этот раз перед моими глазами предстала довольно интересная картина. Несмотря на разгон процессора и памяти на моей машине (30% производительности, если сравнивать по старой версии Safari), результаты позволяют сделать вывод, что, например, Mozilla сделала свой браузер приблизительно в 1.2-1.5 раза быстрее. Эти 2 месяца разработчики браузеров не сидели просто так.</div><div style="text-align: left;">Впечатляют результаты IE9 в этом бенчмарке, хотя <a href="http://digitizor.com/2010/11/17/internet-explorer-9-caught-cheating-in-sunspider-benchmark/">ходят слухи</a>, что он просто заточен под быстрое прохождение этого теста.</div><div style="text-align: left;">Opera удалось обогнать Chrome, что должно послужить стимулом инженерам гуглобраузера. По сути, Chrome практически никак не сдвинулся в плане скорости исполнения JavaScript. И если так пойдет и дальше, то ему в спину скоро будет дышать даже неповоротливый некогда Firefox.</div><div style="text-align: left;"> </div><div style="text-align: left;">На этом все, будем ждать следующей итерации этапа развития современных браузеров.</div></div>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-3140081263992605752011-01-18T19:23:00.000+03:002011-01-18T19:24:05.397+03:00Множественные формы в YiiДа, вам не показалось, в этот раз речь пойдет о <b>PHP</b> фреймворке <b>Yii</b>. И да простит меня домен третьего уровня... :)<br />
<br />
Когда я работал с <b>Zend Framework</b>, мне очень понравилась их реализация <b>множественных форм</b>, о которых я уже когда-то <a href="http://zend-tips.blogspot.com/2010/06/zend-framework.html">рассказывал</a>. Перейдя в свое время на <b>Yii</b>, я огорчился, узнав, что там подобной удобностью и не пахнет. Нет, я, разумеется, знал про <b>CChoiceFormat</b>, который позволял использовать множественные формы примерно следующим образом:<br />
<br />
<pre class="prettyprint">CChoiceFormat::format('n%10==1 && n%100!=11#раз|n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20)#раза|#раз', $data->views);</pre><br />
Но согласитесь, это ни разу не эстетично. И этой записи не было бы, если бы не случился выход <b>Yii</b> 1.1.6, в котором и появилась долгожданная и аккуратная, прописанная в файлах интернационализации, поддержка <b>множественных форм</b>. Теперь и в <b>Yii</b> все стало куда симпатичнее и "правильнее". Аналог вышеописанного использования теперь выглядит так:<br />
<br />
<pre class="prettyprint">Yii::t('yii', 'раз|раза|раз', $data->views);</pre><br />
Приятного вам кодинга! :)Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-20008635316036283642011-01-15T11:06:00.000+03:002011-01-15T11:06:38.862+03:00Очередные приколы imagick в PHP под WindowsВроде бы ничего не предвещало беды, я уже рассказывал о своих <a href="http://zend-tips.blogspot.com/2010/05/xampp-imagemagick.html">похождениях</a> с <b>imagick</b> под <b>Windows</b>. Но в нынешних проектах у моих коллег начали возникать проблемы с неработоспособностью этого расширения. Решив обновить всю свою сборку до актуальных версий, я столкнулся с аналогичными проблемами:<span class="postbody"> </span><br />
<br />
<span class="postbody"><b>Premature end of script headers, 500</b> ошибка возврата от <b>Apache</b>.</span><br />
<br />
Проколупавшись в итоге несколько часов, я набрел на <a href="http://valokuva.org/?p=161#comment-20708">интересный комментарий на блоге Mikko</a>. Для тех, кто не знает английский — с тех пор как <b>ImageMagick</b> (собственно, сам движок обработки изображений) стал собираться в Visual Studio 2010 (компилятором <b>VC10</b>), под <b>PHP</b> в <b>Windows</b> у всех проблемы. Последняя работоспособная версия <b>ImageMagick</b>, собранная <b>VC9</b> — 6.6.4-1. Ее вы можете скачать по этому адресу:<br />
<br />
<a href="http://image_magick.veidrodis.com/image_magick/binaries/ImageMagick-6.6.4-1-Q16-windows-dll.exe">http://image_magick.veidrodis.com/image_magick/binaries/ImageMagick-6.6.4-1-Q16-windows-dll.exe</a><br />
<br />
Удалите все другие, установленные у вас версии и установите эту. Если вы разрабатываете на <b>PHP</b> в <b>Windows</b>, другие версии вам и не понадобятся. Но если вам вдруг потребуется какая-нибудь иная версия из архивов, то поищите ее по следующему адресу:<br />
<br />
<a href="http://image_magick.veidrodis.com/image_magick/binaries/ImageMagick-6.6.4-1-Q16-windows-dll.exe">http://image_magick.veidrodis.com/image_magick/binaries/</a><br />
<br />
В этот раз у меня был установлен <b>PHP 5.3.5 non thread safe (VC9, x86)</b> и аналогичное расширение <a href="http://valokuva.org/builds/">imagick non thread safe (VC9, x86)</a>. <b>Apache</b> работал в режиме <b>FastCGI</b>. Больше ошибок с 500 статусом по поводу <b>imagick</b> у меня не возникает.<br />
<br />
Так и в этот раз я победил <b>imagick</b>. :)Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com1tag:blogger.com,1999:blog-2218634406037583486.post-66152000531126233752010-12-14T21:30:00.000+03:002011-01-15T11:19:37.590+03:00SunSpider 0.9.1 на лезвияхМое предыдущее сравнение производительности браузеров Firefox оставляло желать лучшего. Визуально восприятие информации было просто ужасным. По прошествии некоторого времени мне опять захотелось посмотреть, кто же быстрее ныне в исполнении JavaScript. Я взял последние нестабильные (кроме Safari) версии популярных браузеров и прогнал на них SunSpider 0.9.1<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg97Z-kl8WC9wBkL1lakyxwmjC6r0Qh6iFw7UXmX6ZAMmyCaGMkur-NfyzuRx7e_xebU8PsdzvE0nsm86QN4ZOWkgJMEhTT5eoQKu_LotmEhciSK_i5JIQkbJPjUoxDlPb-CbvJWXsOAZ0/s1600/2010-12-15+Browsers+Comparsion.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="287" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg97Z-kl8WC9wBkL1lakyxwmjC6r0Qh6iFw7UXmX6ZAMmyCaGMkur-NfyzuRx7e_xebU8PsdzvE0nsm86QN4ZOWkgJMEhTT5eoQKu_LotmEhciSK_i5JIQkbJPjUoxDlPb-CbvJWXsOAZ0/s320/2010-12-15+Browsers+Comparsion.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Современные браузеры в бенчмарке SunSpider 0.9.1</td></tr>
</tbody></table>Интересен тот факт, что Firefox серьезно отстает от своих основных конкурентов, но не стоит забывать, что этот браузер является наиболее удобным при разработке веб-приложений. Впереди планеты всей оказался Chrome от компании Google, которому в свою очередь успевает наступать на пятки Opera.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-279317212006603432010-09-18T09:43:00.001+04:002010-09-18T09:43:54.846+04:00Нововведения MySQL 5.5Возможно, вы уже слышали о <b>СУБД MySQL 5.5</b>, которая находится еще в стадии разработки. В новой версии ожидается довольно впечатляющий список вкусных нововведений, о которых и пойдет речь. На своем домашнем сервере я использую последнюю стабильную версию 5.1 и очень жду выхода новой версии этой СУБД.<br />
Итак, перейдем к деталям. Нас ожидает:<br />
<ol><li>Улучшена производительность на многоядерных процессорах. Теперь уже не те времена, когда процессорная мощь наращивалась частотами и можно было спокойно говорить: “Ждите, с новым процессором ваша СУБД станет быстрее”. Ныне разработка <b>MySQL</b> направлена на использование возможностей многоядерных процессоров. Основные усилия сосредоточены на улучшении производительности движка <b>InnoDB</b> и особенно блокировки таблиц.</li>
<li> Подсистема ввода / вывода движка <b>InnoDB</b> оптимизирована для эффективного использования ресурсов устройств ввода / вывода.</li>
<li> Улучшена производительность <b>MySQL Server</b> для <b>ОС Solaris</b>.</li>
<li> Возможность просматривать более полную информацию о используемых системных ресурсах с помощью команды <b>SHOW ENGINE INNODB STATUS</b>.</li>
<li> Поддержка стандартных для <b>SQL</b>: <b>SIGNAL</b> и <b>RESIGNAL</b> операторов.</li>
<li> Поддержка новых многобайтовых кодировок: <b>utf16</b>, <b>utf32</b>, <b>utf8mb4</b>.</li>
<li> Улучшена работа с <b>XML</b>, в том числе введен новый оператор <b>LOAD XML</b>.</li>
<li> Добавлена функция <b>TO_SECONDS()</b>. Эта функция преобразует дату или дату и время в количество секунд, прошедшее с начала 0 года.</li>
</ol>Также нас ждут улучшения в плане партицирования. Но, к сожалению, мой опыт не позволяет писать о них, поэтому я не стану вникать в подробности этих улучшений.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-35970281630363573722010-08-26T16:48:00.000+04:002010-08-26T18:03:39.361+04:003 совета для Zend StudioСегодня хотел бы поделиться парочкой полезных и не очевидных советов, которыми я пользуюсь в Zend Studio.<br />
<b><span style="font-size: large;">Комментарии</span></b><br />
Комментировать код, расставляя вручную // не очень-то удобно. Можно использовать одну из 2 комбинаций:<br />
<ul><li>Ctrl + Shift + C</li>
<li>Ctrl + /</li>
</ul><span id="goog_1395512718"></span><span id="goog_1395512719"></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGgJ86ByrpxiJYa2qRvOEp6oen9aqzBsXc78PM7zallA9kBlIwtdZb_jWiUK5oGRSYi2Y16fnqRTmCneQ5YzMVTc2QWZaeu4bw4vdt41OLBSNc7usNEDK0GVW1PeHxhzI9zytQZYSerY/s1600/uncommented.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwGgJ86ByrpxiJYa2qRvOEp6oen9aqzBsXc78PM7zallA9kBlIwtdZb_jWiUK5oGRSYi2Y16fnqRTmCneQ5YzMVTc2QWZaeu4bw4vdt41OLBSNc7usNEDK0GVW1PeHxhzI9zytQZYSerY/s320/uncommented.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">До комментария</td></tr>
</tbody></table><br />
<span style="font-size: large;"><span style="font-size: small;"></span></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyy9n_2UKTokMlOAv4aUbuh_Z7YIVWlTwx8orZfF32_P5GtP6jzgUappeHOgj0iTp-Ezj52wdXtjBSXv4kGPHoPl0LT4gHYKVTDIxLlyKZiEpHTZourR36nfF2DY0LCGAvBTHHY0kT-BI/s1600/commented.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyy9n_2UKTokMlOAv4aUbuh_Z7YIVWlTwx8orZfF32_P5GtP6jzgUappeHOgj0iTp-Ezj52wdXtjBSXv4kGPHoPl0LT4gHYKVTDIxLlyKZiEpHTZourR36nfF2DY0LCGAvBTHHY0kT-BI/s320/commented.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">После</td></tr>
</tbody></table><b><span style="font-size: large;">CamelCase и Autocomplete</span></b><br />
<span style="font-size: small;">Autocomplete также работает, если набирать заглавные буквы названий классов:</span><br />
<div class="separator" style="clear: both; text-align: center;"></div><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguxvD2lnBy9_leuZGWarfBta2c3AZEkfe2oZ-7d5Ocmchrit8xe4pYUCoZYKeec0raue9sbTmF2jHYLLaaV7zS1yPfdX18M_FwKMaLPzowpqozbo1rWWQnck6EJVMwnEUoxZ-t-im82Fc/s1600/camel_case_autocomplete.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguxvD2lnBy9_leuZGWarfBta2c3AZEkfe2oZ-7d5Ocmchrit8xe4pYUCoZYKeec0raue9sbTmF2jHYLLaaV7zS1yPfdX18M_FwKMaLPzowpqozbo1rWWQnck6EJVMwnEUoxZ-t-im82Fc/s320/camel_case_autocomplete.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Набираем ZFEC для подсказки Zend_Form_Element_Captcha</td></tr>
</tbody></table><span style="font-size: small;"></span><br />
<br />
<b><span style="font-size: large;">Авто обновление рабочего пространства</span></b><br />
<span style="font-size: small;">Каждый ра</span>з выбирать папку и нажимать F5, чтобы студия считала с файловой системы изменения - утомительно, и, порой, неудобно (например, при использовании SVN, мы можем забыть закоммитить файл, добавленный вне студии). Есть одна замечательная опция, которая позволяет это делать автоматически, отслеживая изменения самостоятельно:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvbBAFvUMTj9bDIL4oxXD-qfxtTFNiWEK0Fj8-UOELbypxXSXv7JmEstJbPf1EtMZHZmrXsHsrSWagTs2IvJKmBnyNGNaw3pTMylY1nLwwr97D9NYw1pVamAA4HPYSaAb9_bVJ2lcqiuM/s1600/workspace_auto_update.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvbBAFvUMTj9bDIL4oxXD-qfxtTFNiWEK0Fj8-UOELbypxXSXv7JmEstJbPf1EtMZHZmrXsHsrSWagTs2IvJKmBnyNGNaw3pTMylY1nLwwr97D9NYw1pVamAA4HPYSaAb9_bVJ2lcqiuM/s320/workspace_auto_update.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Ставим галочку Refresh automatically</td></tr>
</tbody></table>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-72173188547399451022010-08-23T18:20:00.000+04:002010-08-23T18:20:10.135+04:00Пошаговый дебаг PHP в Zend Studio (разбираемся с Ubuntu)Давно была интересна эта тема, но руки никак не доходили до того, чтобы привести это в действие: научиться устраивать пошаговый дебаг в <b>Zend Studio</b>.<br />
Итак, мне удалось настроить работу <b>Zend Debugger</b> в <b>Linux Ubuntu</b> и в <b>Windows 7</b>. В этой части статьи будет приведен пример настройки в <b>Ubuntu</b>.<br />
Нехитрое дело посмотреть в <a href="http://static.zend.com/topics/Debugger-Install.pdf">инструкцию по установке</a>. Сразу оговорюсь, отключите <b>eAccelerator</b>, с ним <b>Zend Debugger</b> глючит.<br />
Для начала качаем <b>Studio Web Debugger</b> с <a href="http://www.zend.com/products/studio/downloads">официального сайта</a>. Также очень рекомендую поставить <b>Studio Browser Toolbars</b> для Firefox (качается оттуда же и сильно облегчает жизнь в последующем):<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip0WjhgyVR-2q6dzoZPuweylmuASK8V_fO8RcXkXojD4zdUhyphenhyphenrncBiMlH4LOwDw7JmjRUx7epc6nN_-ZyQHkvyCm3g0Fq4an2jNV_uZkiRfH_UHpbd9CrVGroX2hrJUIQfZmzedZ5Clnk/s1600/zend_toolbar.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip0WjhgyVR-2q6dzoZPuweylmuASK8V_fO8RcXkXojD4zdUhyphenhyphenrncBiMlH4LOwDw7JmjRUx7epc6nN_-ZyQHkvyCm3g0Fq4an2jNV_uZkiRfH_UHpbd9CrVGroX2hrJUIQfZmzedZ5Clnk/s320/zend_toolbar.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><b>Studio Browser Toolbars</b> в браузере <b>Firefox 3.6</b></td></tr>
</tbody></table><b>Zend Debugger</b> является модулем для <b>PHP</b>. Далее некоторые нюансы для разных версий <b>PHP</b> могут различаться, в моем случае был рассмотрен <b>PHP 5.3.3</b>. Из архива достаем ZendDebugger.so, соответствующий нашей версии <b>PHP</b> и копируем его в директорию /usr/lib/php5/20090626+lfs. Прописываем в php.ini новый модуль и базовые настройки:<br />
<blockquote>zend_extension = /usr/lib/php5/20090626+lfs/ZendDebugger.so<br />
<br />
zend_debugger.allow_hosts = 192.168.1.1, 127.0.0.1<br />
zend_debugger.expose_remotely = always</blockquote>Опция <b>allow_hosts</b> в данном случае позволяет нам дебажить с локального хоста и с машины 192.168.1.1.<br />
Запускаем <b>Zend Studio</b>. Выбираем место, в котором желаем остановиться во время выполнения (breakpoint). Делается это двойным щелчком по полоске левее номеров строк:<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCPAQy0_eycy1zF1npe2dCyJyuz6tv_3bGoRswNgp_uScmvjQjHEJTG92_0L6zFMh7rJ9TSwAcD-QBznYOEs4k_NEEaf_JHxOBJb6i7vONcTlVC0WY8xLvGaI09-Z6CGG9QbAOSUhKUso/s1600/breakpoint.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCPAQy0_eycy1zF1npe2dCyJyuz6tv_3bGoRswNgp_uScmvjQjHEJTG92_0L6zFMh7rJ9TSwAcD-QBznYOEs4k_NEEaf_JHxOBJb6i7vONcTlVC0WY8xLvGaI09-Z6CGG9QbAOSUhKUso/s320/breakpoint.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Breakpoint in <b>Zend Studio</b></td></tr>
</tbody></table><br />
<br />
Производим следующие действия:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid6-88tftlFEsfbkoe3kpe74NuhSiIEoVpHXOvNSkNgIOb6_nfnlHGpkg0KFCwhUMDL5Hvvp42_qTsLDqyPBGtLkc8g5LPvNTTWco6qVJotTerGehpqJr39C_b5o-80xUms8lm3MRF5K4/s1600/debug_1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEid6-88tftlFEsfbkoe3kpe74NuhSiIEoVpHXOvNSkNgIOb6_nfnlHGpkg0KFCwhUMDL5Hvvp42_qTsLDqyPBGtLkc8g5LPvNTTWco6qVJotTerGehpqJr39C_b5o-80xUms8lm3MRF5K4/s320/debug_1.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Действие над треугольничком</td></tr>
</tbody></table><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieFzazvKxyrrLMua3r6cj72GdFNvEYZtIyYD9Kgzkt-7uh8yMv5pP-aTbx-0BVuUss0uGxmWn0Cjc4BVPVRGIocCWGSCRnv7aWV6q59tE63ND0cOL-nXNEn_9nul9koj0wdXvuRb2ShsA/s1600/debug_2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEieFzazvKxyrrLMua3r6cj72GdFNvEYZtIyYD9Kgzkt-7uh8yMv5pP-aTbx-0BVuUss0uGxmWn0Cjc4BVPVRGIocCWGSCRnv7aWV6q59tE63ND0cOL-nXNEn_9nul9koj0wdXvuRb2ShsA/s320/debug_2.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Действие над менюшкой</td></tr>
</tbody></table><br />
Далее открывается примерно такое диалоговое окно:<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYtA2_ONOymA5ll2_IY1qGDmwP4QPTN34fmvdjo7RPVRBLQW2gjjlorSCduL8w4OJ_RocPR6fF2tzJ9-0WqtYZysQyiB4TIOJZuT9qHhj3iMHZSMbDV5knjurz9xNcYy4PU-IW3OvhAPM/s1600/debug_url.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYtA2_ONOymA5ll2_IY1qGDmwP4QPTN34fmvdjo7RPVRBLQW2gjjlorSCduL8w4OJ_RocPR6fF2tzJ9-0WqtYZysQyiB4TIOJZuT9qHhj3iMHZSMbDV5knjurz9xNcYy4PU-IW3OvhAPM/s320/debug_url.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Указываем URL, по которому необходимо производить дебаг</td></tr>
</tbody></table>Если все успешно - то дебагер после запуска встанет на первой адекватной строчке index.php (эту настройку тоже можно сменить, но не буду углубляться). Если дебагер не сработал, то, возможно, вам поможет мануал по установке, который я упомянул в самом начале. Основные горячие клавиши для работы с дебагом можно увидеть во всплывающих подсказках на кнопках управления непосредственно дебагом.<br />
Таким образом, мне удалось запустить пошаговый дебаг в <b>Zend Studio</b>. Буду рад, если кому-то это сможет пригодиться.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-56517642255311888832010-08-19T18:39:00.000+04:002010-08-19T18:40:25.952+04:00Установка Zen Coding в Zend Studio 8Решил опробовать сегодня для себя <b>Zen Coding</b>. Скажу, что был приятно удивлен удобству и скорости набора <b>HTML</b> тэгов. Вы можете более подробно почитать о нем на просторах наших интернетов.<br />
Сразу перейду к делу. Чтобы установить эту замечательную вещь в <b>Zend Studio</b>, необходимо сделать следующее:<br />
<ol><li>В студии в меню: Help -> Install new software... Вбиваем адрес http://download.eclipse.org/technology/dash/update/</li>
<li>Выбираем <b>Eclipse Monkey</b>, и устанавливаем. Перезапускаем студию.</li>
<li>Качаем <a href="http://code.google.com/p/zen-coding/downloads/detail?name=Zen.Coding-Aptana.v0.6.0.1.zip&can=2&q=">скрипты Zen Coding для Aptana</a>. Так как <b>Aptana</b> является плагином к <b>Eclipse</b> (как и наша <b>Zend Studio</b>) - эти скрипты нам подойдут.</li>
<li>Распаковываем скрипты в корень проекта в папку scripts (да, проекта... централизованной установки нет).</li>
<li>Обновляем все дерево проекта, чтобы плагин <b>Eclipse Mokey</b> "увидел" папку scripts.</li>
</ol>Можно пользоваться. Но не очень это удобно без горячей клавиши.<br />
Чтобы выставить <b>горячую клавишу</b> на скрипт Expand Abbreviation.js мне пришлось его немного подправить: строку<br />
<blockquote>Key: M1+E</blockquote>заменить<br />
<blockquote>Key: M2+M3+E</blockquote>Таким образом, комбинация для работы скрипта стала Shift + Alt + E. Прошлая комбинация Ctrl + E отказалась работать из-за конфликтов с уже существующими комбинациями, имеющими более высокий приоритет.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com1tag:blogger.com,1999:blog-2218634406037583486.post-48128593627579965542010-08-08T21:05:00.000+04:002010-08-08T21:12:11.306+04:00SunSpider в Firefox (сравнение производительности JavaScript)Решил провести тестирование скорости работы JavaScript трех версий популярного браузера:<br />
<ul><li>Firefox 3.6.8</li>
<li>Firefox 4.0 beta 2</li>
<li>Minefield 4.0 beta 4 pre (ночная сборка 2010.08.08)</li>
</ul>Потратив некоторое время в <a href="http://www2.webkit.org/perf/sunspider-0.9/sunspider.html">SunSpider</a>, я получил довольно интересные и близкие к действительности результаты:<br />
<br />
<pre class="prettyprint">Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
============================================
RESULTS (means and 95% confidence intervals)
--------------------------------------------
Total: 729.8ms +/- 1.7%
--------------------------------------------
3d: 118.6ms +/- 1.2%
cube: 29.4ms +/- 3.8%
morph: 36.6ms +/- 1.9%
raytrace: 52.6ms +/- 2.7%
access: 104.0ms +/- 2.4%
binary-trees: 27.2ms +/- 3.8%
fannkuch: 51.4ms +/- 1.3%
nbody: 16.8ms +/- 3.3%
nsieve: 8.6ms +/- 12.9%
bitops: 29.4ms +/- 5.7%
3bit-bits-in-byte: 1.0ms +/- 0.0%
bits-in-byte: 8.2ms +/- 16.6%
bitwise-and: 2.0ms +/- 0.0%
nsieve-bits: 18.2ms +/- 3.1%
controlflow: 31.0ms +/- 0.0%
recursive: 31.0ms +/- 0.0%
crypto: 37.2ms +/- 2.8%
aes: 22.0ms +/- 5.7%
md5: 9.6ms +/- 7.1%
sha1: 5.6ms +/- 12.2%
date: 126.0ms +/- 2.1%
format-tofte: 62.4ms +/- 3.3%
format-xparb: 63.6ms +/- 1.7%
math: 44.8ms +/- 20.7%
cordic: 26.6ms +/- 35.1%
partial-sums: 13.0ms +/- 0.0%
spectral-norm: 5.2ms +/- 20.0%
regexp: 40.8ms +/- 1.4%
dna: 40.8ms +/- 1.4%
string: 198.0ms +/- 2.5%
base64: 8.0ms +/- 0.0%
fasta: 44.6ms +/- 3.2%
tagcloud: 59.2ms +/- 3.8%
unpack-code: 64.2ms +/- 3.2%
validate-input: 22.0ms +/- 10.6%</pre><br />
<pre class="prettyprint">Mozilla/5.0 (Windows; Windows NT 6.1; WOW64; rv:2.0b2) Gecko/20100720 Firefox/4.0b2
============================================
RESULTS (means and 95% confidence intervals)
--------------------------------------------
Total: 513.2ms +/- 0.9%
--------------------------------------------
3d: 77.8ms +/- 10.9%
cube: 25.0ms +/- 0.0%
morph: 21.0ms +/- 39.7%
raytrace: 31.8ms +/- 1.7%
access: 70.2ms +/- 1.9%
binary-trees: 14.0ms +/- 0.0%
fannkuch: 34.0ms +/- 0.0%
nbody: 14.0ms +/- 6.3%
nsieve: 8.2ms +/- 6.8%
bitops: 22.4ms +/- 3.0%
3bit-bits-in-byte: 0.4ms +/- 170.2%
bits-in-byte: 7.0ms +/- 0.0%
bitwise-and: 1.2ms +/- 46.3%
nsieve-bits: 13.8ms +/- 4.0%
controlflow: 6.2ms +/- 9.0%
recursive: 6.2ms +/- 9.0%
crypto: 28.8ms +/- 8.3%
aes: 17.6ms +/- 10.7%
md5: 7.2ms +/- 7.7%
sha1: 4.0ms +/- 0.0%
date: 68.8ms +/- 1.5%
format-tofte: 43.4ms +/- 1.6%
format-xparb: 25.4ms +/- 2.7%
math: 40.2ms +/- 4.0%
cordic: 22.4ms +/- 3.0%
partial-sums: 12.8ms +/- 4.3%
spectral-norm: 5.0ms +/- 17.6%
regexp: 45.0ms +/- 0.0%
dna: 45.0ms +/- 0.0%
string: 153.8ms +/- 1.8%
base64: 6.8ms +/- 8.2%
fasta: 18.2ms +/- 3.1%
tagcloud: 55.2ms +/- 2.9%
unpack-code: 53.0ms +/- 1.7%
validate-input: 20.6ms +/- 9.2%
</pre><br />
<pre class="prettyprint">Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b4pre) Gecko/20100808 Minefield/4.0b4pre
============================================
RESULTS (means and 95% confidence intervals)
--------------------------------------------
Total: 479.2ms +/- 1.5%
--------------------------------------------
3d: 76.6ms +/- 10.6%
cube: 24.0ms +/- 3.7%
morph: 18.8ms +/- 37.8%
raytrace: 33.8ms +/- 3.1%
access: 65.8ms +/- 1.6%
binary-trees: 14.2ms +/- 7.3%
fannkuch: 36.4ms +/- 3.1%
nbody: 6.8ms +/- 8.2%
nsieve: 8.4ms +/- 8.1%
bitops: 18.8ms +/- 5.5%
3bit-bits-in-byte: 0.2ms +/- 278.0%
bits-in-byte: 7.6ms +/- 9.0%
bitwise-and: 1.2ms +/- 46.3%
nsieve-bits: 9.8ms +/- 5.7%
controlflow: 6.0ms +/- 0.0%
recursive: 6.0ms +/- 0.0%
crypto: 26.4ms +/- 5.4%
aes: 15.4ms +/- 4.4%
md5: 7.4ms +/- 9.2%
sha1: 3.6ms +/- 18.9%
date: 66.2ms +/- 0.8%
format-tofte: 40.4ms +/- 1.7%
format-xparb: 25.8ms +/- 2.2%
math: 43.0ms +/- 2.0%
cordic: 24.0ms +/- 0.0%
partial-sums: 12.4ms +/- 5.5%
spectral-norm: 6.6ms +/- 10.3%
regexp: 43.6ms +/- 5.2%
dna: 43.6ms +/- 5.2%
string: 132.8ms +/- 1.2%
base64: 5.2ms +/- 10.7%
fasta: 17.2ms +/- 3.2%
tagcloud: 51.4ms +/- 4.4%
unpack-code: 46.2ms +/- 7.5%
validate-input: 12.8ms +/- 4.3%</pre><br />
Подводя итоги, становится видна тенденция, что новый браузер Firefox 4 от организации Mozilla будет обрабатывать JavaScript примерно в 1.5-2 раза шустрее, чем нынешний. Выход браузера запланирован на конец 2010 года.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-78984981567373373482010-07-30T16:38:00.000+04:002010-07-30T16:41:36.174+04:00Права в Git и развертываниеСегодня у меня был опыт, которым хотелось бы поделиться. Все началось с того, что наша контора (не без моей инициативы) перебралась с <a href="http://ru.wikipedia.org/wiki/Subversion">SVN</a> на <a href="http://ru.wikipedia.org/wiki/Git">Git</a>. То есть теперь в системе контроля версий мы помимо просто файлов еще храним и права доступа к ним.<br />
<br />
Раньше было так: на девелоперской машине сайт /var/www/site был во владении основного пользователя и IDE могла спокойно работать с этими файлами. Если серверу нужны были права на запись в директорию, то директории выставлялись права 0777, благо через SVN дальше компьютера разработчика это не уходило. Был такой вот мелочный хак.<br />
<br />
Все бы хорошо, но после перехода на Git, отправлять на продакшн права 0777 было бы совсем нехорошо. Решением этой дилеммы стал запуск сервера apache от основного юзера операционки. В Ubuntu ключевой файл находится в следующем месте:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">/etc/apache2/envvars</span><br />
<br />
В нем следует изменить строки<br />
<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">export APACHE_RUN_USER=www-data</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">export APACHE_RUN_GROUP=www-data</span><br />
<div><br />
</div><br />
на<br />
<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">export APACHE_RUN_USER=user</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">export APACHE_RUN_GROUP=user</span><br />
<br />
Где user - имя основного юзера системы.<br />
И стало щастье и IDE, и веб-серверу. В итоге мы можем хранить в Git "правильные" права и разрабатывать приложение в любимом текстовом редакторе запущенном не от www-data или, что еще хуже root'а.<br />
<div><br />
</div><br />
P.S. Под основным юзером я имел ввиду юзера, который собственно работает за компьютером.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-1242018463425678082010-07-15T17:17:00.000+04:002010-07-15T17:17:28.712+04:00Игнорирование изменений пробельного пространства в svn diffИногда, работая над проектами, мы изменяем код так, чтобы он был более удобочитаем / больше подходил под выбранный стиль кодирования / удаляем пробелы с концов строк. Работая в команде, это порой может очень мешать просматривать логические изменения кода.<br />
<br />
Команда svn diff не поддерживает функции игнорирования изменений пробелов и табов. Но зато GNU программа diff умеет это делать.<br />
<br />
Чтобы использовать стороннюю diff команду в svn diff, нужно воспользоваться ключом -x.<br />
Если мы желаем напрямую сравнить два файла, игнорируя пробелы, то нам следует использовать <span style="font-family: "Courier New",Courier,monospace;">diff -uw /path/to/file1 /path/to/file2</span><br />
<br />
Если мы желаем посмотреть наши локальные изменения, игнорируя пробелы, то нам нужна следующая команда:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">svn diff --diff-cmd diff -x -uw /path/to/file</span><br />
<br />
В этом случае мы больше не увидим изменений, которые были сделаны исключительно из эстетических соображений.<br />
<br />
Это был относительно вольный перевод этой записки:<br />
<a href="http://goo.gl/DnKh">http://goo.gl/DnKh</a>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-5485619878359314742010-06-19T09:23:00.000+04:002010-06-19T09:30:36.352+04:00И снова коротко о множественных формах в Zend FrameworkДовольно часто (сплошь и рядом) приходится выводить слова, принципы написания которых зависят от числительного, с которым они связаны.<br />
В моем проекте <a href="http://spaceismine.org/">http://spaceismine.org/</a> к каждой статье выводится количество просмотров. Если дописывать после количества слово "просмотров", то это не всегда будет корректно. Наверное, я достаточно сложно изъясняюсь. Попытаюсь поставить задачу и расписать способ ее решения.<br />
<b>Задача:</b> сделать вывод вместо:<br />
<blockquote>Прочитано раз: 1 / Прочитано раз: 3 / Прочитано раз: 11</blockquote>такой:<br />
<blockquote>Прочитано 1 раз / Прочитано 3 раза / Прочитано 11 раз</blockquote>Не самый удачный пример на слове "раз", так как форма 1 и 11 не отличаются. В большинстве случаев они будут все же разными:<br />
<blockquote>1 просмотр / 3 просмотра / 11 просмотров</blockquote>В русском языке, таким образом, имеется три множественные формы: "просмотр", "просмотра", "просмотров". <a href="http://framework.zend.com/manual/ru/zend.translate.plurals.html">Начиная с версии 1.9, Zend Framework</a> сильно облегчает решение такого рода задач.<br />
<b>Решение:</b> итак, логика вывода у нас работает во view. И по такому случаю уже есть view helper translate. Пишем следующее:<br />
<pre class="prettyprint">Прочитано <?php
echo $article->views, ' ';
echo $this->translate(array('раз', 'раза', 'раз', intval($article->views), 'ru'));
?>
</pre>И получаем желаемый вывод.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-11961462140747606122010-06-09T22:51:00.000+04:002010-06-09T22:53:51.287+04:00Медленный sendmailСегодня моя запись будет довольно короткой. Очередные грабли попались мне при отладке отправки сообщений на почту на локальной машине. Проблема была в <b>очень медленной</b> отправке почты посредством <b>Zend_Mail</b>, который по умолчанию использует транспорт <b>Zend_Mail_Transport_Sendmail</b>, то есть, грубо говоря, программу <b>sendmail</b>. Одно письмо отправлялось около минуты. Начав ковыряться в логах, я обнаружил, что в <b>/var/log/maillog.err </b>пишутся примерно следующие строчки (взяты не из моих логов, так как свои сейчас под рукой не имею):<br />
<pre>Nov 16 18:15:32 desk sendmail[3106]: My unqualified host name (desk) unknown; sleeping for retry
Nov 16 18:16:32 desk sendmail[3106]: unable to qualify my own domain name (desk) -- using short name</pre>Я для локальных адресов использую домены типа <b>site.local</b> (прописываю в <b>/etc/hosts</b> соответствие на петлю <b>127.0.0.1</b>). При этом имя машины, ссылаясь на приведенные лже-записи логов, у меня <b>desk</b> - имя машины. Оно же записано в файле <b>/etc/hostname</b><br />
<br />
<b>Решение</b>: делаем <b>vim /etc/hostname</b>, меняем <b>desk</b> на <b>desk.local</b>, радуемся быстрой работе <b>sendmail</b> :)Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-87053361696003411712010-06-07T16:51:00.000+04:002010-06-07T16:52:13.486+04:002 подводных камня и PHPUnitС недавних пор решил встать на путь истинный и пока я еще совсем новичок в юнит-тестировании. Сегодня споткнулся на некоторых очень неприятных вещах. Использовал <b>PHP 5.3.2 + PHPUnit 3.4.14 + Zend Framework 1.10.5</b><br />
<ol><li>Оказалось, что нельзя в классе, унаследованном от <b>PHPUnit_Framework_TestCase</b>, то есть в тест кейсе использовать свойства класса. Я пытался делать так: в одном методе-тесте в свойство записываю, в другом методе-тесте считываю. Это не работает. Свойство во втором тесте было пустым.</li>
<li>Этот подводный камень очень близок к первому. Аннотация <b>@dataProvider provider</b> является поставщиком данных для тестового метода, но эти данные генерируются в момент создания объекта класса <b>PHPUnit_Framework_TestCase</b>, а не непосредственно перед запуском теста. То есть, опять же, если вы в провайдере используете свойства класса, которые заполняются во время прохождения тестов, то provider вернет пустое значение. Если быть точнее, он вернет значение таким, какое оно было на начало создания объекта класса.</li>
<li>И еще один камень. <b>Zend Studio</b> генерирует тест кейсы и тесты, основываясь на существующих методах классов, что несомненно удобно. Но есть одна проблема: она также генерирует пустой конструктор, который является виной бага <a href="http://framework.zend.com/issues/browse/ZF-4496">[#ZF-4496]</a>. Суть бага в следующем. Если вы используете аннотацию <b>@dataProvider</b> в классе с конструктором, вы будете получать сообщение об ошибке тестов примерно следующего содержания <b>Missing argument 1 for FooTest::testProvider()</b>. Эта ошибка проявляется, если у класса, унаследованного от <b>PHPUnit_Framework_TestCase</b> существует конструктор. Конечно же от нее можно спастись, удалив ненужный конструктор.</li>
</ol>Из первых двух "находок" можно сделать вывод: <b>data provider</b> методы могут быть спокойно описаны как <b>static</b>.<br />
P.S. Ушел продолжать учить матчасть.Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-54971899565441216972010-06-02T21:39:00.000+04:002010-06-06T22:31:24.019+04:00Структура директорий и названия классовХотелось бы поведать свои находки в области наиболее удобной и даже несколько zend-way структуры директорий для проекта.<br />
Глядя на исходники библиотеки ZF, мне хотелось использовать такое же именование классов внутри папки application. Я выбрал такой путь в котором папка application содержит в себе все классы, необходимые для работы проекта. Таким образом, у меня в папке application появились папки plugins, forms, models, controllers.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif1TPCiqpKxxnEi81VBeL5wYJK1RQYLONVwX4h3vg1MmW4kcAp_C4EhYTv-6wBbDIByY04kDznxnbTsBvMmyv3aU86ByOOTGsgH9VgbIq292i233i9u7ru0G4YWiSTnHqPhmWCtogamAs/s1600/zend-tips-directories.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif1TPCiqpKxxnEi81VBeL5wYJK1RQYLONVwX4h3vg1MmW4kcAp_C4EhYTv-6wBbDIByY04kDznxnbTsBvMmyv3aU86ByOOTGsgH9VgbIq292i233i9u7ru0G4YWiSTnHqPhmWCtogamAs/s320/zend-tips-directories.png" /></a></div>Как же правильно сделать так, чтобы все нормально функционировало и в файле Articles.php был класс Model_Articles вместо класса Articles? Это нужно, чтобы избавиться от старого метода автозагрузчика, который запускался следующим образом в файле Bootstrap.php и подключал все пространства имен (зачастую это совершенно излишне):<br />
<pre class="prettyprint">protected function _initAutoload()
{
$loader = Zend_Loader_Autoloader::getInstance();
$loader->setFallbackAutoloader(true);
}</pre>В этом случае на помощь нам может прийти следующий метод нашего класса Bootstrap:<br />
<pre class="prettyprint">protected function _initAutoload()
{
$loader = Zend_Loader_Autoloader::getInstance();
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH,
));
return $moduleLoader;
}
</pre>Таким образом мы создаем модуль автолоадера для загрузки файлов именно нашего приложения, то есть префикс неймспэйса у нас получается пустым и корневая директория - APPLICATION_PATH. Это позволит создавать классы (см. структуру директорий выше) с именами Model_Ratings, Model_Articles. А также уходить вглубь директорий, например положить класс Model_Row_Article в директорию application/models/Row/Article.php В стиле ZF? По-моему, вполне :)Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-21369713089568452682010-05-24T21:36:00.000+04:002010-05-25T05:14:14.746+04:00Дружим XAMPP с ImageMagickНеобходимо мне вдруг стало отлаживать мой хобби-проект <a href="http://spaceismine.org/">http://spaceismine.org/</a> на Windows-машине, который в production-версии работает на Fedora. А на linux-системах нет проблем с установкой расширений, подобных imagick. Для Fedora, к примеру, достаточно установить расширение через yum и перезапустить apache:<br />
<pre class="prettyprint">yum install php-pecl-imagick
service httpd restart</pre>В Windows же не все так просто. Менеджер пакетов PECL под окнами очень капризен и сразу работать не хочет. Для него нужны танцы с бубном, описанные в мануалах. Я решил пойти слегка другим путем: установить imagick, вручную прикрутив его к php.<br />
В целом, ImageMagick - открытое бесплатное программное обеспечение, которое служит для обработки графической информации. А imagick - это php-wrapper (обвязка) для библиотек ImageMagick. Файлы, которые мне понадобились:<br />
<br />
<a href="http://www.imagemagick.org/download/binaries/ImageMagick-6.6.2-0-Q16-windows-dll.exe">http://www.imagemagick.org/download/binaries/ImageMagick-6.6.2-0-Q16-windows-dll.exe</a><br />
<a href="http://valokuva.org/builds/ext/vc9/ts/imagick/2010-05-24_1007/php_imagick_ts.dll">http://valokuva.org/builds/ext/vc9/ts/imagick/2010-05-24_1007/php_imagick_ts.dll</a><br />
<br />
Был выбран wrapper thread-safe, так как версия php, которая была установлена в XAMPP была так же thread-safe. В итоге, я установил ImageMagick и скопировал скачанный php_imagick_ts.dll в место:<br />
<pre class="prettyprint">C:\xampp\php\ext\php_imagick_ts.dll</pre>И тут мне попался огромный подводный камень. Проблемы возникли с тем, что php в XAMPP был скомпилирован с помощью Visual Studio 6.0, а модуль php_imagick_ts.dll - в Visual Studio 9.0 и из-за разных подписей они вместе напрочь отказались работать. А модуль imagick, скомпилированный в VC6 найти так и не удалось.<br />
Я взглянул на версию php, она была 5.3.1, а на production'е у меня 5.3.2. Не очень страшно, но захотелось все же обновить и php. Итак моя, казалось бы безобидная идея, превращается в эпопею. :)<br />
Что ж, я люблю все новое и решил выкачать thread-safe php, собранный в VC9, чтобы он был совместим с imagick. Долго искать не пришлось.<br />
<br />
<a href="http://windows.php.net/downloads/releases/php-5.3.2-Win32-VC9-x86.zip">http://windows.php.net/downloads/releases/php-5.3.2-Win32-VC9-x86.zip</a><br />
<br />
Итак, переименовав на случай отката C:\xampp\php в C:\xampp\php5vc6, я распаковал содержимое свежего php в чистую папку C:\xampp\php. Затем скопировал модуль imagick в C:\xampp\php\ext\php_imagick_ts.dll<br />
Понадобилось скопировать C:\xampp\php\php.ini-development в C:\xampp\php\php.ini, так как последнего не было на месте. Также пришлось немного подкорректировать этот дефолтный php.ini, патч (unified diff) примерно такой:<br />
<pre>--- C:\xampp\php\php.ini Mon May 24 16:09:59 2010 UTC
+++ C:\xampp\php\php.ini-development Wed Mar 3 13:40:56 2010 UTC
@@ -784,7 +784,7 @@
;include_path = ".:/php/includes"
;
; Windows: "\path1;\path2"
-include_path = ".;C:\xampp\php\PEAR"
+;include_path = ".;c:\php\includes"
;
; PHP's default setting for include_path is ".;/path/to/php/pear"
; http://php.net/include-path
@@ -806,7 +806,7 @@
; http://php.net/extension-dir
; extension_dir = "./"
; On windows:
-extension_dir = "ext"
+; extension_dir = "ext"
; Whether or not to enable the dl() function. The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically
@@ -876,7 +876,7 @@
; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
-upload_max_filesize = 10M
+upload_max_filesize = 2M
; Maximum number of files that can be uploaded via a single request
max_file_uploads = 20
@@ -948,7 +948,7 @@
;extension=php_curl.dll
;extension=php_dba.dll
;extension=php_exif.dll
-extension=php_fileinfo.dll
+;extension=php_fileinfo.dll
;extension=php_gd2.dll
;extension=php_gettext.dll
;extension=php_gmp.dll
@@ -956,17 +956,17 @@
;extension=php_imap.dll
;extension=php_interbase.dll
;extension=php_ldap.dll
-extension=php_mbstring.dll
+;extension=php_mbstring.dll
;extension=php_ming.dll
;extension=php_mssql.dll
-extension=php_mysql.dll
+;extension=php_mysql.dll
;extension=php_mysqli.dll
;extension=php_oci8.dll ; Use with Oracle 10gR2 Instant Client
;extension=php_oci8_11g.dll ; Use with Oracle 11g Instant Client
;extension=php_openssl.dll
;extension=php_pdo_firebird.dll
;extension=php_pdo_mssql.dll
-extension=php_pdo_mysql.dll
+;extension=php_pdo_mysql.dll
;extension=php_pdo_oci.dll
;extension=php_pdo_odbc.dll
;extension=php_pdo_pgsql.dll
@@ -985,7 +985,6 @@
;extension=php_xmlrpc.dll
;extension=php_xsl.dll
;extension=php_zip.dll
-extension=php_imagick_ts.dll
;;;;;;;;;;;;;;;;;;;
; Module Settings ;</pre><br />
Таким образом мне удалось подружить XAMPP и imagick, и обновить PHP в XAMPP до версии 5.3.2. Надеюсь, я смог спасти хотя бы кого-нибудь от граблей. :)Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0tag:blogger.com,1999:blog-2218634406037583486.post-85193983603558142862010-05-23T09:30:00.000+04:002010-05-24T20:49:55.878+04:00Autocomplete в Zend StudioНе всегда Zend Studio может определить тип переменной из контекста. Например, когда тип переменной становится ясен только во время интерпретации кода. Случается очень часто, на самом деле, например, когда мы пытаемся пробежаться по rowset'у в цикле foreach.<br />
<pre class="prettyprint">$usersRowset = $usersTable->fetchAll();
foreach ($usersRowset as $userRow) {
$user->... // автокомплит в этом случае не сработает
}</pre>И в таких случаях такая очень важная штука как автокомплит не работает. Класс может содержать огромное количество методов, названия которых вы вряд ли помните все наизусть.<br />
Zend Studio большинство своих автокомплитов распарсивает из комментариев PHPDoc. Поэтому, чтобы заработал автокомплит, необходимо добавить комментарий PHPDoc<br />
<pre class="prettyprint">$usersRowset = $usersTable->fetchAll();
/* @var $userRow Zend_Db_Table_Row */
foreach ($usersRowset as $userRow) {
$user->... // автокомплит работает :)
}</pre>Detonatorhttp://www.blogger.com/profile/17120241971820432748noreply@blogger.com0