PHP genel bir veritabanı arayüzü tasarımı

11 Cevap php

Ben bu yüzden her yeni web sitesi için tekrar tekrar temel işi yapmak zorunda değilsiniz PHP benim web projeleri için küçük bir çerçeve oluşturma. Bu ikinci CakePHP'ye veya CodeIgniter oluşturmak için benim hedefim değil ve ben de ben genelde kendimi oluşturduğunuz şeyleri kullanmayı tercih olarak mevcut çerçeveler herhangi benim web siteleri oluşturmak için planlama değilim.

Ben çekirdek yapısı gibi parçalar geldiğinde, çerçeve tasarımı ve kodlama hiçbir sorunları vardı ele istemek, ve böylece, ama benim modülleri için veritabanı arayüzü tasarımı ile sıkışmış alıyorum var.

Ben zaten MVC deseni kullanarak düşündüm ama benim çok küçük bir proje (ler) için bir overkill biraz olacağını öğrendim.

Yani bakan değilim kesin sorun benim çerçeveler modülleri (viewCustomers, örneğin, bir modül olabilir) veritabanı ile etkileşim nasıl olduğunu.

  • Doğrudan PHP koduna SQL karıştırmak için iyi bir fikirdir (hala) var mı? ("Eski yol" olur: mysql_query( 'SELECT firstname, lastname(.....))?

  • Nasıl soyut olabilir aşağıdaki gibi bir sorgu?

    SELECT firstname, lastname FROM customers WHERE id=X
    

Would MySQL "yardımcı" fonksiyonları gibi

$this->db->customers->getBy( 'id', $x );

iyi bir fikir olabilir mi?

Ben yukarıda hemen hemen önemsiz gibi daha karmaşık sorgu ile uğraşırken yararsız olma eğilimindedir, çünkü gerçekten emin değilim.

  • MVC gelen "Model" model bu çözmek için benim tek gerçek seçenek mi?

  • Şu anda sorunları yukarıda gösterilen çözmek için ne kullanıyorsunuz?

11 Cevap

Eğer hız gerekiyorsa, o ham sorguları kullanın (ama gerçekten prepared queries PDO ile kullanmanız gerekir).

Daha fazla bir şey OOP istiyorsanız,-olabilir gibi yardımcıları ile bu da-tasarım öneririz.

Bir kere, ben şu kavramı vardı benzer bir şey tasarladık:

  1. (Vb MySQL, Oracle gibi farklı veritabanları ve farklı sunuculara çoklu bağlantı işleme) DB bağlantısı / işleyici sınıfları;
  2. İşlem başına A sınıfı (yani SELECT, vb DELETE);
  3. Filtre sınıfları (örn. RangeFilter);

Kod böyle bir şey baktı:

$select = new Select('field1', 'field2', );
$result = $select->from('myTable')
                 ->addFilter(SQLFilter::RangeFilter, 'field2')
                 ->match(array(1, 3, 5))
                 ->unmatch(array(15, 34))
                 ->fetchAll();

O bunu inşa edebilirsiniz nasıl basit bir örnek.

Sen daha ileri gidip, tablo ve alan takma desteği, vb (masalarda iç gözlem kullanarak) tablo ilişkileri, alan türü çek otomatik kullanımını uygular olabilir

Bu uzun ve zor iş gibi görünüyor olabilir, ama aslında, o kadar zaman tüm bu özellikleri (≈ 1 ay) yapmak için o sizi almayacağız.

Veritabanı etkileşimi çözülmüş bir sorundur: bu anlayın.

Yani really bunu yapmak istemediğiniz sürece bir) deneyimi ya da OKB ve sen kullanarak olacak kodun her karakterini bilmek istiyorum çünkü b), sonra varolan bir çözümü tercih ediyorum için .

Ve birçok vardır: ARMUT :: MDB2, Zend :: Db, Creole, Doktrin, uskur, sadece birkaç isim.

Ben sadece "yardımcı fonksiyonlar" yolu kapalı geldim ve beni rahatsız bir şey büyüdü ve aynı veya benzer feshedilmiş fonksiyonları ile büyüdü tek bir dosyada fonksiyonlar ekleyerek devam oldu. Ben hat sayısı 600 oldu ve bu bence tek bir dosya için çok yol olduğunu düşünüyorum. Bu fikir beni ertelemeye değil ama bir sonraki trek için daha organize olacak. Herhalde (select, insert vs ..) db operasyona göre çok dosya içine db fonksiyonları bölünmüş olacak.

Yani benim tavsiyem "yardımcı fonksiyonlar" denemek gitmek ve mümkün gibi organize olmaktır.

