Niezalogowany [ logowanie ]
Subskrybuj kanał ATOM Kanał ATOM    Subskrybuj kanał ATOM dla tagu php Kanał ATOM (tag: php)

Autor wpisu: sokzzuka, dodany: 12.07.2011 09:54, tagi: php

Ostatnio w pracy miałem za zadanie zrobić upload plików w module zarządzania plikami w firmowym CMS-ie. Jak pewnie się domyślacie, oprócz uploadu samego pliku, należy wpisać jakieś informacje o nim do bazy danych, cały proces jest generalnie dość oczywisty nawet dla początkującego. Jeżeli chcemy zachować spójność operacji – czyli mieć pewność, że nie wpiszemy niczego do bazy jeżeli plik nie został poprawnie wrzucony lub na odwrót, że w razie błędu połączenia z bazą danych plik zostanie usunięty z dysku możemy wybrać dwie drogi postępowania:

  • instrukcje warunkowe (zwane popularnie „ifami” ;p )
  • transakcje

Druga  metoda zwykle sprowadza się do bloku „try-catch” oraz transakcji na bazie danych. Ja natomiast dzisiaj chciałbym zaprezentować podejście alternatywne oparte na wzorcu o wdzięcznie przetłumaczonej na polski nazwie „Polecenie” (Command).

Wzorzec „Command” polega na enkapsulacji całej logiki potrzebnej do wykonania jakiejś czynności. Jeżeli cała logika została zaenkapsulowana, to mamy też wszelkie informację by taką operację cofnąć. Poniżej przedstawię implementację.

Implementacja składa się z kilku podstawowych elementów:

Interfejs IExecutable wskazuje na zdolność klasy do bycia wykonanym:

interface IExecutable {

    /**
     * @return boolean
     */
    public function execute();
}

Interfejs IUndoable wskazuje na zdolność klasy do cofnięcia operacji:

interface IUndoable {

    /**
     * @return void
     */
    public function undo();
}

Całość zostaje złożona w abstrakcyjny typ ACommand:

abstract class ACommand implements IUndoable, IExecutable {

}

Kolejno implementacja konkretnych operacji – przyjęcia pliku, oraz aktualizacji bazy danych. Upload:

class UploadHandler extends ACommand {

    private $_field;
    private $_destination;
    private $_targetPath;

    public function __construct($field, $destination) {
        $this->_field = $field;
        $this->_destination = $destination;
    }

    public function execute() {
        $filename = $_FILES[$this->_field]['tmp_name'];
        $targetPath = $this->_destination . $_FILES[$this->_field]['name'];
        $result = move_uploaded_file($filename, $targetPath);
        $this->_targetPath = $targetPath;
        return $result;
    }

    public function undo() {
        if (file_exists($this->_targetPath)) {
            unlink($this->_targetPath);
        }
    }

}

Aktualizacja bazy:

class DbUpdater extends ACommand {

    private $_db;
    private $_table;
    private $_data;
    private $_where;
    private $_savePoint;

    public function __construct(Zend_Db_Adapter_Abstract $db, $table, array $data, $where) {
        $this->_db = $db;
        $this->_table = $table;
        $this->_data = $data;
        $this->_where = $where;
    }

    public function execute() {
        try {
            $query = $this->_db->select();
            $query->from($this->_table);
            $query->where($this->_where);
            $this->_savePoint = $this->_db->fetchRow($query);

            $this->_db->update($this->_table, $this->_data, $this->_where);
            return true;
        } catch (Exception $e) {
            return false;
        }
    }

    public function undo() {
        if (!empty($this->_savePoint)) {
            $this->_db->update($this->_table, $this->_savePoint, $this->_where);
        }
    }

}

By ułatwić korzystanie z undo, stworzyłem jeszcze jedną klasę, reprezentującą transakcje:

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

Autor wpisu: sokzzuka, dodany: 11.07.2011 11:39, tagi: php

