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

Autor wpisu: Tomasz Kowalczyk, dodany: 21.06.2011 22:37, tagi: php, doctrine, symfony

Czasami mam taki nostalgiczny nastrój tęsknoty za "starymi dobrymi czasami", kiedy spod moich palców wyszło całkiem sporo kodu C++. Naprawdę lubię ten język i uważam za dobrą decyzję twórców wielu języków, aby lekko mówiąc "ściągnąć" składnię z tego języka do własnego rozwiązania. PHP w pewnym sensie jest jednym z nich, także istnieje pewne powiązanie pomiędzy [...]

Autor wpisu: Tomasz Kowalczyk, dodany: 12.06.2011 22:20, tagi: doctrine, framework, php, symfony, symfony2

Nie ukrywam, że symfony jest moim ulubionym frameworkiem, jeśli mówimy o tych napisanych w języku PHP. Fabien Potencier stworzył naprawdę dobre narzędzie wspomagające tworzenie stron i aplikacji internetowych. Od pewnego czasu możemy usłyszeć o nowym przedsięwzięciu SensioLabs - frameworku Symfony2. Sf2 to zupełnie nowe podejście do tworzenia aplikacji internetowych, dlatego warto zapoznać się z możliwościami [...]

Autor wpisu: Tomasz Kowalczyk, dodany: 26.04.2011 23:56, tagi: mysql, symfony, framework, doctrine

W codziennej pracy używamy wielu narzędzi wspomagających naszą pracę przy tworzeniu stron internetowych i wykonywaniu innych usług z tym związanych. Poczynając od IDE, poprzez różnego rodzaju narzędzia konsolowe, aż po wtyczki w przeglądarkach internetowych jesteśmy zależni od wielu tysięcy linii kodu, dzięki którym nasze życie jest o wiele łatwiejsze, niż w przypadku, kiedy musielibyśmy wykonać [...]

Autor wpisu: singles, dodany: 09.04.2011 23:18, tagi: php, zend_framework, doctrine

Zend Framework składa się z wielu komponentów, a jednym z nich jest ten odpowiedzialny za komunikację z bazą danych – Zend_Db. Jednakże, celem tego wpisu nie jest opisywanie Zend_Db – to zostało zrobione już w dokumentacji. Celem tego wpisu jest wyrażenie mojej opinii na temat tego co mi się w Zend_Db podoba, a co nie – jest to oczywiście wpis czysto subiektywny. Traktuje ten wpis także jako przyczynek do dyskusji na temat, czy Zend_Db jest naprawdę tak złym komponentem, za jakiego ma go wielu programistów PHP – m.in patrz komentarze do wpisu u batmana. Chciałbym się także odnieść do podanych tam „zarzutów”. Niektóre z przedstawionych przeze mnie zalet bądź wad mogą Wam się wydawać śmieszne bądź banalne, ale kilka takich rzeczy połączonych ze sobą wpływa na wygodę korzystania z danego rozwiązania. Tak więc zaczynamy!

Zalety

Oparty głównie na PDO

Coraz więcej frameworków idzie tą drogą, co uważam za niewątpliwy plus. PDO de facto jest standardem w PHP i bardzo dobrze, że twórcy zdecydowanej większości frameworków się tego trzymają. Dzięki temu, kiedy przychodzi potrzeba napisania bardziej zaawansowanego zapytania możemy skorzystać ze znanych nam metod i oczekiwać tego samego, czego oczekiwaliśmy korzystając z czystego PDO.

Wygoda podczas stosowania klauzuli WHERE

Kwestia oczywiście w pełni subiektywna. Mam na myśli korzystanie głównie z metody fetchAll i automatycznego bindowania parametrów jako odpowiedni typ danych. Przykład:

$model->fetchAll(array(
    'item_id = ?' => 12, //bind as PDO::PARAM_INT, cast it using (string)12 to automatically bind as PDO::PARAM_STR
    'name = ?' => 'foobar', //PDO::PARAM_STR
    'category_id IN (?)' => arrray(1, 2, 4, 7) // bind each array element separately as PDO::PARAM_INT -> gives you: category_id IN (?, ?, ?, ?)
));

Stosunkowo mała liczba plików

Zend_Db w obecnej wersji frameworka (1.11.5) waży ok. 600KB i mieści się w 53 plikach – z czego 17 z nich to puste klasy wyjątków Exception.php. Dla porównania – Doctrine2 DBAL (czyli sama warstwa abstrakcji bazy danych) to 144 pliki, w tym 10 od wyjątków. Oczywiście, w obu przypadkach można te liczby jeszcze bardziej zmniejszyć, wyrzucając niepotrzebne adaptery.

