<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>В лабиринте извилин</title>
	
	<link>http://www.charnad.com</link>
	<description>Блог-центр им. CharnaD</description>
	<lastBuildDate>Wed, 18 Aug 2010 11:11:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/charnad" /><feedburner:info uri="charnad" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Symfony: Optgroup в DoctrineChoice</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/RnGqhOpH6yY/</link>
		<comments>http://www.charnad.com/blog/symfony-optgroup-v-doctrinechoice/#comments</comments>
		<pubDate>Wed, 18 Aug 2010 11:11:56 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[form]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1186</guid>
		<description><![CDATA[Потребовалось мне сделать optgroup в виджете choice, и не просто так, а с условием. Если у объекта есть дочерние элементы - то он становится optgroup, а иначе его можно выбрать. За основу я взял sfWidgetFormDoctrineChoiceNestedSet, который можно взять из плагина sfDoctrineNestedSetPlugin. Я скопировал код, добавил в запрос условие: $query->addWhere('level = ?', 0); Это потому, что [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" />Потребовалось мне сделать optgroup в виджете choice, и не просто так, а с условием. Если у объекта есть дочерние элементы - то он становится optgroup, а иначе его можно выбрать. За основу я взял sfWidgetFormDoctrineChoiceNestedSet, который можно взять из плагина <a href="http://www.symfony-project.org/plugins/sfDoctrineNestedSetPlugin">sfDoctrineNestedSetPlugin</a>. Я скопировал код, добавил в запрос условие:</p>
<pre class="php">$query->addWhere('level = ?', 0);</pre>
<p>Это потому, что все, что ниже уровнем мы будем получать через getChildren. Иначе нам пришлось бы двигать итератор Doctrine_Collection, что более сложно, заумно, и вовсе у меня не получилось (next($objects) почему-то не дает эффекта).<br />
Сделать optgroup в choice совсем несложно, надо лишь сделать элемент массивом. Ну а что получилось собственно внутри поста.<br />
<span id="more-1186"></span><br />
Я еще раз повторюсь, что это код sfWidgetFormDoctrineChoiceNestedSet, за малым изменением.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> weDoctineOptgroupSelectWidget <span style="color: #000000; font-weight: bold;">extends</span> sfWidgetFormDoctrineChoice <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> getChoices<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$choices</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">false</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'add_empty'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$choices</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'add_empty'</span><span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">''</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'add_empty'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table_method'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span> <span style="color: #339933;">===</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query'</span><span style="color: #009900;">&#41;</span> ? Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'model'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">createQuery</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// force manual sorting according to root_id then by lft</span>
      <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOrderBy</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'root_id asc'</span><span style="color: #009900;">&#41;</span>
          <span style="color: #339933;">-&gt;</span><span style="color: #004000;">addOrderBy</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'lft asc'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// Viktoras: we need to fetch only top level, as we'll get the children with getChildren()</span>
      <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addWhere</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'level = ?'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$tableMethod</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table_method'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$results</span> <span style="color: #339933;">=</span> Doctrine_Core<span style="color: #339933;">::</span><span style="color: #004000;">getTable</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'model'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$tableMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$results</span> instanceof Doctrine_Query<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$results</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">execute</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$results</span> instanceof Doctrine_Collection<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$results</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$results</span> instanceof Doctrine_Record<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Doctrine_Collection<span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'model'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$objects</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$results</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$objects</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'method'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$keyMethod</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'key_method'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$object</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// indent item by 4 spaces per level</span>
      <span style="color: #666666; font-style: italic;">// Viktoras: here we check for children and make entry an array if they exists</span>
      <span style="color: #000088;">$node</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">hasChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$node</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getChildren</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$child</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
          <span style="color: #000088;">$choices</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$child</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$keyMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_repeat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;nbsp;'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$child</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'level'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$child</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$choices</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$keyMethod</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_repeat</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&amp;nbsp;'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$object</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'level'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$method</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #000088;">$choices</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>И выглядит это вот так:<br />
<img src="http://img405.imageshack.us/img405/8427/12ece8ab6752487cafefb3c.png"></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-optgroup-v-doctrinechoice/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/symfony-optgroup-v-doctrinechoice/</feedburner:origLink></item>
		<item>
		<title>Symfony Tips: #1</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/GsFBW_o1PFY/</link>
		<comments>http://www.charnad.com/blog/symfony-tips-1/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 15:50:21 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[admin generator]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony tips]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1178</guid>
		<description><![CDATA[Бывает, что находишь какое-то решение в Гугле, а потом когда я сталкиваешься с похожей ситуацией - второй раз уже не можешь найти. Поэтому я буду записывать моменты, которые мне были полезны и могут понадобиться еще, будет что-то вроде рубрики Symfony tips. Как вообще убрать фильтры в admin generator? config: filter: class: false Как повесить иконку [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" />Бывает, что находишь какое-то решение в Гугле, а потом когда я сталкиваешься с похожей ситуацией - второй раз уже не можешь найти. Поэтому я буду записывать моменты, которые мне были полезны и могут понадобиться еще, будет что-то вроде рубрики Symfony tips.</p>
<p><strong>Как вообще убрать фильтры в admin generator?</strong></p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">config:
  filter:
    class: false</pre></div></div>

</p>
<p><strong>Как повесить иконку своему кастомному object_action?</strong></p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#sf_admin_container</span> ul li<span style="color: #6666ff;">.sf_admin_action_</span>#<span style="color: #cc00cc;">#ACTION_NAME</span>## a
<span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">/images/icons/icon.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

</p>
<p><strong>Как недопустить ввода пустой строки в админке?</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'trim'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p><strong>Fatal error: Call to undefined function include_component()</strong><br />
Вы, скорее всего, указали в settings.yml standart_helpers, и забыли добавить в список Partial.</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">all: 
  .settings: 
    standard_helpers:       [I18N, Partial]</pre></div></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-tips-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/symfony-tips-1/</feedburner:origLink></item>
		<item>
		<title>Поездка в Чехию. Часть 1.</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/YCaPgvb-Zkk/</link>
		<comments>http://www.charnad.com/blog/poezdka-v-czechiu-part-1/#comments</comments>
		<pubDate>Wed, 23 Jun 2010 22:11:02 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Обо мне]]></category>
		<category><![CDATA[Прочее]]></category>
		<category><![CDATA[Фото]]></category>
		<category><![CDATA[Чехия]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1116</guid>
		<description><![CDATA[18 июня исполнился год с момента нашей свадьбы, и это событие мы решили отметить поездкой в Чехию. Ехали, конечно же, в Прагу. В планах было посмотреть старый город, Влтаву (река, на которой стоит Прага), мосты, покушать чешской еды и попробовать чешское пиво в самой Чехии. И сейчас я вам расскажу как это было. За день [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/czechia.png" alt="Czechia" />18 июня исполнился год с момента нашей свадьбы, и это событие мы решили отметить поездкой в Чехию. Ехали, конечно же, в Прагу. В планах было посмотреть старый город, Влтаву (река, на которой стоит Прага), мосты, покушать чешской еды и попробовать чешское пиво в самой Чехии. И сейчас я вам расскажу как это было.<br />
<span id="more-1116"></span></p>
<p>За день до поездки мы искали отель, так как собирались пробыть в Праге два дня, а так же изучали карту города и смотрели сайты ресторанов, выбирая поинтереснее и подешевле. Сразу дам ссылочку на <a href="http://www.pragueexperience.com/">сайт</a>, который нам сильно помог. Как раз там мы и заказали номер. Изначально хотели взять что подешевле, но все оказалось уже занятым, поэтому взяли номер на двоих в 4х-звездочном небольшом отеле <a href="http://www.pragueexperience.com/places.asp?PlaceID=711">Antik</a> за 60 евро, включая завтрак. Чуть забегая вперед скажу, что это составило чуть меньше половины всех наших затрат на это путешествие.</p>
<p>Отправились мы из Zittau в 8:45 на поезде до города <a href="http://maps.google.com/maps?hl=en&#038;jsv=250a&#038;sll=50.766594,15.065947&#038;sspn=0.02926,0.077162&#038;ie=UTF8&#038;geocode=FaykBgMdB73lAA&#038;split=0">Liberec</a>. Билеты купили заранее, стоили они всего €2,60 на человека. Дорога заняла всего 35 минут, и в 9:20 мы уже были на месте. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5819.jpg" title="" class="shutterset_singlepic69" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/69__160x120_dsc_5819.jpg" alt="dsc_5819" title="dsc_5819" />
</a>
Либерецкий вокзал на ремонте и выходить пришлось какими-то грязными корридорами. Как вышли - побежали на автобусный вокзал, уж очень хотели успеть на автобус на 10 часов. Для чешских автобусов есть очень удобный сайт <a href="http://www.zluty.cz/online/Booking">Student Agency</a>, где можно заказать билет заранее и оплатить, а потом при входе просто сказать номер своей брони. При бронировании можно увидеть сколько мест осталось свободно и выбрать какие именно места хотите. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5815.jpg" title="" class="shutterset_singlepic68" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/68__160x120_dsc_5815.jpg" alt="dsc_5815" title="dsc_5815" />
</a>
И вот за день до отъезда я хотел забронировать нам места в автобусе на 10 часов, но к сожалению, моя банковская карта не подходит для оплаты через интернет, а мест в автобусе оставалось всего 7. К нашему счастью мы успели купить билеты. До отправления оставалось около 30 минут, так что мы немного погуляли вокруг вокзала, или как его там называют Nádraží.</p>
<p>Ровно в 10 часов подошел наш автобус, такие называют coach. Наши места были 29,30 — как раз напротив входа. Здесь мы были порядком удивлены. За билеты мы заплатили 160 чешских крон, что равно примерно 6 евро. При этом в автобусе было несколько экранов, где можно было смотреть сериал «Друзья» на английском с чешскими субтитрами, для этого бесплатно выдаются наушники. Кроме того стюардесса бесплатно приносит горячие напитки (чай, кофе, горячий шоколад), а для желающих есть туалет. Хотелось встряхнуть головой и протереть глаза, неужели и правда это все за 3 евро с человека. И ведь еще везут куда надо... поразительно. Через 1 час и 5 минут мы приехали в Прагу. Всего получается мы потратили на дорогу 2 часа и 11 евро.</p>

<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5822.jpg" title="" class="shutterset_singlepic70" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/70__160x120_dsc_5822.jpg" alt="dsc_5822" title="dsc_5822" />
</a>

<p>Прибыли мы на автобусный вокзал, где находится станция метро Černý Most. Я думаю несложно догадаться, что по-русски это будет «Черный мост». Вход в метро здесь немного похож на финский, никаких тебе турникетов, только стойки для компостирования билетов. Вот чего я вам не советую, так это приезжать в Прагу в воскресенье - кассы не работают, а автоматы принимают только монеты. Так что с вашими евро, или банкотами из банкомата, придется искать место, где продают билеты. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5824.jpg" title="" class="shutterset_singlepic72" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/72__160x120_dsc_5824.jpg" alt="dsc_5824" title="dsc_5824" />
</a>
Благо они бывюат в газетных киосках, да и вообще в магазинах рядом с метро. Билеты тут действуют определенное количество времени. Есть билет на 20 минут за 18 крон, но на нем далеко не уедешь. Чтобы доехать до центра от Černý Most — берите лучше билет за 26 крон, он будет действовать 75 минут с момента активации. Можно так же взять билеты на 1-3-5 дней (100-330-500 крон соответственно). 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_6652.jpg" title="" class="shutterset_singlepic75" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/75__160x120_dsc_6652.jpg" alt="dsc_6652" title="dsc_6652" />
</a>
При входе в любой транспорт неактивированный билет надо активировать, засунув его в специальный аппарат. Как раз такие и стоят на входе в метро. Будьте внимательны, компостируйте с правильной стороны! Когда мы уже ехали обратно, моя жена неправильно прокомпостировала билет. Заметили не сразу, но решили, что ничего страшного. Так вот у нас обошлось, но вообще штраф 1000 крон, независимо от того что вы иностранец и не понимаете их язык и как у них все устроено. Лучше не рискуйте, берите билет и езжайте спокойно, к тому же стоит он совсем не дорого. (На фото, как видите, один билет не прокомпостирован снизу).</p>
<p>
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5823.jpg" title="" class="shutterset_singlepic71" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/71__160x120_dsc_5823.jpg" alt="dsc_5823" title="dsc_5823" />
</a>

<p>Метро в Праге состоит из 3х линий: зеленая линия А, желтая B и красная C. Černý Most — это конечная станция желтой линии. Когда мы, уже на следующий день, возвращались мы проехали одну станцию по красной линии, а на зеленой так и не побывали. На красной линии нам попался поезд поновее, сидения там были мягче, а двери открывались как в автобусе, немного выезжая вперед. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5829.jpg" title="" class="shutterset_singlepic73" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/73__160x120_dsc_5829.jpg" alt="dsc_5829" title="dsc_5829" />
</a>
На желтой же, поезда хотя и не выглядели старыми, были чуть попроще. С виду такие же, как в Санкт-Петербурге, только переоборудованные внутри. Над дверьми располагается лампочка, которая загорается красным, когда дверь закрывается, естественно при этом еще и предупреждают по-чешски. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5830.jpg" title="" class="shutterset_singlepic74" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/74__160x120_dsc_5830.jpg" alt="dsc_5830" title="dsc_5830" />
</a>
Вестибюли метро довольно простые, похожи на некоторые из самых невзрачных петербургских станций. Эскалатор такой же как в Петербурге, только без ламп посреди баллюстрады.</p>
<p>
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5860.jpg" title="" class="shutterset_singlepic77" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/77__160x120_dsc_5860.jpg" alt="dsc_5860" title="dsc_5860" />
</a>
 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5867.jpg" title="" class="shutterset_singlepic79" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/79__160x120_dsc_5867.jpg" alt="dsc_5867" title="dsc_5867" />
</a>
На метро мы приехали на станцию Náměstí Republiky. Регистрироваться в отеле можно было с 2х часов дня, а было, я напомню, всего 11, поэтому мы пошли гулять. Нас сразу впечатлила Пороховая башня (Prašná brána) и мы захотели поднятся на нее. Внутри была довольно длинная винтовая лестница и подниматься порядком утомило. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5875.jpg" title="" class="shutterset_singlepic82" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/82__160x120_dsc_5875.jpg" alt="dsc_5875" title="dsc_5875" />
</a>
Сперва поднялись до первого внутреннего зала, где стояли доспехи рыцаря, разное оружие старых времени, старинные книги на чешском и все такое прочее. Вместо окон в башне почти везде были витражи. В этом же зале надо платить за вход, по-моему что-то около 100 крон (4 евро). Дальше опять подъем по винтовой лестнице и еще один зал, теперь со сценой средневековой битвы. И наконец, последнее усилие, и мы наверху. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5922_stitch.jpg" title="" class="shutterset_singlepic84" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/84__160x120_dsc_5922_stitch.jpg" alt="dsc_5922_stitch" title="dsc_5922_stitch" />
</a>
 Открывается красивый вид на Прагу. Проход там наверху очень узкий и фотографировать друг друга на фоне города трудно, к тому же окошки не очень большие. То есть это место скорее из разряда посмотреть, чем пофотографировать, но я думаю, что своих денег оно в любом случае стоит. Спускались мы сразу все три части лестницы и голова порядком закружилась.</p>
<p>
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5976.jpg" title="" class="shutterset_singlepic85" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/85__160x120_dsc_5976.jpg" alt="dsc_5976" title="dsc_5976" />
</a>
Дальше наш путь лежал по Целетной улице (Celetná ulice) до очень красивой Староместской площади (Staroměstské náměstí). На самой площади, конечно, было множество народу. На вертелах жарились большие куски свинины и заманчиво пахли. Стоит это удовольствие 85 крон (3 евро) за 100 граммов и мы решили лучше потерпеть потом до ресторана. Так же на площади происходило какое-то событие, была сцена и большой экран, передающий события на сцене. Выступал этнический коллектив с немецкими песнями. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5981_stitch.jpg" title="" class="shutterset_singlepic86" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/86__160x120_dsc_5981_stitch.jpg" alt="dsc_5981_stitch" title="dsc_5981_stitch" />
</a>
 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_5987.jpg" title="" class="shutterset_singlepic87" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/87__160x120_dsc_5987.jpg" alt="dsc_5987" title="dsc_5987" />
</a>
Спонсором, видимо, была марка машин Hyundai, потому что сцена и экран, и еще какие-то инсталляции были облеплены логотипами. Чуть-чуть послушали и пошли дальше. Мимо астрономических часов, рядом с которыми толпились люди. Оказалось, что времени было без десяти час, а в час что-то должно было произойти. И произошло. Фигурки рядом с часами задвигались: 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_6262.jpg" title="" class="shutterset_singlepic89" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/89__160x120_dsc_6262.jpg" alt="dsc_6262" title="dsc_6262" />
</a>
скелет дергал за веревочку и тем самым звонил в колокол, фигура турка (как мы услышали у экскурсовода неподалеку) трясла палкой, с другой стороны часов фигурка лицемерия смотрелась в зеркало, а «жадность» трясла мешком с деньгами. Потом золотой петух над часами прокукарекал, с верхнего этаже здания с часами высунулся трубач и протрубил мелодию. Такое вот небольшое представление. Мы пошли дальше по улице до Карлового моста (Karlův most) через Влтаву. На мосту тоже было много народу, идти приходилось почти проталкиваясь. На перилах были скульптуры, играла какая-то группа и продавала диски, художники предлагали картины, фотографии. На другой стороне моста мы поняли, что уже порядком устали и проголодались. 
<a href="http://www.charnad.com/blog/wp-content/gallery/czechia-06-2010/dsc_6025.jpg" title="" class="shutterset_singlepic88" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/88__160x120_dsc_6025.jpg" alt="dsc_6025" title="dsc_6025" />
</a>
В мои планы входило прогуляться дальше, я не расчитывал что мы так сильно захотим есть в это время, и не искал ресторанов в том районе. Поэтому решили идти в McDonald's, это было проще всего. Когда покушали, время уже перевалило за 2 часа, поэтому мы отправились в отель.</p>
<p>Продолжение следует...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/poezdka-v-czechiu-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/poezdka-v-czechiu-part-1/</feedburner:origLink></item>
		<item>
		<title>Symfony: выборочная I18n для объектов Doctrine [Перевод]</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/6JPKxc5zvhs/</link>
		<comments>http://www.charnad.com/blog/symfony-vyborochnaya-i18n-dlya-obektov-doctrine/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 00:44:59 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[I18n]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[перевод]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1085</guid>
		<description><![CDATA[Мне потребовалось сделать мультиязычный сайт аж на 5 языках. В целом тут нет ничего сложного, кроме того, что пользователю надо будет заполнять 5 форм на разных языках. Логичный вывод - сделать обязательным только один язык, например английский. Остальные заполняются по желанию, а для незаполненных показывается на том же английском. Промучившись некоторое время с рецептами от [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" />Мне потребовалось сделать мультиязычный сайт аж на 5 языках. В целом тут нет ничего сложного, кроме того, что пользователю надо будет заполнять 5 форм на разных языках. Логичный вывод - сделать обязательным только один язык, например английский. Остальные заполняются по желанию, а для незаполненных показывается на том же английском. Промучившись некоторое время с рецептами от Календаря Адвента, и не добившись успеха, я нашел пост [<a href="http://www.miximum.fr/tutos/449-optional-translation-form-for-i18n-objects-with-symfony-and-doctrine#comment-14308">Optional translation form for I18n objects with Symfony and Doctrine</a>], который мне помог. Я считаю, что полезным будет сделать его перевод. Так же я добавлю некоторые свои комментарии. (Перевод вольный, эстеты идут лесом)<span id="more-1085"></span></p>
<p>Некоторые люди утверждают, что Symfony - это подарок богов. Другие считают, что это преувеличение. Но как ни крути, в версиях 1.3/1.4 добавилось много нового и полезного, что может сэкономить вам вермя.<br />
Представим проект, где есть разные заметки (новости, интервью, и т.д.). И они могут быть на разных языках. И это довольно просто сделать с actAs: I18n. Но есть небольшая сложность: переводы должны быть опциональны, чтобы можно было написать статью только на французском, английском или немецком.
</p>
<p>Некоторые материалы по теме: <a href="http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine">раз</a>, <a href="http://symfonyguide.wordpress.com/2009/09/28/symfony-forms-saving-process/">два</a>, <a href="http://vousavezchoisi.com/img/formsdiagram.png">три</a>, <a href="http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms#chapter_06_ignoring_embedded_forms">четыре</a>, <a href="http://www.ze-technology.com/2009/06/05/tests-fonctionnels-avec-symfony-gerer-lidentification/">пять</a>.</p>
<h3>Итак, начнем со схемы.</h3>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">Article:
  actAs:
    Timestampable: ~
    I18n:
      fields: [ title, body ]
      actAs:
        Sluggable: { fields: [ title ], uniqueBy: [ lang, title ] }
&nbsp;
  columns:
    title: { type: string(255), notnull: true }
    body: { type: clob, notnull: true }
    author: { type: string(255), notnull: false }
&nbsp;
News:
  inheritance:
    extends: Article
    type: concrete</pre></div></div>

<p>А так же фикстуры:</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">News:
  n1:
    author: 'Lenta.ru'
    Translation:
      ru:
        title: 'Нет вестей с Титана'
        body: |
          Титан – это шестой и самый крупный спутник Сатурна.
&nbsp;
  n2:
    author: 'Bash.org'
    Translation:
      en:
        title: '#921792'
        body: |
          &lt;Thomas&gt; if women think they arent meant to cook
          &lt;Thomas&gt; why do they have milk and eggs inside them?</pre></div></div>

<p>Загружаем все это добро в базу данных:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php symfony doctrine:build <span style="color: #660033;">--all</span> <span style="color: #660033;">--and-load</span>
php symfony generate:app backend
php symfony doctrine:generate-admin backend News</pre></div></div>

<p>Загляните в только что построенный модуль админки. Нажмите кнопку "редактировать" и оп.. а где все наши переводы? Если вы еще не в курсе, actAs:I18n разделяет таблицу на 2 части, в первой содержатся общие поля, не зависящие от перевода, а во второй те, которые требуют перевода.</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">mysql&gt; SELECT * FROM news;
+----+-------------+---------------------+---------------------+
| id | author      | created_at          | updated_at          |
+----+-------------+---------------------+---------------------+
|  1 | Lenta.ru    | 2010-01-29 12:14:46 | 2010-01-29 12:14:46 | 
|  2 | Bash.org    | 2010-01-29 12:14:46 | 2010-01-29 12:14:46 | 
+----+-------------+---------------------+---------------------+
&nbsp;
mysql&gt; SELECT id, lang, title FROM news_translation;
+----+------+-----------------------------------------------------+
| id | lang | title                                               |
+----+------+-----------------------------------------------------+
|  1 | ru   | Титан – это шестой и самый крупный спутник Сатурна. | 
|  2 | en   | &lt;Thomas&gt; if women think they arent meant to cook ...| 
+----+------+-----------------------------------------------------+</pre></div></div>

<p>Чтобы нам было доступно редактирование переводов - надо воспользоваться функцией embedI18n.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/NewsForm.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> NewsForm <span style="color: #000000; font-weight: bold;">extends</span> BaseNewsForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * @see ArticleForm
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedI18n</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ru'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Вуа ля. Редактировать можно!
</p>
<h3>Немного приберемся</h3>
<p>Наш код сейчас не так хорош, как мог бы быть:<br />
Каждый раз, когда мы будем добавлять новый тип статьи - нам надо будет менять метод configure;<br />
Каждый раз, когда мы будем добавлять/удалять новый язык для статей - нам надо будет менять все формы.</p>
<p>К счастью, с Symfony 1.3, наследование форм повторяет наследование моделей. Смотрите, NewsForm наследует BaseNewsForm, которая в свою очередь наследует ArticleForm.</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;"># config/app.yml
all:
  cultures:
    enabled:
      ru: Russian
      en: English</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/NewsForm.class.php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Revert the changes we added there</span>
<span style="color: #000000; font-weight: bold;">class</span> NewsForm <span style="color: #000000; font-weight: bold;">extends</span> BaseNewsForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * @see ArticleForm
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// lib/form/doctrine/ArticleForm.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> ArticleForm <span style="color: #000000; font-weight: bold;">extends</span> BaseArticleForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * Available languages
   *
   * @var array $languages
   **/</span>
  protected <span style="color: #000088;">$langages</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #339933;">=</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_cultures_enabled'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$langs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedI18n</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$langs</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabel</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Перезагрузите теперь страницу. Вы можете теперь добавлять/удалять языки независимо от количества типов статей.</p>
<h3>Редактируем переводы</h3>
<p>
Давайте теперь попробуем нашу форму для статей. Когда вы попробуете редактировать какую-нибудь новость, то... постыдная неудача. Нельзя сохранить, потому что нет английского или русского перевода. Давайте добавим условие, что если в форме есть пустые поля - мы эти формы не сохраняем.<br />
Для этого мы перекроем метод doBind.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/ArticleForm.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> ArticleForm <span style="color: #000000; font-weight: bold;">extends</span> BaseArticleForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * Available languages
   *
   * @var array $languages
   **/</span>
  protected <span style="color: #000088;">$langages</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #339933;">=</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_cultures_enabled'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$langs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedI18n</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$langs</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabel</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Cleans and binds values to the current form
   *
   * Ignore i18n forms when all their fields are empty
   *
   * @see sfForm::doBind
   **/</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> doBind<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embeddedI18nFormIsEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span>
          <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
          <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doBind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Check if every fields, except for id and lang, are empty
   **/</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> embeddedI18nFormIsEmpty<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'lang'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span> <span style="color: #339933;">!==</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В перекрытом методе doBind, мы проверяем каждую I18n форму, и, если надо делаем ей unset. Теперь все сохраняется как надо, однако же...</p>
<p>Загляните в базу данных, вас там ждет сюрприз.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> id<span style="color: #66cc66;">,</span> lang<span style="color: #66cc66;">,</span> slug <span style="color: #993333; font-weight: bold;">FROM</span> news_translation;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+------------------------------------------------------+</span>
<span style="color: #66cc66;">|</span> id <span style="color: #66cc66;">|</span> lang <span style="color: #66cc66;">|</span> slug                                                 <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+------------------------------------------------------+</span>
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> en   <span style="color: #66cc66;">|</span>                                                      <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> ru   <span style="color: #66cc66;">|</span> Титан – это шестой и самый крупный спутник Сатурна<span style="color: #66cc66;">.</span>  <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">|</span> en   <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">&lt;</span>Thomas<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">IF</span> women think they arent meant <span style="color: #993333; font-weight: bold;">TO</span> cook <span style="color: #66cc66;">...</span> <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+------------------------------------------------------+</span></pre></div></div>

<p>Где-то в процессе сохранения, Symfony создала пустой объект перевода. И вот решение для этой проблемы.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/ArticleForm.class.php</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Add this at the beginnig of the class:</span>
  <span style="color: #009933; font-style: italic;">/**
   * I18n ignored forms
   **/</span>
  protected <span style="color: #000088;">$I18nFormsIgnored</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// update the doBind method:</span>
  <span style="color: #009933; font-style: italic;">/**
   * Unset i18n forms values when every field is empty
   **/</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> doBind<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embeddedI18nFormEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">I18nFormsIgnored</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span>
          <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
          <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doBind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// And override the doUpdateObject method:</span>
  <span style="color: #009933; font-style: italic;">/**
   * Updates the values of the object with the cleaned up values.
   *
   * @param  array $values An array of values
   *
   * @see sfFormDoctrine::doUpdateObject()
   */</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> doUpdateObject<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doUpdateObject</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">I18nFormsIgnored</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Translation</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>На этот раз все сохраняется как надо!
</p>
<p>(Здесь я пропускаю абзац про убирание поля Slug. Там есть сложность с тем, что формы перевода не наследуются. Если вам интересно - посмотрите в оригинальной статье. Я считаю, что основное здесь - как раз перекрытие методов doBind и doUpdateObject.<br />
Тесты, приведенные автором можно посмотреть у него в статье, а можно <a href="http://pastie.org/995806">тут</a> и <a href="http://pastie.org/995807">тут</a>).</p>
<p>На этом все. Надеюсь вам пригодится мой перевод.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-vyborochnaya-i18n-dlya-obektov-doctrine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/symfony-vyborochnaya-i18n-dlya-obektov-doctrine/</feedburner:origLink></item>
		<item>
		<title>Железные дороги Deutsche Bahn</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/BaHXBwQILiU/</link>
		<comments>http://www.charnad.com/blog/zheleznye-dorogi-deutsche-bahn/#comments</comments>
		<pubDate>Thu, 27 May 2010 05:04:04 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Германия]]></category>
		<category><![CDATA[db]]></category>
		<category><![CDATA[германия]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1079</guid>
		<description><![CDATA[Когда речь идет о Германии, очень часто всплывает восхищение немецкими железными дорогами, мол быстро, комфортно. На картинках красивые поезда, довольные немецкие лица. И знаете что я скажу.. чистая правда! РЖД против DB, это как запорожец против мерседеса. В Германии много категорий поездов, я опишу несколько их них. Те, что вы чаще всего видете на картинках [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/deutschland/db_logo.png" alt="" style="float: left; padding-right: 5px;"/>
<p>Когда речь идет о Германии, очень часто всплывает восхищение немецкими железными дорогами, мол быстро, комфортно. На картинках красивые поезда, довольные немецкие лица. И знаете что я скажу.. чистая правда! РЖД против DB, это как запорожец против мерседеса.</p>
<p><span id="more-1079"></span></p>
<p>
<a href="http://www.charnad.com/blog/wp-content/gallery/2010-stuff/0_145d7_dde689d_xl.jpg" title="" class="shutterset_singlepic66" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/66__160x120_0_145d7_dde689d_xl.jpg" alt="0_145d7_dde689d_xl" title="0_145d7_dde689d_xl" />
</a>
В Германии много категорий поездов, я опишу несколько их них. Те, что вы чаще всего видете на картинках - это поезда класса ICE, такие же, но чуть попроще IC: InterCity Express и просто InterCity. Оранжевые поезда, в которых можно ехать с велосипедом, называются RE - Regional Express. Они медленнее, чем IC/ICE, но и, конечно, подешевле. Мне не очень нравится ездить на RE, там не самые удобные места, а половина всех сидячих - откидные. Ну и наконец мой любимый тип поездов - RB, что означает Regional Bahn. 
<a href="http://www.charnad.com/blog/wp-content/gallery/2010-stuff/dsc_4893.jpg" title="" class="shutterset_singlepic67" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/67__160x120_dsc_4893.jpg" alt="dsc_4893" title="dsc_4893" />
</a>
Как видно на картинке, снятой, кстати говоря, из окна RB поезда - это всего пара вагонов. То есть это что-то вроде пригородных электричек. Внутри очень удобно, в целом похоже на автобус. Посередине много площади для багажа и велосипедов, а чуть поднявишь по ступенькам - сидячие места.</p>
<p>Самое шокирующее после поездов России - тут в каждом(!) поезде нормальный, рабочий туалет. В RB я видел предлагаются одноразовые бумажные сидения(!), можно руки помыть с мылом(!) и вытереть бумажными полотенцами(!). Я уж молчу о том, что там есть туалетная бумага (и даже запасная). Помимо туалетов, в RB поездах часто лежат газеты, которые, видимо, можно читать. В RB и RE так же часто есть автоматы по продаже всяких шоколадок/чипсов/лимонада, что бывает полезно в дороге, если забыл взять с собой. То есть прямо едешь и чувствуешь себя человеком.</p>
<p>Да, конечно, этот праздник на колесах кто-то оплачивает. И совсем не кто-то, а уважаемые пассажиры. Поезд ICE Берлин - Мюнхен стоит порядка 130 евро, если ехать 2м классом, это сравнимо с билетом на самолет. В целом чтобы съездить куда-нибудь стоит готовить не менее 40 евро на человека в один конец. Однако здесь не все так страшно. Существуют различные скидки. Например наш любиый Schönes Wochenende Ticket, который позволяет за 37 евро собратья компанией 1-5 человек и ездить куда угодно на RB и RE поездах в течении дня. Так же есть похожий билет по Саксонии - Sachsen Ticket, все то же самое, только 28 евро и в пределах Саксонии. Как раз с помощью таких билетов мы с женой ездили в Берлин и Лейпциг.</p>
<p>Билет на поезд лучше всего брать самому в автомате (там есть английский язык). Сначала там нужно выбрать маршрут и время, после чего вам распечатают Reiseplan - план вашей поездки с указанием на каких поездах, с каких платформ и во сколько вам ехать. Потом можно оплатить в том же автомате наличкой или карточкой. Если вы боитесь нажать не туда - можно купить и в кассе, но тогда с вас возьмут еще на 1-2 евро больше, как плата за услугу оформления.</p>
<p>Немецкие поезда обычно пунктуальны. Но не всегда. Несколько раз я ездил с опозданием в несколько минут. Однажды, когда я ехал один из Берлина домой через Коттбус, поезд сломался. Буквально через 5 минут нас всех пересадили в другой, который подвез нас 1 станцию, где уже ждал запасной поезд до Коттбуса. В итоге мы опоздали на 20 минут, но поезд, на Циттау, в который я должен был сесть дальше, всех подождал и никто не обиделся.</p>
<p>Так что, товарищи, <strike>летайте линиями</strike> ездийте дорогами Германии <img src='http://www.charnad.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/zheleznye-dorogi-deutsche-bahn/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/zheleznye-dorogi-deutsche-bahn/</feedburner:origLink></item>
		<item>
		<title>Python: играем с PyGame. Начало.</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/MlTGAaKBf3A/</link>
		<comments>http://www.charnad.com/blog/python-igraem-s-pygame-nachalo/#comments</comments>
		<pubDate>Tue, 27 Apr 2010 15:51:03 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[pygame]]></category>
		<category><![CDATA[игры]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1062</guid>
		<description><![CDATA[В этом блоге почти все время я писал о PHP и немного о JS. Настало время разнообразить, и разнообразить свой блог я решил Питоном. О том, где взять Python и где поучиться я не буду, материалов полно, и большинство друг друга повторяют, в еще одном от меня смысла я не вижу. Чуть меньше примеров и [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/python_logo.png" alt="" style="float: left; padding-right: 5px;"/>
<p>В этом блоге почти все время я писал о PHP и немного о JS. Настало время разнообразить, и разнообразить свой блог я решил Питоном. О том, где <a href="http://python.org/">взять Python</a> и где <a href="http://diveintopython.org/">поучиться</a> я не буду, материалов полно, и большинство друг друга повторяют, в еще одном от меня смысла я не вижу. Чуть меньше примеров и статей про <a href="http://www.pygame.org">PyGame</a> - свободную графическую библиотеку, базирующуюся на SDL.</p>
<p><span id="more-1062"></span></p>
<p>Проблем с установкой, я надеюсь у вас не возникнет - либо запускате Windows инсталлер, а если вы в Linux - наверняка сами знаете. Не будем тянуть кота за хвост, откроем IDE, создадим проект и уже создадим хотя бы окошко.<br />
<strong>main.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pygame
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Game<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;">#Initial window settings</span>
        pygame.<span style="color: black;">init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        pygame.<span style="color: black;">display</span>.<span style="color: black;">set_mode</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">640</span>, <span style="color: #ff4500;">480</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        pygame.<span style="color: black;">display</span>.<span style="color: black;">set_caption</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'I<span style="color: #000099; font-weight: bold;">\'</span>m super cool Python programmer'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">#Run, Forrest, run</span>
    <span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">track_input</span><span style="color: black;">&#40;</span>pygame.<span style="color: black;">event</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> track_input<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, events<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> event <span style="color: #ff7700;font-weight:bold;">in</span> events:
            <span style="color: #808080; font-style: italic;">#Exit</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> event.<span style="color: #008000;">type</span> == pygame.<span style="color: black;">QUIT</span>:
                exit<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">#Here we go</span>
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    Game<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Сохраняете, запускаете, смотрите. Опа, окошечко. И даже закрывается по крестику. Теперь обьясню как это произошло. Сначала нам нужно импортировать pygame, иначе ничего не получится. Запуск скрипта начинается с последних строчек, которые создают экземпляр класса Game. Такая конструкция с переменной __name__ требуется для того, чтобы при импорте этой программы она не запускалась, а срабатывала только если файл запущен непосредственно. Функция __init__  в классе Game является чем-то вроде конструктора (но не конструктором!). Она вызывает метод pygame.init(), который инициализирует библиотеку, дальше вызываем метод pygame.display.set_mode((640, 480)), который и создает собственно окно размером 640х480. Обратите внимание, мы передаем кортеж, а не просто 2 числа. Дальше даем окну заголовок. На этом можно было бы и остановиться, программа уже будет работать. Но окно выскочит и закроется, потому что программа завершится. Чтобы этого не произошло запускаем функцию run(), которая представляет из себя бесконечный цикл вызовов функции track_input, которая принимает параметром события. И если произошло событие "Выход" (то самое нажатие по крестику), то закрываем. Все можно было бы уместить в одну функцию, но это задел на будущее.</p>
<p>Что же нам хочется дальше? Конечно же, чтобы что-то двигалось по стрелочкам. Почти в любой игре что-нибудь надо двигать, и у нас не будет исключение. Что же нужно? Нужно все так же следить за событиями, только теперь обрабатывать нажатия на кнопки стрелок. Чтобы удобнее было использовать направления (вверх, вправо, вниз, влево) обозначим их цифрами 0, 1, 2, 3. А чтобы не запутаться, введем переменные UP, RIGHT, DOWN, LEFT, которым и дадим эти значения. А переменные положим в отдельный файл directions.py и наступит ваще красота.<br />
<strong>directions.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    exit<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
&nbsp;
UP    = <span style="color: #ff4500;">0</span>
RIGHT = <span style="color: #ff4500;">1</span>
DOWN  = <span style="color: #ff4500;">2</span>
LEFT  = <span style="color: #ff4500;">3</span>
DIRECTIONS = <span style="color: black;">&#91;</span>UP, RIGHT, DOWN, LEFT<span style="color: black;">&#93;</span>
VERTICAL = <span style="color: black;">&#91;</span>UP, DOWN<span style="color: black;">&#93;</span>
HORIZONTAL = <span style="color: black;">&#91;</span>LEFT, RIGHT<span style="color: black;">&#93;</span></pre></div></div>

<p>Обьявили наши переменные и три списка, которые нам пригодятся в будущем. Вернемся в main.py. Добавим к списку импортов directions.py:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> directions</pre></div></div>

<p>В класс Game добавим словарь и 3 переменные:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">x = <span style="color: #ff4500;">100</span>
y = <span style="color: #ff4500;">100</span>
speed = <span style="color: #ff4500;">3</span>
&nbsp;
keymap = <span style="color: black;">&#123;</span>
    pygame.<span style="color: black;">K_LEFT</span>  : directions.<span style="color: black;">LEFT</span>,
    pygame.<span style="color: black;">K_UP</span>    : directions.<span style="color: black;">UP</span>,
    pygame.<span style="color: black;">K_RIGHT</span> : directions.<span style="color: black;">RIGHT</span>,
    pygame.<span style="color: black;">K_DOWN</span>  : directions.<span style="color: black;">DOWN</span>
<span style="color: black;">&#125;</span></pre></div></div>

<p>Три переменные будут отвечать за положение и скорость перемещения объекта. А словарь ставит в соответствие клавиши и направления. Я надеюсь, что очевидно, что когда мы будем нажимать на какую-то кнопку, благодаря этому словарю мы узнаем в каком направлении надо двигать наш игровой объект, из положения x,y на speed пикселей. Далее в track_input добавляем в цикл:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">if</span> event.<span style="color: #008000;">type</span> == pygame.<span style="color: black;">KEYDOWN</span> <span style="color: #ff7700;font-weight:bold;">and</span> event.<span style="color: black;">key</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">keymap</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">keymap</span><span style="color: black;">&#91;</span>event.<span style="color: black;">key</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">in</span> directions.<span style="color: black;">DIRECTIONS</span>:
    <span style="color: #008000;">self</span>.<span style="color: black;">move</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">keymap</span><span style="color: black;">&#91;</span>event.<span style="color: black;">key</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Здесь мы проверяем, что нажата кнопка (нажатия мышки и т.п. нас сейчас не интересуют) и что кнопка указана среди keymap, и то, что по выбранной кнопке в keymap стоит нормальное направление. И если все в порядке - вызываем функцию move с параметром "направление" из словаря.<br />
В Python, насколько я знаю, нету операции switch/case, поэтому здесь мы будем делать финт ушами. Вот функция move, которую мы кладем все в тот же класс Game:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> move<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, direction<span style="color: black;">&#41;</span>:
    movement = <span style="color: black;">&#123;</span>
        directions.<span style="color: black;">UP</span>       : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>,            <span style="color: #008000;">self</span>.<span style="color: black;">y</span>-<span style="color: #008000;">self</span>.<span style="color: black;">speed</span><span style="color: black;">&#93;</span>,
        directions.<span style="color: black;">RIGHT</span>  : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>+<span style="color: #008000;">self</span>.<span style="color: black;">speed</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span><span style="color: black;">&#93;</span>,
        directions.<span style="color: black;">DOWN</span>  : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>,            <span style="color: #008000;">self</span>.<span style="color: black;">y</span>+<span style="color: #008000;">self</span>.<span style="color: black;">speed</span><span style="color: black;">&#93;</span>,
        directions.<span style="color: black;">LEFT</span>    : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>-<span style="color: #008000;">self</span>.<span style="color: black;">speed</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span><span style="color: black;">&#93;</span>
    <span style="color: black;">&#125;</span>
    <span style="color: #008000;">self</span>.<span style="color: black;">x</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span> = movement<span style="color: black;">&#91;</span>direction<span style="color: black;">&#93;</span></pre></div></div>

<p>Здесь у нас словарь с направлениями, по которым лежат списки с изменением параметров x и y, и когда вызывается нужное направление с помощью множественного присваивания мы изменяем сразу x и y.<br />
Ну и наконец, в run() добавляем код, который будет рисовать нам маленький беленький квадратик, который и будет двигаться от наших нажатых кнопок.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">pygame.<span style="color: black;">display</span>.<span style="color: black;">get_surface</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">fill</span><span style="color: black;">&#40;</span>pygame.<span style="color: black;">Color</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
block = pygame.<span style="color: black;">Surface</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
block.<span style="color: black;">fill</span><span style="color: black;">&#40;</span>pygame.<span style="color: black;">Color</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
pygame.<span style="color: black;">display</span>.<span style="color: black;">get_surface</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">blit</span><span style="color: black;">&#40;</span>block, <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
pygame.<span style="color: black;">display</span>.<span style="color: black;">flip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Давайте теперь посмотрим что у нас получилось.</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#! /usr/bin/python</span>
<span style="color: #808080; font-style: italic;"># -*- coding: utf-8 -*-</span>
<span style="color: #ff7700;font-weight:bold;">import</span> pygame
<span style="color: #ff7700;font-weight:bold;">import</span> directions
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> Game<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
&nbsp;
    x = <span style="color: #ff4500;">100</span>
    y = <span style="color: #ff4500;">100</span>
    speed = <span style="color: #ff4500;">3</span>
&nbsp;
    keymap = <span style="color: black;">&#123;</span>
        pygame.<span style="color: black;">K_LEFT</span>  : directions.<span style="color: black;">LEFT</span>,
        pygame.<span style="color: black;">K_UP</span>    : directions.<span style="color: black;">UP</span>,
        pygame.<span style="color: black;">K_RIGHT</span> : directions.<span style="color: black;">RIGHT</span>,
        pygame.<span style="color: black;">K_DOWN</span>  : directions.<span style="color: black;">DOWN</span>
    <span style="color: black;">&#125;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #808080; font-style: italic;">#Initial window settings</span>
        pygame.<span style="color: black;">init</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
        pygame.<span style="color: black;">display</span>.<span style="color: black;">set_mode</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">640</span>, <span style="color: #ff4500;">480</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
        pygame.<span style="color: black;">display</span>.<span style="color: black;">set_caption</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'I<span style="color: #000099; font-weight: bold;">\'</span>m super cool Python programmer'</span><span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">run</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #008000;">True</span>:
            <span style="color: #008000;">self</span>.<span style="color: black;">track_input</span><span style="color: black;">&#40;</span>pygame.<span style="color: black;">event</span>.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            pygame.<span style="color: black;">display</span>.<span style="color: black;">get_surface</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">fill</span><span style="color: black;">&#40;</span>pygame.<span style="color: black;">Color</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            block = pygame.<span style="color: black;">Surface</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">10</span>, <span style="color: #ff4500;">10</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            block.<span style="color: black;">fill</span><span style="color: black;">&#40;</span>pygame.<span style="color: black;">Color</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">255</span>, <span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>
            pygame.<span style="color: black;">display</span>.<span style="color: black;">get_surface</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">blit</span><span style="color: black;">&#40;</span>block, <span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span>
            pygame.<span style="color: black;">display</span>.<span style="color: black;">flip</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> track_input<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, events<span style="color: black;">&#41;</span>:
        <span style="color: #ff7700;font-weight:bold;">for</span> event <span style="color: #ff7700;font-weight:bold;">in</span> events:
            <span style="color: #808080; font-style: italic;">#Exit</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> event.<span style="color: #008000;">type</span> == pygame.<span style="color: black;">QUIT</span>:
                exit<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>
            <span style="color: #ff7700;font-weight:bold;">if</span> event.<span style="color: #008000;">type</span> == pygame.<span style="color: black;">KEYDOWN</span> <span style="color: #ff7700;font-weight:bold;">and</span> event.<span style="color: black;">key</span> <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">keymap</span>.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #008000;">self</span>.<span style="color: black;">keymap</span><span style="color: black;">&#91;</span>event.<span style="color: black;">key</span><span style="color: black;">&#93;</span> <span style="color: #ff7700;font-weight:bold;">in</span> directions.<span style="color: black;">DIRECTIONS</span>:
                <span style="color: #008000;">self</span>.<span style="color: black;">move</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">keymap</span><span style="color: black;">&#91;</span>event.<span style="color: black;">key</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> move<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, direction<span style="color: black;">&#41;</span>:
        movement = <span style="color: black;">&#123;</span>
            directions.<span style="color: black;">UP</span> : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>,            <span style="color: #008000;">self</span>.<span style="color: black;">y</span>-<span style="color: #008000;">self</span>.<span style="color: black;">speed</span><span style="color: black;">&#93;</span>,
            directions.<span style="color: black;">RIGHT</span> : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>+<span style="color: #008000;">self</span>.<span style="color: black;">speed</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span><span style="color: black;">&#93;</span>,
            directions.<span style="color: black;">DOWN</span> : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>,            <span style="color: #008000;">self</span>.<span style="color: black;">y</span>+<span style="color: #008000;">self</span>.<span style="color: black;">speed</span><span style="color: black;">&#93;</span>,
            directions.<span style="color: black;">LEFT</span> : <span style="color: black;">&#91;</span><span style="color: #008000;">self</span>.<span style="color: black;">x</span>-<span style="color: #008000;">self</span>.<span style="color: black;">speed</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span><span style="color: black;">&#93;</span>
        <span style="color: black;">&#125;</span>
        <span style="color: #008000;">self</span>.<span style="color: black;">x</span>, <span style="color: #008000;">self</span>.<span style="color: black;">y</span> = movement<span style="color: black;">&#91;</span>direction<span style="color: black;">&#93;</span>
&nbsp;
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">&quot;__main__&quot;</span>:
    Game<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>Запускаем, и... видим маленький беленький квадратик, который двигается когда мы тыкаем стрелочки. Хотелось бы плавные движения пока нажата клавиша, правда? Но об этом в другой раз.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/python-igraem-s-pygame-nachalo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/python-igraem-s-pygame-nachalo/</feedburner:origLink></item>
		<item>
		<title>Шпрехен зи дойч?</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/eG0cwQ8VKTQ/</link>
		<comments>http://www.charnad.com/blog/sprechen-sie-deutsch/#comments</comments>
		<pubDate>Fri, 02 Apr 2010 13:14:52 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Германия]]></category>
		<category><![CDATA[германия]]></category>
		<category><![CDATA[немецкий язык]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1051</guid>
		<description><![CDATA[Немецкий язык не так уж и прост. По мне так сложнее английского раза в два. В английском основная сложность - времена, остальные приколы типа непрямой речи и past perfect не так важны для общения. В немецком же есть окончания (вот вы по-русски говорите и не задумываетесь об окончаниях. А это на самом деле большая сложность [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/deutschland/de-flag.gif" alt="" style="float: left; padding-right: 5px;"/>
<p>Немецкий язык не так уж и прост. По мне так сложнее английского раза в два. В английском основная сложность - времена, остальные приколы типа непрямой речи и past perfect не так важны для общения. В немецком же есть окончания (вот вы по-русски говорите и не задумываетесь об окончаниях. А это на самом деле большая сложность для остальных), в немецком языке есть падежи, от которых зависит как будет выглядеть артикль, в немецком языке есть разделение по рода (мужской/женский/средний). Оо, это разделение сущая головная боль. Угол (Die Ecke) - женский род, лето (Der Sommer) - мужской род, девочка (Das Mädchen) - средний род. У них все не так как в русском и голова от этого идет кругом.</p>
<p><span id="more-1051"></span></p>
<p>С произношением больших проблем нет, надо только запомнить, что обычно "ch" - "хь", "sch" - "ш", "eu" - "ой", "äu" - "ой", "ei" - "ай", "ie" - "и". Так что уважаемый Тилль поет на самом деле "Ду хаст михь гефрагт", но в связи с его этническим происхождением у него получается "Ду хаст мишь гефрат" (значит это "ты меня спросил(а)). Много веселья у меня вызывает буква V. Это совсем не русская "В" (русская "В" - это W), это "фау". TV - "те фау", DVD - "де фау де". Быстро привыкаешь к букве "S", которая в начале слова в сочетании с буквами t и p звучит как "ш" (st - "шт", sp - "шп"), а в других случаях "з" или "с". Есть еще экзотическая буква ß, что примерно означает двойную "s". Буквы с умляутами легко понять, "üöä" - "юёэ". Объединив все это получаем слова типа: Straße (штрассе) - улица, Verkäufer (феркойфер) - продавец. Это то, что касается произношения.</p>
<p>Немцы любят длинные слова. Artillerieunteroffizierswitwensterbekasse - "похоронный фонд для вдов артиллерийских унтер-офицеров", Siebenhundertsiebenundsiebzigtausendsiebenhundertsiebenundsiebzigster - 777777-й (взял в интернете, самому лень искать примеры). Причем в повседневной жизни все более-менее прилично, то в официальных текстах - туши свет. Половина слов длиннее 12-13 букв.</p>
<p>Русский язык позаимствовал в немецком немало слов. Крах - Krach (треск, грохот), шлагбаум - Schlagbaum (Schlagen - бить, Baum - дерево), бутерброд - Butterbrot (масло, хлеб), плац - Platz (площадь, место) и даже стул - Stuhl. Возможно вы слышали про рунглиш, язык на котором говорят на Брайтоне - помесь русского и английского (хотя кого я обманываю, сами хороши.. роутер не коннектится - аттачи не зааплоадить, продебажить надо). В Германии такого в большом количестве не наблюдается, хотя и есть. Здесь ходят в гешефт(магазин), путцают(чистят) то, что запачкалось, шпрехают(говорят) на немецком, и анмельдуются(регистрируются) по месту жительства.</p>
<p>Известное всем в России Scheisse (дерьмо) употребляют тут даже по телевизору. А матерных слов в немецком языке и вовсе нет. Есть некоторые термины, но как я понял в качестве ругательных они не используются.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/sprechen-sie-deutsch/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/sprechen-sie-deutsch/</feedburner:origLink></item>
		<item>
		<title>О супермаркетах</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/pturZzo32qo/</link>
		<comments>http://www.charnad.com/blog/o-supermarketax/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 12:24:43 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Германия]]></category>
		<category><![CDATA[Lidl]]></category>
		<category><![CDATA[супермаркет]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1028</guid>
		<description><![CDATA[Сегодня я расскажу вам немного о супермаркетах. В нашем городе их достаточно много: Lidl, Toom, Aldi, Netto, Kaufland, и думаю, что это еще не все. Причем Lidl, Aldi и Netto похожи больше на магазины Пятерочка, небольшие, без изысков, но есть все необходимое. Kaufland-же (и Toom) больше похож на Ленту, О'Кей и т.п., то есть очень [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/deutschland/lidl.png" alt="" style="float: left; padding-right: 5px;"/>Сегодня я расскажу вам немного о супермаркетах. В нашем городе их достаточно много: <a href="http://www.lidl.de/">Lidl</a>, <a href="http://toom.de/">Toom</a>, <a href="http://www.aldi-sued.de/">Aldi</a>, Netto, Kaufland, и думаю, что это еще не все. Причем Lidl, Aldi и Netto похожи больше на магазины Пятерочка, небольшие, без изысков, но есть все необходимое. Kaufland-же (и Toom) больше похож на Ленту, О'Кей и т.п., то есть очень большой.<span id="more-1028"></span></p>
<p>По поводу ассортимента: выглядит все как и в России, полки, полки, полки, товары, товары, товары. Цены, тут, кстати пишутся над товаром, а не под ним, что поначалу немного путало. Здесь продается много различного мяса, хлеба и булочек всяких масса, пива большой выбор, приправ очень много. Из непищевых много всего. Удивительно, но мало рыбы. Вероятно регион такой, не рыбный, но кроме селедки, лосося, шпротов и сардин в разных заливках ничего почти и нету. Сыр тоже не блещет разнообразием: гауда, маасдамер, еще парочка видов и все. Мало риса, гречки не видел вообще. Не видел сметаны, вместо нее берем "легкий йогурт", который похож на нее на 95%. Овощей и фруктов выбор не такой и большой, разве что в Toom можно купить что-нибудь экзотическое. Много на выбор напитков, но мало видов. То есть много яблочных и апельсиновых соков и нектаров, а томатного 1-2 вида и то только в Kaufland и за дорого.
<a href="http://www.charnad.com/blog/wp-content/gallery/2010-stuff/toom-flags.jpg" title="" class="shutterset_singlepic65" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/65__160x120_toom-flags.jpg" alt="toom-flags" title="toom-flags" />
</a>
</p>
<p>Цены, конечно, отличаются от российских. 10 килограммов картошки, например, мы купили за 2,5 евро, 5 килограммов яблок за 3,3 евро. Это дешево. Огурцы зато 0,5 евро за.. штуку. Помидоры 2,5-3 евро за кило, что тоже дороговато. Яйца стоят дороже, самые дешевые - 1,29 евро за десяток. В Питере мы покупали 30 штук за ~2,5 евро. В остальном плюс-минус. Что-то дороже, что-то дешевле. Достаточно распространеные различные скидки, в Kaufland-е есть целый стенд "все за евро". Конечно, по большей части там продается барахло, но иногда попадается и что-то полезное. Жена присмотрела себе косметичку, а я набор отверток. Напитки дешевые: шорле (сок + минералка) стоит, как я уже упоминал от 0,3 евро. Обычно мы берем яблочный нектар за 0,59 1,5 литра или за ту же цену 2 литра холодного чая.</p>
<p>Особенностью здешних магазинов является различные марки продуктов. Лучше всего это видно на аптечных товарах. Да, здесь в супермаркетах есть аптечный отдел, где можно купить всякие леденцы от кашля, витаминки, чаи лечебные и т.п. Так вот, в Lidl продается фирма Optisana, все витамины, все чаи, все фирмы Optisana. В Kaufland - Concept, в Aldi - другая фирма, могут быть на 99% такие же чаи и витамины, но другого производителя, в Netto еще другая фирма.</p>
<p>Касс обычно мало, в небольших магазинах типа Lidl обычно работает всего одна, но никто не жалуется, долго жать не приходится. Даже если очередь в 5 челвоек - все проходят за пару минут. И никто, никто не хамит. Я последнее время хожу в магазин с рюкзаком - в нем удобнее нести. И никто мне слова не сказал, в России давно бы попросили снять, показать, убрать или еще чего. Шкафчиков для сумок, кстати тоже нет. Один раз только накупившись в Kauflande и пойдя в Repo (супермаркет хоз.товаров) мы постеснялись идти с полным рюкзаком и пакетом и, спросив у кассирши, поставили сумки у кассы.</p>
<p>Вот и все на сегодня. Если вам что-то интересно - спрашивайте, мне довольно сложно оценить что же будет интересно. Для меня это уже все обыденно и не представляет ничего особенного. Так что жду ваших вопросов.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/o-supermarketax/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/o-supermarketax/</feedburner:origLink></item>
		<item>
		<title>Отдам ключ StarCraft II Бета</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/cI4VH_o_XxI/</link>
		<comments>http://www.charnad.com/blog/otdam-klyuch-starcraft-ii-beta/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 23:23:12 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Обо мне]]></category>
		<category><![CDATA[starcraft 2]]></category>
		<category><![CDATA[игры]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1024</guid>
		<description><![CDATA[Вот такие дела. Пишите комментарии - выберу время и среди комментаторов случайным образом отдам ключ. Если победитель откажется - я передам ключ второму в списке, если откажется второй - третьему, если откажется третий - разыграю среди тех, кто вылетел в полуфинале. Победитель Riot. Всем спасибо за участие. Ромка и Никита, если я буду проводить следующие [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/sc2key/sc2key.png" alt="" align="center"/></p>
<p>Вот такие дела. Пишите комментарии - выберу время и среди комментаторов случайным образом отдам ключ.</p>
<p><span id="more-1024"></span></p>
<p>Если победитель откажется - я передам ключ второму в списке, если откажется второй - третьему, если откажется третий - разыграю среди тех, кто вылетел в полуфинале. Победитель Riot. Всем спасибо за участие. Ромка и Никита, если я буду проводить следующие конкурсы и вы захотите принять в нем участие - обещаю вам привелегии. Я бы вас чем-нибудь наградил за 2-3 место, но у меня вроде ничего такого нету.</p>
<p>Результаты:<br />
Первое место:   17. Riot a*******t@gmail.com<br />
Второе место:   16. Ромка q****4@mail.ru<br />
Третье место:   12. Никита g***********o@yandex.ru</p>
<p>Вылетели после полу-финала:<br />
8. Георгий g*******s@gmail.com<br />
13. Serg v***********s@gmail.com<br />
24. GORN l***********6@yahoo.com</p>
<p>Вылетели после второго раунда:<br />
1. Олег o******1@rambler.ru<br />
2. MaksimOK m**************2@yandex.ru<br />
3. Nightmarko n*********e@gmail.com<br />
4. Dr.Damage b***n@meta.ua<br />
5. gek0n g***n@ukr.net<br />
6. Таня t***********a@rambler.ru<br />
11. Drox d********r@gmail.com<br />
19. Alex A***********y@mail.ru<br />
20. fixx f*****f@gmail.com<br />
21. sk2flash s******h@mail.ru</p>
<p>Вылетели из розыгрыша после первого раунда:<br />
7. Игорь b*********_i@mail.ru<br />
9. Юрий t******n@mail.ru<br />
10. Andrey a*****l@uralweb.ru<br />
14. ivan b********v@gmail.com<br />
15. z96965 z****5@yandex.com<br />
18. Alex Snet **@alexsnet.ru<br />
22. Tama a*******a@gmail.com<br />
23. Roma j*****4@gmail.com<br />
25. KoLT f*****h@ya.ru</p>
<h2>Первый раунд</h2>
<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/sc2key/round1.png" alt="" align="center"/></p>
<h2>Второй раунд</h2>
<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/sc2key/round2.png" alt="" align="center"/></p>
<h2>Полу-финал</h2>
<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/sc2key/round3.png" alt="" align="center"/></p>
<h2>Финал</h2>
<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/sc2key/final.png" alt="" align="center"/></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/otdam-klyuch-starcraft-ii-beta/feed/</wfw:commentRss>
		<slash:comments>63</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/otdam-klyuch-starcraft-ii-beta/</feedburner:origLink></item>
		<item>
		<title>Первая неделя в Германии</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/0wLkMUmH-e0/</link>
		<comments>http://www.charnad.com/blog/pervaya-nedelya-v-germanii/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 12:29:08 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Германия]]></category>
		<category><![CDATA[бюрократия]]></category>
		<category><![CDATA[немцы]]></category>
		<category><![CDATA[непривычное]]></category>
		<category><![CDATA[супермаркет]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1015</guid>
		<description><![CDATA[Вот и подходит к концу моя первая неделя пребывания в Германии. Я постараюсь записывать различные интересные вещи, которые со мной здесь случаются. Кое-что может весьма удивить человека, которому приходилось жить только в странах СНГ. (Хочу сразу оговориться, что мои слова не являются непреложной истиной, а лишь отражают мое видение. А я могу и ошибиться.) Во-первых, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/deutschland/deutschland.gif" alt=""/></p>
<p>Вот и подходит к концу моя первая неделя пребывания в Германии. Я постараюсь записывать различные интересные вещи, которые со мной здесь случаются. Кое-что может весьма удивить человека, которому приходилось жить только в странах СНГ. (Хочу сразу оговориться, что мои слова не являются непреложной истиной, а лишь отражают мое видение. А я могу и ошибиться.)</p>
<p>Во-первых, немцы часто здороваются, встретив кого-либо, когда находятся в здании. Для меня это было достаточно удивительно, когда работники Auslandersamt (ведомство по делам иностранцев) здоровались со всеми людьми ожидающими в холле. В магазине кассирши так же здороваются и часто желают хорошего дня, когда рассчитаетесь. В целом немцы значительно более приветливы, особенно это заметно как раз на работниках бюрократического аппарата. В отношении Германии пока что слово "бюрократ" для меня не носит никакого негативного оттенка, ну просто не к чему придраться.</p>
<p>Мусор. Мусор, конечно же, здесь сортируют. В Саксонии мусор делят на пластик, бумагу, биомусор, стекло (стекло делят на 3 цвета: белый, зеленый и коричневый) и все остальное. Поначалу непонятно куда девать, например бумагу, в которую была завернута еда. Но, как обьяснил домовладелец, бумага есть бумага.</p>
<p>Про пиво и колбаски не спрашивайте, сам не ел, не видел как другие едят/пьют. Но в супермаркете выбор огромнейший. В Германии популярен напиток, который называется шорле. Это сок (почти всегда яблочный) смешанный с минералкой. Стоит, кстати, весьма дешево, что-то около 30 центов за 1,5 литра. В рублях это будет 13, в Санкт-Петербурге за 13 рублей можно только в туалет сходить, и то не везде.</p>
<p>Интересный факт: покупая напиток в бутылке часто надо платить pfand 25 центов (10 руб). Это такой залог за бутылку. Если вернешь ее в магазин - получишь обратно, не вернешь - не получишь. Таким образом немцы следят, чтобы не бросали пластик куда попало (он почти не разлагается, зато прекрасно перерабатывается). Тележки в супермаркете, кстати, взять можно за евро. Привезешь тележку обратно на стоянку - получишь евро обратно, а иначе считай оплатил труд человека, который сделает это за тебя.</p>
<p>Очень часто видим вечером окна первого этажа, которые никак не прикрыты, и прекрасно видно кто внутри и что делает. В России это непозволительная беспечность, а здесь повсеместно.</p>
<p>Вот такие мои небольшие замечания. Дальше, я думаю, буду писать все более развернуто и с фотографиями.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/pervaya-nedelya-v-germanii/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/pervaya-nedelya-v-germanii/</feedburner:origLink></item>
		<item>
		<title>Исходники судоку</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/gZbp_2tcZus/</link>
		<comments>http://www.charnad.com/blog/isxodniki-sudoku/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 19:30:46 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sources]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1005</guid>
		<description><![CDATA[Я уже давно обещал выложить исходные коды судоку (поиграйте в судоку, если еще не играли). Я думал, что со временем исправлю код, сделаю лучше, но нет ни времени, ни желания. Поэтому лучше я выложу как есть, а вы уж сами улучшайте. Посмотреть код. Далее в посте будут комментарии. Что касается алгоритма, то здесь все работает [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/> Я уже давно обещал выложить исходные коды судоку (<a href="http://www.charnad.com/blog/sudoku-na-php-i-jquery/">поиграйте в судоку</a>, если еще не играли). Я думал, что со временем исправлю код, сделаю лучше, но нет ни времени, ни желания. Поэтому лучше я выложу как есть, а вы уж сами улучшайте. <a href="http://pastie.org/private/0hqk6m0flopmpp1eurtjrg">Посмотреть код</a>. Далее в посте будут комментарии.<span id="more-1005"></span></p>
<p>Что касается алгоритма, то здесь все работает так. У нас есть поле 9х9, соответственно начнем мы с</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> generate<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$row</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">9</span><span style="color: #339933;">;</span> <span style="color: #000088;">$row</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$col</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$col</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">9</span><span style="color: #339933;">;</span> <span style="color: #000088;">$col</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>$error_counter служит нам для защиты от тупиков. Сейчас вы увидите о чем речь.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">&gt;</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">retry_after</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Row will be incremented to 0</span>
    <span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$col</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reset</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Если количество ошибок при генерации вышло за определенные пределы - значит звезды сложились неудачно и что-то где-то не сходится. Поэтому генерация сбрасывается и начинается заново.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sudoku</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$col</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Вычисляем какие цифры подходят в текущую клетку</span>
    <span style="color: #000088;">$fit</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">,</span> <span style="color: #000088;">$col</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$percents</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$numbers</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$number</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$percents</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$number</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">percentage</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$number</span><span style="color: #339933;">,</span> <span style="color: #000088;">$row</span><span style="color: #339933;">,</span> <span style="color: #000088;">$col</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fit</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//Here we get all numbers, that are most possible</span>
    <span style="color: #000088;">$available</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$max</span> <span style="color: #339933;">=</span> <span style="color: #990000;">max</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_values</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$percents</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fit</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$number</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$percents</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$number</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$max</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$available</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$number</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Вот тут и происходит вся магия. Сначала вычисляем какие числа могут встать в клетку (смотрим, чтобы по вертикали, горизонтали и в малом квадрате такой не было). Далее для каждого из этих чисел запускается мутная функция percentage. Она вычисляет, какой шанс у числа попасть в эту клетку. Допустим у нас осталось 4 свободные клетки и 4 числа. При этом первое число может попасть в 1 клетку из 4х, второе в две, третье в три, четвертое во все. Эта функция просто делит количество клеток куда число может попасть на количество пустых клеток. Таким образом, выпадет число, у которого меньше всего шансов попасть в другие клетки. При равенстве берем случайное.
</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//It can turn that sudoku generation isn't going well</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$available</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sudoku</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$cell</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$cell</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNum</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$row</span><span style="color: #339933;">--;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span><span style="color: #339933;">++;</span>
    <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В переменной available хранятся те самые числа, которые могут попасть в текущую клетку и имеют наивысшую вероятность попасть. Если вдруг оказывается, что никакое число не может попасть, а ряд еще не закончился - то мы сбрасываем текущий ряд и начинаем генерировать его заново. Ну а если сбрасывается ряд (по умолчанию) 30 раз, тогда, как я уже говорил, перегенерируется вся головоломка.
</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">&gt;</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">retry_after</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sudoku</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$col</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$available</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$available</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Тут все просто, если надо сбросить головоломку - идем в начало и сбрасываем. А если все в порядке - берем случайное число, если их несколько.<br />
Ну а все остальное по-моему достаточно просто и понятно.</p>
<p>That's all folks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/isxodniki-sudoku/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/isxodniki-sudoku/</feedburner:origLink></item>
		<item>
		<title>PHP: эксклюзивный счетчик в Shared Memory</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/C2tlSg9C5b8/</link>
		<comments>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:41:14 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[shared memory]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=992</guid>
		<description><![CDATA[Я надеюсь что вы уже прочитали вводную статью про многопоточность в PHP, или вам это просто не требуется. Теперь я расскажу про счетчик, который будет доступен для потоков приложения, при этом доступ к нему будет эксклюзивным. Разделяемая память - особая область памяти, которая доступа ВСЕМ процессам операционной системы. Доступ к определенному сегменту можно получить с [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Я надеюсь что вы уже прочитали вводную статью про <a href="http://www.charnad.com/blog/mnogopotochnost-na-php/">многопоточность в PHP</a>, или вам это просто не требуется. Теперь я расскажу про счетчик, который будет доступен для потоков приложения, при этом доступ к нему будет эксклюзивным.</p>
<p><span id="more-992"></span></p>
<p>Разделяемая память - особая область памяти, которая доступа ВСЕМ процессам операционной системы. Доступ к определенному сегменту можно получить с помощью двух параметров: имени существующего файла и одного символа, который будет ключом System V IPC. Это нужно для того, чтобы несколько сегментов могли быть выделены основываясь на одном и том же файле. Звучит пока очень туманно, но сейчас я приведу пример, и надеюсь все станет понятно.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$t_key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$shmid</span> <span style="color: #339933;">=</span> <span style="color: #990000;">shmop_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$t_key</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'c'</span><span style="color: #339933;">,</span> <span style="color: #208080;">0755</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">64</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">shmop_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shmid</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">shmop_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shmid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Первой командой, специальной функцией ftok мы получили ключ, по которому будем получать доступ к сегменту разделяемой памяти. Первым параметром мы передали ему имя файла скрипта, а вторым букву 'g'. Почему 'g'? А просто так, можно взять любой символ.<br />
Во второй строке мы собственно открываем доступ к сегменту памяти. Первый параметр - наш ключ, второй параметр 'c' - флаг указывающий на то, что мы создаем сегмент памяти, при том, если он уже существуем - он открывается на чтение/запись. Третий параметр - права на доступ, четвертый - размер в байтах.<br />
В третьей строке мы записываем туда единицу, последний параметр - смещение.<br />
И наконец закрываем сегмент.<br />
Теперь по адресу, который определяется файлом скрипта и буквой 'g' в сегменте размером 64 байта лежит единица, и ее может достать любой процесс.</p>
<p>Теперь представим, что у нас программа работает в 50 потоков, она обрабатывает файл строчка за строчкой. Мы не хотим, чтобы программа два раза обрабатывала одну строку, поэтому кладем в разделяемую память номер строки, которая была обработана последней. И каждый процесс перед тем, как считать строчку берет из разделяемой памяти номер последней обработанной строки, прибавляет единицу, записывает обратно в разделяемую память и идет обрабатывать эту строчку. Следующий процесс возьмет уже строчку с номером на один больше. Все хорошо, все радуются, работает быстро. Однако случается так, что два процесса одновременно решили взять значение из памяти и взяли одинаковое значение и записали одинаковое. А представьте, что сразу 50 процессов одновременно считают значение. В общем дело ясное, что нам надо ограничить доступ к памяти одним процессом.</p>
<p>Как раз для таких случаев придуманы семафоры. Семафор (semaphore) - это такая сущность, которая позволяет ограниченному количеству процессов одновременно получать "зеленый свет" на выполнение чего-либо. Семафор, у которого такое количество равно 1 называется мьютексом (mutex). Именно мьютекс позволит нам не допускать в наш сегмент памяти больше одного процесса и остановит анархию.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sem</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sem_get</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">sem_acquire</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//тут может быть только один процесс</span>
<span style="color: #990000;">sem_release</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Мы получаем ключ для семафора точно таким же образом, как и для разделяемой памяти. Третий параметр - автоматическое "отпускание" семафора, если поток, который был впущен завершился. Те потоки, которые попытаются получить доступ к семафору, будут блокированы до тех пор, пока семафор не освободится. Это похоже на очередь в туалет. Один внутри, остальные снаружи. Один выходит, другой заходит и закрывается, другие продолжают ждать.
</p>
<p>Таким образом, создав ячейку памяти и создав семафор мы получаем счетчик, который позволит нам обрабатывать файл построчно не боясь, что одна строка будет обработана два раза. Для использования этого принципа я сделал класс Counter, который работает в моем многопоточном приложении. Взять его можно <a href="http://pastebin.org/86576">вот здесь</a>. А тут я приведу пример использования:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Ноль это наше начальное состояние счетчика</span>
<span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span>_new<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Порождаем потомков</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> PROCESS_AMOUNT<span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Error spawning new process'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Родительский процесс у нас ничего не будет делать</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Первый параметр - имя счетчика, и заодно часть ключа</span>
        <span style="color: #666666; font-style: italic;">//Второй параметр - увеличивать ли значение счетчика</span>
        <span style="color: #666666; font-style: italic;">//В данном случае мы просто читаем значение</span>
        <span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">//TOTAL_LINES - количество строк в файле</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$counter</span> <span style="color: #339933;">&lt;</span> TOTAL_LINES<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">//Берем значение счетчика и увеличиваем его на 1</span>
            <span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">//Обарабатываем файл</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/</feedburner:origLink></item>
		<item>
		<title>Многопоточность на PHP</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/1VkZs6lDkS8/</link>
		<comments>http://www.charnad.com/blog/mnogopotochnost-na-php/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:05:36 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=988</guid>
		<description><![CDATA[Хочу рассказать вам про многопоточные приложения, взаимодействие процессов (IPC) и применение всего этого на PHP. В качестве примера мы возьмем счетчик с эксклюзивным доступом, доступный для всех процессов. Что такое многопоточность? Это способ разделения программы на отдельные сущности (процессы и треды(threads)) для обеспечивания параллельности выполнения. Зачем это нужно? Для ускорения работы. Ведь открывая какой-нибудь сайт [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Хочу рассказать вам про многопоточные приложения, взаимодействие процессов (IPC) и применение всего этого на PHP. В качестве примера мы возьмем счетчик с эксклюзивным доступом, доступный для всех процессов.</p>
<p><span id="more-988"></span></p>
<p>Что такое многопоточность? Это способ разделения программы на отдельные сущности (процессы и треды(threads)) для обеспечивания параллельности выполнения. Зачем это нужно? Для ускорения работы. Ведь открывая какой-нибудь сайт вы не хотите ждать пока сервер последовательно откроет его всем, кто запросил его до вас. Вы хотите сразу, поэтому сервер выделяет отдельный процесс или поток для обработки вашего запроса. </p>
<p>Сначала немного про многопточность в PHP. PHP не многопоточный язык, PHP не умеет работать с тредами. Однако мы можем использовать системные вызовы операционной системы для создания процессов. Это как если бы мы просто запускали PHP-CLI несколько раз. Основная команда pcntl_fork разделяет выполнение программы на 2 части: родительскую и дочернюю, при этом эта команда вернет идентификатор процесса. Если вернулся -1, значит произошла ошибка, если 0, значит мы в дочернем потоке, если число - значит в родительском. </p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Произошла ошибка'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// Мы в родительском потоке</span>
     pcntl_wait<span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Ждем выполнения потомка</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// Мы в потоке потомке</span>
     <span style="color: #666666; font-style: italic;">// Делаем что-нибудь</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В этом примере мы разделили программу на 2 части. В родительском процессе мы ожидаем завершения дочернего, чтобы тот доложил об успешном завершении. В противном случае он останется висеть в системе, как процесс-зомби. А если мы хотим не 2 потока, а больше? Тогда вызываем pcntl_fork несколько раз.</p>
<p>Приведу пример, как можно использовать pcntl_fork для "демонизации" процесса. Демон (daemon) - процесс выполняющийся в фоновом режиме. Это бывает очень удобно для программ, которые выполняются долгое время и не требуют прямого общения с пользователем. В Windows службы - аналог демонов в *nix системах. Итак, у вас есть программа на PHP, выполняющаяся в командной строке и вы хотите, чтобы она работала в фоне. Конечно, вы всегда можете сделать так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">nohup</span> php script.php <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>Это запустит вашу программу в фоновом режиме, а весь вывод будет перенаправлять в nohup.out. Более того, программа не завершится с выходом пользователя из системы. Но для демонов более правильный вариант создать процесс-потомок, закрыть родительский процесс (да-да, почти как зомби), только мы еще назначим наш дочерний поток "лидером сессии", то есть он сам сможет порождать дочерние потоки.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Demonization</span>
<span style="color: #000088;">$child_pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Если мы получили дочерний id, </span>
<span style="color: #666666; font-style: italic;">// то мы в родительском потоке</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$child_pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">//Здесь мы уже в потомке, а родитель был закрыл</span>
<span style="color: #990000;">posix_setsid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Таким образом мы получим независимо выполняющуюся программу. Завершить ее можно командой kill pid, где pid - идентификатор процесса. Тот самый, который возвращается в родительский поток и представляет собой целое неотрицательное число, уникальное в системе.
</p>
<p>Возникает вопрос, зачем же нужны threads, если есть процессы? Дело в том, что треды выполняются в том же контексте, что и породивший его процесс, то есть все треды имеют общие ресурсы, например открытые файлы. Закрыв файловый дескриптор в одном треде, вы получите ошибку в другом, если попытаетесь прочитать этот файл с тем же дескриптором. В свою очередь процессам нужен особый способ обмениваться данными, если вы хотите открыть один и тот же файл в разных процессах. Для такого общения есть множество инструментов. Один из основных - сигналы.</p>
<p>Сигналы - это системные вызовы, влияющие на поведение процессов. Сигнал может завершить, приостановить, или послать особый сигнал, определенный пользователем. Помимо сигналов есть разделяемая память (shared memory) и семафоры (semaphores). Более подробно о них, и вообще об устройстве posix совместимых операционных систем советую вам поискать в интернете. Это было краткое введение в тему, для подготовки к следующей статье про <a href="http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/">счетчик в shared memory</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/mnogopotochnost-na-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/mnogopotochnost-na-php/</feedburner:origLink></item>
		<item>
		<title>Модальное окно на jQuery blockUI</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/P1tJwHToNlM/</link>
		<comments>http://www.charnad.com/blog/modalnoe-okno-na-jquery-blockui/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 18:53:35 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[blockUI]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[модальное окно]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=930</guid>
		<description><![CDATA[Создание модального диалога с помощью jquery плагина blockUI.]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/blockui/blockui-modal.png" style="float: left; margin-right: 10px;">Я уже писал про создание модальных окон на jQuery с помощью Simplemodal, на этот раз я решил попробовать другой плагин и нашел для себя blockUI. Он потребует jQuery версии не ниже 1.2.3. Итак приступим.<span id="more-930"></span></p>
<p>Данные плагина:</p>
<ul>
<li>название: blockUI v2</li>
<li>размер: 15,6 кб без сжатия</li>
<li><a href="http://www.malsup.com/jquery/block/">сайт плагина</a>, <a href="http://github.com/malsup/blockui/raw/master/jquery.blockUI.js?v2.31">скачать</a>, <a href="http://www.malsup.com/jquery/block/#demos">демо</a></li>
</ul>
<p>На сайте разработчика он выглядит так:<br />
<img class="size-medium wp-image-79" src="http://www.charnad.com/blog/wp-content/uploads/pictures/blockui/blockui-demo.png" alt="" /></p>
<p>Для себя я подобрал определенные настройки, которые делают окна красивее. Во-первых, я хотел, чтобы модальное окно располагалось по центру экрана, а по умолчанию оно находится чуть левее. Во-вторых, я хотел сделать его похожим на модальные окна и дилалоги в Windows.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$.<span style="color: #660066;">blockUI</span>.<span style="color: #660066;">defaults</span>.<span style="color: #660066;">css</span>.<span style="color: #660066;">border</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'0px'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//убираем серую границу</span>
$.<span style="color: #660066;">blockUI</span>.<span style="color: #660066;">defaults</span>.<span style="color: #660066;">fadeIn</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">//ускоряем появление</span>
$.<span style="color: #660066;">blockUI</span>.<span style="color: #660066;">defaults</span>.<span style="color: #660066;">fadeOut</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">100</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//и исчезновение</span>
$.<span style="color: #660066;">blockUI</span>.<span style="color: #660066;">defaults</span>.<span style="color: #660066;">css</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">'40%'</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//окно будет в центре</span></pre></div></div>

<p>Этот код нужно вставить в страницу после подключения плагина. Параметр left:40% зависит от ширины окна, в моем случае оно 275 пикселей.</p>
<p>Что же сделать, чтобы окно выглядело как в Windows? Я конечно не мастер верстки, но результат мне вполне подходит. Сначала делаем макет окна и даем ему стили.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;modal_dialog&quot;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;display:none; cursor: default&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;dialog&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;dialog_title_bar&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;dialog_caption&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>www.charnad.com<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;rotes_kreuz&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;dialog_pane&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Наше модальное окошко<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;margin-top: 10px;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;form</span> <span style="color: #000066;">action</span>=<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">method</span>=<span style="color: #ff0000;">&quot;POST&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;button&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;yes&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Да&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;dialog_button&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
       <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;input</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;button&quot;</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;no&quot;</span> <span style="color: #000066;">value</span>=<span style="color: #ff0000;">&quot;Нет&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;close_dialog dialog_button&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
     <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/form<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
 <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Почему display: none? Потому что плагин автоматически переключит видимость. Теперь CSS:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.dialog</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">cursor</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">default</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1px</span> <span style="color: #993333;">solid</span> <span style="color: #cc00cc;">#000000</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.dialog</span> form <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">0px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Контейнер с заголовком */</span>
<span style="color: #6666ff;">.dialog</span> <span style="color: #6666ff;">.dialog_title_bar</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">17px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">dialog-caption-bg.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Стиль текста заголовка */</span>
<span style="color: #6666ff;">.dialog</span> <span style="color: #6666ff;">.dialog_title_bar</span> <span style="color: #6666ff;">.dialog_caption</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">black</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">font-family</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">sans-serif</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">9pt</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">5px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding-top</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Панель диалога */</span>
<span style="color: #6666ff;">.dialog</span> <span style="color: #6666ff;">.dialog_pane</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> buttonface<span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">center</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;"><span style="color: #cc66cc;">10</span>%</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding-right</span><span style="color: #00AA00;">:</span> <span style="color: #933;"><span style="color: #cc66cc;">10</span>%</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding-top</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">padding-bottom</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Кнопки диалога */</span>
<span style="color: #6666ff;">.dialog</span> <span style="color: #6666ff;">.dialog_button</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">80px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">25px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Красный крест, закрывающий окно */</span>
<span style="color: #6666ff;">.dialog</span> <span style="color: #6666ff;">.rotes_kreuz</span> <span style="color: #00AA00;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">background-image</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">rotes_kreuz.png</span><span style="color: #00AA00;">&#41;</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">28px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">15px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span> <span style="color: #933;">3px</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span>
    <span style="color: #000000; font-weight: bold;">cursor</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">pointer</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>Пути к картинкам, конечно же, поставьте свои. Сами картинки можно взять: <a href="http://www.charnad.com/blog/wp-content/uploads/pictures/blockui/dialog-caption-bg.png">фон заголовка</a>, <a href="http://www.charnad.com/blog/wp-content/uploads/pictures/blockui/rotes_kreuz.png">крест</a>.</p>
<p>Теперь Javascript, чтобы все у нас прыгало и бегало.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">//По этим кнопкам модальное окно закрывается</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'.rotes_kreuz, .close_dialog'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $.<span style="color: #660066;">unblockUI</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//Эта кнопка будет вызывать наше окно</span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#show_modal'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $.<span style="color: #660066;">blockUI</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>message<span style="color: #339933;">:</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#modal_dialog'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> css<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>width<span style="color: #339933;">:</span> <span style="color: #3366CC;">'275px'</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #006600; font-style: italic;">//По кнопке &quot;Да&quot; будет отправляться форма </span>
    $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#modal_dialog #yes'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#modal_dialog form'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">submit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Можно скачать:<p><img align="absmiddle" src="http://www.charnad.com/blog/wp-includes/images/crystal/archive.png" height="20" /> <a href="http://www.charnad.com/download/blockUIdemo.zip" onclick="wpfilebase_dlclick(3, 'download/blockUIdemo.zip')" title="Download blockUI demo">blockUI demo</a> (31.1 KiB)</p> или посмотреть прямо здесь.<br />
<input type="button" id="show_modal" value="Показать модальное окно">
<script type="text/javascript" src="http://www.charnad.com/files/blockui-modal-demo/jquery.blockUI.js"></script><script type="text/javascript">$.blockUI.defaults.css.border = '0px';$.blockUI.defaults.fadeIn = 100;$.blockUI.defaults.fadeOut = 100;$.blockUI.defaults.css.left = '40%';$(document).ready(function() {$('.rotes_kreuz, .close_dialog').click(function() {$.unblockUI();return false;});$('#show_modal').click(function() {$.blockUI({message: $('#modal_dialog'), css: {width: '275px'}});});$('#modal_dialog #yes').click(function() {alert('Да!');});});</script></p>
<style type="text/css">.dialog {cursor: default;border: 1px solid #000000;}.dialog form {margin: 0px;}.dialog .dialog_title_bar {height: 17px;padding: 1px;background-image: url(http://www.charnad.com/files/blockui-modal-demo/dialog-caption-bg.png) ;}.dialog .dialog_title_bar .dialog_caption {color: black;font-family: sans-serif;font-size: 9pt;text-align: left;padding-left: 5px;padding-top: 1px;}.dialog .dialog_pane {background: buttonface;text-align: center;padding-left: 10%;padding-right: 10%;padding-top: 10px;padding-bottom: 10px;}.dialog .dialog_button {width: 80px;height: 25px;}.dialog .rotes_kreuz {background-image: url(http://www.charnad.com/files/blockui-modal-demo/rotes_kreuz.png);width: 28px;height: 15px;position: absolute;right: 3px;top: 3px;float: right;display: block;cursor: pointer;}</style>
<div id="modal_dialog" style="display:none; cursor: default" class="dialog">
<div class="dialog_title_bar">
<div class="dialog_caption">www.charnad.com</div>
<div class="rotes_kreuz"></div>
</div>
<div class="dialog_pane">
<div>Наше модальное окошко</div>
<div style="margin-top: 10px;">
<form action="" method="POST">
<input type="button" id="yes" value="Да" class="dialog_button"/>
<input type="button" id="no" value="Нет" class="close_dialog dialog_button" /></form>
</div>
</div>
</div>
<p>При желании, вы легко можете добавлять поля в форму диалога. У этого плагина есть еще одна интересная черта - оповещения типа Growl (оповещение вверху справа), о котором я надеюсь написать в следующий раз.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/modalnoe-okno-na-jquery-blockui/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/modalnoe-okno-na-jquery-blockui/</feedburner:origLink></item>
		<item>
		<title>Пара советов по SQLite</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/2lrtmqP7ciE/</link>
		<comments>http://www.charnad.com/blog/para-sovetov-po-sqlite/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:16:12 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=926</guid>
		<description><![CDATA[Если у вас возникают ошибки при работе с SQLite, то вот у меня пара решений. Если у вас ошибка "Unable to open database file" и при этом база читается, даже если вы дали права файлу БД 0777, то вам еще надо дать права на запись папке, в которой лежит файл. Дело в том, что при [...]]]></description>
			<content:encoded><![CDATA[<p>Если у вас возникают ошибки при работе с SQLite, то вот у меня пара решений. </p>
<p>Если у вас ошибка "Unable to open database file" и при этом база читается, даже если вы дали права файлу БД 0777, то вам еще надо дать права на запись папке, в которой лежит файл. Дело в том, что при открытии транзакции пишется файл dbfilename-journal. Так же под Windows эта проблема может означать наличие кириллических символов в пути к базе.</p>
<p>Если вы по привычке написали ON DUPLICATE KEY UPDATE ..., и не понимаете в чем ошибка - обратитесь к <a href="http://www.sqlite.org/lang_insert.html">официальному мануалу</a> и просто измените INSERT на REPLACE, а "ON DUPLICATE..." сотрите.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/para-sovetov-po-sqlite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/para-sovetov-po-sqlite/</feedburner:origLink></item>
		<item>
		<title>Ошибка PDO Invalid Argument и Unix socket</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/KfiSvkq9VtM/</link>
		<comments>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 14:56:32 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=910</guid>
		<description><![CDATA[Такая ошибка возникла у меня после перехода на PHP 5.3. Решение я нашел на http://stackoverflow.com, можете там посмотреть, чтобы узнать про эту ошибку более подробно. Выглядит она вот так: Warning: PDO::__construct&#40;&#41; &#91;pdo.--construct&#93;: &#91;2002&#93; Invalid argument &#40;trying to connect via unix://&#41; in /home/blah-blah-blah.php on line 9 &#160; Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Такая ошибка возникла у меня после перехода на PHP 5.3. Решение я нашел на http://stackoverflow.com, можете там посмотреть, чтобы узнать про эту ошибку более подробно. Выглядит она вот так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Warning: PDO::__construct<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>pdo.--construct<span style="color: #7a0874; font-weight: bold;">&#93;</span>: <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2002</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> Invalid argument <span style="color: #7a0874; font-weight: bold;">&#40;</span>trying to connect 
via unix:<span style="color: #000000; font-weight: bold;">//</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php on line <span style="color: #000000;">9</span>
&nbsp;
Fatal error: Uncaught exception <span style="color: #ff0000;">'PDOException'</span> with message <span style="color: #ff0000;">'SQLSTATE[HY000] [2002]
Invalid argument'</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php:<span style="color: #000000;">9</span> Stack trace: <span style="color: #666666; font-style: italic;">#0</span>
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: PDO-<span style="color: #000000; font-weight: bold;">&gt;</span>__construct<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'mysql:host=localhost;dbname=db'</span>, <span style="color: #ff0000;">'USER'</span>, 
<span style="color: #ff0000;">'PASSWORD'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">#1 {main} thrown in /home/blah-blah-blah.php on line 9</span></pre></div></div>

<p>Решается она так: вместо localhost, при написании DSN для PDO пишите 127.0.0.1. А так же стоит указать путь к сокету MySQL в php.ini: pdo_mysql.default_socket=/var/run/mysqld/mysql.sock</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/</feedburner:origLink></item>
		<item>
		<title>Гелиос-81Н</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/UvxqGcPfllA/</link>
		<comments>http://www.charnad.com/blog/gelios-81n/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 19:40:38 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Фото]]></category>
		<category><![CDATA[d60]]></category>
		<category><![CDATA[гелиос-81н]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=891</guid>
		<description><![CDATA[Как вы, возможно, помните я купил себе зеркалку Nikon D60. Я достаточно долго щелкал на китовый объектив и, естественно, захотел новых игрушек. Китовый объектив я отдал хозяину, а себе купил кит от D90 Nikkor 18-105mm f/3,5-5.6, а чуть позже Гелиос-81Н 50мм f/2. Сейчас я коротенько расскажу про Гелиос. Все получилось относительно быстро. Я нашел статью [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" title="Helios-81N" src="http://www.charnad.com/blog/wp-content/uploads/pictures/helios81n.png" alt="Helios 81N" />
<p>Как вы, возможно, <a href="http://www.charnad.com/blog/kupil-chernogo-druga-nikon-d60/">помните</a> я купил себе зеркалку Nikon D60. Я достаточно долго щелкал на китовый объектив и, естественно, захотел новых игрушек. Китовый объектив я отдал хозяину, а себе купил кит от D90 Nikkor 18-105mm f/3,5-5.6, а чуть позже Гелиос-81Н 50мм f/2. Сейчас я коротенько расскажу про Гелиос.</p>
<p><span id="more-891"></span>
<p>Все получилось относительно быстро. Я нашел статью в интернете про то, что советская оптика от фотоаппаратов Киев 17,19,20 имеет байонет Н. А тот в свою очередь был скопирован с никоновского байонета, и поэтому они совместимы без переходников. Это же просто находка для никониста! Из всех объективов с таким байонетом наиболее доступным, и наиболее мне интересным был как раз 81й.
<a href="http://www.charnad.com/blog/wp-content/gallery/helios-81n/img_71172-vk.jpg" title="" class="shutterset_singlepic60" >
	<img class="ngg-singlepic ngg-right" src="http://www.charnad.com/blog/wp-content/gallery/cache/60__160x120_img_71172-vk.jpg" alt="img_71172-vk" title="img_71172-vk" />
</a>
Мой экземплярчик я нашел на Ebay. Продавец оказался из Ростова, и за несколько дней мы договорились, что за ~23$ я получаю его себе. Теперь мой фотоаппаратик выглядит вот так:</p>
<p>Немножко инфы про объектив. Выпускается в нескольких вариантах, если вы хотите поставить его на камеру Nikon - ищите с маркировкой Н. 81 просто и 81-Автомат не подойдут. Почти полным аналогом является Арсат-81Н, разница в чернении лепестков диафрагмы и просветлении. По слухам на Арсатах чернение лепестков осыпается - будьте внимательны. Объектив, естественно, полностью ручной. Диафрагма выставляется в пределах от 2 до 22 на объективе, наведение на резкость производится фокусировочным кольцом. Выдержку и ISO выставлять надо в камере в режиме M. Насколько мне известно, автоматически оценивать экспозицию сможет только D200, но если у вас есть деньги на D200 - наверняка, есть деньги и на современный объектив. Угол поля зрения 45°, разрешение (центр/край) - 40/20 лин/мм. Опять же по памяти этот объектив один из самых лучших по разрешающей способности.</p>
<p>Поначалу, конечно, тяжко все выставлять ручками, привык, понимаешь, к автоматике. Но теперь получаю несравнимое удовольствие от управления всем процессом. Ну и, конечно куда без фоточек. Пока их мало, но я буду выкладывать по мере появления более-менее достойных. Моя первая модель - киска по имени Ириска.<br />

<a href="http://www.charnad.com/blog/wp-content/gallery/helios-81n/dsc_3579.jpg" title="" class="shutterset_singlepic59" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/59__140x105_dsc_3579.jpg" alt="dsc_3579" title="dsc_3579" />
</a>
 
<a href="http://www.charnad.com/blog/wp-content/gallery/helios-81n/dsc_3581_2.jpg" title="" class="shutterset_singlepic61" >
	<img class="ngg-singlepic ngg-left" src="http://www.charnad.com/blog/wp-content/gallery/cache/61__140x105_dsc_3581_2.jpg" alt="dsc_3581_2" title="dsc_3581_2" />
</a>
 
<a href="http://www.charnad.com/blog/wp-content/gallery/helios-81n/dsc_3597_2.jpg" title="" class="shutterset_singlepic62" >
	<img class="ngg-singlepic" src="http://www.charnad.com/blog/wp-content/gallery/cache/62__140x105_dsc_3597_2.jpg" alt="dsc_3597_2" title="dsc_3597_2" />
</a>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/gelios-81n/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/gelios-81n/</feedburner:origLink></item>
		<item>
		<title>PHP: Получить строку по номеру</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/AY9OBA1gKzM/</link>
		<comments>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 13:59:25 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=884</guid>
		<description><![CDATA[Мне нужно было получать строку из файла по порядковому номеру. То есть первую, десятую, 390815-ую, и т.д. Сначала мне хватало цикла fgets, который прокручивал до нужной строки. На строке 500000 такой способ у меня занимал уже почти минуту, что явно плохо. Stream_get_line был совем не быстрее, а даже медленнее процентов на 30. Первый из костылей, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" title="PHP" src="http://static.php.net/www.php.net/images/php.gif" alt="" width="120" height="67" />
<p>Мне нужно было получать строку из файла по порядковому номеру. То есть первую, десятую, 390815-ую, и т.д. Сначала мне хватало цикла fgets, который прокручивал до нужной строки. На строке 500000 такой способ у меня занимал уже почти минуту, что явно плохо. Stream_get_line был совем не быстрее, а даже медленнее процентов на 30.</p>
<p>Первый из костылей, пришедших мне в голову был fseek до значения в 500000 строк (посчитал байты), а оттуда уже крутил fgets. Но так как у меня идет обработка до 100 тысяч строк в сутки, то через пару дней опять пришлось высчитывать смещение для fseek. Опять же, требовался другой выход. И я его таки нашел.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getFileLine<span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;head -n <span style="color: #006699; font-weight: bold;">$line</span> <span style="color: #006699; font-weight: bold;">$file</span> | tail -n 1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Head берет N первых строк файла, tail N последних. Все гениальное просто. 1 миллионная строка берется из файла за 1.027 сек, 40 миллионная - 30 секунд, что очевидно быстрее прокручивания fgets.  (Конечно, если не прыгать fseek до 40 миллионной записи и считывать 40000001-ую)</p>
<p>Конечно, решение ограничено *nix системами, но т.к. моя система и без того использует pcntl_fork, она уже была привязана к никсам, так что хуже мне не стало.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/</feedburner:origLink></item>
		<item>
		<title>Массовый UPDATE в MySQL</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/e85AowoCDek/</link>
		<comments>http://www.charnad.com/blog/massovyj-update-v-mysql/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 21:22:18 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=841</guid>
		<description><![CDATA[Если вы хотите делать массовый апдейт в MySQL, то я могу вам предложить вот такой рецепт. Сначала вы создаете временную таблицу, циклом собираете массовый INSERT запрос и потом вставляете данные из временной таблицы в нужную. Выглядеть это может, например, так: CREATE TEMPORARY TABLE ids &#40;value INT, url VARCHAR&#40;255&#41;&#41;; INSERT INTO ids VALUES &#40;0, 'http://url1.ru'&#41;, &#40;0, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/mysql_logo.png" alt=""/>
<p>Если вы хотите делать массовый апдейт в MySQL, то я могу вам предложить вот такой рецепт. Сначала вы создаете временную таблицу, циклом собираете массовый INSERT запрос и потом вставляете данные из временной таблицы в нужную. Выглядеть это может, например, так:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TEMPORARY</span> <span style="color: #993333; font-weight: bold;">TABLE</span> ids <span style="color: #66cc66;">&#40;</span>value INT<span style="color: #66cc66;">,</span> url VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> ids <span style="color: #993333; font-weight: bold;">VALUES</span> 
    <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'http://url1.ru'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'http://url2.ru'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span> <span style="color: #ff0000;">'http://url3.ru'</span><span style="color: #66cc66;">&#41;</span>;
<span style="color: #993333; font-weight: bold;">UPDATE</span> blogs<span style="color: #66cc66;">,</span> ids <span style="color: #993333; font-weight: bold;">SET</span> my_value <span style="color: #66cc66;">=</span> ids<span style="color: #66cc66;">.</span>value <span style="color: #993333; font-weight: bold;">WHERE</span> blogs<span style="color: #66cc66;">.</span>url <span style="color: #66cc66;">=</span> ids<span style="color: #66cc66;">.</span>url;</pre></div></div>

<p>Поясню. Допустим, мне понадобилось обновить некое значение в таблице в соответствии с URL. Скажем, статистику интернет-магазинов. Я создал временную таблицу из тех значений, по котороым будет вестись поиск, и значений, которые я буду вставлять в нужную мне таблицу. Дальше, идет INSERT сразу нескольких строк. Его очень просто собирать в цикле из массива. Например вот так:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$elements</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$aray</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$url</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$elements</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'('</span><span style="color: #339933;">.</span><span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">escape</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">', '</span><span style="color: #339933;">.</span><span style="color: #000088;">$db</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">escape</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">')'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$insert_string</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$elements</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>После чего, собственно апдейт со вставкой. Временная таблица исчезнет после окончания сессии БД. На то она и временная.</p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/massovyj-update-v-mysql/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/massovyj-update-v-mysql/</feedburner:origLink></item>
		<item>
		<title>Как в Kohana из-за Apache не работал Index Controller</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/c3FAkznCZ44/</link>
		<comments>http://www.charnad.com/blog/kak-v-kohana-iz-za-apache-ne-rabotal-index-controller/#comments</comments>
		<pubDate>Thu, 26 Nov 2009 12:12:09 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[kohana]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=834</guid>
		<description><![CDATA[Закончилась моя суточная эпопея с Kohana, когда я пытался всего лишь работать с контроллером по имени Index. Проблема заключалась в том, что когда я заходил по адресу http://somesite.ru/kohana/index/save с надеждой, что выполнится контроллер index, метод save я получал ошибку о том, что мол страницы save-то и не существует. Особенно странно было то, что эта ошибка [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/apache_feather.png" alt=""/>
<p>Закончилась моя суточная эпопея с Kohana, когда я пытался всего лишь работать с контроллером по имени Index. Проблема заключалась в том, что когда я заходил по адресу http://somesite.ru/kohana/index/save с надеждой, что выполнится контроллер index, метод save я получал ошибку о том, что мол страницы save-то и не существует. Особенно странно было то, что эта ошибка проявлялась только на рабочем сервере под Debian. Сначала я стал дебажить роутинг Коханы, но докопавшись до самых глубин, выяснилось, что Apache отдает неверный параметр сервера PATH_INFO, вместо 'index/save', в роутинг передавался просто 'save', и это уже трактовалось как контроллер. Я перепроверил на всех доступных мне shared хостингах, везде все было в порядке, кроме рабочего сервера. </p>
<p>Ладно, подумал я, и переустановил Apache. Но проблема не решилась. Ладно, снова подумал я, и включил unstable пакеты и установил распоследний Apache, но проблема по прежнему не решилась. Вот тут я уже стал впадать в панику. А я вам скажу, что было уже утро следующего дня, как я обнаружил проблему. Просмотрев конфиги Апача я не нашел ничего криминального. Я грешил уже и на mod_rewrite, и на Debian, и на все подряд. </p>
<p>Почти отчаявшись, я стал разбирать Апач по кусочкам, выключив все модули, кроме mod_rewite и mod_php. И вот тут все заработало. Выяснилось, что mod_negotitation считал, что раз я напрямую не указал index.php в URI, значит я ошибся. И милостливо переписывал имя контроллера index в index.php. </p>
<p>Проблема решилась выключением этого злополучного модуля. Потрачено почти сутки времени и килограмм нервов.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/kak-v-kohana-iz-za-apache-ne-rabotal-index-controller/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/kak-v-kohana-iz-za-apache-ne-rabotal-index-controller/</feedburner:origLink></item>
		<item>
		<title>Судоку на PHP и jQuery</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/WSkYsVKBOyw/</link>
		<comments>http://www.charnad.com/blog/sudoku-na-php-i-jquery/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 16:06:22 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=800</guid>
		<description />
			<content:encoded><![CDATA[<p><iframe frameborder="0" width="480" height="500" align="center" src="http://dev.charnad.com/sudoku" scrolling="no"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/sudoku-na-php-i-jquery/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/sudoku-na-php-i-jquery/</feedburner:origLink></item>
		<item>
		<title>Mercurial и NetBeans</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/lJnqiav4gxg/</link>
		<comments>http://www.charnad.com/blog/mercurial-i-netbeans/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 21:18:51 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[netbeans]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=679</guid>
		<description><![CDATA[В продолжение истории про установку Mercurial я расскажу как настроить IDE NetBeans. По умолчанию плагин для работы с меркуриалом должен быть включен, если же нет, то идите в Tools -> Plugin и там включайте. Репозитарий инициируется в свойствах проекта. Чтобы сохранить все текущие файлы, делаете commit в том же меню, где инициировали проект. Коммитится все [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/logo_netbeans.gif" alt="NetBeans logo" />В продолжение истории про установку Mercurial я расскажу как настроить IDE NetBeans. По умолчанию плагин для работы с меркуриалом должен быть включен, если же нет, то идите в Tools -> Plugin и там включайте. <span id="more-679"></span><br />
<img style="margin: 10px;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/hg-and-nb/hg-active.png" alt="Mercurial active" /><br />
Репозитарий инициируется в свойствах проекта.<br />
<img style="margin: 10px;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/hg-and-nb/hg-init.png" alt="Mercurial init" /><br />
Чтобы сохранить все текущие файлы, делаете commit в том же меню, где инициировали проект. Коммитится все локально, поэтому проблем тут, я думаю, не может быть никаких. (Если у вас выскакивает ошибка, что не найден Mercurial, якобы неверно указан PATH или еще что-нибудь, при том, что вы все точно указали - значит проект слишком большой. Эта проблема есть у NetBeans, попробуйте коммитить проект по частям)<br />
Проблемы начинаются, когда вы хотите сделать pull/push. Он начинается и идет бесконечно. Дело все в том, что авторизация по ssh для NetBeans проходит только с помощью пары ключей. У пользователей Линукса он уже должен быть в ~/.ssh. А те, у кого Windows, <a href="http://www.charnad.com/blog/ssh-pod-windows/">помните</a> мы вместе с ssh копировали ssh-keygen.exe, вот его и настала пора использовать. Запускаете и на все вопросы нажимаете просто Enter. Хотя, по желанию можете установить пароль. В папке, которую вы определили, как HOME, появится .ssh папка с двумя файлами id_rsa и id_rsa.pub (если вы не выбирали другое название). Если вы хотите работать с BitBucket, тогда содержимое pub файла копируете в ваш профиль на сайте. Если вы хотите пушить/пуллить на свой сервер, тогда у пользователя mercurial (или того, кто управляет репозиториями) в папке ~/.ssh создайте файл authorized_keys, если еще нет и добавьте строку с содержимым pub файла. Теперь у вас все должно работать.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/mercurial-i-netbeans/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/mercurial-i-netbeans/</feedburner:origLink></item>
		<item>
		<title>Как подружились Mercurial, Windows и Debian.</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/BeIq18Wqfp8/</link>
		<comments>http://www.charnad.com/blog/kak-podruzhilis-mercurial-windows-i-debian/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 01:52:44 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=657</guid>
		<description><![CDATA[Эта история началась трагически. Я случайно стер исходники проекта, над которым работал несколько дней. Бекапов не делал, svn забросил (я работаю один, без команды), для версионности вполне обходился Local History в Eclipse/NetBeans. Но эта потеря заставила меня как следует задуматься о том, чтобы все-таки использовать VCS, хотя бы для бекапа. Основной выбор был между Git [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/mercurial-logo.png" alt="Mercurial logo"/>Эта история началась трагически. Я случайно стер исходники проекта, над которым работал несколько дней. Бекапов не делал, svn забросил (я работаю один, без команды), для версионности вполне обходился Local History в Eclipse/NetBeans. Но эта потеря заставила меня как следует задуматься о том, чтобы все-таки использовать VCS, хотя бы для бекапа. Основной выбор был между Git и Mercurial (о достоинствах и недостатках CVS/SVN и прочих ищите в поисковиках). За Mercurial для меня сыграло то, что на Bitbucket был бесплатно доступен один приватный репозиторий, в отличии от Github, где все публично. А у меня на некоторых сайтах пароли в коде зашиты.<span id="more-657"></span></p>
<p>Установка Mercurial на Windows делается элементарно: Next, Next, Next, Ok. Скачать можно, например, <a href="http://mercurial.berkwood.com/">здесь</a>. Можете так же скачать <a href="http://bitbucket.org/tortoisehg/stable/wiki/download">TortoiseHg</a>, если вам нравится их TortoiseSVN. Под Linux еще проще.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> mercurial</pre></div></div>

<p> Для Eclipse IDE поищите плагин Eclipse Mercurial, а в NetBeans поддержка встроенная. Возможно вам понадобится прописать в системную переменную PATH путь к тому месту, куда вы установили Mercurial.</p>
<p>И все, вы можете пользоваться Меркуриалом. Ему, в отличии от SVN совершенно не нужно поднимать сервер. Все ваши изменения будут хранится в папке .hg в корне проекта. В отличии от svn Mercurial, Git и другие современные системы не суют свои папки в каждую папку проекта.</p>
<p>Вкратце расскажу о том, как начать работу с этой системой. Если у вас проект лежит локально, то в папке проекта в консоли введите</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg init</pre></div></div>

<p> Тем самым, вы инициируете проект в этой папке. Дальше, как в svn:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg add; hg commit <span style="color: #660033;">-m</span> <span style="color: #ff0000;">'Initial commit'</span>;</pre></div></div>

<p>Тем самым вы добавляете все файлы в текущей папке к проекту и сразу же коммитите с комментарием "Initial commit". Если же проект где-то выложен и вы хотите подключиться к нему, тогда клонируете его себе в пустую папку.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg clone адрес репозитория</pre></div></div>

<p>Я думаю, что как создать и закоммитить проект в IDE вы разберетесь.</p>
<p>Итак, бесплатные репозитории на BitBucket публичны (кроме всего одного приватного), а размер всего 150 мегабайт. Значит надо ставить свой "сервер". Здесь все оказалось довольно быстро и просто. Как установить Mercurial на Debian я уже выше написал. После чего создал нового пользователя mercurial с помощью adduser. Дал ему в распоряжение папку /home/mercurial, закачал на сервер коды проектов по папкам и инициировал в каждой проект Меркуриала. А потом просто в Windows сделал так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">hg pull <span style="color: #c20cb9; font-weight: bold;">ssh</span>:<span style="color: #000000; font-weight: bold;">//</span>mercurial<span style="color: #000000; font-weight: bold;">@</span>myserver<span style="color: #000000; font-weight: bold;">/</span>myproject
hg update</pre></div></div>

<p> Если у вас Винда ругается на отсутствие ssh смотрите <a href="http://www.charnad.com/blog/ssh-pod-windows/">здесь</a>. Обьясню, что я сделал. Так как в Mercurial нет центрального сервера, то все репозитории равны. И вы всегда коммитите в свой локальный. А чтобы обменяться изменениями вы делаете pull (скачиваете) или push (закачиваете). Таким образом я скачал проект с сервера, чтобы удостоверится, что все работает. Надеюсь, что и у вас все получилось. А если нет - спрашивайте в комментариях.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/kak-podruzhilis-mercurial-windows-i-debian/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/kak-podruzhilis-mercurial-windows-i-debian/</feedburner:origLink></item>
		<item>
		<title>SSH под Windows</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/ab23FHxVblU/</link>
		<comments>http://www.charnad.com/blog/ssh-pod-windows/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 00:53:27 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[ssh]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=651</guid>
		<description><![CDATA[Мне потребовалось получить ssh доступ к удаленной машине из под Windows. И, хотя PuTTY меня всем устраивал, в данном случае он помочь не мог - ssh требовался распределенной системе контроля версий Mercurial. Ну что ж, надо значит надо. Чтобы запустить консольный OpenSSH клиент в Винде нужно поставить Cygwin, а так же пакеты zlib и openssh. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/ssh_pic.png" alt="" />Мне потребовалось получить ssh доступ к удаленной машине из под Windows. И, хотя PuTTY меня всем устраивал, в данном случае он помочь не мог - ssh требовался распределенной системе контроля версий Mercurial. Ну что ж, надо значит надо.<span id="more-651"></span></p>
<p>Чтобы запустить консольный OpenSSH клиент в Винде нужно поставить Cygwin, а так же пакеты zlib и openssh. Cygwin позволяет запускать линуксовые приложения под виндой. Я всегда довольно подозрительно отношусь к софту, который меняет поведение системы, поэтому собирал ssh не запуская инсталлятор Cygwin. (Для тех, кому не терпится - в конце есть все готовое, чтобы скачать.)</p>
<p>Для начала я сделал папку SSH в Program Files. На одном из <a href="http://www.cygwin.com/mirrors.html">этих</a> сайтов я скачал пакеты cygwin, zlib, openssh, openssl и minires. Из них нужно в нашу папку SSH положить файлы: cygwin1.dll из пакета cygwin, cygz.dll из zlib, ssh.exe и ssh-keygen.exe из ssh, cygcrypto-0.9.8.dll из openssl, и cygminires.dll из minires. Дальше идем в настройки переменных окружения, в PATH прописываем путь к папке SSH, а так же создаем переменную HOME и так же прописываем путь к папке SSH. Хочу, однако, отметить, что HOME можно не указывать, тогда ищите папку .ssh в папке вашего юзера. Например C:/Users/CharnaD/.ssh. Все!</p>
<p>
<img src="http://www.charnad.com/blog/wp-content/uploads/pictures/ssh_working.png" align="center" alt="Working ssh"/></p>
<p>Те, кто не хочет заморачиваться со всем этим, может просто скачать уже готовый архив с SSH: <p><img align="absmiddle" src="http://www.charnad.com/blog/wp-includes/images/crystal/archive.png" height="20" /> <a href="http://www.charnad.com/download/ssh_for_win.zip" onclick="wpfilebase_dlclick(2, 'download/ssh_for_win.zip')" title="Download SSH для Windows">SSH для Windows</a> (1.4 MiB)</p> Вам останется только прописать переменные окружения.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/ssh-pod-windows/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/ssh-pod-windows/</feedburner:origLink></item>
		<item>
		<title>Как защитить upload</title>
		<link>http://feedproxy.google.com/~r/charnad/~3/CwSdhNpKyqk/</link>
		<comments>http://www.charnad.com/blog/kak-zashitit-upload/#comments</comments>
		<pubDate>Sat, 03 Oct 2009 02:14:50 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=638</guid>
		<description><![CDATA[Иногда в скриптах нужна возможность аплоада файлов. Картинок на сервер, архивов, чего угодно. Делается это все несложно, однако есть опасность, что некто сумеет обойти ваши фильтры и таки закачает php скрипт. Существует два метода и оба с помощью .htaccess. Вариант первый: php_value engine Off Это отключит интерпретацию и скрипты злоумышленника не будут работать. Только свои [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/apache_feather.png" alt=""/>Иногда в скриптах нужна возможность аплоада файлов. Картинок на сервер, архивов, чего угодно. Делается это все несложно, однако есть опасность, что некто сумеет обойти ваши фильтры и таки закачает php скрипт. Существует два метода и оба с помощью .htaccess.<br />
Вариант первый:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php_value engine Off</pre></div></div>

<p>Это отключит интерпретацию и скрипты злоумышленника не будут работать. Только свои скрипты не кладите рядом, иначе любой сможет их скачать в виде исходных кодов. Но есть одно "НО". Нужно настроить опцию AllowOverride в конфиге Apache. Насколько я понял хватит AllowOverride Options. На shared хостингах, где PHP работает в CGI режиме, этой фичей воспользоваться не получится.</p>
<p>Вариант второй, предложенный <a href="http://kobzarev.com/"><strong>mihdan</strong></a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">RemoveHandler .php
AddType application<span style="color: #000000; font-weight: bold;">/</span>x-httpd-php-source .php
RemoveType .php
Options <span style="color: #660033;">-ExecCGI</span> <span style="color: #660033;">-Indexes</span></pre></div></div>

<p>Этот метод совместим с большим количеством хостингов и на данный момент видится более предпочтительным.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/kak-zashitit-upload/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://www.charnad.com/blog/kak-zashitit-upload/</feedburner:origLink></item>
	</channel>
</rss>
