Temel bir ORM uygulamak öğrenmek için ipuçları / kaynaklar / desenleri

2 Cevap php

Burada çeşitli MVC çerçeveler yanı sıra bağımsız ORM çerçeveler PHP için, hem de diğer ORM soruları gördüm; Ancak, soruların çoğuna olan, başlamak için mevcut çerçeveler sormak için not Ben aradığım. (Ben de this SO question okudum, ama ben cevaplar muğlak olarak bunu yapmak için ne emin değilim.)

Bunun yerine, ben ellerimi kirli alma ve aslında daha basit bir kendi ORM, yazarak iyi öğrenirler düşündüm. Gerçekten ben diğer ORMs görmek kod çok karmaşık, özellikle bu yana, nasıl başlayacağınızı bilmiyorsanız hariç.

Benim PHP 5.2.x (this is important) MVC framework ile ben olan temel bir özel veritabanı soyutlama katmanı var:

  • connect($host, $user, $pass, $base), query($sql, $binds), vb gibi çok basit yöntemler
  • Desteklediği her DBMS için altsınıflar
  • SQL sonuç kümelerini temsil etmek için A sınıfı (ve ilgili alt sınıfları)

Ama does not var:

  • Ben kabul Active Record işlevsellik, (Yanılıyorsam beni düzeltin) bir ORM şey

EDIT: netleştirmek için, ben sadece bir veritabanı soyutlama katmanı var. Ben model yok henüz, ama ben bunları uygulamak zaman ben onları, (tabiri caizse) dolayısıyla bu soru yerli ORM model olmak istiyorum.

ORM hakkında biraz yukarı okudum ve benim anlayış onlar PHP tabanlı sınıfları / nesneleri başka bir şey gibi verileri temsil ederek veritabanından kendisinden daha soyut veri modelleri için bir araç sağlamak; ben yanlış ya da herhangi bir şekilde kaçırmış tekrar, beni düzeltin.

Yine de, ben ORM çerçeveler ile daha fazla veya daha az amatörce oluyor herkesten bazı basit ipuçlarını istiyorum. Ben, basit, akademik bana başvurmak için numuneler, ya da ben okuyabiliyorum kaynakları dikkate almak gereken başka bir şey var mı?

2 Cevap

Bu soru oldukça eski olduğu gibi, ben zaten bir ORM kendiniz yazmadan adresinden denemek vardı sanırım. Ben iki yıl önce özel bir ORM yazdığı gibi Bununla birlikte, hala benim deneyim ve fikirlerini paylaşmak istiyorum.

Ben iki yıl önce özel bir ORM uygulanan ve hatta orta ölçekli projeler için küçük bazı başarı ile kullanılan dedi. Ben o zaman (ve hatta şimdi) gibi ORM işlevsellikten yoksun oldukça popüler CMS içinde entegre. Dahası, o zamanlar, Doktrini gibi popüler çerçeveler gerçekten beni ikna etmedi. Çok ben şimdi kendi ORM uygulama ve üretim kullanımı için Doktrini 2 gibi popüler çerçeveler birini kullanarak arasındaki seçim olsaydı, bu hiçbir olurdu, o zamandan beri değişti ve Doctrine 2 katı bir çerçevede gelişti, bu yüzden gelmiştir tüm soru - mevcut, kararlı çözümleri kullanın. AMA: (basit bir şekilde) bu tür bir çerçevenin uygulanmasında çok değerli bir öğrenme egzersiz olduğunu ve nesne ilişkisel haritalama ile ilgili tuzaklar ve zorluklar için daha iyi bir anlayış almak gibi, bana büyük açık kaynak ORMs ile çalışan bir çok yardımcı oldu.

Temel ORM işlevselliğini uygulamak çok zor değildir, ancak en kısa sürede nesneler arasındaki ilişkileri haritalama devreye girer gibi, çok, çok daha zor / ilginç olur.


How did I get started?

Ne bana kaptırdı Martin Fowlers kitap Patterns of Enterprise Application Architecture idi. Kendi ORM programlamak istediğiniz veya sadece bazı ORM çerçeve ile çalışıyor olsa bile, buy this book. Bu nesne ilişkisel alana ilişkin temel ve ileri tekniklerin çok kapsayacak en değerli kaynaklarından biri ise haritalama. Bunun üzerine kadar okuyun, bir ORM arkasında desenleri çok büyük fikirleri olsun.

Basic Architecture

Ben daha çok bir Active Record ya da yaklaşımı çeşit kullanmak istiyorsanız karar Data Mapper. Bu karar veritabanından veri varlık eşleştirilir nasıl etkiler. Ben basit bir veri Eşleştiricisi'ni, Java kullanan yılında Doctrine 2 veya Hibernate olarak aynı yaklaşımı uygulamaya karar verdi. Zend Framework içinde (bunu o kadar arayabilirsiniz) Active Record ORM işlevselliği yaklaşımdır. Active Record Veri Eşleyici'ye sonra çok basit, ama aynı zamanda çok daha sınırlı. Bu kalıpları kadar okuyun ve belirtilen çerçeveler kontrol, oldukça hızlı fark olsun. Bir Data Mapper ile gitmek karar verirseniz, aynı zamanda PHPs reflection API kadar okumalısınız.

