<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Category PHP</title>
    <link>http://blog.zabiello.com/articles/category/php</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Ruby 1.9 (YARV) vs. Python, Lua &amp;amp; PHP</title>
      <description>&lt;p&gt;Korzystaj&#261;c z tego, &#380;e &lt;a href="http://redhanded.hobix.com/cult/yarvIsRubyItIsItReallyIs.html"&gt;niedawno do repozytorium Rubiego zosta&#322; dodany &lt;span class="caps"&gt;YARV&lt;/span&gt;&lt;/a&gt; (wirtualna maszyna Rubiego)  pokusi&#322;em si&#281; o ma&#322;e por&#243;wnanie wydajno&#347;ci. Jako test u&#380;y&#322;em prostego programu jaki &lt;a href="http://groups.google.com/group/pl.comp.lang.python/browse_thread/thread/61095f8a08ca5f9e/1646948032dc08c0?lnk=st&amp;#38;q=&amp;#38;rnum=2&amp;#38;hl=pl#1646948032dc08c0"&gt;pojawi&#322; si&#281; na li&#347;cie pl.comp.lang.pyhon&lt;/a&gt; (musia&#322;em tylko troch&#281; zwi&#281;kszy&#263; p&#281;tle do 10 milion&#243;w iteracji, aby by&#322;y widoczne jakie&#347; wyniki) U&#380;yty sprz&#281;t: Athlon64 3700+, 64bit Ubuntu 6.0.6.&lt;/p&gt;


	&lt;p&gt;Sprawdzi&#322;em te&#380; z ciekawo&#347;ci &lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2 na tym samym sprz&#281;cie. Dla tak prostego testu powinien m&#243;c da&#263; z siebie wszystko. Jest jednak wolniejszy od Rubiego 1.9.&lt;/p&gt;


	&lt;p&gt;Kod dla Pythona:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10000000&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

Kod dla Lua:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;span class="number"&gt;10000000&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;os&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;clock&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kod dla Rubiego:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
&lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="number"&gt;1&lt;/span&gt;&lt;span class="punct"&gt;..&lt;/span&gt;&lt;span class="number"&gt;10_000_000&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Kod dla &lt;span class="caps"&gt;PHP&lt;/span&gt;:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&amp;lt;?php
function microtime_float() {
 $time = microtime();
 return (double)substr($time, 11) + (double)substr($time, 0, 8);
}
$t =  microtime_float();
$a = 0;
for ($i = 0; $i &amp;lt; 10000000; $i++) {
  $a += $i;
}
print &amp;quot;$a\n&amp;quot;;
print  microtime_float()- $t;
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Wyniki:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;Lua: 1.14 s&lt;/li&gt;
		&lt;li&gt;Ruby 1.9: &lt;strong&gt;1.49 s&lt;/strong&gt;&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2: 1.74 s&lt;/li&gt;
		&lt;li&gt;Python 2.5: 2.64 s&lt;/li&gt;
		&lt;li&gt;Python 2.4.3: 2.72 s&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5: 3.83 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h2&gt;Drugie podej&#347;cie&lt;/h2&gt;


	&lt;p&gt;Tym razem wynik u&#347;redniam dla 10 pr&#243;b. Zwi&#281;kszy&#322;em ilo&#347;&#263; iteracji do &lt;strong&gt;20 mln&lt;/strong&gt;. No i&amp;#8230; Ruby 1.9 pobi&#322; wszystko. Zar&#243;wno Pythona jak i Lua! (PHP 5.2 po 30 sek. zg&#322;osi&#322; timeout. Musia&#322;em wi&#281;c u&#347;redni&#263; po 5 wynikach.)&lt;/p&gt;


	&lt;h3&gt;&lt;span class="caps"&gt;PYTHON&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;import&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;bench&lt;/span&gt;&lt;span class="punct"&gt;():&lt;/span&gt;
    &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
    &lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;xrange&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;20000000&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
        &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;+=&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;
    &lt;span class="keyword"&gt;return&lt;/span&gt; &lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;time&lt;/span&gt;&lt;span class="punct"&gt;()-&lt;/span&gt;&lt;span class="ident"&gt;t&lt;/span&gt;
&lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="keyword"&gt;for&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="keyword"&gt;in&lt;/span&gt; &lt;span class="ident"&gt;range&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;):&lt;/span&gt;
  &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;bench&lt;/span&gt;&lt;span class="punct"&gt;()&lt;/span&gt;
&lt;span class="ident"&gt;print&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;10.0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;RUBY&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;bench&lt;/span&gt;
  &lt;span class="ident"&gt;a&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt;
  &lt;span class="number"&gt;20_000_000&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;a&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;i&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
  &lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;now&lt;/span&gt; &lt;span class="punct"&gt;-&lt;/span&gt; &lt;span class="ident"&gt;t&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="number"&gt;0&lt;/span&gt;
&lt;span class="number"&gt;10&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;times&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;i&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;+=&lt;/span&gt; &lt;span class="ident"&gt;bench&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;/&lt;/span&gt; &lt;span class="number"&gt;10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;LUA&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_lua "&gt;function bench()
  a = 0
  t = os.time()
  for i = 1, 20000000 do
    a = a + i
  end
  return os.time() - t
end
result = 0
for x = 1,10 do
  result = result + bench()