Ayrıca, ben ilk defa PDO'yu kullanılan ve oldukça sevdim. Gibi bazı mysql () işlevleri veya kabartmak teknoloji onun gibi düşük değil teknoloji biz söz olacak ama olamazdı. Ben tekrar PDO kullanarak olacak.

Bu konuyla ilgili çok farklı görüşler var gibi görünüyor ve ben burada henüz gerçekten tatmin edici bir cevap bulamadı ve lütuf neredeyse bitti gibi, ben sadece biraz deneme yanılma sonra son günlerde gelip ne yazacağım :

Ben bağlantı ve çok temel sorguları yanı sıra oluşabilecek hataları işlemek için bir tek MySQL sınıfını kullanıyorum.

/users/show/1 (kullanarak mod_rewrite) gibi tek bir sayfa ham SQL ama aşağıdaki örnekte olduğu gibi çalışır hafif ORM çeşit kullanmayın:

$user = $this->db
             ->users
             ->getBy( 'id', $id );

$this->db bir __get( $tableName ) yöntemi ile Veritabanı Soyutlama sınıfının bir örneğidir. Sonra tanımlanmamış users özelliğine erişerek bunu tetikler. Gerisi kendisi açıklıyor; Bir sorgu getBy( ) (SQL öncelemeli da onun tarafından işlenir) ve sonuçları bir dizi olarak döndürülür geçirilen argümanlar oluşur.

Ben henüz fikrine bitmiş değil, ama veritabanına yeni bir kullanıcı ekleyerek aşağıdaki gibi görünebilir:

$user = $this->db
             ->users
             ->new;
$user->id = 2;
$user->name = 'Joe';
$user->save( );

As I said the concept isn't really completed and may have (huge) flaws in it. Yet I think that it may be easier to write, more secure and easier to maintain than plain MySQL. Some other good sides of the whole "thing" would be that it is small, therefore rather fast and also pretty straightforward.

Ben bu zaten orada son derece güçlü ORMs ve çerçeveler ile rekabet edemez biliyorum ama ben yine de benim yukarıdaki yorumların birinde geçen bazı nedenlerden dolayı bu oluşturma.

Bir veritabanı sınıf yapma planı yaparsanız siz, bunu oluştururken / bildirerek olmadan kullanmak için izin, bir tekiz yapma içine bakarak bir fikir olabilir ...

global $db;
$db = new db;
$db->query ('... sql ...');

Yapabileceğiniz zaman biraz gereksiz

db::query ('... sql ...');

Ben mesela tek bir çağrı, için SQL sürü kaçan bir multi-line olarak kullanılan ne azaltmak için yakın bir düzenli olarak kullanmak SQL işlevleri bir dizi var:

get_element ($table, $element, $value, $column='id');
get_row ($table, $value, $column='id');

Yani sadece id 4 bir tablo 'müşterilerden' dan adını almak istiyorsanız:

$name = db::get_element ('customers', 'name', 4);

Orada sadece ona bir SQL dizesi geçmek eşlik fonksiyonları query_element ve query_row, aynı zamanda ve tek bir unsur / satır döndürür.

Ekleme / güncelleme, örneğin için fonksiyonları ile birlikte

$array = array (
    'name' => 'bob jones',
    'age' => 28
);
$insert_id = db::insert_array ('customers', $array);

$customer_details = db::get_row ('customers', $insert_id);

$customer_details['age'] = 30;

