Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: bastard13, dodany: 31.05.2012 14:38, tagi: oop

final - what for is that?

Wielu programistów zapewne nigdy nie użyła słowa final w celu oznaczenia klasy lub metody. Dlaczego? Z prostego powodu, a raczej jego braku. "Po co?" W końcu, jeżeli ktoś będzie chciał sobie dziedziczyć bądź nadpisywać niech sobie robi to, co mu się żywnie podoba. W czym problem? Jak na ironię ten argument wcale nie jest 'przeciw' stosowaniu final, jak błędnie uważają niektórzy. Jest to najważniejszy powód, dla którego to słowo kluczowe powinno być wykorzystywane, ponieważ przemyślane jego zastosowanie może opłacić się w przyszłości. Czytaj więcej »

Autor wpisu: bastard13, dodany: 31.05.2012 14:38, tagi: php, oop

klasa abstrakcyjna

Czym jest klasa abstrakcyjna? Nie będę się rozpisywał na temat konstrukcji (jak zwykle:), ponieważ w internecie można znaleźć sporo definicji.We wstępie chciałbym się natomiast skupić na podziale klas abstrakcyjnych. Co prawda, z tego co się orientuję, żadnego oficjalnego podziału nie ma, ale po jakimś czasie programowania można wyróżnić trzy powtarzające się wzorce (nie w znaczeniu wzorców projektowych) klas abstrakcyjnych: Czytaj więcej »

Autor wpisu: batman, dodany: 31.05.2012 08:00, tagi: zend_framework

Nieco ponad tydzień temu otrzymałem maila z zapytaniem jak przy pomocy Zend_Layout wykonać układ wielokolumnowy. Wbrew pozorom nie jest to proste do wykonania, ponieważ do wyboru mamy kilka możliwości. Najprostszą z nich byłoby napisanie helpera widoku, który naszpikowany if-ami wyświetlałby stosowną zawartość. O ile w przypadku prostej aplikacji niewymagającej drastycznych zmian wyglądu dynamicznej kolumny, zdałoby to egzamin, tak w momencie gdy kolumny będą znacząco się od siebie różnić w zależności od aktualnej akcji, możemy stworzyć potworka, którego będziemy wstydzili się pokazać nawet niewidomej osobie.

Nie oznacza to, że powinniśmy całkowicie zrezygnować z helperów widoku. Wręcz przeciwnie, będą one stanowić podstawę dynamicznej kolumny. Wystarczy dodać skrypt widoku oraz pobrane z modelu dane, a całość przekazać do layotu. Resztą zajmie się Zend.

Zacznijmy do helpera widoku. Poniższy przykład będzie bardziej niż prosty – ma celu zaprezentowanie idei opisywanego rozwiązania.

class Zend_View_Helper_Column1 extends Zend_View_Helper_Abstract
{
    public function column1(array $data)
    {
        $this->view->data = $data;
        return $this->view->render('column1.phtml');
    }
}

Helper przyjmuje tablicę z danymi, a następnie wyświetla je przy pomocy skryptu widoku, który prezentuje się następująco.

Aktywni użytkownicy
<ul>
    <?php foreach ($this->data as $userName): ?>
        <li><?php echo $userName; ?></li>
    <?php endforeach; ?>
</ul>

Mamy już helper oraz skrypt widoku, pora zająć się layoutem. Załóżmy, że nasza aplikacja będzie składać się z dwóch kolumn.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>multicolumn layout</title>
    </head>
    <body>
        <section class="content">
            <?php echo $this->layout()->content; ?>
        </section>
        <aside class="aside">
            <?php echo $this->layout()->aside; ?>
        </aside>
        <div class="clear"></div>
    </body>
</html>

Domyślnie Zend Framework przekazuje do placeholdera o nazwie content zawartość skryptu widoku bieżącej akcji. My wykorzystamy ten sam mechanizm do wyświetlenia dodatkowej kolumny. Stąd właśnie w powyższym kodzie znalazł się placeholder aside. Ponieważ Zend Framework nie wie co ma się w nim znaleźć, nie będzie on nic wyświetlał. Sami musimy zadbać o poinformowanie ZF jaka treść ma wyświetlić. A zrobimy to w akcji kontrolera.

public function indexAction()
{
    $this->_helper->getHelper('Layout')->assign(
        'aside',
        $this->view->column1(array('Jan Kowalski', 'Ewa Nowak'))
    );
}

W prawdziwej aplikacji dane przekazane do helpera będą pochodzić z modelu, jednak dla uproszczenia przykładu, zastosowałem najzwyklejszą tablicę.

I to już wszystko co jest potrzebne do wykonania wielokolumnowego układu strony z dynamiczną kolumną. Nie jest to uniwersalne rozwiązanie, ponieważ jak to zwykle w życiu bywa, wszystko zależy od aplikacji, nad którą właśnie pracujemy. Niemniej w większości przypadków sprawdzi się doskonale i będzie wymagać jedynie drobnych modyfikacji.