ActiveRecord

Podoba mi się fakt, że mogę zdefiniować własne metody odnoszące się bezpośrednio do rekordu O ile twórcy ZF piszą o Zend_Db_Table_Row jako o implementacji Row Data Gateway, jednakże z punktu widzenia używającego go programisty niedaleko mu do ActiveRecord. Mam na myśli możliwość definiowania własnych metod odnoszących się do konkretnego rekordu. Banalny przykład:

// /application/models/Product.php
class Model_Product extends Zend_Db_Table_Abstract
{
    protected $_name = 'product';
    protected $_rowClass= 'Model_ProductRow'; //use Model_ProductRow instead Zend_Db_Table_Row
}
 
// application/models/ProductRow.php
class Model_ProductRow extends Zend_Db_Table_Row_Abstract
{
    public function getPriceWithTax()
    {
        return $this->price * 0.23; //where price is column in database defining price without VAT tax rate
    }
}

To samo tyczy się obiektów kolekcji – w przypadku Zend Frameworka dziedziczących po klasie Zend_Db_Table_Rowset. Mogę ustawić własną klasę, gdzie zaimplementuje potrzebne mi metody kolekcji.

Wspracie dla interfejsów ArrayAccess oraz Iterable w przypadku obiektów i kolekcji

Kolejna rzecz, która wpływa na wygodę. Mogę odnosić się do właściwości obiektu używając notacji tablicowej. Mogę także iterować po obiekcie kolekcji używając foreach, bez wykonywania za każdym razem toArray().

Zend_Db_Select == QueryBuilder

O ile na początku korzystanie z Zend_Db_Select sprawiało mi sporą trudność (moim kolegom z zespołu także), tak po pewnym czasie jest to dla nas natywny sposób pisania bardziej skomplikowanych zapytań podczas korzystania z ZF. Właśnie dzięki jego obiektowej naturze i wykorzystaniu fluent interface mogę dowolnie łączyć warunki zapytania bądź zmieniać je korzystając z metody reset(). Przykład:

class Model_Foo extends Zend_Db_Table_Abstract
{
    private $_name = 'foo';
 
    // use fluent interface and add condition
    public function fetchWithLeftJoinWhereBarIsntNull()
    {
        $select = $this->_getBaseSelect();
        $select->where('bar IS NOT NULL');
        return parent::fetchAll();
    }
 
    // user reset() and remove LEFT JOIN
    public function fetchWithoutLeftJoin()
    {
        $select = $this->_getBaseSelect();
        $select->reset(Zend_Db_Select::LEFT_JOIN);
        return parent::fetchAll($select);
    }
 
    private function _getBaseSelect()
    {
        $select = $this->select();
        $select->from('table1')
               ->setIntegrityCheck(false) // allow to join another tables
               ->joinInner('table2', 'table1.id = table2.table1_id')
               ->joinLeft('table3', 'table1.id = table3.table1_id');
 
        return $select;
    }
}

Wady

Brak nazwanych relacji

O używaniu relacji w Zend Framework pisał już batman we wpisie Zend_Db i relacje. Jednak mi nie odpowiada fakt, że korzystając domyślnej metody opisywanej praktycznie wszędzie muszę odnosić się do rekordów podrzędnych po nazwie klasy, a nie nazwie zdefiniowanej relacji. Chciałbym, abym mógł napisać tak:

$params = $userRow->findDependentRowset('UserParamsRelationWithCustomName'); //instead of specifying model class

Nazwa klasy zawsze może się zmienić, a to ułatwia refactoring. Dodatkowo, chciałbym móc w ramach relacji zdefiniować dodatkowe parametry dotyczące połączenia – nie tylko kolumnę, po jakiej ma się ono odbyć, ale także warunki do kolumn dodatkowych. Istnieje co prawda Zend_Db_Table_Definition, jednak rozwiązanie to ma dwie wady. Po pierwsze wymaga osobnej definicji dla każdej klasy modelu, co jest niewygodne. Po drugie, nadal nie pozwala na definiowanie dodatkowych warunków dla połączeń.

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

Autor wpisu: sokzzuka, dodany: 18.01.2011 00:13, tagi: php, doctrine

Ostatnio wiele mówi się o bazach danych NoSQL (NotOnlySQL). Jako, że nie zauważyłem nic w polskim światku PHP na ten temat, stwierdziłem, że pora wypełnić tę lukę i zagłębić się w temat.