db:update_array ('customers, $customer_details);

Yeni bir satır oluşturmak istiyorsunuz, bu veritabanına yeniden yazmak daha sonra, yaş güncellemek, dışarı geri ayrıntıları çekin.

Bir tablo başına üzerinde özel bir SQL erişim modülleri oluşturma genel olarak ben her zaman bulduk bir hatadır - sadece jenerik mantıklı fonksiyonlarını kullanarak veritabanını sorgulamak için iyidir.

Eğer karmaşık birleşimler ile bir şey kullanmak zorunda yoksa o zaman (örneğin) o GetCustomerInfo için fonksiyonu oluşturmak için her zaman en iyi olduğunu, ancak sadece isterseniz özel yöntemler çok yapmak bir genel tablo değeri arama sadece birinde hata şansını artırır onları. Ayrıca veri kaçan çok önemli - Eğer her şey düzgün oldukça kolay kaçtı sağlayabilen, mümkün olduğunca sigara kullanmanız sql ve birkaç temel fonksiyonların aracılığıyla huni eğer.

Sen benim özel veritabanı sınıf bakmak istiyorsanız bana bildirin.

Ben sadece modülünden DB erişmek istiyorum inanıyorum. Ben doğrudan kodundan mysql_query kullanarak önlemek istiyorum. Aksine, soyutlanmış DB erişimi basit model için kolay oluyor ve düz ileri olurdu.

Örneğin, bu kod ile model / Customers.php gibi bir dosya olabilir:

<?php

class Customers {

    public function getById($id) {
        $sql = "SELECT first_name, last_name FROM customers WHERE id='$id'";
        $res = $DB::getRow($sql);
        return ($res);
    }
}

Ben DB yardımcısı çeşit önceden başlatılmış ve $ DB olarak mevcuttur varsayarak yaşıyorum. Here PDO'yu kullanan basit bir.

Şimdi, modül bu içerir ve şu şekilde kullanmak gerekir:

<?php

include_once "models/Customers.php";

$customers = new Customers();
$theCustomer = $customers->getById(intval($_REQUEST['cust_id']));


echo "Hello " . $theCustomer['first_name']

Şerefe.

Eğer http://www.doctrine-project.org/ veya diğer php orm çerçeveler (Zend_Db akla geliyor) içine baktım?

Üç ipuçları:

  • Saklı yordamları kullanın (böylece db php ayırabilirsiniz)
  • Kullanın PDO / MySQLi hazırlanan tablolar için CALL NEWS_LIST(?, ?)
  • DB için bir statik sınıfı kullanın. Eğer herhangi bir modül içinde erişmek için izin verir.

Ham SQL benim için hala kazanan, ben sunucuya göndermek ne kontrol etmek istiyorum (indeks kullanımı gibi durumlarda, karmaşık hükümler vb JOIN) Ben genellikle uzak yardımcı işlevler uzak kalmak.

Zaten çok fazla güç sağlar PDO kullanmanız gerektiğini ve bu yeterli değilse, (örneğin aslında veritabanı sorgulama önce Memcached / APC hit kontrol olarak, kendi fonksiyonları ile muhtemelen) o uzatabilirsiniz. Ayrıca gibi kendi SQL fonksiyonlarını uygulamak için sınıf uzatabilirsiniz:

function getUser($user_id) {
    return $this->query("SELECT * FROM users WHERE id = " . (int) $user_id);
}

Tabii ki bu, model hala göndermek mümkün olmalıdır:

$this->db->query("SELECT * FROM users WHERE id = " . (int) $user_id);

ve aynı sonucu alırsınız. Bu site bağımlı olacak gibi bir kısayol ve genişletilmiş sınıf çerçevesine dahil edilmemelidir gibi işlevler sadece hareket etmelidir.

O zaman ne gerek içine verileri dönüştürmek için size sadece bir sürücü ve model olarak veritabanını kullanabilirsiniz, çünkü MVC deseni içine bu güzel uyacak. Basit bir MVC yapısı oluşturmak zor değil ve daha sonra size yarar getirecektir.

Sen bana benziyorsun. Eğer http://github.com/Xeoncross/micromvc ve bir dosya ORM gördük http://github.com/Xeoncross/database? Benim kod kazmak ve ben size aradığınızı bulacaksınız düşünüyorum.

Hala başka şeyler için (CodeIgniter'ın AR gibi) ORM ve sorgu inşaatçılar verirken - çözüm bazı sorguları tam ham güç kullanmaktır.

Her ikisi de iyi.

Değil ben kesin cevabı biliyorum (ne i var sizce), ama ben sadece ben burada ne var paylaşabilirsiniz düşündüm. Ben kendi db 'çerçeve', hafif (şu anda ~ 1000 satır) ve kullanmak için kullanımı kolay. Benim ana hedefi bu programcı (me :) değil 'gizlemek' için, sql kullanımını basitleştirmek oldu. Bazı örnekler:

 // row() is 'query' + 'fetch' in one
 $user = $db->row("select * from users where id=25");

 // the same, injection safe
 $user = $db->row("select * from users where id=?", $_GET['id']);

 // ? placeholders are smart
 $someUsers = $db->rows("select * from users where id IN(?)", array(1, 2, 10));

 // ...and even smarter
 $data = array('name' => 'Joe', 'age' => 50);
 $id = 222;
 $db->exec("update users set ?a where id=?", $data, $id);

 // 'advanced' fetch functions
 $topNames   = $db->vlist("select name from users order by name limit 10");
 $arrayOfIds = $db->nlist("select id from users where age > 90");

 // table() returns a Table Gateway
 $db->table('users')->delete('where id=?', 25);

 // yes, this is safe
 $db->table('users')->insert($_POST);

 // find() returns a Row Gateway object
 $db->table('users')
     ->find('where name=?', 'Joe')
     ->set('status', 'confirmed')
     ->save();