Pewnie niektórzy stali czytelnicy mojego bloga pamiętają, że jakiś czas temu rozpocząłem cykl o Domain Driven Design. Zaczął się on od prostego wprowadzenia, po którym coraz to bardziej zagłębiałem się w temat od strony teoretycznej, by w pewnym momencie zaanonsować, że niedługo umieszczę przykładową aplikację w PHP napisaną przy pomocy tej metodyki. Ostatni artykuł z tego cyklu umieściłem 12 listopada 2010… (tu zapada niezręczna cisza). Jako, że od tego czasu blog cały czas żył, mogło by się wydawać, że zaniedbuje moich drogich czytelników zainteresowanych tym tematem. Nic bardziej błędnego ! Prawda jest taka, że przez cały czas zgłębiałem swą wiedzę oraz implementowałem konkretną aplikację w metodyce DDD.

Aplikacja, którą tworzyłem, była w istocie tą samą, którą chciałem stworzyć w ramach zapowiedzianego  przykładu DDD. Co więcej, jako, że było to już moje drugie podejście do tematu (aplikację w tej samej domenie tradycyjnymi metodami już raz stworzyłem), miałem okazję przyjrzeć się oraz przekonać jakie różnice są między obiema podejściami oraz poznać ich wady i zalety.

Pewnie za jakiś czas zaprezentuje wyniki mojej pracy na forum publicznym, natomiast jak na razie, chciałbym wymienić benefity, których już doświadczyłem, ze względu na zastosowanie DDD:

  • łatwość w modyfikacji
  • łatwość w znajdywaniu i usuwaniu błędów

Powyższe efekty wynikają bezpośrednio z takich cech oprogramowania pisanego w metodyce DDD jak:

  • skupienie się na metodach biznesowych
  • maksymalna enkapsulacja
  • terminy ze słownika domeny użyte w kodzie
  • przejrzysty przepływ sterowania
  • pełna testowalność

Więcej szczegółów ujawni się z pewnością samo, przy okazji oglądania kodu owej aplikacji, gdy już ją opublikuje. Tymczasem zachęcam wszystkich do przeczytania swoistego wstępu do DDD, który ostatnio pojawił się w czasopiśmie Software Developers Journal, gdzie Sławomir Sobótka – znany ekspert w dziedzinie DDD dzieli się swoją wiedzą wraz ze zrozumiałymi przykładami w Javie / C#. Czasopismo oczywiście można pobrać za darmo w formie PDF-a.

Autor wpisu: Tomasz Kowalczyk, dodany: 10.07.2011 12:29, tagi: framework, php, symfony, symfony2

Pomimo raczej niezbyt odległej w czasie premiery stabilnej wersji Symfony2 wiele istniejących aplikacji zostało napisanych w pierwszej wersji tego frameworka i niestety przeniesienie ich na "dwójkę" nie jest możliwe z wielu powodów. W związku z tym, że pomimo tego, że ekscytujemy się nowymi możliwościami w kodzie, nadal musimy utrzymywać te starsze, dzisiejszy Linkdump chciałbym poświęcić [...]

Autor wpisu: sokzzuka, dodany: 09.07.2011 15:56, tagi: php

Witam, z racji, że wprowadzono nowy tryb rozwijania PHP, od teraz każdy nowy feature w momencie kiedy jest gotowy, ląduje pod głosowanie, w którym prawo mają brać udział osoby mające konto na wiki.php.net. Najnowsze głosowanie odbywa się nad nowościami, które mają się znaleźć w PHP 5.4.  Jego aktualne wyniki możecie znaleźć stronie https://wiki.php.net/todo/php54/vote ,w każdym głosowaniu można również zobaczyć, kto i jak głosował.

Jedną z informacji, która pewnie wielu ucieszy, jest to, że prawdopodobnie przejdzie krótki zapis tablic w postaci:

