Debugowanie kodu PHP (bez debuggera)

konrados

1. Raportowanie błędów

Żeby w ogóle móc zacząć debugować musimy mieć włączone raportowanie błędów. Według mnie najlepiej debugować na localhost.

Po pierwsze musimy włączyć raportowanie błędów, jeśli jest wyłączone. Możemy to zrobić na trzy sposoby:

  • Ustawić raportowanie błędu w piku konfiguracyjnym - otwieramy php.ini notatnikiem, naciskamy Ctrl+F i wpisujemy "display_errors=", jeśli wartość jest "off" to zmieniamy na "on".
  • Ustawić raportowanie błędów w runtime'ie - na początku pliku php piszemy :
<?php
ini_set('display_errors', 1);
  • jeszcze jedna możliwość, najgorsza, nie działa w przypadku błędów parsowania; Ustawienie niestandardowego error handlera - Na początku kodu dodajemy:
    <?php
    function error($type, $message, $file, $line) {
        echo "$message in $file on line $line";
    }
    set_error_handler('error');
    

Po drugie, musimy ustawić to, które z błędów będą raportowane:

  • Albo ustawić to w runtime'ie:
    • Musimy więc na początku kodu umieścić:
      <?php
      error_reporting(E_ALL | E_NOTICE | E_STRICT);
      
  • Albo w pliku konfiguracyjnym:
    • tym razem szukamy w pliku php.ini słówka "error_reporting=" i zmieniamy wartość na "E_ALL | E_NOTICE | E_STRICT".

Dlaczego taką? W starczych wersjach PHP stała E_ALL zawierała w sobie tylko errory i warningi (trzeba było też dodać notice'y i błędy strict). W nowszych wersjach PHP (od PHP 5.4) można już pisać samo E_ALL.

2. Brak raportowania błędów

Gdy nie mamy możliwości włączenia raportowania błędów możemy:

  • na końcu kodu dodać
echo 1;

oraz zakomentować cały pozostały kod /* */, i jeśli na ekranie pojawi się 1 to komentujemy coraz mniejsze fragmenty kodu, aż 1 się nie pojawi i będziemy wiedzieli mniej więcej w których okolicach kodu jest błąd.

  • co jakiś czas dajemy echo, np.
$a = 1;
$b = 1;
echo 1;
$c = 1;
$d = 1;
echo 2;	

3. Debugowanie zapytań do baz danych.

Jeśli do zapytania dodajesz jakieś wartości ze zmiennych to najpierw sprawdź jakie zapytanie idzie do bazy:

<?php
mysql_query($q = 'UPDATE s SET d = ' . $a . ' WHERE c = ' . $e);
echo $q;

Jeśli wyjdzie "UPDATE s SET d = WHERE c = 1" to wiesz, że zmienna $a jest pusta.

Treść błędu SQL

Dalej, treść błędu: `mysql_query()` w przypadku nie powodzenia zwraca false, więc możemy zrobić tak:
<?php
mysql_query('UPDATE s SET d = '.$a.' WHERE c = '.$e) or die(mysq_error());

Zobaczymy wtedy dokładnie jaki jest problem z zapytaniem (a nie tylko z jego składnią).

4. Treści błędów

Tutaj będę wypisywał najpopularniejsze treści błędów i ich rozwiązanie.
  • Parse error: syntax error, unexpected T_* in *

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a = 1;
    $b = 1
    function s()
    {
        echo 1;
    }
    

    wywala Parse error: syntax error, unexpected T_FUNCTION in ŚCIEŻKA DO PLIKU on line 7. Błąd oznacza, że zapomnieliśmy średnika ; w 7 linijce.

    Poprawnie:

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a = 1;
    $b = 1;
    function s()
    {
        echo 1;
    
  • Parse error: syntax error, unexpected $end in *

    • Kod skończył się w niespodziewanym momencie (nie zamknięty string, nie zamknięta funkcja, nie zamknięta klasa, etc.)

    np.

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a = 1;
    $b = 1;
    function s() {
        echo 1;
    

    Błąd oznacza, że zapomnieliśmy klamry zamykającej: }.

    Poprawnie:

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a = 1;
    $b = 1;
    function s() {
        echo 1;
    }
    
  • Parse error: syntax error, unexpected T_*, expecting '{' *

    • zapomnieliśmy klamry zamykającej: }.
  • Fatal error: Call to undefined function *() *

    Próbujemy wywołać nie zdefiniowaną funkcje

    np.

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a = 1;
    $b = 1;
    function s() {
        echo 1;
    }
    
    ss();
    

    Kod powyżej wywali Fatal error: Call to undefined function ss() in on line 12, podczas gdy powinniśmy napisać kod tak:

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a = 1;
    $b = 1;
    function s() {
        echo 1;
    }
    
    s();
    
  • Notice: Undefined variable: X in *:

    • oznacza, że nie zdefiniowaliśmy zmiennej o nazwie X przed jej użyciem.
  • Strict Standards: Creating default object from empty value in *

    <?php
    error_reporting(E_ALL | E_NOTICE | E_STRICT);
    
    $a->b = 1;            // źle, odniesienie się do niezainicjalizowanej zmiennej
    
    $a = new stdClass();  // utworzenie obiektu
    $a->b = 1;           // dobrze, odniesienie się do już zainicjalizowanej zmiennej
    
  • Notice: Undefined index: X in *

    • oznacza, że w tabeli nie istnieje indeks o nazwie X

2 komentarzy

Należałoby jeszcze napisać w jaki sposób można uruchomić debugger w IDE oraz przenieść podpunkt 4 do jakiegoś innego tematu, bo nie ma zbyt wiele wspólnego z debugownaniem.