<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Корчагин Станислав &#187; базы данных</title>
	<atom:link href="http://korchasa.ru/index.php/tag/%d0%b1%d0%b0%d0%b7%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85/feed/" rel="self" type="application/rss+xml" />
	<link>http://korchasa.ru</link>
	<description>Разработка, тестирование, запуск</description>
	<lastBuildDate>Mon, 24 May 2010 23:28:58 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Bulk update в MySQL</title>
		<link>http://korchasa.ru/index.php/2009/11/bulk-update-%d0%b2-mysql/</link>
		<comments>http://korchasa.ru/index.php/2009/11/bulk-update-%d0%b2-mysql/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 02:28:57 +0000</pubDate>
		<dc:creator>korchasa</dc:creator>
				<category><![CDATA[Мелочи]]></category>
		<category><![CDATA[базы данных]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://korchasa.ru/?p=251</guid>
		<description><![CDATA[Ревизия #2
В порыве пятничного отлынивания от работы, совместно с коллегой, родили нечто.
Нечто позволяет одним запросом обновлять неограниченное количество записей. Причем разные столбцы, на разные данные, в зависимости от уникального ключа.
Нечто имеет следующие недостатки:

требует уникального ключа
если строки с подходящим ключом нет, то она добавится
для построения требует знаний о типах полей таблицы
мускл на него ругается ворнингами
NULL таким [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #c0c0c0;">Ревизия #2</span></p>
<p>В порыве пятничного отлынивания от работы, совместно с <a href="http://didyk.moikrug.ru/" target="_self">коллегой</a>, родили нечто.</p>
<p>Нечто позволяет одним запросом обновлять неограниченное количество записей. Причем разные столбцы, на разные данные, в зависимости от уникального ключа.</p>
<p>Нечто имеет следующие недостатки:</p>
<ul>
<li>требует уникального ключа</li>
<li>если строки с подходящим ключом нет, то она добавится</li>
<li>для построения требует знаний о типах полей таблицы</li>
<li>мускл на него ругается ворнингами</li>
<li>NULL таким образом вставить невозможно</li>
</ul>
<p><span id="more-251"></span></p>
<p>SQL:</p>
<pre><code class="SQL">CREATE TABLE  `bulk_update` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `int` int(11) NOT NULL DEFAULT '7',
  `str` varchar(5) NOT NULL DEFAULT 'def',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

INSERT INTO `bulk_update` (`id`, `int`, `str`)
  VALUES (1, 1, 'a'), (2, 2, 'b'), (3, 3, 'c');

INSERT INTO `bulk_update` (`id`, `int`, `str`)
  VALUES (1, 22, null), (2, null, 'bb')
  ON DUPLICATE KEY UPDATE
    `int` = IFNULL(NULLIF(VALUES(`int`), 0), `int`),
    `str` = IFNULL(NULLIF(VALUES(`str`), ''), `str`);

SELECT * FROM bulk_update;
+----+-----+-----+
| id |   int | str |
+----+-----+-----+
|  1 |   22 | a   |
|  2 |   2  | bb  |
|  3 |   3  | c   |
+----+-----+-----+</code></pre>
<p>Тесты скорости показали следующие результаты:</p>
<table border="0">
<tbody>
<tr>
<th>Обновляемых записей</th>
<th>По одному (qps)</th>
<th>Кучкой (qps)</th>
</tr>
<tr>
<td>10</td>
<td>2296</td>
<td>3620</td>
</tr>
<tr>
<td>100</td>
<td>3480</td>
<td>11097</td>
</tr>
<tr>
<td>1000</td>
<td>3959</td>
<td>18804</td>
</tr>
</tbody>
</table>
<p>Во время теста параллельно пускались три скрипта, делающие разнообразные селекты к таблице.</p>
<p>Тест, как всегда, <a href="http://korchasa.googlepages.com/multiple_updates.php">прилагается</a>.</p>
<p>В общем штука получилась интересная, но какая-то костылеподобная.</p>
<p>UPD: Теперь работает и для столбцов с NOT NULL и без оного.</p>
]]></content:encoded>
			<wfw:commentRss>http://korchasa.ru/index.php/2009/11/bulk-update-%d0%b2-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Денормализация связей многие-ко-многим, через битовые маски</title>
		<link>http://korchasa.ru/index.php/2009/05/%d0%b4%d0%b5%d0%bd%d0%be%d1%80%d0%bc%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d0%b2%d1%8f%d0%b7%d0%b5%d0%b9-%d0%bc%d0%bd%d0%be%d0%b3%d0%b8%d0%b5-%d0%ba%d0%be-%d0%bc%d0%bd%d0%be%d0%b3/</link>
		<comments>http://korchasa.ru/index.php/2009/05/%d0%b4%d0%b5%d0%bd%d0%be%d1%80%d0%bc%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d0%b2%d1%8f%d0%b7%d0%b5%d0%b9-%d0%bc%d0%bd%d0%be%d0%b3%d0%b8%d0%b5-%d0%ba%d0%be-%d0%bc%d0%bd%d0%be%d0%b3/#comments</comments>
		<pubDate>Mon, 04 May 2009 02:28:02 +0000</pubDate>
		<dc:creator>korchasa</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[базы данных]]></category>
		<category><![CDATA[Добавить метку]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://korchasa.ru/?p=240</guid>
		<description><![CDATA[Ситуация довольно банальная: есть, например, статьи и тэги, связанные многие-ко-многим, и необходимо быстро находить статьи с определенным тэгом или несколькими тэгами.]]></description>
			<content:encoded><![CDATA[<p>Ситуация довольно банальная: есть статьи и тэги, связанные многие-ко-многим, и необходимо быстро находить статьи с определенным тэгом или несколькими тэгами. Необходимо обойтись без JOIN и одним простым запросом.</p>
<p>В mysql есть <a href="http://dev.mysql.com/tech-resources/articles/mysql-set-datatype.html">тип данных set</a>, который вполне для этого подходит. Но можно и ручками</p>
<p>Посмотрим взлетит оно или нет:</p>
<pre lang="mysql">CREATE TABLE  `tests`.`article` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `mask` int(10) unsigned default NULL,
  `cset` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20') default NULL,
  PRIMARY KEY  (`id`),
  KEY `mask` (`mask`),
  KEY `cset` (`cset`)
) ENGINE=InnoDB;</pre>
<p>Добавление записей:</p>
<pre lang="mysql">INSERT INTO article VALUES(NULL, 3, '1,2');</pre>
<p>Выбор по одному тэгу:</p>
<pre lang="mysql">select count(*) from article where mask & 1; //помеченные тэгом #1
select count(*) from article where cset & 1;</pre>
<p>Выбор по нескольким тэгам &#8211; объединение:</p>
<pre lang="mysql">select count(*) from article where mask & 3; //помеченные тэгом #1 ИЛИ #2
select count(*) from article where cset & 3;</pre>
<p>Выбор по нескольким тэгам  &#8211; пересечение:</p>
<pre lang="mysql">select count(*) from article where mask &#038; 1 AND mask & 2; //помеченные и  тэгом #1 И тэгом #2
select count(*) from article where cset &#038; 1 AND cset & 2;</pre>
<p>По скорости варианты равноценны, и на табличке с 500К записей (20 разных тэгов, по 1-20 тэгов на статью) все запросы обрабатывались за, примерно, 0.3 секунды, на средненькой домашней машинке.</p>
]]></content:encoded>
			<wfw:commentRss>http://korchasa.ru/index.php/2009/05/%d0%b4%d0%b5%d0%bd%d0%be%d1%80%d0%bc%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%81%d0%b2%d1%8f%d0%b7%d0%b5%d0%b9-%d0%bc%d0%bd%d0%be%d0%b3%d0%b8%d0%b5-%d0%ba%d0%be-%d0%bc%d0%bd%d0%be%d0%b3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Лебедь, рак и щука: огранизация работы нескольких программистов на малых и средних проектах</title>
		<link>http://korchasa.ru/index.php/2008/11/%d0%bb%d0%b5%d0%b1%d0%b5%d0%b4%d1%8c-%d1%80%d0%b0%d0%ba-%d0%b8-%d1%89%d1%83%d0%ba%d0%b0-%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d0%bd/</link>
		<comments>http://korchasa.ru/index.php/2008/11/%d0%bb%d0%b5%d0%b1%d0%b5%d0%b4%d1%8c-%d1%80%d0%b0%d0%ba-%d0%b8-%d1%89%d1%83%d0%ba%d0%b0-%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d0%bd/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 09:00:00 +0000</pubDate>
		<dc:creator>korchasa</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[базы данных]]></category>
		<category><![CDATA[разработка]]></category>

		<guid isPermaLink="false">http://korchasa.ru/?p=3</guid>
		<description><![CDATA[Для начала определимся с тем, что мы делаем. Обычно наш продукт состоит из:

сервера или нескольких серверов
настроек сторонних приложений (http-сервера, СУБД, прочие хранилища данных и утилиты)
нашей схемы размещения файлов (фото, видео, и прочий хлам контент)
наших кэшей
нашей структуры БД
нашего кода
бессоных ночей

Начнем с конца, пропустив бессоные ночи.

Обычно все начинают с одного и того же&#8230;
Коммунизм
Один сервер, одна база, один [...]]]></description>
			<content:encoded><![CDATA[<p>Для начала определимся с тем, что мы делаем. Обычно наш продукт состоит из:</p>
<ul>
<li>сервера или нескольких серверов</li>
<li>настроек сторонних приложений (http-сервера, СУБД, прочие хранилища данных и утилиты)</li>
<li>нашей схемы размещения файлов (фото, видео, и прочий хлам контент)</li>
<li>наших кэшей</li>
<li>нашей структуры БД</li>
<li>нашего кода</li>
<li>бессоных ночей</li>
</ul>
<p>Начнем с конца, пропустив бессоные ночи.</p>
<p><span id="more-66"></span></p>
<p><span style="font-style: italic;">Обычно все начинают с одного и того же&#8230;</span></p>
<h3>Коммунизм</h3>
<p>Один сервер, одна база, один код. Правим по очереди или по алфавиту. Правки то и дело сопровождаются криками «Не трогайте пока User.php. Мне надо выборки поправить». Версионность кода поддерживается ежедневным архивированием папочки с кодом и дампом БД.</p>
<p><span style="font-style: italic;">И надоело им материться, и явился им <a href="http://ru.wikipedia.org/wiki/Subversion">SVN</a> (<a href="http://ru.wikipedia.org/wiki/CVS">CVS</a>, <a href="http://ru.wikipedia.org/wiki/Git">Git</a>, <a href="http://en.wikipedia.org/wiki/Bazaar_%28software%29">Bazaar</a>, нужное подчеркнуть). И поняли они, что это хорошо&#8230;</span></p>
<h3>База на то и база, чтобы одна была</h3>
<p>Стало лучше, но все равно то и дело слышаться возгласы «Ёп! Кто поле is_hidden у статьи убрал? Оно же во всех выборках! Давай коммить (новые выборки) быстрей!».</p>
<p>Призадумались ребята. Подумали, поспали, еще подумали. И поняли, что схему БД надо «привязывать» к коду, который с ней работает. Погуглили, и нашли:</p>
<ul>
<li><a href="http://www.google.com/search?q=mysql+diff">кучу утилит</a>, которые умеют делать «diff» между двумя базами</li>
<li>для ROR на Ruby &#8211; <a href="http://www.railsforum.com/viewtopic.php?id=1011">миграции</a> на SQL DDL</li>
<li>для Django на Python &#8211; <a href="http://www.aswmc.com/dbmigration/">DbMigration</a></li>
<li>а для РНР — всю туже кучу утилит типа mysql diff, ну еще и <a href="http://www.doctrine-project.org/documentation/manual/1_0?chapter=migration">Doctrine Migration</a> для <a href="http://ru.wikipedia.org/wiki/ORM">ORM</a> <a href="http://www.doctrine-project.org/">Doctrine</a>.</li>
</ul>
<p>А отдельные храбрецы, разрабатывающие на <a href="http://limb-project.com/">LIMB</a>&#8216;е используют <a href="https://svn.limb-project.com/limb/misc/migration/">вот эту радость</a>. Радость представляет из себя набор консольных утилит для автоматического создания, тестирования и применения миграций, а так же для создания дампов БД. Подробности <a href="http://forum.limb-project.com/viewtopic.php?t=2315">можно прочитать</a> на нашем <a href="http://forum.limb-project.com/">форуме</a>.<br />
Все вроде бы хорошо, но вот беда — на продакшене кэши решили хранить в <a href="http://ru.wikipedia.org/wiki/Memcached">memcached</a>, а на машинах разработчиков толи памяти мало, толи им на содержимое кэша часто смотреть приходится.</p>
<h3>Делим cash, то есть cache</h3>
<p>Что у нас есть такое куда смотреть легко, и где место не жалко. Эврика! Файлы на диске. Теперь дело за малым — нужна библиотечка, которая позволит простым изменением настройки переключаться между разными хранилищами.</p>
<p>ИМХО, каждый, уважающий себя, фреймворк должен иметь такую штуку. Хотя бы для того, чтобы мерятся с другими. У <a href="http://framework.zend.com/">Zend Framework</a> есть Zend_Cache. В <a href="http://limb-project.com/">LIMB</a> таких штук целых две. Пакет сache — нормально работает и вполне стабилен (по API), и второй писал я, со всеми вытекающими. Пакет <a href="https://svn.limb-project.com/limb/3.x/trunk/limb/cache2/">cache2</a>:</p>
<ul>
<li>6 хранилищ: память скрипта, APC, memcached, БД, файлы, сессия, фейк для тестов, (и еще, как минимум, добавится кэш в РНР-файл)</li>
<li>хранилища будут иметь абсолютно одинаковый интерфейс и потокобезопасность:
<ul>
<li>add</li>
<li>get</li>
<li>set</li>
<li>delete</li>
<li>flush</li>
<li>increment/decrement</li>
<li>safeIncrement/safeDecrement</li>
<li>lock/unlock</li>
</ul>
</li>
<li>логгер, позволяющий отслеживать операции с кэшом</li>
<li>утилитка для проведения микротестов</li>
<li>полустабильное состояние</li>
</ul>
<p>Вся информация о хранилище задается с помощью <a href="http://en.wikipedia.org/wiki/Database_Source_Name">DSN</a>. Например:</p>
<pre lang="PHP">file:///tmp/cache //кэш на файлах
apc:///?prefix=foo //кэш в APC, ключи префиксуются строкой foo.</pre>
<p><span style="font-style: italic;">Ну совсем все радостно, но файлы на продакшене на отдельном сервере лежат, а у разработчиков локально надо. Или настройкой sphinx занимается только один человек, и поднимать его у остальных — бессмысленно.</span></p>
<h3>Абстракция. Как много в этом слове</h3>
<p>Как известно любая проблема, кроме одной, решается введением абстракции. Решим и нашу.</p>
<p>Для начала разделим каждый наш файл конфигурации на две части: общую и специфичную для конкретной машины. У нас это, например, <code>avatar.conf.php</code> и <code>avatar.conf.override.php</code>. Специфичные штуки игнорируем в нашей системе контроля версий. Общие кладем рядом с кодом. Желательно, чтобы в файле с общими настройками задавались настройки для продакшена. Тогда вы во-первых их(настройки продакшена) не потеряете, а во-вторых проще будет продакшен обновлять.</p>
<p>Разница при работе с медиа-файлами обычно сводится к двум задачам:</p>
<ul>
<li>куда-то положить</li>
<li>откуда-то запросить</li>
</ul>
<p>Для указания размещения файлов мы, используем URL и обычную функцию copy(). Например на продакшене</p>
<pre lang="PHP">'scp://storage_user@storage_host1/'
.'?rsa_pub='.urlencode('/home/php-fpm/.ssh/id_rsa.pub')
.'&amp;rsa;=' .urlencode('/home/php-fpm/.ssh/id_rsa').'/media'</pre>
<p>, а на машине разработчика просто</p>
<pre lang="PHP">'/www/somesite/www/media/'</pre>
<p>Ну а с тем откуда запрашивать еще проще. Для продакшена <code>'img-1.somesite.ru/media/'</code>, а у разработчика <code>somesite.pupkin.local/media/'</code>. Это базовые пути и URL&#8217;ы для медиа-файлов. Остальное определяется, исходя из id файла.</p>
<p>Со Sphinx&#8217;ом поступим схожим образом. Добавим в конфигурационный файл директиву fake_search, которая будет определять тип поискового сервиса. Используя фабричный метод, наподобие такого:</p>
<pre lang="PHP">static function createSearchService($config)
{
  if(!isset($config['fake_search']) || !$config['fake_search'])
    return SphinxClient();
  else
    return FakeSphinxClient();
}</pre>
<p>, т.к.  SphinxClient и  FakeSphinxClient реализуют общий интерфейс, то для остальной программы такая замена пройдет незаметно.  FakeSphinxClient будет просто отдавать первые  подходящие объекты, а следовательно верстальщик сможет застилить страницу с результатами поиска, не занимаясь такими «магическими» штуками, как установка Sphinx.</p>
<p><span style="font-style: italic;">Разработчики рады, и поют песни, восхваляющие абстракции. Осталась одна маленькая проблемка — разница в версиях ПО третих сторон, и их настройках.</span></p>
<h3>Может хватит, а?</h3>
<p>Вот на этом шаге мы остановились и находимся в данный момент. Следующий этап эволюции   это работа в среде, максимально приближенной к «боевой». Т.е. работа на общем сервере, где с помощью виртуализации поддерживается среда, в которой нам придется работать на продакшене. У каждого свой код, своя база(и не одна), в общей СУБД, свои хосты. Все межсерверные взаимодействия отлаживаются еще на этапе разработки. И проблем с разными версиями ПО не возникает.</p>
<p>Коммит.</p>
]]></content:encoded>
			<wfw:commentRss>http://korchasa.ru/index.php/2008/11/%d0%bb%d0%b5%d0%b1%d0%b5%d0%b4%d1%8c-%d1%80%d0%b0%d0%ba-%d0%b8-%d1%89%d1%83%d0%ba%d0%b0-%d0%be%d0%b3%d1%80%d0%b0%d0%bd%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d1%80%d0%b0%d0%b1%d0%be%d1%82%d1%8b-%d0%bd/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP 5.3: что пых грядущий нам готовит?</title>
		<link>http://korchasa.ru/index.php/2008/02/php-53-%d1%87%d1%82%d0%be-%d0%bf%d1%8b%d1%85-%d0%b3%d1%80%d1%8f%d0%b4%d1%83%d1%89%d0%b8%d0%b9-%d0%bd%d0%b0%d0%bc-%d0%b3%d0%be%d1%82%d0%be%d0%b2%d0%b8%d1%82/</link>
		<comments>http://korchasa.ru/index.php/2008/02/php-53-%d1%87%d1%82%d0%be-%d0%bf%d1%8b%d1%85-%d0%b3%d1%80%d1%8f%d0%b4%d1%83%d1%89%d0%b8%d0%b9-%d0%bd%d0%b0%d0%bc-%d0%b3%d0%be%d1%82%d0%be%d0%b2%d0%b8%d1%82/#comments</comments>
		<pubDate>Fri, 22 Feb 2008 00:00:00 +0000</pubDate>
		<dc:creator>korchasa</dc:creator>
				<category><![CDATA[Статьи]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[базы данных]]></category>
		<category><![CDATA[производительность]]></category>
		<category><![CDATA[разработка]]></category>

		<guid isPermaLink="false">http://korchasa.ru/?p=36</guid>
		<description><![CDATA[То о чем так долго говорили большевики&#8230;
Кратенько:

пространства имен
mysqlnd
позднее статическое связывание
динамические вызовы статических методов
Прочие изменения

А теперь подробно&#8230;

Пространства имен
/* Серое и унылое настоящее */
class MyAclSimpleRole {}
$a = new MyAclSimpleRole;

/* или (Zend FW) */
class My_Acl_Simple_Role {}
$a = new My_Acl_Simple_Role;

/* А теперь так */
namespace My::Acl::Simple;
class Role {}

/* По прежнему можем использовать полное имя */
$a = new My::Acl::Simple::Role;

/* А если [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>То о чем так долго говорили большевики&#8230;</p></blockquote>
<p>Кратенько:</p>
<ul>
<li>пространства имен</li>
<li>mysqlnd</li>
<li>позднее статическое связывание</li>
<li>динамические вызовы статических методов</li>
<li>Прочие изменения</li>
</ul>
<p>А теперь подробно&#8230;<br />
<span id="more-36"></span></p>
<h3>Пространства имен</h3>
<pre><code class="php">/* Серое и унылое настоящее */
class MyAclSimpleRole {}
$a = new MyAclSimpleRole;

/* или (Zend FW) */
class My_Acl_Simple_Role {}
$a = new My_Acl_Simple_Role;

/* А теперь так */
namespace My::Acl::Simple;
class Role {}

/* По прежнему можем использовать полное имя */
$a = new My::Acl::Simple::Role;

/* А если use добавить... */
use My;
$a = new Acl::Simple::Role;

use My::Acl;
$a = new Simple::Role;

use My::Acl::Simple;
$a = new Role;

/* А если alias добавить, то вообще красота */
use My::Acl::Simple as defaultAcl;
$a = new defaultAcl::Role;

use My as default;
$a = new default::Acl::Role;</pre>
<p>Помимо этого введена константа __NAMESPACE__, добавки в рефлексии, глобальное пространство "::".</p>
<p>Людям, использующим в названии классов идеологию, схожую с идеологией Zend Framework, данная фича очень понравится. Возможно она "под него" и вводилась <img src='http://korchasa.ru/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>К сожалению не смог найти информацию о том, можно ли будет повесить обработчик на команду use, а следовательно анализировать и всячески инициализировать пространства.</p>
<h3><a href="http://blog.ulf-wendel.de/?p=149">mysqlnd</a> (MySQL native driver)</h3>
<p>Наконец то в РНР появится замена для libmysql, причем "заточенная" под PHP на C-шном уровне. Напомню, что в самом начале 5-ой ветки libmysqli пришлось убрать из ядра по лицензионным соображениям. mysqlnd же выпускается под <a href="http://www.php.net/license">лицензией PHP</a>. Вы наверное уже обрадовались, что из-за нового API, сможете выбить из начальства время на review всего кода, работающего с БД?</p>
<p>К сожалению я не знаю код символа изображающего фигу, сейчас бы пригодился.</p>
<p>mysqlnd это низкоуровневая С-шная библиотека для работы с базой данных, а не новое расширение для PHP. mysqlnd уже "понимает" API ext/mysqli, поддержка PDO/MySQL сейчас пишеться, а поддержки ext/mysql не будет.</p>
<p><a href="http://www.hristov.com/andrey/projects/php_stuff/pres/mysqlnd_vikinger.pdf"><img src="http://blog.ulf-wendel.de/images/mysqlnd2.gif" alt="#########" /></a></p>
<p>Уже приведены <a href="http://blog.ulf-wendel.de/?p=136">бенчмарки</a>, и их результаты мягко говоря радуют.</p>
<h3>Позднее статическое связывание</h3>
<p>Проще всего текущее бедственное состояние будет пояснить на примере:</p>
<pre lang="php">class Foo {
  public static function whoIsItDrinkins() {
      return __CLASS__;
  }
}

class Bar extends Foo {}

echo Bar::whoIsItDrinkins(); //Foo</pre>
<p>Проблема в том, что переменная указывающая на текущий класс (__CLASS__ или self) указывает на тот класс, в котором метод объявляется, а не тот, у которого он вызван.</p>
<p>Острее всего эта проблема проявляется при попытке реализовать в РНР паттерн <a href="http://wiki.limb-project.com/doku.php?id=limb3:ru:packages:active_record">ActiveRecord</a>, и приводит к <a href="http://forum.agiledev.ru/index.php?t=msg&amp;goto=5540">использованию грязноватых хаков</a> <img src='http://korchasa.ru/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>В версии 5.3 появится метод get_called_class(), который будет указывать на класс, у которого этот метод вызван.</p>
<pre lang="php">class Foo {
  public static function whoIsItDrinkins() {
      return get_called_class();
  }
}

class Bar extends Foo {}

echo Bar::whoIsItDrinkins(); //та-да!</pre>
<h3>__callstatic()</h3>
<pre lang="php">class FooFactory {
  static function call() {
    echo 'Простите все операторы сейчас заняты';
  }
  static function __callStatic( $methodname, $args ) {
    echo '

Добрый день! Вы только вызвали статический метод ' . $methodname . '

';
    echo '

С параметрами:

';
    echo '</pre>
<pre>' . print_r( $args, true ) . '</pre>
<p>';<br />
echo '</p>
<p>Спасибо. Ваш вызов для нас очень важен.</p>
<p>';<br />
}<br />
}</p>
<p>FooFactory :: call();<br />
FooFactory :: callAnotherTime('А ну отозвались!');</p>
<p>Давно пора. Это же какие красоты открываются. Можно например автоматом маппить поиски в, уже упомянутый, <a href="http://wiki.limb-project.com/doku.php?id=limb3:ru:packages:active_record">ActiveRecord</a>:</p>
<pre lang="php">$posted_articles = Articles::findByIsPosted(true);

$new_members = Member::findByRegistrationDateLessWhat($today);</pre>
<p>И все это без единой дополнительной строчки в классах Article и Member!</p>
<p><small>Когда же появиться нативная функция для преобразования camel case в underlines <img src='http://korchasa.ru/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </small></p>
<h3>Динамические вызовы статических методов</h3>
<pre lang="php">$method = 'callAnotherTime';
FooFactory :: $method('Я вас каждый день вызывать буду!');</pre>
<p>Практического применения я вот так сходу найти не смог, но но думаю оно как суслик, я его не вижу, а оно есть</p>
<h3>Новый уровень ошибок E_DEPRECATED</h3>
<p>Новый уровень позволит заранее начать избавляться от функционала, который впоследствии не будет поддерживаться</p>
<h3>Конфигурационные файлы</h3>
<ul>
<li>конфиги теперь можно делать для конкретной директории, а не использовать для этого .htaccess и php_value/php_admin_valie</li>
<li>в php.ini добавлены секции для конкретных директорий. Их опции не могут переопределяться ни в скриптах, ни в конфигурационных файлах директорий</li>
<li>сообщения об ошибках в конфигурационных файлах теперь более "говорящие"</li>
<li>добавлена поддержка ключей для массивов</li>
</ul>
<h3>Прочие изменения</h3>
<ul>
<li>в расширение openSSL добавленна поддержка алгоритма <a href="http://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%94%D0%B8%D1%84%D1%84%D0%B8_%E2%80%94_%D0%A5%D0%B5%D0%BB%D0%BB%D0%BC%D0%B0%D0%BD%D0%B0">Диффи-Хеллмана</a>, который необходим для тех, кто работает с OpenID.</li>
<li>функция <a href="http://php.net/getopt">get_opt()</a> теперь кроссплатформенная</li>
<li>в расширение sqlite добавленна поддержка Sqlite3</li>
<li>сделано несколько улучшений в SPL</li>
<li>добавлена константа __DIR__, которая заменит dirname(__FILE__)</li>
</ul>
<p><strong>UPD</strong>: добавлена информация о __DIR__</p>
]]></content:encoded>
			<wfw:commentRss>http://korchasa.ru/index.php/2008/02/php-53-%d1%87%d1%82%d0%be-%d0%bf%d1%8b%d1%85-%d0%b3%d1%80%d1%8f%d0%b4%d1%83%d1%89%d0%b8%d0%b9-%d0%bd%d0%b0%d0%bc-%d0%b3%d0%be%d1%82%d0%be%d0%b2%d0%b8%d1%82/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
