2015-05-22

Debuggowanie aplikacji webowych za pomocą Xdebug i PhpStorm

PhpStorm umożliwia debuggowanie kodu, który wyświetlany jest aktualnie przez przeglądarkę internetową. Aby móc cieszyć się tym dobrodziejstwem musimy przejść kilka kroków opisanych poniżej (instrukcja dla dystrybucji linuksa Ubuntu/Mint).

Instalacja Xdebug

sudo apt-get install php5-xdebug
Do php.ini dodajemy:
zend_extension="/usr/lib/php5/20121212/xdebug.so"
xdebug.remote_enable=1
xdebug.remote_handler=dbgp 
xdebug.remote_mode=req
xdebug.remote_host=127.0.0.1 
xdebug.remote_port=9000
xdebug.max_nesting_level=300

Restartujemy Apache'a:
sudo service apache2 restart

Utworzenie przycisków odpalających debuggera

Aby uruchomić i zatrzymać debuggera w przeglądarce trzeba podać jej specjalne parametry. Można to zrobić ręcznie lub utworzyć sobie do tego odpowiednie przyciski - np. na pasku zakładek (ja używam właśnie takiego rozwiązania). Pod adresem https://www.jetbrains.com/phpstorm/marklets/ można wygenerować potrzebny kod. 

Start debugger:
javascript:(/** @version 0.5.2 */function() {document.cookie='XDEBUG_SESSION='+'PHPSTORM'+';path=/;';})()

Stop debugger:
javascript:(/** @version 0.5.2 */function() {document.cookie='XDEBUG_SESSION='+''+';expires=Mon, 05 Jul 2000 00:00:00 GMT;path=/;';})()

Uruchomienie debuggera

W przeglądarce uruchamiamy debuggera (np. przyciskiem start debugger), przechodzimy do PhpStorma i tam również włączamy debuggowanie (po wcześniejszym ustawieniu breakpointów oczywiście). Wracamy do przeglądarki, uruchamiamy badaną aplikację PHP i po napotkaniu breakpointa powinno nas przenieść automatycznie do PhpStorma w zaznaczone miejsce.

Więcej na ten temat znaleźć można tutaj.

2015-05-10

Utworzenie lokalnej domeny przy użyciu Apache2 i Virtual Hosts