$someArray = ['jeden' => 1, 'dwa' => 2, 'trzy' => 3];

ostateczną śmierć poniosą również ukochane przez wielu magic_quotes.

Autor wpisu: Tomasz Kowalczyk, dodany: 08.07.2011 01:31, tagi: php

Kilka dni temu trafiłem na pytanie o pomoc w przeskalowaniu obrazka do uploadu na pewnej stronie internetowej. Pomyślałem sobie: "kurczę, znowu ktoś nie umie takich podstawowych rzeczy", aczkolwiek w opisanych wymaganiach znalazły się nie tylko informacje na temat docelowego rozmiaru, ale także rozdzielczości. Nauczony doświadczeniem zasugerowałem, żeby ten ostatni parametr zostawić w spokoju, ponieważ "i [...]

Autor wpisu: singles, dodany: 07.07.2011 21:32, tagi: php

Jednym z powodów, dla których ludzie wychwalają Ruby bądź Pythona jest tzw. interactive shell, konsola rozprowadzana razem z interpreterami tych języków. Pozwalają one szybko przetestować jakiś fragment kodu, bez tworzenia pliku i odpalania go w trybie CLI bądź nawet z poziomu Apache’a.

Tak, są tacy co nie wiedzą, że PHP ma tryb CLI. A nawet Ci co o CLI słyszeli, nie wiedza, że PHP także posiada interaktywną konsolę wywoływaną poleceniem ‘php -a’. Ale dzisiejszy krótki wpis skupi się na narzędziu zwanym phpsh (od PHP shell) – wspomnianym wcześniej php -a na sterydach. Ale wcześniej dwie ciekawostki:

  • narzędzie napisali developerzy Facebooka
  • napisane jest głównie w Pythonie (!)

Początki

Do prawidłowego działania potrzebny będzie nam, oprócz oczywiście PHP, interpreter Pythona – (ja mam 2.6.1).

Instalacja i pierwsze uruchomienie:

     $ git clone git://github.com/facebook/phpsh.git
     $ cd phpsh
     $ sudo python setup.py install
     $ phpsh
     Starting php
     Install pcntl to enable forking on every command.
     type 'h' or 'help' to see instructions & features
     php>

Możliwości

Jakie możliwości ma phpsh? Lista tych ciekawszych poniżej. Zaznaczam, że niektóre z nich dostępne sa także w domyślnej konsoli PHP.

  • autocomplete za pomocą TAB (co ciekawe, nie chce u mnie działać)
  • historia poleceń – bez konieczności kompilacji PHP z readline
  • kolorowy output: zwracane wartości wyświetlane są na żółto, te z stdout na niebiesko, a stderr na czerwono
  • wbudowana dokumentacja (wystarczy wpisać d nazwa_funkcji)
  • łatwe includowanie i ponowne wczytywanie plików zewnętrznych (r functions.php)
  • szybkie wykonywanie poleceń za pomocą znaku = – nie trzeba pisać echo rand(1, 23) tylko = rand(1,23)

Więcej informacji znajdziecie na stronie projeku.

phpsh bez problemu zadziała na systemach POSIXowych, użytkownicy Windowsa możliwe, że będą musieli się trochę pomęczyć.

Autor wpisu: Tomasz Kowalczyk, dodany: 06.07.2011 01:16, tagi: php

W przypadku wielu programów ich twórcy chwalą swoje produkty jako działające bezbłędnie, mimo nieustannych prób użytkownika skierowanych w stronę zakłócenia tego błogostanu. O ile zdecydowana część tychże spełnia wspomniane warunki, o tyle kosztem osiągnięcia takiego celu jest głównie poprawność działania wyłącznie w zakresie podstawowych funkcji. Jeśli użytkownik zechce zrobić coś bardziej zaawansowanego - wtedy zaczynają [...]
Wszystkie wpisy należą do ich twórców. PHP.pl nie ponosi odpowiedzialności za treść wpisów.