Autor wpisu: batman, dodany: 11.08.2010 19:42, tagi: zend_framework
Problem “Select query cannot join with another table” jest dosyć powszechny, a jego rozwiązanie wyjątkowo banalne. Niemniej wymaga kilku/kilkunastu minut na analizę i wprowadzenie poprawki. Błąd pojawia się w momencie, gdy chcemy na obiekcie Zend_Db_Table_Select, skorzystać z metody join. Najprostszym obejściem tego problemu jest użycie metody setIntegrityCheck z argumentem false. Warto również pamiętać o przekazaniu do metody select argumentu true (Zend_Db_Table_Abstract::SELECT_WITH_FROM_PART), gdyż w przeciwnym razie zapytanie nie będzie zawierało klauzuli join. Poniżej prosty przykład.
$model = new Application_Model_Db_Foo(); $select = $model->select(Zend_Db_Table_Abstract::SELECT_WITH_FROM_PART); $select->setIntegrityCheck(false); $select->joinLeft(array('b' => 'bar'), 'b.id = idbar');
Autor wpisu: sokzzuka, dodany: 10.08.2010 22:44, tagi: php
W jednym z wpisów na php.internals w dyskusji o dacie wersji alpha releasu kolejnej wersji php (5.4 ?) Johannes Schlüter który jest release managerem dla brancha 5.3, zaproponował by publikacje nowych wersji języka przeprowadzać w pewnych konkretnych cyklach. Cykle wydawnicze php miały by być oparte o model cykli Ubuntu. Co to oznacza ? Mniej więcej tyle, że istniałby stabliny branch typu LTS (long term support) który żył by określoną z góry ilość czasu (np. 2 lata) i otrzymywał by przez ten czas tylko poprawki (np. 5.3), równolegle istniał by kolejny branch (5.4) z pewną ilością zmian w stosunku do poprzedniej wersji, który otrzymywałby poprawki do czasu aż nie wyszedł by kolejny (5.5) z nowymi featurami. Taka polityka ma kilka zasadniczych zalet:
- szybkie wprowadzanie nowości do języka
- większa motywacja dla deweloperów by nowości do języka wprowadzali sprawniej
- określony cykl wydawniczy pozwalający końcowym użytkownikom prowadzenie efektywnej polityki migracji
Z ostatnich wpisów na liście wynika, że prawdopodobnie propozycja ta zostanie zaakceptowana, a nowe wersje języka będą pojawiały się raz do roku.
Co wy o tym sądzicie ?
Autor wpisu: sokzzuka, dodany: 10.08.2010 22:15, tagi: php
Nie jest to dokładnie kolejna część cyklu o Domain Driven Design, ponieważ nie zawiera żadnej konkretnej treści. Umieszczam tutaj kilka linków do artykułów o DDD wraz z krótkim opisem, które mogą okazać się przydatne dla wszystkich zainteresowanych tą metodyką. Życzę miłego czytania http://msdn.microsoft.com/en-us/magazine/dd419654.aspx – MVP Microsoftu opisuje metodologie DDD na przykładzie aplikacji dla firmy ubezpieczeniowej, bardzo wartościowy artykuł
http://art-of-software.blogspot.com/search/label/Domain%20Driven%20Design – kopalnia wiedzy (po polsku!), niestety mało przykładów na żywym kodzie
http://www.opentaps.org/docs/index.php/Domain_Driven_Architecture – wiki z przykładową aplikacją
przykladowe aplikacje (wszystkie w c#) :
http://code.google.com/p/ndddsample/
http://myshop.codeplex.com/
http://dddpds.codeplex.com/
http://www.fincher.org/tips/General/SoftwareEngineering/DomainDrivenDesign.shtml – dziwnie wyglądający blog ale merytorycznie artykuł ok
http://www.developerfusion.com/article/9794/domain-driven-design-a-step-by-step-guide-part-1/ – seria o ddd
http://www.infoq.com/minibooks/domain-driven-design-quickly – książka o ddd do ściągnięcia
Autor wpisu: sokzzuka, dodany: 10.08.2010 09:49, tagi: php
Dzisiaj kolejny post z nieoficjalnej serii „zaprzyjaźnij się z PHP” a dokładnie z php 5.3. Opiszę w nim jak zbudować generator. Czym jest generator ? Jak wyjaśnia nam Wikipedia generator jest rodzajem Iteratora, który zamiast zwracać wygenerowaną wcześniej zawartość oblicza nam ją wraz z kolejnym przebiegiem, dzięki czemu nie musimy od razu pobierać np. całej zawartości jakiejś kolekcji. Nasz mały generator będzie implementował interfejs „Iterator” i pobierał w konstruktorze jako swój argument dowolną anonimową funkcję, która będzie generować kolejny wynik. Kod:
class Generator implements Iterator { protected $_function; protected $_maxN; protected $_n = 0; public function __construct($function, $maxN) { $this->_function = $function; $this->_maxN = $maxN; } public function current() { $fFunc = $this->_function; return $fFunc($this->_n); } public function key() { return $this->_n; } public function next() { $this->_n++; } public function rewind() { $this->_n = 0; } public function valid() { if ($this->_n < $this->_maxN) { return true; } return false; } }
Nasz generator użyjemy do wygenerowania pierwszych n elementów ciągu fibonnaciego. Najpierw funkcja:
$cFib = function($n) use (&$cFib) { if ($n == 0) { return 0; } if ($n == 1) { return 1; } return $cFib($n - 1) + $cFib($n - 2); };
Jak widzimy jest to klasyczna implementacja funkcji obliczającej kolejny element ciągu fibonacciego. Z rzeczy które warto zauważyć – jest to domknięcie (closure) i aby funkcja mogła się rekurencyjnie wywołać musi dostać referencje do samej siebie (trochę jest to hak ale inaczej się nie da, __FUNCTION__ nie działa tak jak powinno).
Zastosowanie:
$oGenerator = new Generator($cFib, 5); foreach($oGenerator as $n => $value){ echo $n, ' ', $value, '<br/>'; }
Wynik:
0 0
1 1
2 1
3 2
4 3
Koniec końców uzyskaliśmy wygodną klasę do generowania kolejnych wartości. Przy odrobinie większym wysiłku, można by do implementować jeszcze interfejs ArrayAccess i mieć już całkowitą iluzję obcowania z tablicą -
echo $oGenerator[4]; //zwroci 3
Autor wpisu: batman, dodany: 09.08.2010 20:00, tagi: zend_framework
Dzisiejszym wpisem z serii “Poradniki” wracam do pierwotnych założeń, jakie przyświecały powstaniu tej kategorii, czyli “wpisy ku pamięci”. Ich celem jest pozostawienie w ogólnodostępnym miejscu informacji na temat konkretnego zadania tak, by nie musieć ponownie szukać rozwiązania, które na ogół jest banalne. Tyle tytułem wstępu, do rzeczy.
Każdy kto miał do zrobienia stronę z galerią zdjęć, stawał przed wieloma problemami z tym związanymi. Począwszy od stworzenia bezpiecznego i funkcjonalnego formularza, na przechowywaniu zdjęć kończąc. Wszystkie problemy można rozwiązać w bardzo prosty sposób w kilkunastu wierszach kodu.
Co musimy zrobić? Stworzyć galerię zdjęć w serwisie Picasaweb, a następnie dodać do niej zdjęcia. Jeśli zdjęć mamy dużo, korzystamy z aplikacji desktopowej – Picasa. Na koniec pozostanie napisanie prostego skryptu, który pobierze zdjęcia.
/* cache */ $frontendOptions = array( 'lifetime' => 3600 * 3, 'automatic_serialization' => true ); $backendOptions = array( 'cache_dir' => APPLICATION_PATH . '/../data/cache' ); $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); /* utworzenie obiektu, ktory pobierze zdjecia */ $service = new Zend_Gdata_Photos(); $photos = array(); /* jesli nie ma zdjec w cache, pobierz je z Picasy */ if(!$photos = $cache->load('photos')) { /* obiekt zapytania do albumow zdjec */ $query = new Zend_Gdata_Photos_AlbumQuery(); /* ustawienie nazwy uzytkownika, z konta ktorego beda pobierane zdjecia */ $query->setUser('some.username'); /* ustawienie nazwy albumu, z ktorego beda pobierane zdjecia */ $query->setAlbumName('SomeAlbumame'); /* pobranie zdjec */ $albumFeed = $service->getAlbumFeed($query); /* pobranie informacji o sciezce do zdjec */ foreach($albumFeed as $photo) $photos[] = (string)$photo->content->src; /* zapisanie danych do cache */ $cache->save($photos, 'photos'); }
Uważni obserwatorzy na pewno zauważą, iż scieżki, kierują do zdjęć pełnowymiarowych. Na szczęście Picasa tworzy miniaturki zdjęć i “przechowuje” je w folderach o nazwach zawierających szerokość zdjęcia. Aby dostać się do miniaturek, wystarczy użyć funkcji pathinfo.
$info = pathinfo($photo); $mini = $info['dirname'] . '/s150/' . $info['basename'];
W miejscu s150 można wstawić dowolny inny rozmiar zdjęcia poprzedzony małą literą s, np s237.
Autor wpisu: eRIZ, dodany: 08.08.2010 23:27, tagi: php
Od momentu wprowadzenia namiastki obiektów do naszego kochanego języka, coraz bardziej zaczęły nasilać się narzekania, że PHP jest sto lat za konkurencją pod wieloma względami. Pewnie lista narzekań ciągnęłaby się aż do wyczerpania zapasów papieru toaletowego w WC, ale na pewne rzeczy progamista nie ma po prostu wpływu.
Jeśli nie da się czegoś rozwiązać wprost, zawsze można spróbować to… obejść. Wbrew pozorom, w programowaniu zdarza się to nierzadko.
A o czym chcę napisać? O wyrzucaniu błędów przez PHP zamiast wyjątków.