end
print(result/10)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;&lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h3&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&amp;lt;?php
function bench() {
  $a = 0;
  $t =  time();
  for ($i = 0; $i &amp;lt; 20000000; $i++) $a += $i;
  return time() - $t;
}
$result = 0;
for ($x = 1; $x &amp;lt;= 5; $x++) $result += bench();
print $result / 5.0;
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3&gt;Wyniki&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;strong&gt;Ruby 1.9:       2.0953268 s.&lt;/strong&gt;&lt;/li&gt;
		&lt;li&gt;Lua 5.1:        2.4 s.&lt;/li&gt;
		&lt;li&gt;Python 2.5:     2.49481592178 s.&lt;/li&gt;
		&lt;li&gt;Python 2.4.3:   2.71687791348 s.&lt;/li&gt;
		&lt;li&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.2:        4.2 s.&lt;/li&gt;
		&lt;li&gt;Ruby 1.8.5:     9.0153751 s.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Jestem ciekaw kiedy wyjdzie &lt;a href="http://i.loveruby.net/d/20060220.html#p10"&gt;Rails dostosowany do Ruby 1.9&lt;/a&gt;. Zapowiada si&#281; bardzo obiecuj&#261;co!&lt;/p&gt;</description>
      <pubDate>Mon, 01 Jan 2007 19:36:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:195b9e84-80ff-47b9-a2ae-38070f3da6f0</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/01/01/ruby19-yarv</link>
      <category>PHP</category>
      <category>Python</category>
      <category>Ruby</category>
      <category>lua</category>
      <category>python</category>
      <category>ruby</category>
      <category>php</category>
      <category>yarv</category>
      <category>benchmark</category>
    </item>
    <item>
      <title>Django i Rails bij&#261; PHP</title>
      <description>&lt;p&gt;&lt;a href="http://wiki.rubyonrails.com/rails/pages/Framework%20Performance"&gt;Por&#243;wnanie wydajno&#347;ci&lt;/a&gt; trzech framework&#243;w: &lt;a href="http://www.symfony-project.com/" title="PHP5"&gt;Symfony&lt;/a&gt;, &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; i &lt;a href="http://www.djangoproject.com/" title="Python"&gt;Django&lt;/a&gt; pokazuje &#380;e Rails jest znacznie szybszy od pehapowego Symfony, a Django znacznie szybszy od Rails&#243;w. Co ciekawe, &lt;span class="caps"&gt;PHP5&lt;/span&gt; u&#380;ywa&#322; akceleratora.&lt;/p&gt;</description>
      <pubDate>Fri, 14 Jul 2006 17:34:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:fdc523c1-2bf2-44ba-b27e-6bddd69d4adf</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/07/14/django-i-rails-bij%C4%85-php</link>
      <category>Ruby on Rails</category>
      <category>PHP</category>
      <category>Django</category>
      <category>django</category>
      <category>rails</category>
      <category>php</category>
    </item>
    <item>
      <title>Lightpd &amp;amp; FastCGI vs. Apache &amp;amp; mod_php,mod_python...</title>
      <description>Serwer &lt;a href="http://httpd.apache.org/"&gt;Apache&lt;/a&gt; jest bardzo popularnym i solidnym serwerem www. Nie dziwi wi&#281;c powszechne u&#380;ywanie jego modu&#322;ow do obs&#322;ugi Perla, &lt;span class="caps"&gt;PHP&lt;/span&gt; czy Pythona. Uzywanie mod_php jest wr&#281;cz nagminne (ca&#322;y serwis &lt;a href="http://sourceforge.net"&gt;sourceforge.net&lt;/a&gt; stoi na mod_php). Podobnie tw&#243;rcy pythonowego frameworku &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt; 