Kompletny kod aplikacji znajdziecie na GitHubie.

Autor wpisu: l3l0, dodany: 29.05.2012 13:29, tagi: symfony

Jak prawdopodobnie wiecie, niedawno pojawiła się nowa wersja behat-a (2.4). Musiałem ją po prostu sprawdzić. Wszystko jest opisane na blogu @everzet-a: http://everzet.com/post/22899229502/behat-240, więc ja się nie będę powtarzał. Poprostu zainstaluję nowego behata z symfony 2.1

Autor wpisu: Śpiechu, dodany: 26.05.2012 12:46, tagi: php

Zgodnie z obietnicą dzisiaj część dotycząca bezpiecznego uruchamiania zewnętrznych skryptów PHP. Od razu mówię, że nie jestem jakimś guru dot. zabezpieczeń systemów Unix. Zebrałem rozsypane po internecie informacje i spróbowałem złożyć to w całość.

Gist został uaktualniony o klasę ICMPPingProcesserrzućcie okiem. Posłuży jako baza do naszych działań.

Jak już wspomniałem w poprzednim wpisie, w Linuksie nie można wykonać polecenia socket_create() na typowym użytkowniku Apache, czyli www-data. Aby obejść ten problem skorzystałem z polecenia posix_seteuid(0) zmieniającego użytkownika procesu na roota na czas życia obiektu ICMPPing. Z kolei aby wykonać to polecenie musimy stać się rootem :-). Z terminala nic trudnego:

sudo php icmp.php http://spiechu.pl

Zostaniemy zapytani o hasło i dostajemy odpowiedź skryptu. Problem pojawia się gdy chcemy wywołać polecenie z poziomu innego skryptu PHP. W Ubuntu nie da się/nie umiem (a próbowałem na wiele sposobów) wpisać hasła dla sudo z poziomu lini komend. Wobec tego trzeba zmusić sudo aby nie pytał o hasło. Oczywiście opcja aby nadać użytkownikowi www-data wszystkie uprawnienia roota na stałe nie wchodzi w grę. Trzeba maksymalnie zawęzić „pole manewru” dla www-data.

Wobec tego przyczepiamy się do pliku /etc/sudoers, który przechowuje uprawnienia związane z poleceniem sudo. Przypominam, że plik sudoers należy edytować wyłącznie za pomocą polecenia visudo, a więc w terminalu:

sudo visudo

i jedziemy z edycją:

# Ustawiamy kilka aliasow
# gdy skryptow zrobi sie sporo
# bedzie latwiej zarzadzac tym balaganem
User_Alias APACHE_USER = www-data
Runas_Alias ROOT_USER = root
Host_Alias PHP_MACHINE = dave-ubunciak
Cmnd_Alias ICMP_SCRIPT = /usr/bin/php /home/dave/icmp.php http\://*
 
# Wlasciwe polecenie
APACHE_USER PHP_MACHINE = (ROOT_USER) NOPASSWD: ICMP_SCRIPT

Polecenie można przetłumaczyć tak: Użytkownik www-data na maszynie dave-ubunciak jako root może wykonać skrypt php o nazwie icmp.php bez hasła z parametrem rozpoczynającym się od http://. Wszelkie odstępstwa będą traktowane komunikatem sudo: no tty present and no askpass program specified Sorry, try again. Od tego momentu możemy w dowolnym skrypcie wywoływać:

// na czas developmentu warto na koncu polecenia wpisac
// 2>&1 dzieki czemu strumien stderr przekierujemy na wyjscie
$process = shell_exec('sudo php /home/user/icmp.php http://www.spiechu.pl');
echo $process;

Co jeszcze można zrobić z samym plikiem icmp.php? Możemy zmienić mu użytkownika i grupę na root i ograniczyć możliwość jego wykonania wyłącznie do roota, czyli:

sudo chown root icmp.php
sudo chgrp root icmp.php
sudo chmod 400 icmp.php

Na koniec przyczepię się do samego icmp.php. Napisałem klasę ICMPPingProcesser, która sprawdza czy podany adres www jest prawidłowy i odsiewa wszystko poza podstawowym adresem hosta. Poniżej przytaczam w całości:

class ICMPPingProcesser
{
    /**
     * @var string
     */
    protected $urlAddress;
 
    /**
     * @param string $urlAddress
     */
    public function __construct($urlAddress)
    {
        $this->urlAddress = $urlAddress;
    }
 
