<?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>BBProject.net &#187; php</title>
	<atom:link href="http://www.bbproject.net/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bbproject.net</link>
	<description>Programowanie, webmastering, informatyka</description>
	<lastBuildDate>Mon, 26 Jul 2010 08:03:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Magiczne stałe PHP</title>
		<link>http://www.bbproject.net/2010/06/magiczne-stale-php/</link>
		<comments>http://www.bbproject.net/2010/06/magiczne-stale-php/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 08:55:09 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[magiczne]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[stała]]></category>
		<category><![CDATA[stałe]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=370</guid>
		<description><![CDATA[Stałe noszące miano „magicznych” w języku PHP to zbiór stałych które posiadają przedefiniowaną i niezmienną wartość, jednak jest ona określona jedynie w obrębie wykonywania danego skryptu. Oznacza to że w przypadku innego pliku wartości poszczególnych stałych będą inne. Mało tego, niektóre z nich mogą zmieniać swą zawartość w zależności od miejsca wywołania (np.: wew. funkcji [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-371" title="Magiczny kapelusz" src="http://www.bbproject.net/wp-content/uploads/2010/06/magic_hat-160x160.png" alt="" width="160" height="160" />Stałe noszące miano „magicznych” w języku PHP to zbiór stałych które posiadają przedefiniowaną i niezmienną wartość, jednak jest ona określona jedynie w obrębie wykonywania danego skryptu.</p>
<p>Oznacza to że w przypadku innego pliku wartości poszczególnych stałych będą inne. Mało tego, niektóre z nich mogą zmieniać swą zawartość w zależności od miejsca wywołania (np.: wew. funkcji czy metody klasy).</p>
<p>Owe „magic constans” są jednak bardzo przydatne w programowaniu w PHP i każdy powinien je znać, aby niepotrzebnie nie wynajdywać od nowa przysłowiowego koła. Zapraszam do zapoznania się z nimi.</p>
<p><span id="more-370"></span>Dla każdej poniższej stałej, został dołączony przykład użycia wraz z wynikiem wykonania danego kodu.</p>
<h4>__LINE__</h4>
<p>Zawiera numer linii pliku skryptu, w której została użyta ta stała.</p>
<pre class="brush: php">echo __LINE__;</pre>
<pre>2</pre>
<h4>__FILE__</h4>
<p>Przechowuje bezwzględną ścieżkę do pliku skryptu który jest wykonywany.</p>
<pre class="brush: php">echo __FILE__;</pre>
<pre>G:\Server\www\~dev\magicconstants.php</pre>
<h4>__DIR__</h4>
<p>Przechowuje bezwzględną ścieżkę do folderu skryptu który jest wykonywany (bez slasha na końcu jeśli nie jest to folder główny &#8211; root). Stała ta dostępna jest począwszy od wersji PHP 5.3.0.</p>
<pre class="brush: php">echo __DIR__;</pre>
<pre>G:\Server\www\~dev</pre>
<h4>__FUNCTION__</h4>
<p>Nazwa funkcji w której użyta została stała.</p>
<pre class="brush: php">function test_function()
{
  return __FUNCTION__;
}
echo test_function();</pre>
<pre>test_function</pre>
<h4>__CLASS__, __METHOD__</h4>
<p>Pierwsza z stałym zwraca nazwę klasy obiektu w którym została użyta. Druga natomiast, dodaje do tego ciągu dodatkowo nazwę wywołanej metody owej klasy.</p>
<pre class="brush: php">class test_obj
{
  public function test_class()
  {
    return __CLASS__;
  }
  public function test_method()
  {
    return __METHOD__;
  }
}
$test_obj = new test_obj();
echo $test_obj-&gt;test_class()."\n";
echo $test_obj-&gt;test_method();</pre>
<pre>test_obj
test_obj::test_method</pre>
<h4>__NAMESPACE__</h4>
<p>Nazwa aktualnej przestrzeni nazw &#8211; jednej z głównej nowości w PHP 5.3.0.</p>
<pre class="brush: php">namespace test_namespace;
echo __NAMESPACE__;</pre>
<pre>test_namespace</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/06/magiczne-stale-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Podświetlanie składni PHP</title>
		<link>http://www.bbproject.net/2010/06/podswietlanie-skladni-php/</link>
		<comments>http://www.bbproject.net/2010/06/podswietlanie-skladni-php/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 08:23:00 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[highlight]]></category>
		<category><![CDATA[highlight_file]]></category>
		<category><![CDATA[highlight_string]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[składnia]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=368</guid>
		<description><![CDATA[Szybki wpis pod tytułem, jak podświetlić składnię języka PHP w samym PHP. Sprawa jest dziecinnie prosta, i sprowadza się do użycia jednej z dwóch wbudowanych funkcji samego języka: mixed highlight_string  (  string $str  [,  bool $return = false  ] ) &#8230;lub: mixed highlight_file  (  string $filename  [,  bool $return = false  ] ) Pierwsza koloruje [...]]]></description>
			<content:encoded><![CDATA[<p>Szybki wpis pod tytułem, jak podświetlić składnię języka PHP w samym PHP. Sprawa jest dziecinnie prosta, i sprowadza się do użycia jednej z dwóch wbudowanych funkcji samego języka:</p>
<pre>mixed <a href="http://pl2.php.net/manual/en/function.highlight-string.php"><strong>highlight_string</strong></a>  (  string $str  [,  bool $return = false  ] )</pre>
<p>&#8230;lub:</p>
<pre>mixed <a href="http://pl2.php.net/manual/en/function.highlight-file.php"><strong>highlight_file</strong></a>  (  string $filename  [,  bool $return = false  ] )</pre>
<p>Pierwsza koloruje i wyróżnia składnię w zadanym ciągu znaków, druga z kolei w podanym pliku. Prosty przykład demonstrujący działanie:</p>
<pre class="brush: php">&lt;?php
  $var = 'Ten skrypt PHP podswietla skladnie samego siebie';
  $num = 1024;
  highlight_file(__FILE__);
?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/06/podswietlanie-skladni-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Klasyka PHP &#8211; licznik odwiedzin</title>
		<link>http://www.bbproject.net/2010/03/klasyka-php-licznik-odwiedzin/</link>
		<comments>http://www.bbproject.net/2010/03/klasyka-php-licznik-odwiedzin/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 08:27:37 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[file_get_contents]]></category>
		<category><![CDATA[file_put_contents]]></category>
		<category><![CDATA[licznik]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=209</guid>
		<description><![CDATA[Dlaczego klasyka? Gdyż to chyba jeden z najpopularniejszych skryptów o jakich myśli każdy początkujący programista PHP. Fakt faktem, że przy dzisiejszych usługach typu Google Analytics jest to mało komfortowe rozwiązanie i nie dostarcza wielu informacji, nie mniej na pewno dużo satysfakcji . Bez zbędnego przedłużania przechodzimy do sedna sprawy. Nasz licznik będzie maksymalnie uproszczony &#8211; [...]]]></description>
			<content:encoded><![CDATA[<p>Dlaczego klasyka? Gdyż to chyba jeden z najpopularniejszych skryptów o jakich myśli każdy początkujący programista PHP. Fakt faktem, że przy dzisiejszych usługach typu Google Analytics jest to mało komfortowe rozwiązanie i nie dostarcza wielu informacji, nie mniej na pewno dużo satysfakcji <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_smile.png' alt=':)' class='wp-smiley' /> .</p>
<p>Bez zbędnego przedłużania przechodzimy do sedna sprawy. Nasz licznik będzie maksymalnie uproszczony &#8211; będzie zliczał każde przeładowanie strony. Aby zbytnio się nie napracować skorzystamy z funkcji <a href="http://pl.php.net/manual/en/function.file-get-contents.php"><em>file_get_contents</em></a> oraz <a href="http://pl.php.net/manual/en/function.file-put-contents.php"><em>file_put_content</em></a>s do przechowania aktualnego stanu licznika w pliku.</p>
<p><span id="more-209"></span>Jak działa zatem prosty licznik? Pobiera z pliku ilość odsłon, dodaje 1, zapisuje i wyświetla aktualny stan.</p>
<pre class="brush: php">$fn = 'data.txt';
$counter = (file_exists($fn) ? (int)file_get_contents($fn) : 0) + 1;
file_put_contents($fn, $counter);</pre>
<p>I to już w zasadzie wszystko. Pierwsza linia określa nazwę pliku danych licznika. Druga odczytuje jego aktualny stan, o ile plik istnieje. Ostatnia zapisuje ponownie ilość osłon do pliku. W zmiennej <em>$counter</em> znajduje się ich aktualna ilość którą możemy umiejscowić gdzieś na stronie:</p>
<pre class="brush: php">echo $counter;</pre>
<p>Nasz licznik jest już gotowy. Cały kod możesz pobrać <a href="http://www.bbproject.net/wp-content/uploads/2010/03/counter.zip">tutaj</a>.</p>
<h4>Dla ambitnych</h4>
<p>Jeśli nie chcesz aby licznik zliczał każdą pojedynczą odsłonę, a jedynie użytkowników, to musimy pokusić się o skorzystanie z cookies (ciasteczek) przeglądarki.</p>
<p>Podobnie jak w przykładzie wyżej, nie jest to jakiś skomplikowany mechanizm i łatwo go obejść, ale spełnia swoje zadanie w minimum jakie od niego wymagamy.</p>
<pre class="brush: php">$fn = 'data.txt';
$counter = file_exists($fn) ? (int)file_get_contents($fn) : 0;

$cookiename = 'simple_counter_d3v8';
if ( ! isset($_COOKIE[$cookiename]))
{
  file_put_contents($fn, ++$counter);
  setcookie($cookiename, '1', time()+60*60*24);
}</pre>
<p>Jeśli użytkownik odwiedzi stronę, zapisujemy w jego przeglądarce ciasteczko. Przy kolejnej odsłonie tylko wtedy podwyższamy wartość licznika jeśli owo ciasteczko <strong>nie</strong> istnieje. Po 24h, odsłona tego samego użytkownika jest ponownie zliczana &#8211; można to regulować zmieniając liczbę sekund w trzecim parametrze funkcji <a href="http://pl.php.net/manual/en/function.setcookie.php"><em>setcookie</em></a>.</p>
<p>Kompletny kod można pobrać <a href="http://www.bbproject.net/wp-content/uploads/2010/03/counterext.zip">tutaj</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/03/klasyka-php-licznik-odwiedzin/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>If&#8230;else czy return?</title>
		<link>http://www.bbproject.net/2010/03/if-else-czy-return/</link>
		<comments>http://www.bbproject.net/2010/03/if-else-czy-return/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 11:03:18 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Laboratorium]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[funkcja]]></category>
		<category><![CDATA[instrukcja warunkowa]]></category>
		<category><![CDATA[optymalizacja]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=112</guid>
		<description><![CDATA[Trudno wymyślić sensowny tytuł dla zagadnienia które chcę opisać. Zawsze zastanawiało mnie czy pisząc w PHP funkcję która początkowo przeprowadza walidację przekazanych argumentów, stosować konstrukcję typu: function nazwa($argument) { if (warunek) { return FALSE; } ... ciało funkcji } &#8230;czy też: function nazwa($argument) { if (warunek) { return FALSE; } else { ... ciało funkcji [...]]]></description>
			<content:encoded><![CDATA[<p>Trudno wymyślić sensowny tytuł dla zagadnienia które chcę opisać. Zawsze zastanawiało mnie czy pisząc w PHP funkcję która początkowo przeprowadza walidację przekazanych argumentów, stosować konstrukcję typu:</p>
<pre class="brush: php">function nazwa($argument)
{
  if (warunek)
  {
    return FALSE;
  }
  ... ciało funkcji
}</pre>
<p>&#8230;czy też:</p>
<pre class="brush: php">function nazwa($argument)
{
  if (warunek)
  {
    return FALSE;
  }
  else
  {
    ... ciało funkcji
  }
}</pre>
<p>Intuicyjnie może się wydawać że pierwszy metoda będzie działać szybciej, gdyż po spełnieniu warunku wychodzimy od razu z funkcji &#8211; parser nie musi przetwarzać reszty kodu. Z kolei w drugiej, mimo iż to co znajduje się w bloku <em>else</em> się nie wykona i tak musi zostać przeczytane przez PHP. Jak jest w rzeczywistości? Sprawdźmy to!</p>
<p><span id="more-112"></span>Pierwsza konstrukcja, w której po spełnieniu warunku wykluczającego dalsze przetwarzanie, od razu zwracamy wartość jest na pewno bardziej przejrzysta. Nie musimy ciągnąć za sobą nawiasu kończącego blok <em>else</em> przez całą resztę instrukcji. Drugi fragment kodu z kolei charakteryzuje się bardziej logiczniejszą strukturą &#8211; gdyż wyraźnie widzimy co się stanie w przypadku spełnienia warunku jak i jego odrzucenia.</p>
<p>Przejdźmy zatem do testów. Przygotowałem na tą okazję dwie, identyczne pod względem działania, funkcje korzystające z dwóch w/w konstrukcji zapisu:</p>
<pre class="brush: php">function test_return($arg)
{
  if ($arg % 2 == 0)
  {
    return 0;
  }
  $arg = $arg*7+2;
  $a = $arg+3;
  $b = 1024;
  $arg = $a - $b*$arg;
  $arg =- 500;
  $arg *= 2;
  return $arg+256;
}</pre>
<p>&#8230;oraz:</p>
<pre class="brush: php">function test_else($arg)
{
  if ($arg % 2 == 0)
  {
    return 0;
  }
  else
  {
    $arg = $arg*7+2;
    $a = $arg+3;
    $b = 1024;
    $arg = $a - $b*$arg;
    $arg =- 500;
    $arg *= 2;
    return $arg+256;
  }
}</pre>
<p>Jak można zauważyć, funkcje te nie mają zbytniego sensu, nie mniej ich głównym celem jest odrzucanie liczb parzystych a przetwarzanie jedynie nieparzystych.</p>
<p>Procedura testowa polegała na wykonaniu jednego miliona iteracji każdej z funkcji, podając kolejne liczby całkowite jako argument poczynając od 0.</p>
<pre class="brush: php">for ($i = 0; $i &lt; 1000000; $i++)
{
  test_return($i);
}</pre>
<p>Wyniki jakie otrzymałem prezentują się następująco:</p>
<table>
<tbody>
<tr>
<th>Nazwa funkcji</th>
<th>Czas wykonania 1 000 000 iteracji</th>
</tr>
<tr>
<td>test_return()</td>
<td>~760ms</td>
</tr>
<tr>
<td>test_else()</td>
<td>~760ms</td>
</tr>
</tbody>
</table>
<p>Jak widać, wyniki są identyczne. W praktyce występowały pewne wahania w zależności od wywołania skryptu, nie mniej średnio, obie funkcje wykonują się w tym samym czasie. Nie ma więc znaczenia jakiego typu konstrukcji użyjemy &#8211; najlepiej tej która bardziej nam w danej chwili odpowiada.</p>
<p>Dlaczego tak się dzieje? Przyczyny braku różnicy w czasie wykonania można dopatrywać się tym, iż parser PHP bądź co bądź musi przeczytać całą zawartość skryptu przed jego kompilacją i uruchomieniem. Skompilowany kod jednej i drugiej funkcji nie różni się zatem niczym, co mogło by w istotny sposób wpłynąć na czas jego wykonania.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/03/if-else-czy-return/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Referencja w pętli foreach &#8211; bug który nie jest bugiem</title>
		<link>http://www.bbproject.net/2010/02/referencja-w-petli-foreach-bug-ktory-nie-jest-bugiem/</link>
		<comments>http://www.bbproject.net/2010/02/referencja-w-petli-foreach-bug-ktory-nie-jest-bugiem/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 11:30:44 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[foreach]]></category>
		<category><![CDATA[pętla]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[referencja]]></category>
		<category><![CDATA[wskaźnik]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=133</guid>
		<description><![CDATA[Weźmy pod lupę prostą pętle foreach w PHP, która zamienia we wszystkich elementach tablicy litery na duże: $words = array('system', 'baza', 'telefon'); foreach ($words as &#38;$item) { $item = strtoupper($item); } Jak widać, kolejne elementy tablicy pobierane są po przez referencję, tj. tworzony jest wskaźnik na konkretny element a nie jego kopia w pamięci. Dlatego [...]]]></description>
			<content:encoded><![CDATA[<p>Weźmy pod lupę prostą pętle <a href="http://pl.php.net/manual/en/control-structures.foreach.php"><em>foreach</em></a> w PHP, która zamienia we wszystkich elementach tablicy litery na duże:</p>
<pre class="brush: php">$words = array('system', 'baza', 'telefon');
foreach ($words as &amp;$item)
{
  $item = strtoupper($item);
}</pre>
<p>Jak widać, kolejne elementy tablicy pobierane są po przez referencję, tj. tworzony jest wskaźnik na konkretny element a nie jego kopia w pamięci. Dlatego też, zmieniając w pętli zawartość zmiennej <em>$item</em> modyfikujemy pierwotną tablicę. W czym zatem tkwi problem?</p>
<p><span id="more-133"></span>Po wykonaniu powyższego kodu tablica <em>$words</em> wygląda następująco (<em>var_dump($words)</em>):</p>
<pre class="brush: plain">array(3) {
  [0]=&gt;
  string(4) "SYSTEM"
  [1]=&gt;
  string(4) "BAZA"
  [2]=&gt;
  &amp;string(6) "TELEFON"
}</pre>
<p>Wszystko wygląda na pierwszy rzut oka tak jak oczekiwaliśmy. Spróbujmy zatem wyświetlić teraz wszystkie elementy:</p>
<pre class="brush: php">foreach ($words as $item)
{
  echo $item.' ';
}</pre>
<p>&#8230;w rezultacie otrzymujemy:</p>
<pre class="brush: plain">SYSTEM BAZA BAZA</pre>
<p>Zdziwieni? Dzieje się tak dlatego, iż po pierwszej pętli zmienna <em>$item</em>, która jest wskaźnikiem, wciąż wskazuje na ost. element tablicy. W kolejnym przejściu, mimo iż nie użyliśmy już referencji, to zmienna <em>$item</em> wciąż jest typu wskaźnikowego i następuje wówczas wyciągnięcie aktualnego elementu w pętli <em>foreach</em> i przechowywanie go w ost. komórce tablicy którą analizujemy (zamiast w osobnej zmiennej). Z tej przyczyny, w końcowym kroku, ost. komórka zawiera wartość z kroku poprzedniego &#8211; stąd powtórzone słowo „BAZA”. Oryginalna tablica <em>$words</em> również posiada zmodyfikowaną wartość, co nie powinno mieć miejsca.</p>
<p>Aby uniknąć takich sytuacji możemy zastosować kilka rozwiązań. Pierwsze i chyba najlepsze, zwalniać zmienną iteracyjną po skończonej pętli jeśli używaliśmy referencji:</p>
<pre class="brush: php">$words = array('system', 'baza', 'telefon');
foreach ($words as &amp;$item)
{
  $item = strtoupper($item);
}
unset($item);</pre>
<p>Drugie wyjście, użyć innej zmiennej (o innej nazwie) w ew. kolejnej pętli <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_wink.png' alt=';)' class='wp-smiley' /> . I na koniec, rozwiązanie na siłę:</p>
<pre class="brush: php">$words = array('system', 'baza', 'telefon');
foreach ($words as $key =&gt; $item)
{
  $words[$key] = strtoupper($item);
}</pre>
<p>&#8230;aczkolwiek jeśli używamy referencji to z reguły z powodu z którego nie możemy użyć w/w konstrukcji.</p>
<p>To zachowanie, mimo iż poprawne z punktu widzenia języka PHP, jest częstą przyczyną zgryzów u osób które nie zetknęły się nigdy z tym problemem. Często też jest to uważane za <a href="http://bugs.php.net/bug.php?id=29992">błąd</a> samego parsera, który de facto nim nie jest.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/02/referencja-w-petli-foreach-bug-ktory-nie-jest-bugiem/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kopiowanie pliku między serwerami w PHP</title>
		<link>http://www.bbproject.net/2010/01/kopiowanie-pliku-miedzy-serwerami-w-php/</link>
		<comments>http://www.bbproject.net/2010/01/kopiowanie-pliku-miedzy-serwerami-w-php/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 10:55:15 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[copy]]></category>
		<category><![CDATA[kopiowanie]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[plik]]></category>
		<category><![CDATA[serwer]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=142</guid>
		<description><![CDATA[Swego czasu, gdy publikowałem jeden ze swoich projektów, w celu odciążenia serwera głównego (limit transferu) wysyłałem plik jeszcze na kilka innych. Jako iż jego rozmiar osiągał 30MB, a łącze jakim dysponowałem nie było demonem prędkości, powstał problem &#8211; jak przyspieszyć ten proces? W tym momencie natknąłem się na możliwość kopiowania plików między serwerami przy pomocy [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignright size-thumbnail wp-image-192" title="Pliki" src="http://www.bbproject.net/wp-content/uploads/2010/01/files-160x197.jpg" alt="" width="160" height="197" />Swego czasu, gdy publikowałem jeden ze swoich projektów, w celu odciążenia serwera głównego (limit transferu) wysyłałem plik jeszcze na kilka innych. Jako iż jego rozmiar osiągał 30MB, a łącze jakim dysponowałem nie było demonem prędkości, powstał problem &#8211; jak przyspieszyć ten proces?</p>
<p>W tym momencie natknąłem się na możliwość kopiowania plików między serwerami przy pomocy skryptu PHP. Serwery dostawców usług hostingowych są wyposażone w bardzo szybkie łącza (z reguły), a co za tym idzie, ściągnięcie pliku z innej lokalizacji trwa sekundy zamiast długich minut jakie ja poświęcałem na wrzucenie pliku na każdy FTP z osobna.</p>
<p>Wszystko co musimy zrobić to napisać prosty skrypt PHP i umieścić go w lokalizacji docelowej &#8211; a ten, wykona za nas cała czarną robotę.</p>
<p><span id="more-142"></span>Właściwie wpis ten ogranicza się do jeden komendy w języku PHP: <a href="http://pl2.php.net/manual/en/function.copy.php"><em>copy</em></a>. To za jej pomocą możliwe jest kopiowanie plików. Ale to co nas interesuje to fakt, że plik źródłowy nie musi znajdować się na lokalnym serwerze. Składnia polecenia wygląda następująco:</p>
<pre>bool <strong>copy</strong> ( string <tt>$source</tt> , string <tt>$dest</tt> [, resource <tt>$context</tt> ] )</pre>
<p>Pierwszym parametrem jest plik źródłowy, drugim docelowy, a sama funkcja zwraca wartość PRAWDA/FAŁSZ, mówiąca nam o tym czy operacja kopiowania się udała. Przykładowo:</p>
<pre class="brush: php">copy('http://downloads.sourceforge.net/sevenzip/7z465.exe', '7z465.exe');</pre>
<p>W wyniku otrzymamy pobrany plik <em>7z465.exe</em> do folderu bieżącego (tego w którym znajduje się sam skrypt PHP).</p>
<p>I to w zasadzie wszystko. Czy opłaca się bawić w takie rozwiązania? W moim przypadku, czyli dla serwera na którym stoi ten blog, kopiowanie plików z innego serwera odbywa się z średnią prędkością <strong>60mbps</strong>! W stosunku do moich marnych 512kbps upload&#8217;u jest to kolosalna różnica i oszczędność czasu. Oczywiście wszystko zależy od łącza naszego serwera i docelowego, nie mniej w większości przypadków, są to prędkości przewyższające te jakie oferują nam dostawcy internetu (w akceptowalnych cenach <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_smile.png' alt=':)' class='wp-smiley' /> ).</p>
<p>Na sam koniec, udostępniam prosty <a href="http://www.bbproject.net/wp-content/uploads/2010/01/copy.zip">skrypt PHP</a>, który umożliwia wygodne wykorzystanie funkcji <em>copy</em> &#8211; zawiera formularz oraz wyświetla statystyki po zakończeniu kopiowania.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/01/kopiowanie-pliku-miedzy-serwerami-w-php/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Kodowanie polskich znaków w PHP</title>
		<link>http://www.bbproject.net/2009/12/kodowanie-polskich-znakow-w-php/</link>
		<comments>http://www.bbproject.net/2009/12/kodowanie-polskich-znakow-w-php/#comments</comments>
		<pubDate>Sat, 26 Dec 2009 11:20:25 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[charset]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[kodowanie]]></category>
		<category><![CDATA[meta]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[utf-8]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=93</guid>
		<description><![CDATA[Prawdziwym problemem dla początkujących programistów PHP, może być nie rzadko brak wyświetlania polskich znaków w skryptach PHP. Zamiast miotać się pomiędzy różnymi edytorami kodu, które w taki czy inny sposób oferują zmianę kodowania pliku, prześledźmy po kolei wszystkie etapy tej przypadłości i rozwiążmy je raz na zawsze. Przyczyny mogą być różne, od błędnego zapisania pliku, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-94" title="Polski font" src="http://www.bbproject.net/wp-content/uploads/2009/12/pl_font-160x113.png" alt="" width="160" height="113" />Prawdziwym problemem dla początkujących programistów PHP, może być nie rzadko brak wyświetlania polskich znaków w skryptach PHP. Zamiast miotać się pomiędzy różnymi edytorami kodu, które w taki czy inny sposób oferują zmianę kodowania pliku, prześledźmy po kolei wszystkie etapy tej przypadłości i rozwiążmy je raz na zawsze.</p>
<p>Przyczyny mogą być różne, od błędnego zapisania pliku, aż po wymuszone kodowanie znaków w nagłówku HTTP. Jeśli spotkałeś się nie raz z popularnymi krzakami na swojej stronie, zamiast polskich znaków diakrytycznych, to zapraszam do przeczytania dalszej części wpisu.</p>
<p><span id="more-93"></span>Po pierwsze musimy zdecydować się na jakiś system kodowania znaków, których używamy w tworzonych plikach. W moim przypadku będzie to, obecnie najpopularniejszy, system <a href="http://pl.wikipedia.org/wiki/UTF-8"><em>utf-8</em></a>. Nic nie stoi przeszkodzie aby używać chociażby <em>iso-8859-2</em>, jednakże <em>utf-8</em> oferuje nam znacznie szerszy zestaw znaków i jest obsługiwany obecnie przez coraz więcej systemów docelowych (np.: przeglądarki mobilne).</p>
<h4>Edytor</h4>
<p>Zacznijmy od edytora w jakim tworzymy nasz skrypt. Początkowo jest to zapewne systemowy notatnik. Program ten, o ile nie wybierzemy inaczej, domyślnie zapisuje pliki w kodowaniu <em>windows-1250</em>. Kodowanie to obsługiwane jest wyłącznie na systemach firmy Microsoft i należy go unikać jak ognia na dzień dzisiejszy. Podczas zapisywania pliku, mamy możliwość zmiany na <em>utf-8</em> na dole okna dialogowego &#8211; pole wyboru <em>Kodowanie</em>.</p>
<p>Osobiście, polecam korzystanie z narzędzi o większych możliwościach, takich jak środowiska <a href="http://www.netbeans.org">NetBeans</a> czy <a href="http://www.eclipse.org">Eclipse</a>. Mogą one wyglądać skomplikowanie dla początkującego programisty, jednakże oferują gamę udogodnień i przydatnych funkcji.</p>
<h4>Sekcja meta</h4>
<p>Przypuśćmy że mamy już poprawnie zapisany plik w wybranym przez nas systemie kodowania znaków. Uruchamiamy skrypt na lokalnym bądź wirtualnym serwerze a naszym oczom ukazują się znaczki o nieznanym dla nas pochodzeniu, które na pewno nie są naszymi rodzimymi ogonkami.</p>
<p>Drugim, często popełnianym błędem, jest brak sekcji <em>meta</em> strony, informującej o jej kodowaniu. Aby poprawnie zdefiniować kodowanie dokumentu HTML, używamy następującego zapisu:</p>
<pre class="brush: xml">&lt;meta http-equiv="content-type" content="text/html; charset=utf-8"&gt;</pre>
<p>&#8230;który umieszczamy między znacznikami <em>&lt;head&gt;</em>&#8230;<em>&lt;/head&gt;</em>. Przykładowo:</p>
<pre class="brush: xml">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv="content-type" content="text/html; charset=utf-8"&gt;
    &lt;title&gt;Moja strona w utf-8&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;...&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Co jednak zrobić jeśli wciąż nie otrzymujemy oczekiwanego efektu?</p>
<h4>Nagłówek HTTP</h4>
<p>Nagłówek protokołu <a href="http://pl.wikipedia.org/wiki/Hypertext_Transfer_Protocol">HTTP</a> zawiera szereg informacji przesyłanych do przeglądarki, mówiący o tym co tak właściwie jest wysyłane. Jedną z tych informacji jest kodowanie znaków dokumentu &#8211; znowu.</p>
<p>Problem polega na tym, iż przeglądarki wyświetlają stronę w takim kodowaniu, jakie zostało im przedstawione w nagłówku protokołu. W praktyce to co zostało zdefiniowane w sekcji meta strony nie ma znaczenia, chyba że nagłówek HTTP nie zawiera takiej informacji.</p>
<p>Bardzo często, parser PHP ma wymuszone wysyłanie dokumentów w jednym, określonym systemie kodowania znaków. Odpowiada za to następujący wpis w pliku konfiguracji <em>php.ini</em>:</p>
<pre class="brush: plain">default_charset = "iso-8859-1"</pre>
<p>O ile dysponujemy własnym, lokalnie postawionym serwerem, możemy łatwo edytować bądź całkowicie wyłączyć tą linię, to w przypadku serwera wirtualnego z reguły nie posiadamy takiej władzy.</p>
<p>W takim wypadku musimy nadpisać sami nagłówek HTTP w skrypcie PHP. Służy do tego polecenie <em><a href="http://php.net/manual/en/function.header.php">header</a></em>. Nas interesuje oczywiście zmiana samego kodowania, inne możliwości tej komendy na razie zostawmy w spokoju. Dodajemy zatem do naszego skryptu następującą linię:</p>
<pre class="brush: php">header('Content-Type: text/html; charset=utf-8');</pre>
<p>Nie mniej musimy pamiętać o tym, że ustawienie parametru nagłówka HTTP przy pomocy w/w komendy, musi nastąpić zanim wyślemy jakiekolwiek inne dane do przeglądarki. Innymi słowy, nie może użyć polecenia <em>echo</em> czy też <em>print</em> zanim nie ustawimy nagłówka. Jak sama nazwa wskazuje, jest to nagłówek, czyli znajduje się przed docelową treścią dokumentu.</p>
<h4>Podsumowanie</h4>
<p>Mój docelowy plik, jaki stworzyłem na potrzeby tego wpisu, prezentuje się następująco:</p>
<pre class="brush: php">&lt;?php header('Content-Type: text/html; charset=utf-8'); ?&gt;
&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta http-equiv="content-type" content="text/html; charset=utf-8"&gt;
    &lt;title&gt;Moja strona w utf-8&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;p&gt;&lt;?php echo 'ęóąśłżźćń'; ?&gt;&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<p>Jak widzimy, wymusiliśmy tutaj kodowanie <em>utf-8</em> w nagłówku HTTP, sekcji <em>meta</em>, oraz sam plik został zapisany z poprawnym kodowaniem znaków. Tak przygotowany dokument, nie powinien sprawiać żadnych problemów w dowolnej konfiguracji serwera. W efekcie otrzymamy poprawnie zakodowane oraz wyświetlone polskie znaki diakrytyczne.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2009/12/kodowanie-polskich-znakow-w-php/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Własny serwer WWW, instalacja Apache i PHP</title>
		<link>http://www.bbproject.net/2009/12/wlasny-serwer-www-instalacja-apache-i-php/</link>
		<comments>http://www.bbproject.net/2009/12/wlasny-serwer-www-instalacja-apache-i-php/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 08:51:38 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[konfiguracja]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[serwer]]></category>
		<category><![CDATA[www]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=62</guid>
		<description><![CDATA[W życiu każdego webmastera, czy też developera, nadchodzi taki moment, w którym postanawia on uruchomić własny serwer WWW w celu pracy na lokalnej maszynie. Nikt nie lubi, po każdorazowym zapisaniu skryptu PHP, wrzucać go na docelowy serwer z obsługą PHP tylko po to, aby zobaczyć efekt działania. Dużo wygodniejszym rozwiązaniem, jest skorzystanie z lokalnie postawionego [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-64" title="Serwer" src="http://www.bbproject.net/wp-content/uploads/2009/12/server_cables-160x108.jpg" alt="Serwer" width="160" height="108" />W życiu każdego webmastera, czy też developera, nadchodzi taki moment, w którym postanawia on uruchomić własny serwer WWW w celu pracy na lokalnej maszynie. Nikt nie lubi, po każdorazowym zapisaniu skryptu PHP, wrzucać go na docelowy serwer z obsługą PHP tylko po to, aby zobaczyć efekt działania. Dużo wygodniejszym rozwiązaniem, jest skorzystanie z lokalnie postawionego serwera wraz z obsługą PHP oraz bazą danych MySQL.</p>
<p>Istnieją wprawdzie gotowe paczki, zawierające w sobie wszystkie te komponenty, instalowane automatycznie bez zbędnych zabaw z konfiguracją, niemniej jednak, z reguły pakiety te posiadają nieaktualne już wersji programów składowych, czy też instalują nadmiar rzeczy nam zbędnych. Być może ręczna instalacja serwera, parsera oraz bazy danych jest bardziej skomplikowana, jednakże, mamy kontrolę nad tym co, gdzie i jak instalujemy.</p>
<p><span id="more-62"></span>Wpis ten, jest pierwszą częścią instrukcji, krok po kroku, jak postawić lokalny serwer WWW. Opis skierowany jest w kierunku maszyny roboczej, która jest używana do pisania strony WWW, bądź skryptu PHP a niżeli jako docelowy system serwerowy.</p>
<h4>Apache</h4>
<p><img class="size-full wp-image-65 alignright" title="Apache" src="http://www.bbproject.net/wp-content/uploads/2009/12/apache.png" alt="Apache" width="150" height="150" /><a href="http://pl.wikipedia.org/wiki/Apache_%28serwer%29">Apache</a> HTTP, jest to serwer WWW, czyli aplikacja sprawiająca, że po wpisaniu adresu IP naszego komputera, możliwe jest przeglądanie stron udostępnionych przez ów serwer.</p>
<p>Pierwszą czynnością, jakiej musimy dokonać, jest oczywiście pobranie samego programu. Przechodzimy zatem na <a href="http://httpd.apache.org">stronę producenta</a> i pobieramy najnowszą wersję na platformę Windows. W tym celu, z lewego menu wybieramy <em>Download</em> &gt; <em>from a mirror</em>. Pobieramy paczkę oznaczoną jako <em>Win32 Binary without crypto</em>.</p>
<h5>Instalacja</h5>
<p>Po udanym pobraniu pliku, przechodzimy do instalacji, uruchamiany zapisany na dysku plik. Pierwszy ekran powitalny informuje nas o wersji pakietu, przechodzimy do następnego okna. Po zaakceptowaniu licencji dochodzimy do <em>Server Information</em> w którym musimy podać parametry naszego serwera. W zasadzie możemy pozostawić wartości domyślne, nie mają one większego znaczenie, zwłaszcza że docelowo sami będzie edytować plik konfiguracji serwera.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-66" title="Apache - Server Information" src="http://www.bbproject.net/wp-content/uploads/2009/12/apache_server_information.png" alt="Apache - Server Information" width="504" height="381" /></p>
<p>W oknie <em>Setup Type</em> wybieramy <em>Typical</em>. Ścieżka instalacji może pozostać domyślna. Kończmy instalację klikając <em>Install</em>.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-67" title="Apache - Installing" src="http://www.bbproject.net/wp-content/uploads/2009/12/apache_installing.png" alt="Apache - Installing" width="504" height="381" /></p>
<p>Po zakończonej instalacji, wpisując w pasku adresu przeglądarki adres <em>localhost</em>, naszym oczom powinien pokazać się napis <strong>It works!</strong> Jeśli takowego nie widzimy, możliwe że inna aplikacja nasłuchuje już na porcie 80, stąd serwer Apache nie może zostać uruchomiony. Jedną z takich aplikacji, jest komunikator Skype, nie wiadomo dlaczego, zajmuje on port 80, mimo iż jest to port zarezerwowany właśnie dla usług serwera WWW. W tej sytuacji wymagany będzie restart komputera. Stan serwera możemy sprawdzić, klikając na nową ikonę w zasobniku systemowym.</p>
<h5>Konfiguracja</h5>
<p>Po zakończeniu instalacji, musimy jeszcze dokonać kilku drobnych zmian w konfiguracji serwera. Między innymi przenieść folder z dokumentami html do innej lokacji, najlepiej takiej która nie znajduje się na partycji systemowej. Robimy to w celu odseparowania plików jakie serwer ma udostępniać od samego oprogramowania.</p>
<p>Przechodzimy do folderu w którym zainstalowaliśmy Apache, do podkatalogu <em>conf</em>, domyślnie będzie to <em>C:\Program Files\Apache Software Foundation\Apache2.2\conf</em>. Otwieramy do edycji plik <em>httpd.conf</em>.</p>
<p>Odszukujemy linię zaczynającą się od <em>ServerAdmin</em> i zmieniamy jej wartość na nasz adres e-mail:</p>
<pre class="brush: plain">ServerAdmin twoj@adres.email</pre>
<p>Nieco niżej odnajdujemy parametr <em>#ServerName</em> i zmieniamy go w następujący sposób:</p>
<pre class="brush: plain">ServerName :80</pre>
<p>Znaczek # na początku linii, oznacza komentarz, usuwamy go załączając w ten sposób daną komendę. Najważniejsze dla nas ustawienie to <em>DocumentRoot</em>, wskazujące folder przechowywania plików udostępnianych przez serwer. Wybieramy dogodną dla siebie lokalizację na dysku i zmieniamy wartość parametru.</p>
<pre class="brush: plain">DocumentRoot "G:\Server\www"</pre>
<p>Podobnie musimy postąpić z linią:</p>
<pre class="brush: plain">&lt;Directory "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs"&gt;</pre>
<p>&#8230;zmieniając ją na:</p>
<pre class="brush: plain">&lt;Directory "G:\Server\www"&gt;</pre>
<p>Zapisujemy plik konfiguracji a następnie restartujemy serwer w celu jej uaktywnienia.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-68" title="Apache - Service Monitor" src="http://www.bbproject.net/wp-content/uploads/2009/12/apache_service_monitor.png" alt="Apache - Service Monitor" width="531" height="331" /></p>
<p>Po odświeżeniu adresu <em>localhost</em> w przeglądarce, powinniśmy otrzymać zawartość folderu, z uwagi na fakt iż nie unieśliśmy żadnego pliku w zmienionej ścieżce dokumentów serwera. Naprawiamy szybko ten błąd tworząc przykładowy plik html i zapisując go pod nazwą <em>index.html</em>.</p>
<pre class="brush: xml">&lt;html&gt;
  &lt;head&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Hello world!&lt;/h1&gt;
  &lt;/body&gt;
&lt;/html&gt;</pre>
<h5>Podsumowanie</h5>
<p>Cały proces może wyglądać dość skomplikowanie, jednakże sprowadza się on do instalacji oprogramowania serwera, kilku drobnych zmian w pliku konfiguracyjnym oraz zrestartowania usługi.</p>
<p>Jeśli posiadamy publiczny adres IP, wpisując go w przeglądarce innej maszyny niż nasza, powinniśmy ujrzeć dokładnie tą samą stronę co lokalnie.</p>
<h4>PHP</h4>
<p><img class="alignright size-thumbnail wp-image-69" title="PHP" src="http://www.bbproject.net/wp-content/uploads/2009/12/php-160x84.png" alt="PHP" width="160" height="84" /><a href="http://pl.wikipedia.org/wiki/PHP">PHP</a> jest parserem języka PHP <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_smile.png' alt=':)' class='wp-smiley' /> , umożliwiając nam uruchamianie jego skryptów. Główne zastosowanie, znajduje on właśnie w dynamicznym generowaniu treści stron internetowych.</p>
<p>Podobnie jak w przypadku serwera WWW, musimy najpierw pobrać odpowiednie oprogramowanie. Przechodzimy zatem na stronę <a href="http://www.php.net">php.net</a> i z prawej kolumny pobierany najnowszą wersję stabilną (<em>stable</em>). W moim wypadku było to PHP 5.3.1. W sekcji <em>Windows Binaries</em> zostaniemy przeniesieni na kolejną <a href="http://windows.php.net/download">stronę</a>, gdzie znajdują się pliki wykonywalne dla platformy Windows. Pobieramy wersję <em>VC6 x86 Thread Safe</em> w postaci archiwum ZIP. Jest to na tyle istotne, gdyż inna, z czterech dostępnych, nie będzie poprawnie współpracować z serwerem Apache.</p>
<h5>Instalacja</h5>
<p>Instalacja sprowadza się do wypakowania zawartości archiwum. Jako iż wersja ta nie wymaga instalacji, najlepiej będzie jeśli umieścimy ją w stworzonym wcześniej folderze Server w podkatalogu php.</p>
<h5>Konfiguracja</h5>
<p>Przejdźmy zatem do konfiguracji. W głównym folderze PHP robimy kopię pliku <em>php.ini-development</em> i zmieniamy nazwę na <em>php.ini</em>. Otwieramy nowy plik do edycji. Aby nie zaciemniać obrazu, znajdujemy poniższe parametry i zmieniamy je tak jak poniżej:</p>
<pre class="brush: plain">doc_root = "G:\Server\www"</pre>
<pre class="brush: plain">extension_dir = "G:\Server\php\ext"</pre>
<pre class="brush: plain">date.timezone = "Europe/Warsaw"</pre>
<p>Jeśli któryś z parametrów jest poprzedzony znakiem komentarza ; (średnikiem), należy go usunąć. Odpowiednie ścieżki modyfikujemy w zależności od tego gdzie umieściliśmy nasz folder z dokumentami html, oraz sam parser PHP. Jeżeli będziemy używać w PHP funkcji do wysyłania poczty elektronicznej, dobrze jest też ustawić parametry serwera SMTP:</p>
<pre class="brush: plain">SMTP = twoj.serwer.smtp</pre>
<pre class="brush: plain">sendmail_from = twoj@adres.email</pre>
<p>Oczywiście należy tutaj podać swój serwer SMTP oraz domyślny adres e-mail, jaki ma widnieć w polu „od”, wysłanych za pośrednictwem PHP listów.</p>
<p>Nas sam koniec przechodzimy do sekcji <em>Dynamic Extensions</em>. Poniżej niej, znajdziemy listę wszystkich dostępnych rozszerzeń w PHP. Domyślnie wszystkie nie są ładowane (znak komentarza przed każdą z linijek). Aby w przyszłości uniknąć niepotrzebnego stresu, z marszu możemy załączyć kilka z nich:</p>
<ul>
<li>php_curl.dll</li>
<li>php_gettext.dll</li>
<li>php_mbstring.dll</li>
<li>php_mysql.dll</li>
<li>php_mysqli.dll</li>
<li>php_sockets.dll</li>
<li>php_sqlite3.dll</li>
</ul>
<p>W razie potrzeby, nic nie stoi na przeszkodzie, aby później włączyć/wyłączyć któreś z rozszerzeń. Usuwamy znak komentarza z w/w dodatków aby uczynić je aktywnymi.</p>
<p>Zasadniczo jeśli chodzi o PHP to już cała konfiguracja. Ostatnie co musimy zrobić to nakazać serwerowi WWW parsowanie plików z rozszerzeniem php, a nie ich wyświetlanie jako zwykły tekst. W tym celu otwieramy ponownie plik <em>httpd.conf</em> w folderze Apache.</p>
<p>W pierwszej kolejności odnajdujemy fragment:</p>
<pre class="brush: plain">&lt;IfModule dir_module&gt;
  DirectoryIndex index.html
&lt;/IfModule&gt;</pre>
<p>&#8230;i zmieniamy na:</p>
<pre class="brush: plain">&lt;IfModule dir_module&gt;
  DirectoryIndex index.php index.html
&lt;/IfModule&gt;</pre>
<p>Zmiana ta, nakazuje serwerowi wyszukiwanie domyślnego pliku folderu nie tylko wśród plików html, ale także i php.</p>
<p>Przechodzimy na sam koniec pliku i doklejamy taki oto fragment:</p>
<pre class="brush: plain">LoadModule php5_module "G:\Server\php\php5apache2_2.dll"
AddType application/x-httpd-php .php
PHPIniDir "G:\Server\php"</pre>
<p>Jak zwykle pamiętamy o odpowiednich ścieżkach. Ostatecznie, te trzy linijki odpowiedzialne są za przekazanie plików PHP do parsera i zwrócenie wyniku z powrotem do serwera, aby w rezultacie móc obserwować wygenerowaną stronę.</p>
<h5>Jazda próbna</h5>
<p>Czas na przetestowanie czy parser PHP działa poprawnie. Po zapisaniu zmian w pliku konfiguracji PHP oraz Apache, przeprowadzamy restart serwera. Kolejno tworzymy następujący plik <em>index.php</em> i zapisujemy go w głównym folderze serwera (gdzie wcześniej umieściliśmy plik <em>index.html</em>).</p>
<pre class="brush: xml">&lt;?php
  phpinfo();
?&gt;</pre>
<p>Po odwołaniu się do naszej strony w przeglądarce internetowej, naszym oczom powinien ukazać się wynik działania powyższego skryptu &#8211; informacje o parserze PHP.</p>
<p style="text-align: center;"><a href="http://www.bbproject.net/wp-content/uploads/2009/12/phpinfo.png"><img class="alignnone size-large wp-image-70" title="PHP Info" src="http://www.bbproject.net/wp-content/uploads/2009/12/phpinfo-512x409.png" alt="PHP Info" width="512" height="409" /></a></p>
<h5 style="text-align: left;">W razie problemów</h5>
<p style="text-align: left;">Jeśli z jakiegoś powodu, nie uda się ponowny start serwera po dołączeniu do niego obsługi skryptów PHP, możliwe że musimy dodatkowo zmodyfikować ścieżkę przeszukiwania systemu Windows, dodając do niej folder z samym PHP jak i jego rozszerzeniami. W tym celu, przechodzimy do właściwości systemu, zakładka zaawansowane, zmienne środowiskowe. W grupie <em>Zmienne systemowe</em> odnajdujemy tą o nazwie <em>Path</em> i ją edytujemy. Na końcu, po znaku średnika, dopisujemy:</p>
<pre class="brush: plain">G:\Server\php;G:\Server\php\ext</pre>
<p style="text-align: left;">&#8230;pamiętając przy tym, by nie naruszyć znajdujących się tam już danych.</p>
<p style="text-align: center;"><img class="alignnone size-full wp-image-72" title="Edytowanie zmiennej systemowej Path" src="http://www.bbproject.net/wp-content/uploads/2009/12/windows_path_var.png" alt="Edytowanie zmiennej systemowej Path" width="452" height="520" /></p>
<p style="text-align: left;">Po zatwierdzeniu, ponawiamy próbę uruchomienia serwera WWW.</p>
<h4 style="text-align: left;">Posumowanie</h4>
<p style="text-align: left;">I tym sposobem, postawiliśmy nasz serwer WWW wraz z PHP. Jeśli dopiero zaczynasz przygodę z tym językiem, pewne zmiany w pliku konfiguracyjnym mogą Ci się wydać niezrozumiałe, dlatego ograniczyłem je do niezbędnego minimum. Wraz z wzrostem wtajemniczenia, zaczniesz dokonywać własnych modyfikacji, tak aby pracować możliwe jak najwydajniej.</p>
<p style="text-align: left;">Na koniec załączam oba <a href="http://www.bbproject.net/wp-content/uploads/2009/12/server_conf.zip">pliki konfiguracyjne</a>, jeśli zaprezentowana treść okazała by się niewystarczająca.</p>
<p style="text-align: left;">Do pełni szczęścia, brakuje nam już tylko serwera bazodanowego MySQL oraz narzędzia, które znacznie ułatwia pracę na bazach danych &#8211; phpMyAdmin. Tymi zagadnieniami zajmiemy się w <a href="http://www.bbproject.net/2010/01/wlasny-serwer-www-instalacja-mysql-i-phpmyadmin">kolejnej części</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2009/12/wlasny-serwer-www-instalacja-apache-i-php/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Piszemy parser BBCode</title>
		<link>http://www.bbproject.net/2009/12/piszemy-parser-bbcode/</link>
		<comments>http://www.bbproject.net/2009/12/piszemy-parser-bbcode/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 09:05:03 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[bbcode]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regexp]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=23</guid>
		<description><![CDATA[BBCode jest to język formatowania wiadomości internetowych, pojawiający się często na forach dyskusyjnych. Głównym założeniem tego skryptu jest ułatwienie osobie nieznającej składni HTML odpowiedniego zmodyfikowania wypowiedzi na jej potrzeby. Źródło: http://pl.wikipedia.org/wiki/BBCode Jak dodać obsługę znaczników BBCode do własnej strony, forum czy też systemu komentarzy? Zajmiemy się dziś rozwiązaniem tego problemu przy pomocy wyrażeń regularnych w [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>BBCode jest to język formatowania wiadomości internetowych, pojawiający się często na forach dyskusyjnych. Głównym założeniem tego skryptu jest ułatwienie osobie nieznającej składni HTML odpowiedniego zmodyfikowania wypowiedzi na jej potrzeby.</p>
<p>Źródło: <a href="http://pl.wikipedia.org/wiki/BBCode">http://pl.wikipedia.org/wiki/BBCode</a></p></blockquote>
<p>Jak dodać obsługę znaczników BBCode do własnej strony, forum czy też systemu komentarzy? Zajmiemy się dziś rozwiązaniem tego problemu przy pomocy wyrażeń regularnych w języku PHP.</p>
<p><span id="more-23"></span></p>
<h4>BBCode, wyrażenia regularne</h4>
<p>Wyrażenia regularne służą do zaawansowanego dopasowania szukanej w tekście frazy. Tym razem zaprzęgniemy je do zamiany tagów BBCode, na odpowiedni kod HTML w celu uzyskania pożądanego formatowania.</p>
<p>Znaczników BBCode może być kilka lub kilkadziesiąt <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_wink.png' alt=';)' class='wp-smiley' />  w zależności od implementacji jaką będzie nam dane spotkać, my skupimy się na tych podstawowych jak <strong>pogrubienie</strong>, <em>pochylenie</em>, <span style="text-decoration: underline;">podkreślenie</span> tekstu, zmianę <span style="color: #ff6600;">koloru</span>, rozmiaru oraz tworzenie <a href="http://www.bbproject.net">hiperłączy</a>. Pozostałe, czy nawet swoje własne łatwo dodać bazując na tych podstawowych.</p>
<p>Funkcja służącą do dopasowania wyrażenie regularnego do treści jest <a href="http://pl.php.net/manual/en/function.preg-match.php">preg_match</a>, z kolei do zamiany treści <a href="http://pl.php.net/manual/en/function.preg-replace.php">preg_replace</a>. Nie chcę tutaj skupiać się na tym jak wyglądają/działają wyrażenia regularne, gdyż z pewnością zajęło by to więcej czasu niż napisanie całego parsera BBCode, omówię zatem tylko ogólnie co dane wyrażenie rogi.</p>
<h4>Pogrubienie tekstu</h4>
<p>Zacznijmy zatem od pogrubienia tych treści które zostały opatrzone tagami [b]&#8230;[/b]:</p>
<pre class="brush: php">$text = preg_replace
(
  '|\[b\](.*?)\[/b\]|i',
  '&lt;span style="font-weight: bold;"&gt;\1&lt;/span&gt;',
  $text
);</pre>
<p>Zastosowane wyrażenie regularne:</p>
<pre class="brush: php">|\[b\](.*?)\[/b\]|i</pre>
<p>&#8230;ma za zadanie odszukać wszystkie wystąpienia ciągu [b](dowolny tekst)[/b] i zamienić go na odpowiednie znaczniki HTML (zaopatrzone w styl dodający pogrubienie czcionki). Końcowy przełącznik „i”, sprawa że wielkość liter jest ignorowana, zatem nie ma znaczenia czy użyte taki BBCode będą wpisane z małej czy też dużej litery.</p>
<h4>Zmiana koloru i rozmiaru</h4>
<p>Jak można się domyślić, podobnie wyglądać będzie kod dla pozostałych formatowań. Przejdźmy teraz do znaczników z dodatkowym parametrem, takim jak zmiana koloru ([color=red]&#8230;[/color]) oraz rozmiaru tekstu ([size=16]&#8230;[/size]):</p>
<pre class="brush: php">$text = preg_replace
(
  '|\[color=([a-z]+)\](.*?)\[/color\]|i',
  '&lt;span style="color: \1;"&gt;\2&lt;/span&gt;',
  $text
);

$text = preg_replace
(
  '|\[size=([0-9]+)\](.*?)\[/size\]|i',
  '&lt;span style="font-size: \1px;"&gt;\2&lt;/span&gt;',
  $text
);</pre>
<p>Tym razem wyrażenia regularne wyłuskują 2 parametry jakimi jest rozmiar/kolor tekstu oraz właściwy fragment który należy odpowiednio sformatować.</p>
<h4>Hiperłącza</h4>
<p>I jedyne co pozostało to hiperłącza ([url=moja_strona.pl]&#8230;[/url]):</p>
<pre class="brush: php">$text = preg_replace
(
  '|\[url=(http://)?(.+?)\](.*?)\[/url\]|i',
  '&lt;a href="http://\2"&gt;\3&lt;/a&gt;',
  $text
);</pre>
<p>Dodatkowo, powyższy fragment kodu, sprawdza czy adres został podany z czy też bez przedrostka http://, i przy jego braku dodaje go. Zapewnia to większą uniwersalność działania.</p>
<h4>Gotowe rozwiązanie</h4>
<p>Zbierzmy zatem wszystko w ładną całość w postaci funkcji:</p>
<pre class="brush: php">function bbcode($text)
{
  $patterns = array
  (
    '|\[b\](.*?)\[/b\]|i',
    '|\[i\](.*?)\[/i\]|i',
    '|\[u\](.*?)\[/u\]|i',
    '|\[color=([a-z]+)\](.*?)\[/color\]|i',
    '|\[size=([0-9]+)\](.*?)\[/size\]|i',
    '|\[url=(http://)?(.+?)\](.*?)\[/url\]|i'
  );
  $replacements = array
  (
    '&lt;span style="font-weight: bold;"&gt;\1&lt;/span&gt;',
    '&lt;span style="font-style: italic;"&gt;\1&lt;/span&gt;',
    '&lt;span style="text-decoration: underline;"&gt;\1&lt;/span&gt;',
    '&lt;span style="color: \1;"&gt;\2&lt;/span&gt;',
    '&lt;span style="font-size: \1px;"&gt;\2&lt;/span&gt;',
    '&lt;a href="http://\2"&gt;\3&lt;/a&gt;'
  );
  $text = str_replace("\n", '&lt;br&gt;', trim($text));
  $text = preg_replace($patterns, $replacements, $text);
  return $text;
}</pre>
<p>Najwyższy czas na sprawdzenie jak spisuje się skonstruowana przez nas funkcja. Weźmy przykładowy tekst i przepośćmy go przez funkcję bbcode():</p>
<pre class="brush: plain">Lorem [b]ipsum dolor[/b] sit amet enim. [i]Etiam ullamcorper[/i]. Suspendisse a pellentesque dui, non felis.
Maecenas malesuada elit lectus felis, [u]malesuada[/u] ultricies.
Curabitur et ligula. Ut molestie a, ultricies porta urna.

Vestibulum [color=green]commodo volutpat,[/color] a, convallis ac, laoreet enim. [size=30]P[/size]hasellus fermentum in, dolor.
Pellentesque [url=bbproject.net]facilisis[/url]. Nulla imperdiet sit amet magna.
Vestibulum [size=20][b][color=red]dapibus[/color][/b][/size], mauris nec [b][i][u]malesuada[/u][/i][/b] fames ac turpis velit,
[size=24][url=http://www.bbproject.net]rhoncus[/url][/size] eu, luctus et interdum adipiscing wisi.</pre>
<p>&#8230;i sprawdźmy jej wynik:</p>
<p style="text-align: left;">Lorem <span style="font-weight: bold;">ipsum dolor</span> sit amet enim. <span style="font-style: italic;">Etiam ullamcorper</span>. Suspendisse a pellentesque dui, non felis.<br />
Maecenas malesuada elit lectus felis, <span style="text-decoration: underline;">malesuada</span> ultricies.<br />
Curabitur et ligula. Ut molestie a, ultricies porta urna.</p>
<p style="text-align: left;">Vestibulum <span style="color: green;">commodo volutpat,</span> a, convallis ac, laoreet enim. <span style="font-size: 30px;">P</span>hasellus fermentum in, dolor.<br />
Pellentesque <a href="http://bbproject.net">facilisis</a>. Nulla imperdiet sit amet magna.<br />
Vestibulum <span style="font-size: 20px;"><span style="font-weight: bold;"><span style="color: red;">dapibus</span></span></span>, mauris nec <span style="font-weight: bold;"><span style="font-style: italic;"><span style="text-decoration: underline;">malesuada</span></span></span> fames ac turpis velit,<br />
<span style="font-size: 24px;"><a href="http://www.bbproject.net">rhoncus</a></span> eu, luctus et interdum adipiscing wisi.</p>
<h4 style="text-align: left;">Podsumowanie</h4>
<p>Tym sposobem zakończyliśmy ten krótki przewodnik po BBCode i ich wykorzystaniu przy pomocy wyrażeń regularnych w PHP. Osobiście zachęcam do zgłębienia wiedzy na temat samych wyrażeń regularnych, gdyż jest to potężne narzędzie jeśli wiemy jak się nim posługiwać, a możliwości jego wykorzystania nie kończą się na PHP, gdyż wiele nowoczesnych języków również je obsługuje (czy też nawet niektóre środowiska IDE do wyszukiwania treści).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2009/12/piszemy-parser-bbcode/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