zalecaj&#261; u&#380;ywanie mod_pythona. W &lt;a href="http://www.djangoproject.com/documentation/install/"&gt;dokumentacji&lt;/a&gt; pisz&#261;, &#380;e: 
	&lt;blockquote&gt;
		&lt;p&gt;&amp;#8220;je&#347;li chcesz u&#380;ywa&#263; Django na serwerze produkcyjnym, uzywaj Apache&amp;#8217;a z mod_pythonem (...) Django wymaga Apache 2.x oraz mod_python 3.x.&amp;#8221;&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Zupe&#322;nie inne podej&#347;cie zalecaj&#261; tw&#243;rcy frameworka &lt;a href="http://rubyonrails.com"&gt;Ruby on Rails&lt;/a&gt;. Nie do&#347;&#263;, &#380;e zalecaj&#261; u&#380;ycie modu&#322;u &lt;a href="http://www.fastcgi.com/"&gt;FastCGI&lt;/a&gt; to na dodatek, zalecaj&#261; (o grozo:) u&#380;ywanie innego serwera www: &lt;a href="http://www.lighttpd.net/"&gt;Ligttpd&lt;/a&gt;. Kt&#243;re podej&#347;cie jest lepsze?&lt;/p&gt;


	&lt;h2&gt;Problem z uniwersalno&#347;ci&#261;&lt;/h2&gt;


	&lt;p&gt;Korzystanie z modu&#322;&#243;w Apache&amp;#8217;a wi&#261;&#380;e nas na dobre i z&#322;e z tym serwerem. korzystanie z fastcgi daje nam wi&#281;ksze pole manewru. Mo&#380;emy korzysta&#263; z Apache, Lighttpd, &lt;span class="caps"&gt;IIS&lt;/span&gt; i innych serwer&#243;w www.&lt;/p&gt;


	&lt;h2&gt;Problem stabilno&#347;ci serwera&lt;/h2&gt;


	&lt;p&gt;Jakikolwiek b&#322;&#261;d w skryptach pracuj&#261;cych  w trybie mod_php czy mod_python odbija si&#281; bardzo niebezpiecznie na stabilno&#347;ci ca&#322;ego serwera. Jeden b&#322;&#281;dnie dzia&#322;aj&#261;cy skrypt mo&#380;e zawiesi&#263; ca&#322;y serwer! Dotyczy to nie tylko Apache, ale tak&#380;e windowsowego &lt;span class="caps"&gt;IIS&lt;/span&gt; i modu&#322;&#243;w &lt;span class="caps"&gt;ISAPI&lt;/span&gt;. Co ciekawe, modu&#322; &lt;span class="caps"&gt;ISAPI&lt;/span&gt; dla j&#281;zyka &lt;span class="caps"&gt;PHP&lt;/span&gt; jest wiecznie w fazie niestabilnej i testowej. Co z tego, &#380;e jest szybszy ni&#380; klasyczny &lt;span class="caps"&gt;CGI&lt;/span&gt;, skoro jeden drobny b&#322;&#261;d w skrypcie &lt;span class="caps"&gt;PHP&lt;/span&gt; potrafi zawiesi&#263; ca&#322;y serwer i unieruchomi&#263; ca&#322;a sie&#263; intranetow&#261; na nim opart&#261;? To jeden z powod&#243;w dla kt&#243;rych &lt;span class="caps"&gt;PHP&lt;/span&gt; nie nadaje si&#281; najlepiej do pracy pod Windowsami (wiem, &#380;e istnieje Apache/win32 ale z r&#243;&#380;nych powod&#243;w, kt&#243;rych tu nie b&#281;d&#281; rozwija&#322;,  korporacyjne sieci intranetowe oparte na Windows Server wol&#261; u&#380;ywa&#263; &lt;span class="caps"&gt;IIS&lt;/span&gt;)&lt;/p&gt;


	&lt;p&gt;Procesy FastCGI s&#261; &lt;strong&gt;izolowane&lt;/strong&gt; od serwera. Jak kt&#243;ry&#347; si&#281; zawiesi, to serwerowi nic si&#281; nie stanie. Proces mo&#380;na ubi&#263;, zrestartowac. Daje to znacznie wi&#281;ksz&#261; stabilno&#347;&#263; pracy serwera.&lt;/p&gt;


	&lt;h2&gt;Problem bezpiecze&#324;stwa&lt;/h2&gt;


	&lt;p&gt;Ka&#380;dy skrypt odpalany w trybie mod_php na Apache&amp;#8217;u jest odpalany w kontek&#347;cie &lt;strong&gt;tego samego uzytkownika&lt;/strong&gt;. Tworzy to dosy&#263; powa&#380;n&#261; dziur&#281; bezpiecze&#324;stwa na serwerach hostingowych. Ka&#380;dy u&#380;ytkownik na serwerze za pomoc&#261; prostego kodu &lt;span class="caps"&gt;PHP&lt;/span&gt; mo&#380;e przegl&#261;da&#263; &lt;strong&gt;&#378;r&#243;d&#322;a&lt;/strong&gt; dowolnego pliku  innych u&#380;ytkownik&#243;w. Wszyscy maj&#261; dost&#281;p  do wszystkich! Napisa&#322;em nawet swego czasu prosty skrypt wedruj&#261;cy po ca&#322;ym sourceforge.net i przegl&#261;daj&#261;cy &#378;r&#243;d&#322;a wszystkich dost&#281;pnych tam projekt&#243;w. :) Ka&#380;dy, &#347;rednio zaawansowany programista z &#322;atwo&#347;ci&#261; napisze sobie taki kod. Nie ma znaczenia, czy to b&#281;dzie Perl (mod_perl), Python (mod_python) czy &lt;span class="caps"&gt;PHP&lt;/span&gt; (mod_php).&lt;/p&gt;


	&lt;p&gt;W FastCGI tego problemu nie ma. Ka&#380;dy u&#380;ytkownik mo&#380;e pracowa&#263; na swoich prawach w pe&#322;nej izolacji. Wystarczy ka&#380;demu przydzieli&#263; po procesie FastCGI na prawach danego u&#380;ytkownika.&lt;/p&gt;


	&lt;h2&gt;Marnowanie mo&#380;liwo&#347;ci Apache&amp;#8217;a 2.x&lt;/h2&gt;


	&lt;p&gt;To mo&#380;e nie jest najwa&#380;niejszy problem. Apache 2.x potrafi pracowa&#263; w trybie wielow&#261;tkowym (worker) lub wieloprocesowym (prefork) kt&#243;ry jest zgodny ze starym Apache 1.x . Ten pierwszy jest nowocze&#347;niejszy, szybszy i po&#380;era mniej pami&#281;ci. Problem jednak w tym, &#380;e najbardziej popularny j&#281;zyk skryptowy nie posiada poprawnie zaimplementowanej wielow&#261;tkowo&#347;ci. Je&#347;li wi&#281;c chcesz u&#380;ywa&#263; &lt;span class="caps"&gt;PHP&lt;/span&gt;, to zapomnij o trybie workera. Musisz pracowa&#263; w starym trybie prefork. Zajmuje to wi&#281;cej pami&#281;ci, ale za to nie b&#281;dzie problem&#243;w z r&#243;&#380;nymi bibliotekami &lt;span class="caps"&gt;PHP&lt;/span&gt;.&lt;/p&gt;


	&lt;h2&gt;Problem zasobo&#380;erno&#347;ci&lt;/h2&gt;


	&lt;p&gt;Gdy uruchamiamy Apache 1.x lub Apache 2.x w trybie prefork, uruchamiamy szereg podproces&#243;w. Ka&#380;dy z nich zajmuje okre&#347;lon&#261; ilo&#347;&#263; pami&#281;ci. Ka&#380;dy z zainstalowanych modu&#322;&#243;w&amp;#8230; r&#243;wnie&#380;. A to przecie&#380; nie ma sensu! W praktyce nie chcemy wykorzystywa&#263; wszystkich proces&#243;w do przetwarzania mod_pythona. Wi&#281;kszo&#347;&#263; proces&#243;w jest zaj&#281;ta podawaniem statycznej warto&#347;ci (obrazki, pliki ze stylami kaskadowymi, skryptami JavaScript itp).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;FastCGI pozwala na ograniczenie ustalenie ilo&#347;ci swoich proces&#243;w&lt;/strong&gt; w spos&#243;b niezale&#380;ny od wszystkich proces&#243;w serwera www. Np. mo&#380;emy sobie zadecydowa&#263;, aby 100 proces&#243;w zajmowa&#322;o si&#281; warto&#347;ci&#261; statyczn&#261;, a tylko 10 warto&#347;ci&#261; dynamiczn&#261;. Takie co&#347; jest niemo&#380;liwe wypadku korzystania z mod_php czy mod_pythona. A oszcz&#281;dno&#347;ci na zu&#380;yciu pami&#281;ci b&#281;d&#261; kolosalne!&lt;/p&gt;


	&lt;p&gt;Np. mo&#380;na za&#322;ozy&#263;, &#380;e pojedy&#324;czy proces Apache podczas serwowania statycznych stron zajmie nie wi&#281;cej ni&#380; ok 5 MB pami&#281;ci. Natomiast w wypadku u&#380;ycia mod_ruby mo&#380;e wzrosn&#261;&#263; nawet do ok. 20-30MB na proces. U&#380;ycie zatem 100 proces&#243;w Apache&amp;#8217;a z tylko 10 procesami FastCGI zu&#380;yje ok. 800MB pami&#281;ci. Za&#347; u&#380;ycie mod_ruby bez problemu po&#380;re nawet i 3GB!&lt;/p&gt;


	&lt;h2&gt;Dlaczego Lighttpd a nie Apache?&lt;/h2&gt;


	&lt;p&gt;Na ko&#324;cu chcia&#322;bym jeszcze zastanowi&#263; si&#281; czy tw&#243;rcy Rails&#243;w nie maj&#261; racji i czy w og&#243;le nie warto zrezygnowa&#263; z Apache na rzecz Lighttpd? S&#261; generalnie 3 powody za i jeden przeciw.&lt;/p&gt;


	&lt;h3&gt;Za: lepiej dopracowany modu&#322; FastCGI&lt;/h3&gt;


	&lt;p&gt;Modu&#322; FastCGI do Apache&amp;#8217;a ma opini&#281; nie do ko&#324;ca stabilnego i dopracowanego. To powoduje obaw&#281; wi&#281;kszo&#347;ci u&#380;ytkownik&#243;w od u&#380;ywania go dla serwera Apache. Z kolei serwer Lighttpd od samego pocz&#261;tku k&#322;ad&#322; nacisk na dobr&#261; implementacj&#281; swego modu&#322;u FastCGI. Jest on stabilniejszy i lepiej dopracowany ni&#380; pod Apachem.&lt;/p&gt;


	&lt;h3&gt;Za: Wbudowana mo&#380;liwo&#347;&#263; rozk&#322;adania obci&#261;&#380;enia&lt;/h3&gt;


	&lt;p&gt;Lighttpd ma wbudowany mechanizm rozk&#322;adania ruchu na wiele serwer&#243;w. Je&#347;li wi&#281;c nawet kto&#347; upiera si&#281; przy Apache&amp;#8217;u, to w wypadku kiedy jeden serwer nie jest wystarczaj&#261;cy do obs&#322;ugi ruchu, mo&#380;e warto rozwa&#380;y&#263; aby postawi&#263; na froncie jeden serwer Lighttpd kt&#243;ry by rozk&#322;ada&#322; ruch pomi&#281;dzy kilka serwer&#243;w?&lt;/p&gt;


	&lt;p&gt;(Najnowszy  Apache 2.2 ma posiada&#263; podobny mechanizm. Jednak jest to jeszcze bardzo &#347;wie&#380;a wersja, kt&#243;ra (w momencie pisania tego tekstu) nie ma nawet prekompilowanej instalacji dost&#281;pnej dla Windows&#243;w oraz nie wiadomo jak jest ze stabilno&#347;ci&#261; wszystkich modu&#322;&#243;w.)&lt;/p&gt;


	&lt;h3&gt;Za: Lighttpd jest szybszy&lt;/h3&gt;


	&lt;p&gt;O ile najnowszy Apache 2.2 nie zmieni sytuacji, to wszystko wskazuje na to, ze Lighttpd &lt;a href="http://www.lighttpd.net/benchmark/"&gt;jest po prostu szybszy&lt;/a&gt;. Nie tylko zdecydowanie szybciej podaje statyczne dane ale tak&#380;e szybciej dzia&#322;a &lt;span class="caps"&gt;PHP&lt;/span&gt; pod Lighttpd ni&#380; mod_php pod Apachem. To nie s&#261; drobne r&#243;&#380;nice. To s&#261; r&#243;&#380;nice rz&#281;du 2-3 razy!&lt;/p&gt;


	&lt;h3&gt;Przeciw: Apache ma wi&#281;cej modu&#322;&#243;w&lt;/h3&gt;


	&lt;p&gt;W&#322;a&#347;ciwie jedynym powodem aby u&#380;ywa&#263; Apache zamiast Lighttpd jest to, &#380;e do Apache napisano znacznie wi&#281;cej r&#243;&#380;nych modu&#322;&#243;w. Ale szczerze m&#243;wi&#261;c, w praktyce to rzadko ma znaczenie. Wi&#281;kszo&#347;&#263; os&#243;b uzywa g&#322;&#243;wnie kilku modu&#322;&#243;w. Za&#347; Lighttpd posiada praktycznie wszystko, co potrzeba: mod_fastcgi, mod_cgi, mod_redirect, mod_access, mod_auth, mod_compress, mod_webdav, mod_ssl, mod_alias, mod_proxy, mod_rewrite, itp. itd.&lt;/p&gt;


	&lt;h2&gt;Lighttpd + FastCGI. To dzia&#322;a!&lt;/h2&gt;


	&lt;p&gt;Na szcz&#281;&#347;cie, dzi&#281;ki standardowi &lt;a href="http://www.python.org/dev/peps/pep-0333/"&gt;&lt;span class="caps"&gt;WSGI&lt;/span&gt;&lt;/a&gt;, u&#380;ytkownicy Pythona nie musz&#261; s&#322;ucha&#263; zalece&#324; developer&#243;w Django. Teraz praktycznie wszystkie frameworki Pythona pozwalaj&#261; dzi&#281;ki &lt;span class="caps"&gt;WSGI&lt;/span&gt; korzysta&#263; z dobrodziejstw FastCGI. Ja r&#243;wnie&#380; na swoim serwerze wyrzuci&#322;em Apache&amp;#8217;a i zastapi&#322;em go Lighttpd. Podaje zar&#243;wno strony statyczne jak i obs&#322;uguje ten blog, a nawet &lt;a href="http://apologetyka.com/biblia"&gt;&lt;span class="caps"&gt;PHP 5&lt;/span&gt;.1&lt;/a&gt;. Nawet &lt;a href="http://plone.org"&gt;Plone&lt;/a&gt; mi uda&#322;o mi si&#281; uruchomi&#263; z Lighttpd &lt;a href="http://creationism.org.pl"&gt;na przodzie&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 24 Apr 2006 19:40:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:9c3499f2-8be7-48b5-bf23-432e30cabb37</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/04/24/lightpd-fastcgi-vs-apache-mod_php-mod_python</link>
      <category>PHP</category>
      <category>Python</category>
      <category>Django</category>
      <category>apache</category>
      <category>lighttpd</category>
      <category>fastcgi</category>
      <category>mod_python</category>
    </item>
    <item>
      <title>Edytory dla Pythona, Ruby, PHP</title>
      <description>&lt;p&gt;Osoby zaczynaj&#261;ce prac&#281; z j&#281;zykiem Python, Ruby czy &lt;span class="caps"&gt;PHP&lt;/span&gt; cz&#281;sto pytaj&#261; si&#281; na grupach dyskusyjnych na temat edytor&#243;w zalecanych do pracy. Istniej&#261; dwie szko&#322;y, ci kt&#243;rym zale&#380;y na minimalnych wymaganiach pami&#281;ci i procesora oraz ci, kt&#243;rzy chcieliby aby edytor nie tylko kolorowa&#322; sk&#322;adni&#281;, ale tak&#380;e podpowiada&#322; kod, uzupe&#322;nia&#322; sk&#322;adni&#281;, mia&#322; wbudowany debugger itp.&lt;/p&gt;


	&lt;h3&gt;Edytory tekstowe (nie &lt;span class="caps"&gt;IDE&lt;/span&gt;):&lt;/h3&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.scintilla.org/SciTE.html"&gt;SciTE&lt;/a&gt;  &amp;#8211; &#322;atwy w obs&#322;udze, kolorowanie b. wielu j&#281;zyk&#243;w&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; &amp;#8211; powszechny na ka&#380;dym linuksie, jest wersja dla win32. B. szybki, doskona&#322;y do obs&#322;ugi wielkich plik&#243;w, niezbyt intuicyjna obs&#322;uga, np. kto by wpad&#322; na pomys&#322; aby wyj&#347;&#263; z edytora za pomoc&#261; kombinacji: Esc + :q! (klawisz Escape, potem znak cudzys&#322;owa, ma&#322;e q i znak wykrzyknika)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;
&lt;a href="http://notepad-plus.sourceforge.net/uk/site.htm"&gt;Notepad++&lt;/a&gt; &amp;#8211; prosta, intuicyjna obs&#322;uga, po instalacji podmienia dla Internet Explorera idiotycznego Notatnika do podgl&#261;du &#378;r&#243;de&#322; stron html, warto instalowa&#263; cho&#263;by dla tej jednej cechy i wymiany starego Notatnika.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://community.jedit.org/"&gt;JEdit&lt;/a&gt; &amp;#8211; napisany w Javie, mn&#243;stwo plugin&#243;w&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.xemacs.org/"&gt;XEmacs&lt;/a&gt; &amp;#8211; kompletnie nieintuicyjna obs&#322;uga, ten edytor zupe&#322;nie w niczym nie przypomina skr&#243;t&#243;w klawiszy z innych program&#243;w, ale jest b. pot&#281;&#380;ny. Jak kto&#347; ju&#380; si&#281; przekatuje i go nauczy, to podobno jest to doskona&#322;e narz&#281;dzie. Mnie nigdy nie starczy&#322;o cierpliwo&#347;ci aby go opanowa&#263;. Wol&#281; ju&#380; edytor Vi.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Edytory &lt;span class="caps"&gt;IDE&lt;/span&gt; &amp;#8211; Python&lt;/h3&gt;


	&lt;p&gt;U&#380;ytkownikom win32 polecam instalacj&#281; &lt;a href="http://activestate.org/Products/Download/Download.plex?id=ActivePython"&gt;ActivePython&lt;/a&gt;  zamiast instalacji na &lt;a href="http://python.org"&gt;stronie g&#322;&#243;wej Pythona&lt;/a&gt;. Do Pythona istnieje mn&#243;stwo niez&#322;ych &lt;a href="http://wiki.python.org/moin/PythonEditors"&gt;edytor&#243;w tekstowych&lt;/a&gt; jak i &lt;a href="http://wiki.python.org/moin/IntegratedDevelopmentEnvironments"&gt;edytor&#243;w &lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/a&gt;. Moimi ulubionymi s&#261;:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; + &lt;a href="http://pydev.sourceforge.net/"&gt;pyDEV&lt;/a&gt; &amp;#8211; chyba najlepsza opcja. Edytor Eclipse jest napisany w Javie i wymaga troch&#281; pami&#281;ci, ale jest b. dobry. Posiada intuicyjny interfejs, mn&#243;stwo plugin&#243;w daj&#261;cych sp&#243;jne &#347;rodowisko do pracy z jav&#261;, pythonem, ruby i php. pyDEV z zintegrowanym pakietem &lt;a href="http://www.logilab.org/projects/pylint"&gt;pyLint&lt;/a&gt; nie tylko podpowiada kod, ale tak&#380;e ma mo&#380;liwo&#347;&#263; wy&#322;apania nieu&#380;ytej zmiennej, czy brak zgodno&#347;ci stylu programowania z zaleceniem &lt;a href="http://python.org/peps/pep-0008.html"&gt;&lt;span class="caps"&gt;PEP8&lt;/span&gt;&lt;/a&gt; itp. Oczywi&#347;cie jest te&#380; zintegrowany debugger.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://activestate.org/Products/Download/Download.plex?id=ActivePython"&gt;PythonWin&lt;/a&gt;  &amp;#8211; standardowo instalowany w ActivePython. Jest znacznie szybszy i l&#380;ejszy od Eclipse, bo jest napisany w j&#281;zyku C. Ma &#347;wietny debugger, wbudowan&#261; konsol&#281;, podgl&#261;d obiekt&#243;w &lt;span class="caps"&gt;COM&lt;/span&gt;. Jedyn&#261; jego wad&#261; jest brak obs&#322;ugi utf-8. Zalet&#261; jest te&#380; to, &#380;e nadaje si&#281; do szybkiej edycji pojedy&#324;czych plik&#243;w (Eclipse wymaga tworzenia projektu, co cz&#281;sto jest b. niewygodne). PythonWin ma tak&#380;e ulepszon&#261; konsol&#281;, bo pe&#322;noekranow&#261;. &#321;atwiej w nim szybko zaznaczy&#263; fragment poprzedniej komendy i uzupe&#322;ni&#263;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://pythonide.stani.be/"&gt;&lt;span class="caps"&gt;SPE&lt;/span&gt;&lt;/a&gt; &amp;#8211; edytor napisany w Pythonie z wykorzystaniem biblioteki wxPython. Ma unikalne, b. &#322;adne kolorowe zak&#322;adki (umo&#380;liwia lepsze wy&#347;wietlanie podgl&#261;du metod i atrybut&#243;w klas). Wbudowany debugger, list&#281; Todo, wyszukiwanie po wielu plikach i co wa&#380;niejsze: lepiej podpowiada kod ni&#380; np. PythonWin.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.die-offenbachs.de/eric/index.html"&gt;Eric&lt;/a&gt; &amp;#8211; napisany w Pythonie z u&#380;yciem biblioteki &lt;a href="http://wiki.python.org/moin/PyQt"&gt;PyQT&lt;/a&gt;. Ma du&#380;o mo&#380;liwo&#347;ci, wspomaganie tworzenia unittest&#243;w, refactoring, debugger itp. Obs&#322;uguje nie tylko Pythona ale i Rubiego.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://boa-constructor.sourceforge.net/"&gt;Boa Constructor&lt;/a&gt; &amp;#8211; ten edytor mo&#380;e zainteresowa&#263; osoby pisz&#261;ce aplikacje oparte na &lt;a href="http://www.wxpython.org/"&gt;wxPython&lt;/a&gt; bo posiada wbudowane wizualne wspomaganie tego procesu. Wzorowany jest na Delphi.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;Komodo: Kombajn podobnie jak Eclipse. Wyst&#281;puje w wersji &lt;a href="http://www.activestate.com/products/komodo_ide/"&gt;&lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/a&gt; (p&#322;atnej, ale licencja od razu obejmuje Windows, Linux i Mac &lt;span class="caps"&gt;OS X&lt;/span&gt;) i &lt;a href="http://www.activestate.com/products/komodo_edit/"&gt;Edit&lt;/a&gt; (bezp&#322;atnej). Ma &#347;wietny debuger do Pythona. Jest szybszy od Eclipse i obs&#322;uguje dobrze Pythona, Rubiego, &lt;span class="caps"&gt;PHP&lt;/span&gt;, C++ i inne j&#281;zyki (nawet szablony Django). Bardzo dobrze podpowiada kod &lt;span class="caps"&gt;HTML&lt;/span&gt;, CSS, zamyka tagi &lt;span class="caps"&gt;HTML&lt;/span&gt; podobnie jak Dreamweaver. Niestety, podpowiadanie kodu pozbawione jest na razie wy&#347;wietlania zintegrowanej dokumentacji (docstring&#243;w dla Pythona czy rdoc dla Rubiego, wy&#347;wietlana jest tylko lista metod).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://wingware.com/wingide"&gt;WingIDE&lt;/a&gt; &amp;#8211; wymieniam go na ko&#324;cu bo jest p&#322;atny. Doskonale (zdecydownie najlepiej z wszystkich) podpowiada kod, posiada mo&#380;liwo&#347;&#263; edycji w &lt;a href="http://zope.org"&gt;Zope&lt;/a&gt;, doskona&#322;y debugger.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Edytory &lt;span class="caps"&gt;IDE&lt;/span&gt; &amp;#8211; Ruby&lt;/h3&gt;


	&lt;p&gt;Do Rubiego istnieje te&#380; &lt;a href="http://wiki.rubyonrails.pl/rails/show/faq-ide"&gt;sporo niez&#322;ych edytor&#243;w&lt;/a&gt;, cho&#263; nie a&#380; tyle co do Pythona.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://deadlock.nbextras.org/hudson/job/ruby/"&gt;Netbeans &lt;span class="caps"&gt;IDE 6&lt;/span&gt;.x&lt;/a&gt; ma zdecydowanie najlepsze podpowiadanie sk&#322;adni do Rubiego. Najlepszy &lt;span class="caps"&gt;IDE&lt;/span&gt; do Rubiego i Rails obok Aptana &lt;span class="caps"&gt;IDE&lt;/span&gt;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://aptana.org/"&gt;Aptana &lt;span class="caps"&gt;IDE&lt;/span&gt;+Rails&lt;/a&gt; (RadRails zosta&#322; przej&#281;ty) to  nic innego jak Eclipse dostosowany do pracy z Ruby on Rails. Posiada wszystkie zalety Eclipse, np. po dodaniu plugin&#243;w ma dobre wsparcie dla innych j&#281;zyk&#243;w, np. Pythona. Od chwili wch&#322;oni&#281;cia RadRails przez Aptan&#281;, posiada &#347;wietne dodatkowe mocne wsparcie dla kodu &lt;span class="caps"&gt;HTML&lt;/span&gt;, CSS, JavaScript.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.ruby-ide.com/ruby/ruby_ide_and_ruby_editor.php"&gt;Arachno &lt;span class="caps"&gt;IDE&lt;/span&gt;&lt;/a&gt; &amp;#8211; bardzo &#322;adny i szybki. Mo&#380;e kolorowa&#263; kod (nie tylko samego &lt;a href="http://ruby-lang.org"&gt;Rubiego&lt;/a&gt; ale tak&#380;e szablon&#243;w ERb, czyli nadaje si&#281; dobrze do &lt;a href="http://rubyonrails.com"&gt;Rails&#243;w&lt;/a&gt;) podobnie jak &lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt;, ma wbudowany debugger, generowanie dokumentacji RDoc dla projektu, przegl&#261;darka klas Rubiego i zainstalowanych gems&#243;w. Niestety jest p&#322;atny i bie&#380;&#261;ca wersja nie obs&#322;uguje jeszcze utf-8.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt; &amp;#8211; dzia&#322;a tylko z systemem OS-X, czyli wymaga Macintosha. Ale jest to ulubiony edytor developer&#243;w Rails&#243;w. Sam edytor jest niestety p&#322;atny. Ma bardzo rozbudowane makra (snipety) przy&#347;pieszaj&#261;ce wprowadzanie kodu, ale ma beznadziejnie s&#322;abe podpowiadanie kodu, nie rozwija metod do bibliotek wbudowanych Rubiego, dokumentacji &lt;span class="caps"&gt;RDOC&lt;/span&gt; w og&#243;le nie ma scalonej z podpowiedziami do kodu. Do Pythona jest jeszcze gorzej. Ale edytor jest szybki, lekki i ma &#322;adne kolorowanie wielu j&#281;zyk&#243;w.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://homepage2.nifty.com/sakazuki/rde_e.html"&gt;&lt;span class="caps"&gt;RDE&lt;/span&gt;&lt;/a&gt; czyli Ruby Development Environmnent. Edytor jest b. szybki i pomocny jak kto&#347; chce pisa&#263; kod w czystym Ruby.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;Edytory &lt;span class="caps"&gt;IDE&lt;/span&gt; &amp;#8211; &lt;span class="caps"&gt;PHP&lt;/span&gt;&lt;/h3&gt;


	&lt;p&gt;Do &lt;span class="caps"&gt;PHP&lt;/span&gt; istnieje sporo edytor&#243;w, ale moim zdaniem wi&#281;kszo&#347;&#263; to badziewie. Sam &lt;span class="caps"&gt;PHP&lt;/span&gt; jest j&#281;zykiem kt&#243;ry bardzo utrudnia napisanie na niego dobrego debuggera. W&#322;a&#347;ciwie w nic dobrego tu nie ma poza komercyjnym Zendem. Ale gdybym mia&#322; wybiera&#263;, to wybra&#322;bym:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.eclipse.org/"&gt;Eclipse&lt;/a&gt; + plugin &lt;a href="http://www.phpeclipse.de/tiki-view_articles.php"&gt;phpeclipse&lt;/a&gt; &amp;#8211; po pierwsze jest darmowy, po drugie doskonale zarz&#261;dza kodem &lt;span class="caps"&gt;PHP&lt;/span&gt; i koloruje szablony Smarty. Po trzecie, doskonale wsp&#243;&#322;pracuje z &lt;span class="caps"&gt;SVN&lt;/span&gt;. Mia&#322;em okazj&#281; sprawdzi&#263; nowy Zend Studio 5.1. Mimo, &#380;e lepiej podpowiada kod, to nie koloruje Smart&#243;w i kiepsko wsp&#243;&#322;pracuje z &lt;a href="http://www.subversion.tigris.org/"&gt;&lt;span class="caps"&gt;SVN&lt;/span&gt;&lt;/a&gt;, beznadziejnie wr&#281;cz.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.zend.com/products/zend_studio"&gt;Zend Studio&lt;/a&gt; &amp;#8211; komercyjny &lt;span class="caps"&gt;IDE&lt;/span&gt; stworzony przez tw&#243;rc&#243;w &lt;span class="caps"&gt;PHP&lt;/span&gt;. Najlepiej ze wszystkich podpowiada kod (lepiej od Eclipse) Niestety nie potrafi kolorowa&#263; kodu popularnych szablon&#243;w &lt;a href="http://smarty.php.net"&gt;Smarty&lt;/a&gt; (Eclipse to potrafi!) Szybko&#347;&#263; ta sama co Eclipse, wymagania co do pami&#281;ci &amp;#8211; te&#380;.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://macromedia.com/software/dreamweaver/"&gt;Macromedia Dreamwever 8&lt;/a&gt; &amp;#8211; komercyjny, ale nie&#378;le koloruje i podpowiada kod. Najnowsza wersja Dreamweawera ma sporo usprawnie&#324;, np. w ko&#324;cu bada ko&#324;ce blok&#243;w (klamr). Dreamweawer jest te&#380; oczyw&#347;cie szybszy od Zend Studio i Eclipse bo jest napisany w j&#281;zyku C.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Niestety edytory &lt;span class="caps"&gt;PHP&lt;/span&gt; maj&#261; fatalne mo&#380;liwo&#347;ci debugowania kodu w stosunku do tego, co mo&#380;na spotka&#263; dla Pythona i Ruby. Do szybkiego testowania kodu &lt;span class="caps"&gt;PHP&lt;/span&gt;, najlepiej u&#380;y&#263; &lt;a href="http://www.scintilla.org/SciTE.html"&gt;SciTE&lt;/a&gt;. Mo&#380;na mu ustawi&#263; opcj&#281; aby po wci&#347;ni&#281;ciu klawisza F5 natychmiast generowa&#322; wynik bez &#380;adnego po&#347;rednictwa serwera www.&lt;/p&gt;</description>
      <pubDate>Sun, 12 Feb 2006 00:17:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:626b627c-18ca-4f23-9e82-ca9a73379dce</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/02/12/edytory-dla-pythona-ruby-php</link>
      <category>Ruby on Rails</category>
      <category>PHP</category>
      <category>Python</category>
      <category>Ruby</category>
      <category>edytory</category>
      <category>php</category>
      <category>python</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Symfony - kolejny na&#347;ladowca RoR</title>
      <description>&lt;p&gt;Pojawia si&#281; coraz wi&#281;cej na&#347;ladowc&#243;w drogi jak&#261; pod&#261;&#380;aj&#261; frameworki &lt;a href="http://rubyonrails.com"&gt;Ruby on Rails&lt;/a&gt; i &lt;a href="http://djangoproject.com"&gt;Django&lt;/a&gt;. Bardzo ciekawie wygl&#261;da pehapowy framework &lt;a href="http://www.symfony-project.com/"&gt;Symfony&lt;/a&gt;. Polecam przyjrze&#263; si&#281; udost&#281;pnionemu na stronie g&#322;&#243;wnej &lt;a href="http://downloads.symfony-project.com/demo/cart/cart.mov"&gt;filmowi&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Tue, 10 Jan 2006 07:30:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:c3baa782-4f51-4b91-8ea2-f66c71402eca</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2006/01/10/symfony-kolejny-na%C5%9Bladowca-ror</link>
      <category>PHP</category>
      <category>php</category>
      <category>rails</category>
    </item>
    <item>
      <title>Brakuj&#261;ca metoda GetMany dla ADOdb</title>
      <description>Jedn&#261; z najlepszych bibliotek opakowuj&#261;cych po&#322;&#261;czenia do baz relacyjnych dla PHP jest "ADOdb":http://adodb.sf.net. Pomijaj&#261;c wiele zalet u&#380;ywania ADOdb (zintegrowany cache, modu&#322; w C, czytelne API) zamiast PEAR::DB lub natywnych (i koszmarnych sk&#322;adniowo) funkcji PHP chcia&#322;bym zatrzyma&#263; si&#281; nad jedn&#261; niedor&#243;bka. Ot&#243;&#380; od dawna brakuje tam Funkcji GetMany() kt&#243;ra by&#322;aby odpowiedzialna za pobieranie porcji danych z bazy. 

Jest co prawda funkcja SelectLimit() ale jest jest beznadziejna gdy&#380; nie umo&#380;liwia korzystania z parametryzowanych zapyta&#324; SQL. Poza tym ma fataln&#261;, nieintuicyjn&#261; nazw&#281;. Skoro jest GetOne(), GetAll(), GetRow() to dlaczego jej te&#380; nie nazwali GetMany()?

Postanowi&#322;em te braki uzupe&#322;ni&#263;. Poni&#380;ej przyk&#322;ad implementacji opartej na ADOdb:

&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_php "&gt;&lt;notextile&gt;&amp;lt;?php
require_once 'adodb/adodb.inc.php';
require_once 'adodb/adodb-errorhandler.inc.php';

class Database
{
    var $conn;
    
    function Database($cfg)
    {
        $this-&amp;gt;conn =&amp;amp; NewADOConnection($cfg['dbtype']);
        $this-&amp;gt;conn-&amp;gt;Connect(
            $cfg['host'], 
            $cfg['user'], 
            $cfg['passwd'], 
            $cfg['db']);
         $this-&amp;gt;conn-&amp;gt;SetFetchMode(ADODB_FETCH_ASSOC);
    }
    
    function GetAll($sql, $params=null)
    {
        return $this-&amp;gt;conn-&amp;gt;GetAll($sql, $params);
    }
       
    function GetRow($sql, $params=null)
    {
        return $this-&amp;gt;conn-&amp;gt;GetRow($sql, $params);
    }   
    
    function GetOne($sql, $params=null)
    {
        return $this-&amp;gt;conn-&amp;gt;GetOne($sql, $params);
    }   
    
    function GetMany($sql, $params=null, $from, $limit)
    {
        $result = array();
        $recordSet = $this-&amp;gt;conn-&amp;gt;Execute($sql, $params);
        while (!$recordSet-&amp;gt;EOF) {
            if ($from &amp;gt; 0) {
                $from -= 1;
                $recordSet-&amp;gt;MoveNext();
            } elseif ($limit &amp;gt; 0) {
                $limit -= 1;
                $result[] = $recordSet-&amp;gt;fields;
                $recordSet-&amp;gt;MoveNext();
            } else {
                $recordSet-&amp;gt;MoveNext();
            }
        }
        return $result;
    }   
}

$cfg = array(
    'dbtype' =&amp;gt; 'mysql',
    'host' =&amp;gt; 'localhost',
    'user' =&amp;gt; 'root',
    'passwd' =&amp;gt; '',
    'db' =&amp;gt; 'baza',
    );

# przyk&#322;ad:

$db = new Database($cfg);
var_dump($db-&amp;gt;GetMany(&amp;quot;SELECT * FROM tabelka&amp;quot;, null, 0, 10));
?&amp;gt;&lt;/notextile&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;


</description>
      <pubDate>Tue, 15 Nov 2005 12:01:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:089055b1-812c-4d71-a471-6004811609b3</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2005/11/15/brakuj%C4%85ca-metoda-getmany-dla-adodb</link>
      <category>PHP</category>
      <category>php</category>
    </item>
  </channel>
</rss>
