Archiwum dla May, 2008

Ostatnio natrafiłem na pewien problem podczas prac nad nowym projektem (opartym o Zend Framework). Rozwiązanie problemu sprowadza się do odpowiedzi na pytanie: Co jest ważniejsze: optymalizacja czy zasady programowania obiektowego?

Mamy model Photos oraz klasę PhotosRow reprezentujący pojedynczy rekord. W aplikacji istnieją różne rodzaje zdjęć (profile, albumy, wydarzenia). Każde zdjęcia, w zależności od typu posiada kilka różnych rozmiarów.

class Photos extends Advaf_Db_Table {
    public function deleteAlbumPhoto($photosId, $usersId) {
         if ($this->_hasAccessToPhoto(..., 'albums')) {
             $row = $this->findOne($photosId);
             return $row->delete();
         }
         return null;
    }

    public function deleteEventPhoto($photosId, $usersId) {
         if ($this->_hasAccessToPhoto(..., 'events')) {
             $row = $this->findOne($photosId);
             return $row->delete();
         }
         return null;
    }
}
class PhotosRow extends Advaf_Db_Table_Row {
    public function _postDelete() {
        $mgr = new PhotoMgr();
        foreach ($mgr->getSizes(this->type) as $size) {
            $path = $mgr->getPhotoFullPath(...);
            if(file_exists($path)) {
                unlink($path);
            }
        }
    }
}

Chciałem umieścić w metodzie _postDelete() klasy PhotosRow cały kod odpowiedzialny za usuwanie z przestrzeni dyskowej odpowiednich zdjęć. Mój kolega, Szymon od razu zwrócił uwagę, że to nie jest optymalne. Aby usunąć rekord, najpierw go pobieramy, potem usuwany (SELECT + DELETE, zamiast tylko DELETE). Wykonujemy jedno zapytanie dodatkowo, dla każdego zdjęcia. Dla 20 zdjęć do 20 extra zapytań! Szymon zaproponował aby przenieść cały kod odpowiedzialny za usuwanie zdjęć do Photos, a zdjęcia usuwać bezpośrednio $this->delete($where).

class Photos extends Advaf_Db_Table {
    public function deleteAlbumPhoto($photosId, $usersId) {
         if ($this->_hasAccessToPhoto(..., 'albums')) {
            $where = $this->quoteInto('id = ?', $photosId);
            $this->_unlink(...);
            return $this->delete(where);
         }
         return null;
    }

    private function _unlink(...) {

    }
}

Mimo wszystko obstaje przy swoim. Zgodnie z zasadą odpowiedzialności to klasa PhotosRow powinna po sobie posprzątać. Wydaje mi się, że właśnie w tym celu developerzy Zenda stworzyli takie metody jak _postDelete czy _postInsert w klasie Zend_Db_Table_Row.

Nie oznacza to oczywiście, że twórcy ZF nie moją głupich pomysłów… moim zdaniem do nich m.in należy obsługa formularzy i osobiście preferuje rozwiązanie Szymona: Fasic_Form.

Jestem bardzo Ciekawy twojej opinii, bo sprawa nadal nie jest rozstrzygnięta. Być może znasz lepsze rozwiązanie?

category życie programisty Komentarze (13)

Bardzo polecam obejrzeć prezentacje Marka Hołyńskiego jaką przeprowadził na Bootstrapie 8.5. Dowiecie się z niej między innymi o historii startup’ów, o różnicy w rozwiązywaniu problemów w akademicki i biznesowy sposób. Poznacie również co się stało z pewnym geniuszem z Grecji.

Bezpośredni link do relacji.

category programowanie, życie programisty Komentarze (2)

Tytuł może być trochę mylący. Bo nie jest możliwe przesyłanie plików poprzez XMLHTTPRequest! Wszystkie znane Wam z sieci ajaxowe uploady bazują na pewnych trickach, o których zamierzam opowiedzieć.

IFrame

Tak to ten sam stary dobry IFRAME, kiedy web nie miał jeszcze numerka, a na stronach www rządził kolor szary i niebieskie linki. Minęło trochę czasu i ten znacznik został zapomniany, a nawet wyklęty. Jednak bez ten trick nie będzie mógł działać.
Przepis jest prosty. Formularz z polem input type="file" umieszczamy w pływającej ramce. Kiedy naciśniemy przycisk wyślij - zacznie się uplodowanie pliku, ale wszystkie pięknie w ‘tle’. Można dodać indykator tak, aby użytkownik myślał, że to ajax.

Plusy

  • Bardzo proste rozwiązania

Minusy

  • Brak paska postępu
  • Można uploadować tylko jeden plik naraz

Flash upload

Kolejne rozwiązanie bazuje na flashu i javascript. Cały proces uploadu przechodzi przez ‘niewidzialny’ obiekt flasha. Sposób jest prawie idealny… problem tkwi w tym, że flash uruchamia własną sesje. A to jest dużym problemem (np. autoryzacja). Rozwiązanie tego problemu to przejęcie sesji, w php można to uzyskać poprzez session_id($passedId).

swfupload logo

Moim zdaniem najlepsza implementacją uploadu z wykorzystanie flashu jest biblioteka swfupload. Jest napisane w czystym javascripcie, dlatego można ją integrować z dowolnym innych kodem js. Ma sporą społeczność i jest ciągle rozwijana

Plusy

  • Można zaznaczyć wiele plików naraz
  • Pasek postępu dla każdego pliku
  • Wstępna walidacja przed uplodem

Minusy

  • tworzy własną sesje
  • limit wielkości pliku do 100MB

swfupload

category javascript, jquery, programowanie Komentarze (3)

Zostać programistą to pikuś, wyzwaniem jest zostać dobrym programistą. Niniejszym otwieram serię wpisów z kategorii rozwój osobisty, w której będę na podstawie własnego doświadczenia pokazywał drogę do sukcesu.

czytaj dalej …

category życie programisty Komentarze (8)