Aby utworzyć lokalną domenę (np. http://test.lh), która zastąpiłaby adres http://localhost/test/ wystarczy kilka prostych ruchów:
  • Tworzymy katalog test w katalogu /var/www/html/
  • Tworzymy plik index.html w katalogu test
  • Dajemy uprawnienia 0775 dla katalogu test
  • W pliku index.html wpisujemy hello world!
  • Tworzymy plik test_lh.conf w katalogu /etc/apache2/sites-available/
  • W pliku test_lh.conf wpisujemy:
    
      ServerAdmin marcin.zaremba@gmail.com
      ServerName test.lh
      ServerAlias *.test.lh
      DocumentRoot /var/www/html/test
      ErrorLog /var/log/apache2/test_error.log
      CustomLog /var/log/apache2/test_access.log combined
      
        # enable the .htaccess rewrites
        AllowOverride All
        Allow from All
        Require all granted
      
    
    
    Uwaga! Zamiast id="/var/www/html/test" piszemy po prostu /var/www/html/test.
  • W katalogu /etc/apache2/sites-enabled/ tworzymy link symboliczny do /etc/apache2/sites-available/test_lh.conf
    ln -s /etc/apache2/sites-available/test_lh.conf /etc/apache2/sites-enabled/test_lh.conf
  • W pliku /etc/hosts dodajemy linijkę 127.0.0.1 test.lh
  • Uruchamiamy przeglądarkę, wpisujemy w pasek adresy test.lh i cieszymy się z napisu hello world!

Skrypt do tworzenia lokalnej domeny


Na githubie umieściłem skrypt, który wykonuje wszystkie opisane ruchy w sposób automatyczny. Wystarczy wpisać w konsoli:
sudo ./addLocalHost.sh test
a wszystkie wyżej opisane kroki wykonają się za nas i będziemy mogli cieszyć się nową lokalną domeną test.lh.

Poniżej przedstawiam kod, który wykonuje to zadanie:

2015-04-27

PHP Deprecated - comment starting with '#'

PHP Deprecated:  Comments starting with '#' are deprecated in /etc/php5/cli/conf.d/imap.ini on line 1 in Unknown on line 0

W przypadku powyższego błędu wchodzimy w plik imap.ini i zastępujemy znak '#' znakiem ';'.

2015-04-03

Symfony2 i generowanie plików PDF

KnpSnappyBundle

Do generowania plików PDF w Symfony2 wiele osób poleca bundla o nazwie KnpSnappyBundle. Wykorzystuje on jednak wkhtmltopdf (open source'owe konsolowe narzędzie do tworzenia plików PDF na podstawie HTML), które trzeba dodatkowo zainstalować na serwerze produkcyjnym (wraz z wieloma innymi bibliotekami). To według mnie spora wada tego bundla ale jeszcze do przeskoczenia. Większym minusem wkhtmltopdf jest to, że PDF'y na różnych maszynach generują różne pliki PDF. Różnice są niby niewielkie ale przy mojej pracy zupełnie dyskwalifikujące to rozwiązanie.

PdfBundle

PdfBundle autorstwa Piotra Śliwy eliminuje wady wcześniej omówionego bundla. Nie trzeba na serwerze instalować osobnych  systemowych narzędzi i na każdej maszynie wydruk wygląda identycznie. PdfBundle korzysta z biblioteki PHPPfd tego samego autora. PHPPfd tworzy pliki PDF (lub pliki graficzne) na podstawie plików XML co może być to istotną wadą dla niektórych użytkowników. Dla mnie jednak jest to rozwiązanie niemal idealne.

PdfBundle - problem z img

Podczas pracy trafiłem na problem, który zawieszał całego Apache'a przy próbie wygenerowania pliku PDF z dużym plikiem jgp:

    
        
    

Aby pozbyć się problemu wystarczy element dynamic-page zmienić na page - czyli:

    
        
    

2015-01-28

Firefox - przekroczono limit czasu połączenia

Jeśli pojawia Ci się taki komunikat po ok. 300 sekundach (mimo wszelkich zmian w php.ini) to być może odpowiada za to zmienna network.http.response.timeout. Firefox domyślnie ma przy tej zmiennej wartość 300 sekund - aby to zmienić wystarczy wejść w opcje (about:config), zwiększyć odpowiednio wartość zmiennej i zrestartować przeglądarkę.

2015-01-14

Doctrine i Symfony - wyświetlenie SQL'a z parametrami

Wyświetlić utworzonego SQL'a możemy za pomocą polecenia:
$qb->getQuery()->getSQL();

a parametry tegoż zapytania za pomocą polecenia:
$qb->getParameters();

Wcześniej oczywiście tworzymy obiekt $qb oraz zapytanie - np:
$qb = $this->createQueryBuilder('l')
 ->where('l.del = :del')
 ->andWhere('l.wysw = :wysw')
 ->andWhere('lower(l.nazwisko) LIKE lower(:szukana) OR lower(l.nrpwz) LIKE lower(:szukana)')
 ->orderBy('l.nazwisko')
 ->setParameters(array(
  'del' => 'false',
  'wysw' => 'true',
  'szukana' => '%' . $szukana . '%'
 ));

Wynik zapytania pobieramy w poniższy sposób:
$qb->getQuery()->getResult();

2015-01-13

Doctrine Symfony PostgreSQL - LIKE i OR

Przykład zapytania SQL z klauzulą LIKE:
$qb = $this->createQueryBuilder('k')
 ->where('k.kod_res_8 = :kod_res_8')
 ->andWhere('lower(k.ulica) LIKE lower(:ulica)')
 ->setParameter('kod_res_8', $kod_res_8)
 ->setParameter('ulica', $ulica . '%')
 ->setMaxResults(1);

Przykład zapytania SQL z klauzulą LIKE i OR:
$qb = $this->createQueryBuilder('j')
 ->where('j.del = :del')
 ->andWhere('j.wysw = :wysw')
 ->andWhere('lower(j.nazw) LIKE lower(:szukana) OR lower(j.regon) LIKE lower(:szukana)')
 ->orderBy('j.nazw')
 ->setParameters(array(
  'del' => 'false',
  'wysw' => 'true',
  'szukana' => '%' . $szukana . '%'
 ));

return $qb->getQuery()->getResult();