    /**
     * Returns 'Trying {$urlAddress}: PING RESPONSE: Everything OK'
     * when url address replied correctly
     *
     * @return string
     */
    public function ping()
    {
        try {
            $message = '';
            $urlToPing = $this->processUrl($this->urlAddress);
            if (!$this->isUrlExists($urlToPing)) {
                throw new Exception("{$urlToPing} doesn't exist!");
            }
            $icmp = new ICMPPing();
            $respond = $icmp->sendPacket($urlToPing, 'Everything OK');
            $message = "Trying {$urlToPing}: ";
            $message .= "PING RESPONSE: {$icmp->analyzeRespond($respond)}";
 
            return $message;
        } catch (Exception $e) {
            $message .= $e->getMessage();
 
            return $message;
        }
    }
 
    /**
     * Returns sanitized url host from param
     *
     * @param  string    $urlAddress
     * @return string    url host
     * @throws Exception when url address is not valid
     */
    protected function processUrl($urlAddress)
    {
        $sanitizedUrl = filter_var($urlAddress, FILTER_SANITIZE_URL);
        if ($sanitizedUrl === false || filter_var($sanitizedUrl, FILTER_VALIDATE_URL) === false) {
            throw new Exception("{$urlAddress} is not valid URL");
        }
 
        return parse_url($sanitizedUrl, PHP_URL_HOST);
    }
 
    /**
     * Checks if url address exists
     *
     * @param  string  $urlAddress
     * @return boolean
     */
    protected function isUrlExists($urlAddress)
    {
        if (gethostbyname($urlAddress) === $urlAddress) {
            return false;
        }
 
        return true;
    }
 
}
 
if (PHP_SAPI === 'cli' && isset($_SERVER['argv'][1])) {
    $pingProcesser = new ICMPPingProcesser($_SERVER['argv'][1]);
    echo $pingProcesser->ping();
} else {
    echo 'Not in cli mode or agument not set';
}

Ostatnie kilka linijek sprawdza czy skrypt odpalany jest w trybie lini komend i czy istnieje jakiś argument.

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: d3ut3r, dodany: 25.05.2012 15:44, tagi: php

Raczej każdy kto używa przeglądarki FireFox do codziennej pracy nad kodem (x)HTML/CSS/JS zna genialne narzędzie o nazwie FireBug, użytkownicy którzy dodatkowo pracują z PHP być może korzystali z FirePHP jako, że przesiadłem się z FireFox’a na Chrome szukałem odpowiednika FirePHP dla tej przeglądarki i w końcu znalazłem.

Słowem wstępu dla niewiedzących FirePHP pozwalał nam w stosunkowo prosty sposób wykorzystać konsolę FireBuga do wyświetlania komunikatów ze skryptów PHP. Rozwiązanie w moim przypadku idealne, ponieważ często przychodzi mi poprawiać błędy na istniejących już stronach gdzie nie dopuszczalne jest aby odwiedzający widział moje tajemne wiadomości pomagające w debugowaniu kodu :D

Rozszerzenie dla Chrome możemy pobrać z tego miejsca dodatkowo musimy pobrać klasę ChromePHP.

Gdy mamy już zainstalowane rozszerzenie w przeglądarce, możemy przystąpić do testów. Stworzyłem przykładowy plik test.php o zawartości:

<?php
    include('ChromePhp.php');

    for ($i=0;$i<=10;$i++){
        ChromePhp::info($i);
    }
?>

Teraz wystarczy otworzyć naszą stronę w przeglądarce, po wczytaniu za pomocą kombinacji ctrl+shift+j uruchamiamy konsolę JavaScript w której znajdziemy wynik działania naszego polecenia ChromePhp::info($i); wszystko powinno wyglądać mniej więcej w ten sposób:

Oczywiście możliwości ChromePhp nie kończą się na wyświetlaniu zwykłego tekstu ChromePhp posiada szereg metod dzięki którym informacje w konsoli będą czytelne i logicznie poukładane.

1. ::warn,::info,::error

To podstawowe i najczęściej używane metody każda z nich wyświetla inny typ komunikatu odpowiednio: ostrzeżenie , informacja , błąd. Wszystkie metody przyjmują do 2 parametrów poprawne użycie może wyglądać tak:

<?php
    include('ChromePhp.php');

    function badDay(){
      throw new Exception('To bardzo zły dzień');
    }
   
    ChromePhp::info('czas z serwera',date('d-m-Y, H:i:s'));

    try{
     badDay();
    } catch (Exception $e){
     chromePhp::error($e);
    }

     chromePhp::warn('aaaa','bbbbb');
   
?>

powyższy kod powinien dać nam taki rezultat:

Czytaj dalej tutaj (rozwija treść wpisu)
Czytaj dalej na blogu autora...

Autor wpisu: bastard13, dodany: 25.05.2012 10:29, tagi: internet

No i nadszedł ten czas, żeby zaznaczyć swoją obecność również na twitterze:) Czytaj więcej »
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.