Querying

Ben çok DQL Doktrini veya HQL Hibernate gibi, benim kendi sorgu dili oluşturmak için iddialı bir hedef vardı. Yakında özel bir SQL ayrıştırıcı / lexer yazma gibi karmaşık bir yol gibiydi, terkedilmiş (ve gerçekten!). Ne yaptım tablo sorguda yer almaktadır bilgilerin saklanması amacıyla, bir Query Object uygulamak oldu (önemli şu her tablo için ilgili sınıflara veritabanından verileri eşleştirmek gerekir gibi).

Benim ORM bir nesne için sorgulama bu gibi görünüyordu:

public function findCountryByUid($countryUid) {
    $queryObject = new QueryObject();
    $queryObject->addSelectFields(new SelectFields('countries', '*'))
            ->addTable(new Table('countries'))
            ->addWhere('countries.uid = "' . intval($countryUid) . '"');

    $res = $this->findByQuery($queryObject);
    return $res->getSingleResult();
}

Configuration

Normalde, ayrıca yapılandırma biçimi çeşit olması gerekir, Hazırda (diğerleri) XML kullanır, Doktrin 2 PHP açıklamaları kullanır, EZComponents yapılandırma biçimi olarak Persistent Object component PHP dizi kullanır. Ben kullanılan thats ne de ben de, kullanılan PHP yapılandırma biçimi ile çalıştı doğal bir seçim ve CMS gibi görünüyordu.

Bu yapılandırma ile tanımlamak

  • hangi sınıf eşleştirilir aldığı tablo
  • Hangi alanlarda sınıf örneği eşleştirilmiş almalısınız
  • what type the fields of the table have (int, string, vb)
  • varlıklar arasındaki ilişkiler (örneğin bir kullanıcı sınıfı bir KullanıcıGrubu sınıf için bir başvuru var)
  • vb

Ve nesnelere DB sonucu haritasına Veri Eşleyicisi'ndeki kullanmak bilgi şu.

Implementation

Çünkü özel bir ORM yazma karmaşık doğası, güçlü bir tahrik testi yaklaşımı ile gitmeye karar verdi. TDD ya da değil, pek çok birim testleri yazarken böyle bir proje gerçekten iyi bir fikirdir. Bunun dışında: ellerini kirli almak ve Fowlers kitap yakın tutun. ;-)


Ben bu çabaya gerçekten değdi, ama ben çok çünkü günümüzde var olgun çerçeveler, tekrar yapmak istemem dediği gibi.

Ben diğerleri arasında, birçok özelliği çalıştı, ama yoksun, artık benim ORM kullanmayın: vb tembel yükleme, komponent haritalama, işlem desteği, önbelleğe alma, özel türleri, hazırlanan tablolar / parametreleri Ve bu performansı yeterince iyi değildi bulunuyor büyük ölçekli projelerde bunu kullanmak için.

Yine de, ben zaten bunları biliyordum olmasaydı ben, ORM alanında bazı başlangıç ​​noktaları verebilir umuyoruz. ;-)

Basit bir ORM __get() ve __set() kullanılarak inşa edilebilir ve özel yöntemlerden bir çift (muhtemelen kullanarak __call()), burada basit bir pseudo-kod:

class ORM
{
  private $table = null;
  private $fields = array();

  function __construct($table)
  {
    $this->table = $table;
  }

  function __get($key)
  {
    return isset($this->fields[$key]) ? $this->fields[$key] : false;
  }

  function __set($key, $value)
  {
    $this->fields[$key] = $value;
  }

  function load($id, $field = 'id')
  {
    // populate $this->fields with SELECT * FROM $this->table WHERE $field = $id;
  }

  function save()
  {
    if (isset($this->fields['id']))
    {
      // UPDATE $this->table SET $this->fields;
    }

    else
    {
      // INSERT INTO $this->table $this->fields;
    }
  }
}

$user = new ORM('user');

$user->name = 'name';
$user->pass = '1337';

$user->save();

Bu başlamak için sadece temel bir örnektir. Sen id, örneğin daha başka alanlara göre sonuç almak için __call() sihirli yöntemini kullanarak başka mantığı ekleyebilirsiniz.

Çeşitli ORM uygulamaları gerçekten etkili sorgular üretmek yolu yavaş değil olma eğilimindedir beri ancak ben normalde benim için ilişkileri işlemek için herhangi bir ORM güvenmiyorum, farklılık nerede verdim örnek ilişkileri ele gelmez Unutmayın, o.