<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>printf(&#34; SaltwaterC &#34;); &#187; PHP</title>
	<atom:link href="http://www.saltwaterc.net/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.saltwaterc.net</link>
	<description>Developer blog</description>
	<lastBuildDate>Mon, 09 Aug 2010 15:47:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Căi UNIX corecte în PHP</title>
		<link>http://www.saltwaterc.net/programare/cai-unix-corecte-in-php.html</link>
		<comments>http://www.saltwaterc.net/programare/cai-unix-corecte-in-php.html#comments</comments>
		<pubDate>Thu, 03 Jun 2010 11:50:11 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[Administrare]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>

		<guid isPermaLink="false">http://www.saltwaterc.net/?p=810</guid>
		<description><![CDATA[Se dă următoarea problemă, aparent mai simplă decât zice titlul: să se determine dacă o cale de tip UNIX este corectă. Buba este faptul că această cale poate să fie către un fișier ce nu există, spre exemplu o cale de UNIX socket ce va fi creat într-un director ce va conține un pool de [...]]]></description>
			<content:encoded><![CDATA[<p>Se dă următoarea problemă, aparent mai simplă decât zice titlul: să se determine dacă o cale de tip UNIX este corectă. Buba este faptul că această cale poate să fie către un fișier ce nu există, spre exemplu o cale de UNIX socket ce va fi creat într-un director ce va conține un pool de socket-uri. Deci funcțiile la nivel de filesystem nu vor ajuta, cel puțin nu în primă fază. În cazul  în care există vreo încercare de intuiție a scopului, da, scriu server scripting și în PHP. *sh este prea limitat pentru anumite chestii mai avansate, sau are nevoie de prea mult &#8220;boilerplate code&#8221;, pe când în Perl nu sunt încă fluent. Pentru cei ce au pierdut știrile de la ora 5, PHP nu mai este de mult un limbaj strict &#8220;web oriented&#8221;, funcționează bine merci și pentru &#8220;general purpose&#8221;.</p>
<p>Să revin la problema inițială. Practic se pot identifica două probleme: a) validarea unei căi inexistente &#8211; deci apelăm la regex; b) validarea directorului &#8211; deși fișierul poate să nu existe în timpul execuției de validare, directorul e musai să fie acolo. De regulă aplicațiile care creează câte un UNIX socket nu verifică aceasta și vor eșua să pornească.</p>
<p>Rezumat, codul arată cam așa:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$validate</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/^(\/[^\0]*?\/?)[^\0\/]+$/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$path</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</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: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$validate</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> <span style="color: #009900; font-weight: bold;">TRUE</span> OR <span style="color: #990000;">is_dir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">TRUE</span> OR <span style="color: #990000;">is_dir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!==</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// handle error here</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Acum, discuție pe marginea textului. Acest regex satisface direct ambele probleme. Prima, este fix problema de validare. Se ține cont doar de căi absolute &#8211; acesta fiind contextul în care operez. Cu toate acestea, soluția se poate adapta ușor pentru căi relative.</p>
<p>Singurul capturing group din expresie preia întreaga cale, mai puțin numele fișierului. A fost făcută să funcționeze inclusiv pentru root (/). Calea capturată trebuie să fie către un director, pe când calea întreagă trebuie să nu fie un director.</p>
<p>Teoria căilor este simplă. O cale UNIX poate să conțină orice caracter, mai puțin nul, iar / este folosit pe post de separator de directoare, deci este rezervat acestui scop. Căile de tip //var///www//// sunt valide. Exemplul anterior va duce în //var/www unde // în general (Linux, BSD) este tot una cu /. Nu am lucrat pe sisteme unde // să fie distinct față de /, deci nu am considerat că este nevoie să tratez cazul prin expresia de mai sus.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/cai-unix-corecte-in-php.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I can has Makavelis numbers</title>
		<link>http://www.saltwaterc.net/programare/i-can-has-makavelis-numbers.html</link>
		<comments>http://www.saltwaterc.net/programare/i-can-has-makavelis-numbers.html#comments</comments>
		<pubDate>Wed, 12 May 2010 22:00:42 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>

		<guid isPermaLink="false">http://www.saltwaterc.net/?p=771</guid>
		<description><![CDATA[S-a găsit Google Reader să mă scoată cu nasul din shell cu următoarea problemă, dată pe undeva pe aici. Practic rezolvarea problemei: AB + CD + AC + BD = 100 Ca orice &#8220;nerd&#8221; ce se respectă, am pus mâna pe Eclipse pentru a rezolva problema, nu pe o foaie de hârtie, din moment ce [...]]]></description>
			<content:encoded><![CDATA[<p>S-a găsit Google Reader să mă scoată cu nasul din shell cu următoarea problemă, <a title="Uitati cum sta treaba" href="http://makavelis.com/2010/05/uitati-cum-sta-treaba.html" target="_blank">dată pe undeva pe aici</a>. Practic rezolvarea problemei:</p>
<p>AB + CD + AC + BD = 100</p>
<p>Ca orice &#8220;nerd&#8221; ce se respectă, am pus mâna pe Eclipse pentru a rezolva problema, nu pe o foaie de hârtie, din moment ce prin natura ei există 10<sup>4</sup> ( da, 10.000) soluții posibile, dar doar 25 sunt corecte, considerând faptul că A, B, C pot lua valoarea 0. De fapt, am scris soluția ca pe una configurabilă pentru a-i servi și alt input dacă nu am nimerit-o și A, B, C încep de la 1. Oricum, muncă de 5 minute, dar i-am dat un refactor, să moară dușmanii de ciudă, fără număr la bandă.</p>
<p>Din moment ce propria pacoste de motan mi-a servit drept inspirație, codul e scris lolstyle (dar totuși câtuși de cât profesionist). Ca idee, I_can_has_numbers este clasa ce se ocupă de toate chestiile, iar fișierul I_can_has_everything.php este cel apelabil, fie din browser, pentru cei cu o stivă PHP instalată, fie folosind PHP CLI.</p>
<p>Cod: PHP5/OOP</p>
<p>Download: <a title="I can has Makavelis numbers" href="http://saltwaterc.net/wp-download/I_can_has_Makavelis_numbers.zip" target="_self">I_can_has_Makavelis_numbers.zip</a></p>
<p>Pentru cei născuți cu lene de a mai rula cod, acestea sunt soluțiile:</p>
<pre>Number of solutions: 25

A = 0; B = 0; C = 8; D = 6; 0 + 86 + 8 + 6 = 100
A = 0; B = 1; C = 7; D = 6; 1 + 76 + 7 + 16 = 100
A = 0; B = 2; C = 6; D = 6; 2 + 66 + 6 + 26 = 100
A = 0; B = 3; C = 5; D = 6; 3 + 56 + 5 + 36 = 100
A = 0; B = 4; C = 4; D = 6; 4 + 46 + 4 + 46 = 100
A = 0; B = 5; C = 3; D = 6; 5 + 36 + 3 + 56 = 100
A = 0; B = 6; C = 2; D = 6; 6 + 26 + 2 + 66 = 100
A = 0; B = 7; C = 1; D = 6; 7 + 16 + 1 + 76 = 100
A = 0; B = 8; C = 0; D = 6; 8 + 6 + 0 + 86 = 100
A = 1; B = 0; C = 6; D = 7; 10 + 67 + 16 + 7 = 100
A = 1; B = 1; C = 5; D = 7; 11 + 57 + 15 + 17 = 100
A = 1; B = 2; C = 4; D = 7; 12 + 47 + 14 + 27 = 100
A = 1; B = 3; C = 3; D = 7; 13 + 37 + 13 + 37 = 100
A = 1; B = 4; C = 2; D = 7; 14 + 27 + 12 + 47 = 100
A = 1; B = 5; C = 1; D = 7; 15 + 17 + 11 + 57 = 100
A = 1; B = 6; C = 0; D = 7; 16 + 7 + 10 + 67 = 100
A = 2; B = 0; C = 4; D = 8; 20 + 48 + 24 + 8 = 100
A = 2; B = 1; C = 3; D = 8; 21 + 38 + 23 + 18 = 100
A = 2; B = 2; C = 2; D = 8; 22 + 28 + 22 + 28 = 100
A = 2; B = 3; C = 1; D = 8; 23 + 18 + 21 + 38 = 100
A = 2; B = 4; C = 0; D = 8; 24 + 8 + 20 + 48 = 100
A = 3; B = 0; C = 2; D = 9; 30 + 29 + 32 + 9 = 100
A = 3; B = 1; C = 1; D = 9; 31 + 19 + 31 + 19 = 100
A = 3; B = 2; C = 0; D = 9; 32 + 9 + 30 + 29 = 100
A = 5; B = 0; C = 0; D = 0; 50 + 0 + 50 + 0 = 100
</pre>
<p>&nbsp;</p>
<p>Update: F (nu o să îi dezvălui numele din moment ce a decis să se semneze doar cu F <img src='http://www.saltwaterc.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ) a atras antețina asupra faptului că am făcut brute-force în soluția mea sofisticată, deci vin în întâmpinare cu un algoritm bazat pe modelarea matematică a soluției. Algoritmul rezolvă problema în numărul minim de pași (24), plus adăugarea soluției iregulate (unde trișez, este hardcoded). Numărul de bucle s-a redus la două cu număr minim de pași (4 pentru A, inițial 9 pentru B, după care scade, C și D sunt deduse).</p>
<p>Download: <a title="I can has Makavelis numbers v0.2" href="http://saltwaterc.net/wp-download/I_can_has_Makavelis_numbers_v0.2.zip" target="_self">I_can_has_Makavelis_numbers_v0.2.zip</a></p>
<p>Update: din moment ce primii doi algoritmi sunt de cacao (fără o), primul e pur brute-force iar al doilea nu reprezintă o modelare matematică ce să includă toate soluțiile, revin pe scenă cu ultima soluție (finală) a problemei de mai sus.</p>
<p>Sursa algoritmului propriu zis:</p>
<pre>
for ($a = 0; $a < = 5; $a++)
{
	$double_a = 2 * $a;
	$end_b = 8 - $double_a;
	$d = $a + 6;
	for ($b = 0; $b <= $end_b; $b++)
	{
		$c = (8 - $double_a) - $b;

		if ($d % 10 === 0)
		{
			$a++;
			$d = 0;
		}

		$this->solutions[] = array
		(
			'a' => $a,
			'b' => $b,
			'c' => $c,
			'd' => $d,
		);
	}
}
</pre>
<p>&nbsp;</p>
<p>Download: <a title="I can has Makavelis numbers v0.3" href="http://saltwaterc.net/wp-download/I_can_has_Makavelis_numbers_v0.3.zip" target="_self">I_can_has_Makavelis_numbers_v0.3.zip</a></p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/i-can-has-makavelis-numbers.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Importanța unui PHP framework bine scris</title>
		<link>http://www.saltwaterc.net/programare/importanta-unui-framework-php-bine-scris.html</link>
		<comments>http://www.saltwaterc.net/programare/importanta-unui-framework-php-bine-scris.html#comments</comments>
		<pubDate>Mon, 11 Jan 2010 21:32:08 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>
		<category><![CDATA[Securitate]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/programare/importanta-unui-framework-php-bine-scris.html</guid>
		<description><![CDATA[Spuneam la GeekMeet-ul din octombrie (damn it, iarăși fac referință la el) în timpul prezentării mele, pentru cei absenți, o abordare de la OS până la coder în privința Web Security, despre importanța folosirii unui framework ce să facă în mod implicit filtrare XSS și SQL Injection (SQLi) a input-ului, în biblioteca ce se ocupă [...]]]></description>
			<content:encoded><![CDATA[<p>Spuneam la GeekMeet-ul din octombrie (damn it, iarăși fac referință la el) în timpul prezentării mele, pentru cei absenți, o abordare de la OS până la coder în privința Web Security, despre importanța folosirii unui framework ce să facă în mod implicit filtrare <a href="http://en.wikipedia.org/wiki/Cross-site_scripting" title="Cross-site scripting" target="_blank">XSS</a> și <a href="http://en.wikipedia.org/wiki/SQL_injection" title="SQL injection" target="_blank">SQL Injection</a> (SQLi) a input-ului, în biblioteca ce se ocupă de baza de date. Iar pentru chestii riscante, chiar o filtrare XSS cu <a href="http://htmlpurifier.org/" title="HTML Purifier - Standards-Compliant HTML Filtering" target="_blank">HTML Purifier</a>, o bibliotecă a cărui filtru XSS a fost creat să treacă de <a href="http://ha.ckers.org/xss.html" title="XSS (Cross Site Scripting) Cheat Sheet Esp: for filter evasion" target="_blank">XSS (Cross Site Scripting) Cheat Sheet</a>.</p>
<p>Știu, nu vreau să fac &#8220;carieră&#8221; din astfel de post-uri pe blog și nu prea cred că o să mă vedeți vreodată să trimit chestii către <a href="http://hackersblog.org/" title="hackersblog" target="_blank">http://hackersblog.org/</a>. Sunt preocupat de a proteja, de a-i învăța pe alții cum să se protejeze, și mai puțin de a demonstra vulernabilități. Sunt orientat către ce nu ar trebui să facă aplicația și mai puțin înspre a demonstra cum ajungi acolo. De altel aș prefera ca lumea să nu se ia de &#8216;junk&#8217;-ul de WordPress ce rulează pe blog, sunt prea ocupat pentru a scrie un engine sigur cu un număr echivalent de facilități. Mă rog, va urma un contra-exemplu pentru a susține cele din paragraful anterior.</p>
<p>Povestea începe de la faptul că am avut o mică discuție cu <a href="http://boem.me/" title="necenzurat" target="_blank">necenzurat</a> despre importanța folosirii unui framework, dar el o susținea pe a lui cu alea 10 kile de cod. Doar pentru ce îți trebuie un framework de 1.25 megi (dimensiunea minimă, maxim 1.49) pentru o aplicație banală? Pai în primul rând bune sunt cele de PHP5 folosind OOP și clase cu auto-load. Poți face multiple instalări folosind aceleași surse ale framework-ului exceptând aplicația în sine. Folosești ce încarci. A da, și ai filtrare implicită. De ce? Pentru că nimeni nu este perfect. Greșeli apar și în codul programatorilor ce au trecut de fazele tatonării. Vorbesc din experiența lucrului și mai mult din experiența lucrului în echipă. Dacă tu ca programator nu o dai de gard, se prea poate să dea altul.</p>
<p>Acu recunosc, am trișat puțin. M-am uitat puțin prin cele 10 kile de cod astfel încât buba a fost oarecum imediată. Dar nu imposibil de descoperit cu puțină răbdare și stil având în vedere regulile simple de URL rewrite, destul de evidente, și faptul că era vorba de un singur parametru vulnerabil. De fapt am reușit 3 in 1: XSS, blind SQLi și disclosure în același input.</p>
<p>A da, a folosi mysql_error() în producție este una dintre cele mai proaste idei. XSS-ul și disclosure-ul au fost posibile prin intermediul acestei funcții magice ce ar trebui folosite doar pentru dezvoltare, nu și pentru producție.</p>
<p>Momentan nu dăm poze, așteptăm să aplice patch-ul trimis <img src='http://www.saltwaterc.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/importanta-unui-framework-php-bine-scris.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP sub Windows, Zend Server, WinCache și un cluster FastCGI cu Process Manager</title>
		<link>http://www.saltwaterc.net/windows/php-sub-windows-zend-server-wincache-%c8%99i-un-cluster-fastcgi-cu-process-manager.html</link>
		<comments>http://www.saltwaterc.net/windows/php-sub-windows-zend-server-wincache-%c8%99i-un-cluster-fastcgi-cu-process-manager.html#comments</comments>
		<pubDate>Wed, 06 Jan 2010 22:11:45 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/windows/php-sub-windows-zend-server-wincache-%c8%99i-un-cluster-fastcgi-cu-process-manager.html</guid>
		<description><![CDATA[La GeekMeet-ul din Octombrie de la Sibiu, Todi Pruteanu ne zicea printre altele despre WinCache &#8211; un accelerator de PHP dedicat platformei Windows. Nelămurirea mea legată de WinCache a fost următoarea: dacă Microsoft iși anunță colaborarea pentru a susține PHP sub Windows, atunci de ce nu au colaborat cu echipa APC (Alternative PHP Cache) din [...]]]></description>
			<content:encoded><![CDATA[<p>La GeekMeet-ul din Octombrie de la Sibiu, <a href="http://studentclub.ro/todi/" title="Deschis celor deschiși" target="_blank">Todi Pruteanu</a> ne zicea printre altele despre <a href="http://www.iis.net/expand/WinCacheForPHP" title="Windows Cache Extension for PHP" target="_blank">WinCache</a> &#8211; un accelerator de PHP dedicat platformei Windows. Nelămurirea mea legată de WinCache a fost următoarea: dacă Microsoft iși anunță colaborarea pentru a susține PHP sub Windows, atunci de ce nu au colaborat cu echipa <a href="http://pecl.php.net/package/APC" title="Alternative PHP Cache" target="_blank">APC</a> (Alternative PHP Cache) din moment ce acesta este proiectul de casă și va fi introdus în nucleul PHP începând cu versiunea 6? Întrebarea a rămas fără răspuns. Cu toate acestea, experimentând puțin, am găsit un loc pentru această extensie, deși am impresia că acceleratorul &#8216;closed source&#8217; de la Zend, <a href="http://files.zend.com/help/Zend-Server-Community-Edition/zendoptimizerplus.html" title="Zend Optimizer+" target="_blank">ZendOptimizer+</a> alăruri de <a href="http://files.zend.com/help/Zend-Server-Community-Edition/zenddatacache.html" title="Zend Data Cache" target="_blank">Zend Data Cache</a> ce oferă un API de caching compatibil cu APC poate să preia aceeași funcție. Poate pentru că echipa Zend a scris printre altele un modul de Apache, tot closed source, &#8216;Zend Enabler for Apache&#8217; ce oferă un FastCGI Process Manager pentru Windows suficient de deștept, dar care face o chestie: rularea de mai multe procese FastCGI care deservesc același server web. În plus, Zend Server oferă suport și pentru Microsoft IIS, deci backend-ul PHP nu este restricționat la Apache.</p>
<p>Paragraful anterior rezumă problema, dacă citim printre rânduri. Problema sub Windows este rularea mai multor procese FastCGI ce să servească pe același port, practic un cluster local cu &#8217;round robin load balance&#8217;. Tehnic vorbind &#8211; se poate. Dincolo de un simplu FastCGI wrapper cum este spawn-fcgi, proiect de casă al lighttpd, a apărut <a href="http://redmine.lighttpd.net/boards/2/topics/686" title="Spawn-FCGI Win32" target="_blank">o versiune nativă de Windows</a> pe forurile respective. De curiozitate am luat <a href="http://redmine.lighttpd.net/attachments/727/spawn-fcgi-win32.c" title="Spawn-FCGI Win32 Source" target="_blank">sursa</a>, am compilat-o cu MinGW (gcc -O2 -lws2_32 -o spawn-fcgi-win32.exe spawn-fcgi-win32.c) și am început să mă joc. Într-un mod așteptat, suportul pentru PHP FastCGI childs nu funcționează sub Windows, din motive tehnice. De fapt cercetând sursele PHP pentru cgi SAPI (php-src/sapi/cgi/cgi_main.c) partea cu child process este pusă între niște blocuri de preprocesare pentru compilator: #ifndef PHP_WIN32 &#8230; #endif ceea ce practic anulează FastCGI Process Manager-ul rudimentar implementat de către echipa de dezvoltare a PHP. Motivele sunt simple: spre deosebire de *NIX, sub Windows nu există conceptul de fork() al proceselor. Ba mai mult, sub *NIX există PHP-FPM(FastCGI Process Manager) ceea ce dă apă la moară și mai mult unei platforme non-Windows pentru PHP. Fanii nginx știu despre ce este vorba.</p>
<p>Vestea bună este faptul că acel spawn-fcgi-win32.exe știe să lanseze mai multe procese ce să servească pe același port TCP. Dă și idei despre cum ar trebui implementat un FastCGI Process Manager sub Windows pentru PHP. Ba mai mult, cum ziceam și în paragraful anterior,  acestea vor servi prin round robin load balance. Această arhitectură multiproces, deși nu se pretează stilului Windows ce este preponderent multithread, rezolvă problemele cu extensiile de PHP ce nu au implementat acel &#8216;thread safety&#8217;, iar clusterul poate să facă uz de o arhitectură SMP, fără a apela la threading.</p>
<p>Acum poate apare întrebarea: de ce mai multe procese FastCGI pentru a procesa scripturile PHP? În primul rând practica ne invață că un &#8216;segmentation fault&#8217; poate să apară oricând, iar în producție nu este faptul cel mai de dorit. Arhitecturile multiproces s-au dovedit a fi cele mai potrivite. Vezi cazul Google Chrome cu 1 proces per tab. În al doilea rând, un proces PHP ce servește cereri FastCGI are o limită de 500 de cereri după care acel proces se închide. Acea limită este codată în sursele PHP (tot în cgi_main.c). Acea limită se poate altera prin &#8216;environment variables&#8217;, și anume prin: PHP_FCGI_MAX_REQUESTS. Problema care se ivește: o limită mare poate duce la probleme de memorie ocupată abuziv (memory leaks). În concluzie, această limită este necesară. Prin design-ul serverului FastCGI al PHP, limita este obligatorie și finită deci este nevoie de un PHP FastCGI Process Manager. Apache are ceva extensii (mod_fastcgi si mod_fcgid, doar mod_fastcgi știe să folosească TCP binding) sau soluția Zend Server: Zend Enabler for Apache, IIS are propriul manager. Piața de web servere de Windows ce <em>întâmplător</em> știu de FastCGI nu se termină aici. Spre exemplu eu folosesc versiunea nativă a nginx sub Windows pentru simplul fapt că folosesc nginx și sub alte platforme. Am o târlă de motive pentru care nginx este trecut în preferințele subsemnatului ca web server excelent. Dar, în același timp, nu pot să mă iau după toate &#8216;tutorialele&#8217; de PHP FastCGI sub Windows unde &#8216;php-cgi.exe -b 127.0.0.1:9000&#8242; este suficient pentru a rula. Este suficient până la primul crash sau până la 500 de cereri. În plus, eu ca web developer poate că îmi doresc o soluție complet separată de web server.</p>
<p>Bun, acum am pus bazele ideei despre cum ar trebui făcut un Process Manager. Una dintre probleme este acel &#8216;race condition&#8217;: dacă toate procesele au aceeași viață, spre exemplu un cluster local de 4 cu limită implicită de 500, atunci acestea se vor termina în modul următor: la cererea 1997 &#8211; primul, la cererea 1998 &#8211; al doilea, la cererea 1999 &#8211; al treilea, la cererea 2000 &#8211; ultimul. Dacă process managerul nu se prinde de faptul că nu mai exista cineva care să proceseze ceva.php, atunci web serverul va servi clasica eroare 504 (Gateway Timeout) iar clienții conectați la webserver vor fi nemulțumiți. Acel php-cgi.exe nu oferă o metodă de identificare a faptului că rămâne fără cereri. Nu există în cod suport pentru IPC (Inter Process Communication) cu un manager. În concluzie, după bootstrap, un manager poate doar să monitorizeze clusterul. Nu susțin faptul că nu s-ar putea implementa. Ori, această monitorizare poate avea întârzieri, și pe un server încărcat aceasta nu este de dorit. În concluzie, printr-un algoritm, managerul ar putea mări artificial și temporar viața proceselor 2, 3 și 4 pentru a pune un interval de întârziere și a fi cineva acolo care să servească până monitorul se prinde de faptul că lipsește cineva. Altă idee ar mai fi modificarea pentru Windows a serverului FastCGI ca să suporte respawn (autospawn), înainte de a se închide, deși încă nu am investigat dacă această posibilitate este realizabilă din punct de vedere tehnic. Teoretic ar fi OK, cel puțin din câte mă prind citind despre varii funcții din Windows API. Ar rezolva problema existenței unui child care să servească, in concluzie managerul s-ar transforma în simplu monitor de procese după secvența de bootstrap unde lansează clusterul. Idei am, din păcate n-am mai pus mâna pe C decât ocazional în ultimii 5 ani. Din fericire mai pricep ce e prin codul altora <img src='http://www.saltwaterc.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Ziceam și pe <a href="http://twitter.com/SaltwaterC/status/7451025800" title="De ce nu există un PHP - FastCGI Process Manager sub Windows?" target="_blank">Twitter</a>: <span class="status-body"><span class="entry-content">De ce nu există un PHP &#8211; FastCGI Process Manager sub Windows? Pentru că nimeni nu și-a dat interesul să scrie unul. Posibilităti există!</span></span></p>
<p>Ceea ce ne aduce iarăși la WinCache. N-am început degeaba cu el. Unei platforme PHP îi stă bine și cu un opcode cache (PHP accelerator, whatever). Pe lângă PHP din Zend Server &#8211; ce vine cu multe jucării de la mama lui, Zend, cred că se poate pune un nginx. Problema acceleratorului și al Cache API-ului ar fi rezolvată. Ba ar fi compatibil codul cu un eventual APC folosit în producție, chiar dacă în teorie, având în vedere soluțiile multiple, se recomandă o bibliotecă abstractă cu drivere pentru varii extensii PHP. Bun, ar zice unii: dar APC ce are? Păi, ultima versiune pusă la dispoziție de unul dintre oamenii ce se ocupă de build-ul de PHP pentru Windows, precum și de dezvoltarea lui, a pus la dispoziție o <a href="http://downloads.php.net/pierre/" title="Windows PHP extensions" target="_blank">chestie compatibilă PHP 5.3.x</a> ce din păcate pusă în setup-ul multiproces expus mai devreme duce la crash. Practic din 4 procese, 3 crapă, unul rulează relativ stabil. Contravine ideii de multiproces. XCache deși este excelent, nu foloseste shared memory pentru data cache, deci practic acesta va fi împărțit într-un număr egal cu numărul de procese. Nu știu code cache-ul cum se comportă. WinCache știe doar code cache, dar face uz de shared memory și funcționează bine cu load balancer-ul. În concluzie, cel puțin pe termen scurt WinCache are un rol acolo. Mai mult, WinCache funcționează doar cu versiunile de PHP non-thread-safe, compilate cu Visual C++ 9, și teoretic cu IIS, practic Microsoft a mințit. Funcționează cu nginx fără probleme și de ce nu, cu alte servere.</p>
<p>Altă idee: un server web sub *NIX ar putea folosi un server FastCGI sub Windows. nginx poate să folosească backend-uri multiple, eventual cu load balance între mai multe mașini. Deși încă sunt de părere că PHP sub Windows cam suge datorită faptului că are multe lacune iar majoritatea bibliotecilor ce le integrează provin din *NIX, are un atu: suportul COM/.NET &#8211; ceea ce înseamnă că într-o arhitectură existentă se poate adăuga un server Windows cu PHP ce să poată beneficia de anumite SDK-uri comerciale ce se distribuie sub formă de COM.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/windows/php-sub-windows-zend-server-wincache-%c8%99i-un-cluster-fastcgi-cu-process-manager.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Pentru toti devii PHP</title>
		<link>http://www.saltwaterc.net/php/pentru-toti-devii-php.html</link>
		<comments>http://www.saltwaterc.net/php/pentru-toti-devii-php.html#comments</comments>
		<pubDate>Wed, 19 Nov 2008 11:28:09 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/pics/pentru-toti-devii-php.html</guid>
		<description><![CDATA[Am primit acesta (evident) de la un alt PHP dev &#8230;]]></description>
			<content:encoded><![CDATA[<p style="float: left; margin-right: 10px"><a href="http://saltwaterc.net/wp-content/uploads/php.jpg" title="PHP"><img src="http://saltwaterc.net/wp-content/uploads/php.thumbnail.jpg" alt="PHP" /></a></p>
<p>Am primit acesta (evident) de la un alt PHP dev &#8230;</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/php/pentru-toti-devii-php.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>XHTML Video Embed v0.3</title>
		<link>http://www.saltwaterc.net/programare/xhtml-video-embed-v03.html</link>
		<comments>http://www.saltwaterc.net/programare/xhtml-video-embed-v03.html#comments</comments>
		<pubDate>Sun, 08 Jun 2008 12:37:06 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/programare/xhtml-video-embed-v03.html</guid>
		<description><![CDATA[XHTML Video Embed a ajuns la versiunea 0.3. Dupa doua luni in care mai mult taras-grapis am scris si implementat noi chestii, mi-am rupt un weekend din timpul subsemnatului si am finalizat aceasta versiune. Aduce in plus: suport pentru Jumpcut. suport pentru a face override la dimensiunile unificate folosind parametri speciali in structura tag-ului. localizare [...]]]></description>
			<content:encoded><![CDATA[<p>XHTML Video Embed a ajuns la versiunea 0.3. Dupa doua luni in care mai mult taras-grapis am scris si implementat noi chestii, mi-am rupt un weekend din timpul subsemnatului si am finalizat aceasta versiune. Aduce in plus:</p>
<ul>
<li>suport pentru Jumpcut.</li>
<li>suport pentru a face override la dimensiunile unificate folosind parametri speciali in structura tag-ului.</li>
<li>localizare in engleza si romana. Pentru alte limbi o sa am nevoie de voluntari.</li>
<li>suport pentru videoclipurile high definition de pe YouTube.</li>
<li>introducerea suportului pentru FLV embedding ce a aparut in branch-ul 0.2.4.x dupa ce dezvoltarea acestei versiuni a inceput.</li>
<li>design complet nou al aplicatiei. Nu, nu ma refer la interfata ci la modul in care lucreaza. Partea publica a plug-in-ului a fost puternic optimizata deoarece modelul de dezvoltare din v0.1.x/v0.2.x incepuse sa puna probleme. Desi admin-panel-ul poate fi mai lent decat cel din versiunile anterioare, acesta este generat complet dinamic, deci adaugarea unui serviciu nou presupune foarte putin lucru.</li>
<li>securizare mai buna a anumitor componente.</li>
</ul>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/xhtml-video-embed-v03.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ID-uri numerice curate in PHP</title>
		<link>http://www.saltwaterc.net/programare/id-uri-numerice-curate-in-php.html</link>
		<comments>http://www.saltwaterc.net/programare/id-uri-numerice-curate-in-php.html#comments</comments>
		<pubDate>Tue, 25 Mar 2008 22:15:44 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/programare/id-uri-numerice-curate-in-php.html</guid>
		<description><![CDATA[Adesea m-am lovit de problema sanitizarii variabilelor care provin din input, si nu zic asta facand referire la PHP, ci la programare in general. Din moment ce am avut boala sa studiez catusi de cat bazele securitatii, mi-a ramas in cap un principiu foarte bine formulat: &#8220;all user input is evil!&#8221;. Adevarat grait. Deci am [...]]]></description>
			<content:encoded><![CDATA[<p>Adesea m-am lovit de problema sanitizarii variabilelor care provin din input, si nu zic asta facand referire la PHP, ci la programare in general. Din moment ce am avut boala sa studiez catusi de cat bazele securitatii, mi-a ramas in cap un principiu foarte bine formulat: &#8220;all user input is evil!&#8221;. Adevarat grait. Deci am inceput sa gandesc aplicatiile dupa metoda user proof. In primul rand cand testez ceva nou, nu testez dupa cum ar trebui sa fie utilizata aplicatia in mod corect, ci cum NU ar trebui sa fie folosita, si ce sa se intample in acele cazuri. In primul rand pentru ca o aplicatie nu este o chestie democratica unde userul face ce vrea el si adesea face prost. Deasemenea intervine si cealata extrema. Unde nu este prostie &#8211; este viclenie &#8211; deci se poate trezi cate un h4x0r de asta cu mai mult timp liber la dispozitie sa te caute la oo (a se citi: securizare).</p>
<p>Problema ID-urilor numerice in PHP desi este una destul de banala, rezolvarea este multipla. De-alungul timpului am testat mai multe chestii, dar doar recent am ajuns la o forma finala care sa ma multumeasca deplin. De ce ID-uri numerice? Pentru ca este foarte usor de lucrat cu ele cand se interactioneaza cu o baza de date. Orice tabela care trebuie sa stocheze in mod unic niste chestii, are o cheie primara. Pana acum cea mai desteapta chestie in materie de chei primare este cheia intreaga care se seteaza cu auto-increment &#8211; ceea ce asigura complet unicitatea datelor. Recomandarea ar fi ca auto incrementul sa inceapa de la 0 (chestia asta o sa se lege de ce o sa zic mai jos). Bonus ar fi faptul ca fiecare tabela de acest gen ar trebui sa aiba cheia primara indexata pentru a reduce considerabil timpul de cautare al ei.</p>
<p>Adesea aceste chei primare din baza de date sunt trimise prin intermediul requesturilor de tip GET, deci se vor regasi in componenta URL-ului. Problema se pune atunci cand pe langa acel ID numeric, utilizatorul (in mod intentionat) introduce si altceva pe langa acel ID. Treaba poate sa se imputa de la XSS (Cross Site Scripting) &#8211; atunci cand acea cheie se regaseste in pagina, sau la atacuri de tip <a href="http://en.wikipedia.org/wiki/SQL_injection" title="SQL injection" target="_blank">SQL injection</a> (mai grav).</p>
<p>Desi exista functii native in suportul de MySQL pentru PHP, acestea sunt destul de triste la ID-uri numerice, deci am preferat propria metoda:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> clean_id<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$id</span><span style="color: #339933;">=</span><span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;@[^0-9]@&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</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: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000088;">$id</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> <span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Chestia asta de mai sus face vreo doua chestii &#8230; prima este aceea ca da strip la tot inputul care nu e numeric. A doua verifica ce a mai ramas, iar daca are valoarea 0 (orice 0 din PHP), atunci returneaza un 0 numeric. Este important acest zero numeric &#8230; ziceam ceva mai sus de el &#8230; acest zero numeric are grija ca interogarea sa nu dea de o chestie gen &lt;&lt;WHERE id=&#8221;&gt;&gt; si sa bubuie o eroare de SQL (care in anumite cazuri &#8230; ar putea la randul ei sa divulge alte chestii).</p>
<p><strong>Actualizare:</strong></p>
<p>Datorita observatiei lui <em>AgLiAn</em> am ajuns la concluzia ca functia mea initiala nu rezolva o problema: interger overflow, chestie ce mai departe se traduce in interpretarea ca float de catre PHP &#8211; si de unde pot aparea alte probleme. Si pentru ca am mentionat pe undeva mai sus de auto-increment (si acest obicei nu o sa se transforme peste noapte pana la proba contrara ce demonstreaza un obicei prost), functia clean_id(); devine:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> clean_id<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">return</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</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><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/id-uri-numerice-curate-in-php.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>iif() in PHP</title>
		<link>http://www.saltwaterc.net/programare/iif-in-php.html</link>
		<comments>http://www.saltwaterc.net/programare/iif-in-php.html#comments</comments>
		<pubDate>Tue, 26 Feb 2008 12:52:28 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/programare/iif-in-php.html</guid>
		<description><![CDATA[Se intampla ca anumite constructii pretentioase sa aiba nevoie de o selectie &#8230; Problema care se pune este sa se scrie cat mai putin cod pentru rezolvarea problemei respective. Deci exista operatiile ternare care pot fi facute si de catre o functie. In mod normal ar fi o chestie gen: if &#40;$expression==true&#41; $var=&#34;value&#34;; else $var=&#34;other_value&#34;; [...]]]></description>
			<content:encoded><![CDATA[<p>Se intampla ca anumite constructii pretentioase sa aiba nevoie de o selectie &#8230; Problema care se pune este sa se scrie cat mai putin cod pentru rezolvarea problemei respective. Deci exista operatiile ternare care pot fi facute si de catre o functie. In mod normal ar fi o chestie gen:</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;">$expression</span><span style="color: #339933;">==</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>
	<span style="color: #000088;">$var</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;value&quot;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span>
	<span style="color: #000088;">$var</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;other_value&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Am gasit o abordare diferita a problemei operatiilor ternare (chestie care o folosesc de o buna bucata de timp), si anume operatia ternara:</p>
<php lang="php">$var=($expression==true) ? &#8220;value&#8221; : &#8220;other_value&#8221;;<br />
care poate fi concatenata intr-un string, sau utilizata intr-o variabila. Problema este ca imi cam rup degetele cu aceasta scriere (nu prea folosesc ? si : cand codez PHP), deci am gasit o implementare de <a href="http://en.wikipedia.org/wiki/IIf" title="iif()" target="_blank">iif()</a> in PHP. De fapt doua. Prima abordare se bazeaza chiar pe translatarea operatiei ternare:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> iif<span style="color: #009900;">&#40;</span><span style="color: #000088;">$expression</span><span style="color: #339933;">,</span> <span style="color: #000088;">$returntrue</span><span style="color: #339933;">,</span> <span style="color: #000088;">$returnfalse</span><span style="color: #339933;">=</span><span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$expression</span> ? <span style="color: #000088;">$returntrue</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$returnfalse</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Desi este o abordare destul de interesanta, are mici probleme, si anume faptul ca se evalueaza toate argumentele inainte de executie, iar daca $returntrue si $returnfalse sunt rezultate ale altor functii, se itampla sa apara rezultate neasteptate in practica deoarece operatorul ? poate sa scurtcircuiteze evaluarea.</p>
<p>A doua abordare, aia pe care o folosesc, este urmatoarea:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> iif<span style="color: #009900;">&#40;</span><span style="color: #000088;">$expression</span><span style="color: #339933;">,</span> <span style="color: #000088;">$returntrue</span><span style="color: #339933;">,</span> <span style="color: #000088;">$returnfalse</span><span style="color: #339933;">=</span><span style="color: #0000ff;">''</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;">$expression</span><span style="color: #009900;">&#41;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$returntrue</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">else</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$returnfalse</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Dupa niste RTFM am ajuns la concluzia ca tot a doua abordare este mai buna, chiar daca este mai putin eleganta, si se obtine cod ceva mai scurt si mai putin alambicat, mai ales cand vine vorba de interogari SQL cu grad mare de nesimtire.</php>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/iif-in-php.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>301 redirect fara .htaccess si mod_rewrite</title>
		<link>http://www.saltwaterc.net/programare/301-redirect-fara-htaccess-si-mod_rewrite.html</link>
		<comments>http://www.saltwaterc.net/programare/301-redirect-fara-htaccess-si-mod_rewrite.html#comments</comments>
		<pubDate>Wed, 20 Feb 2008 14:50:40 +0000</pubDate>
		<dc:creator>SaltwaterC</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programare]]></category>

		<guid isPermaLink="false">http://saltwaterc.net/programare/301-redirect-fara-htaccess-si-mod_rewrite.html</guid>
		<description><![CDATA[Arata cam asa (in PHP, pentru alte limbaje nu ma ostenesc): if &#40; &#40; !preg_match &#40; &#34;@www@i&#34;, $_SERVER&#91;'HTTP_HOST'&#93; &#41; &#41; &#38;amp;&#38;amp; &#40; preg_match &#40; &#34;@example\.com@i&#34;, $_SERVER&#91;'HTTP_HOST'&#93; &#41; &#41; &#41; &#123; $_urlHead = &#40; isset&#40; $_SERVER&#91;'HTTPS'&#93; &#41; &#38;amp;&#38;amp; strtolower &#40; $_SERVER&#91;'HTTPS'&#93; &#41; == 'on' &#41; ? &#34;https://www.&#34; : &#34;http://www.&#34;; $_redirURL=$_urlHead . $_SERVER&#91;'HTTP_HOST'&#93; . $_SERVER&#91;'REQUEST_URI'&#93;; header &#40; [...]]]></description>
			<content:encoded><![CDATA[<p>Arata cam asa (in PHP, pentru alte limbaje nu ma ostenesc):</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: #009900;">&#40;</span> <span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;@www@i&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_HOST'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">preg_match</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;@example\.com@i&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_HOST'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$_urlHead</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTPS'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #990000;">strtolower</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTPS'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'on'</span> <span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">&quot;https://www.&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;http://www.&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$_redirURL</span><span style="color: #339933;">=</span><span style="color: #000088;">$_urlHead</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_HOST'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;HTTP/1.1 301 Moved Permanently&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Location: <span style="color: #006699; font-weight: bold;">$_redirURL</span>&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Initial eram ceva mai recalcitrant in ceea ce priveste manaritul prin .htaccess, dar chiar si fara a fi, mai exista cate un server de pe vremea lui Nae ce nu vrea sa te lase nene sa il stresezi cu astfel de directive.</p>
<p><strong>Explicatii:</strong> if-ul asta smecher verifica daca exista www in HTTP_HOST care se modeleaza in functie de request. Adica daca folosesc saltwaterc.net atunci HTTP_HOST=saltwaterc.net, daca folosesc www.saltwaterc.net atunci HTTP_HOST=www.saltwaterc.net, iar daca scot din buzunar un port magic si serverul asculta sa zicem pe 8080 deci requestul se face pe saltwaterc.net:8080 atunci evident, nu mai tre sa zic care este HTTP_HOST-ul pentru ca este clar. A doua verificare se face in functie de un nume de domeniu, si anume ala pe care se va hosta scriptul. Nu este necesara, dar este utila pentru serverele de development care cel mai adesea sunt hostate local si nu prezinta www. Redirectionarea se face compunand &#8220;manual&#8221; URL-ul de redirect si trebuie avut grija ca acel www sa fie acolo. REQUEST_URI-ul are grija sa tina minte ce s-a bagat in bara de adresa dupa HTTP_HOST, deci redirectionarea se face la sigur. Smecheria aia cu HTTPS are grija ca in cazul in care se folosesc conexiuni criptate, redirectionarea sa fie facuta corect tot catre o conexiune criptata.</p>
<p><strong>Unde trebuie adaugat:</strong> inainte de a se face orice fel de output cand se executa scriptul. Daca s-a trimis output catre browser, nu se mai poate drege busuiocul deoarece e o limitare a protocolului HTTP de a nu mai putea trimite headere dupa output.</p>
<p><strong>Solutia inversa &#8211; www to no-www:</strong> avand in vedere cele zise mai sus, este de-a dreptul triviala &#8230;</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: #009900;">&#40;</span> <span style="color: #990000;">preg_match</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;@www@i&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_HOST'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$_urlHead</span><span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">isset</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTPS'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #990000;">strtolower</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTPS'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'on'</span> <span style="color: #009900;">&#41;</span> ? <span style="color: #0000ff;">&quot;https://&quot;</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">&quot;http://&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$_redirURL</span><span style="color: #339933;">=</span><span style="color: #000088;">$_urlHead</span> <span style="color: #339933;">.</span> <span style="color: #990000;">preg_replace</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;@www\.@i&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_HOST'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;HTTP/1.1 301 Moved Permanently&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Location: <span style="color: #006699; font-weight: bold;">$_redirURL</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Se observa cu usurinta ca dispare particula dedicata platformei de development &#8230; nu mai este nevoie de asa ceva din motivul pomenit mai sus.</p>
<p>PS: de mod_rewrite nu e nevoie pentru a face un 301, dar e nevoie pentru smecherii cu CNAME si alte avioane. Adica ce ziceam mai sus, dar pe alta limba. Am scos aberatiile scrise pe acilea prin articol a.k.a. de pe vremea cand eram mic si prost.</p>
<p><a class="a2a_dd addtoany_share_save" href="http://www.addtoany.com/share_save"><img src="http://www.saltwaterc.net/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share/Bookmark"/></a> </p>]]></content:encoded>
			<wfw:commentRss>http://www.saltwaterc.net/programare/301-redirect-fara-htaccess-si-mod_rewrite.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