Czym są bazy NoSQL ?

Jak podpowiada nam ciotka wikipedia. Bazy NoSQL są to bazy danych, które nie są klasycznymi relacyjnymi bazami danych jakie znamy (MySQL,PostgreSQL etc). Termin NoSQL nie odpowiada żadnym wspólnym cechom tych baz, a raczej temu, że na pewno nie są one RDBMS-ami.

Popularne bazy NoSQL są magazynami danych. W przeciwieństwie do klasycznych odpowiedników nie posiadają stałego schematu, a dane przechowują jako pary klucz – wartość.

Jako przykład dla naszych rozważań wybrałem bazę MongoDB. Dlaczego akurat tą? Istnieją dwa główne powody. Pierwszym z nich jest to, że twórcy projektu Doctrine, stworzyli również ORM w wersji dla tej bazy. Drugim natomiast to, że baza jest szczególnie przyjazna dla webdeveloperów.

Jej przyjazność objawia się tym, że baza żyje i oddycha Javascriptem. Shell przyjmuje komendy tylko w tym języku. Natomiast odpowiedź na zapytania zwracana jest w formacie JSON. Ciekawą rzeczą, może mniej dla webdeveloperów a bardziej dla zwolenników funkcyjnego podejścia do programowania, jest to, że baza wspiera rozproszony model obliczeń oparty na paradygmacie map-reduce. Na roztrząsanie tego tematu czas przyjdzie później. Natomiast teraz przejdźmy do części praktycznej.

Instalacja

  1. Na stronie projektu, wyszukujemy odpowiednią dla nas paczkę i ściągamy
  2. Rozpakowujemy ją w dowolnym katalogu
  3. W głównym katalogu dysku tworzymy folder data/db
  4. W katalogu gdzie rozpakowaliśmy paczkę z bazą odpalamy plik bin/mongod.exe
  5. Z sourceforge ściągamy driver do php w postaci rozszerzenia (w archiwum są dll-e dla odpowiednich wersji php)

W tej chwili mamy już działającą bazę MongoDB. Kolejnym krokiem będzie zaprzęgnięcie Doctrine’a do pracy.

Struktura projektu:

|--application
|---model
|----MailBox
|------Message.php
|-----User.php
|--lib
|---vendor
|----Doctrine
|--proxies
|--index.php

Do katalogu Doctrine ściągamy ODM (Object Document Mapper).

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

Autor wpisu: batman, dodany: 22.12.2010 19:27, tagi: doctrine, php

Ekipa odpowiedzialna za Doctrine poinformowała o wydaniu pierwszej stabilnej wersji Doctrine 2. Spośród wszystkich zmian jakie zaszły w projekcie, najważniejszą zdaje się być brak kompatybilności z poprzednią wersją oraz fakt, iż Doctrine 2 działa tylko na PHP 5.3.

Pełną informację na temat zmian znajdziecie na blogu Doctrine. Zachęcam również do zapoznania się z tutorialem oraz dokumentacją.

Autor wpisu: Damian Rusinek, Piotr Wierzgała, dodany: 02.07.2010 12:23, tagi: doctrine, symfony

Overriding methods should not be a problem, but it can make you confused if you don’t know how magic functions are used in Symfony 1.4 models.

In this short article I will explain why usual overriding does not work in Symfony models and how to override methods handled by magic functions.

Suppose, we have a base model class BaseTopic:

abstract class BaseTopic extends sfDoctrineRecord { public function setTableDefinition() { $this->setTableName('topic'); $this->hasColumn('name', 'string', 255, array( 'type' => 'string', 'notnull' => true, 'length' => 255, )); $this->hasColumn('updates_count', 'integer', null, array( 'type' => 'integer', )); } }

and our class:

public class Topic extends BaseTopic { }

Now we want to update updates_count field each time we modify name field.

First guess is to do the following:

public class Topic extends BaseTopic { public function setName($name) { $this->updates_count++; return parent::setName($name); } }

However it will not work unless you have declared method setName in BaseTopic literally (magical __call does not count).

Upper method will do the following:

  1. Increment updates_count field
  2. Call setName method from BaseTopic (which does not exist literally) so it will look for this method in parents
  3. Because there is no setName in any parent class, it will go to Doctrine_Record and call __call method which will find setName method in Topic class
  4. Call setName from Topic class again

To solve this problem you have to use _set function from Doctrine_Record class:

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

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