PHP Veraset ve MySQL

3 Cevap php

Yani PHP ile iyi bir nesne yönelimli programlama teknikleri benimsemeye çalışıyorum. Benim projelerin (tüm okuma) En MySQL veritabanı içerir. Benim acil sorun ben geliştirmek için gereken kullanıcıların modeli ile ilgilenir.

Benim şu anki proje Ajanlar ve İlanlar vardır. Hem Ajanlar ve İlanlar aynı bilgileri çok olan kullanıcılar vardır. Yani, açıkçası, ben bir sınıf Ajanlar istiyorum ve bir sınıf, ortak bir sınıf Kullanıcılar uzatmak yol açar. Aşağıdaki gibi Şimdi, benim soru:

Nasıl SQL iyi bu nesnelerin yüklenmesi için ele alınmalıdır? Ben bir Ajan veya bir kurşun örneğini zaman birden fazla SQL ifadeleri çalıştırmak istemiyorum. Ancak, mantık Kullanıcılar yapıcı ateş edildiğinde, bu Ajanlar ve Teklifleri arasındaki ortak bilgileri (kullanıcı adı, şifre, e-posta, iletişim bilgileri, vb) yüklemek için bir SQL deyimini yürütmek gerektiğini söyler. Mantık aynı Ajanlar veya kurucu Talepleri ateş edildiğinde, tekrar, mantık da 2 çalıştırmak için kötü bir fikir olduğunu bana söyler, Ajanlar veya sınıf Talepleri benzersiz veri yüklemek için SQL yürütmek istiyorum .... Ama bana söyler (Her binlerce olabilir) SQL ifadeleri her zaman ben bir Ajan veya Kurşun gerekir.

Ben ... Belki de sadece yanlış bir şey arıyorum bu genellikle hiçbir başarı ile nasıl işlendiğini örnekler için arama denedim?

3 Cevap

Temelde bu sorunun üç yaklaşımlar (Ben hemen bertaraf edeceğiz biri) var:

  1. Sınıf başına bir tablo (bu ben ortadan kaldırmak gerekir biridir);
  2. İsteğe bağlı sütunlar ile bir rekor tipi; ve
  3. Eğer katılmak türüne bağlı olarak bir alt tablo ile bir kayıt türü.

Basitlik için ben genelde (2) öneririz. Yani tablo var bir kere:

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  type VARCHAR(10),
  name VARCHAR(100)
);

nerede türü (örneğin) 'AJAN' veya 'KURŞUN' olabilir. Alternatif bir karakter türü kodları kullanabilirsiniz. Daha sonra nesne modeli ile boşlukları doldurmak için başlayabilirsiniz:

  • Bir kullanıcı ana sınıfı var;
  • , Kurşun ve Ajan: İki çocuk sınıfları var
  • Bu çocuklar sabit bir türü var.

ve oldukça kolayca yerine girmelidir.

Bir açıklamada yüklemek için nasıl gelince, ben fabrika çeşit kullanabilirsiniz. Bu barebones sınıflar varsayarsak:

class User {
  private $name;
  private $type;
  protected __construct($query) {
    $this->type = $query['type'];
    $this->name = $query['name'];
  }
  ...
}

class Agent {
  private $agency;
  public __construct($query) {
    parent::constructor($query);
    $this->agency = $query['agency'];
  }
  ...
}

class Lead {
  public __consruct($query) {
    parent::constructor($query);
  }
  ...
}

Bir fabrika bu gibi görünebilir:

public function loadUserById($id) {
  $id = mysql_real_escape_string($id);  // just in case
  $sql = "SELECT * FROM user WHERE id = $id";
  $query = mysql_query($sql);
  if (!query) {
    die("Error executing $sql - " . mysql_error());
  }
  if ($query['type'] == 'AGENT') {
    return new Agent($query);
  } else if ($query['type'] == 'LEAD') {
    return new Lead($query);
  } else {
    die("Unknown user type '$query[type]'");
  }
}

Alternatif olarak, fabrika yöntemi kullanıcı sınıfı, diyelim ki, bir statik yöntem olduğu ve / veya sınıflar türleri için bir arama tablosu kullanabilirsiniz.

Belki de bu gibi sorgu sonucu kaynak ile sınıfları kirleten katı OO anlamda şaibeli bir tasarım olduğunu, ama basit ve işe yarıyor.

Hiç bir kurşun ya da Ajan değil bir kullanıcı var mı? Bu sınıf gerçekten tüm veritabanından veri çekmek gerekir mi?

Öyle ise, neden siz çocuk sınıf oluşturmak zaman geçersiz bir fonksiyonun içine SQL sorgusu çekmeyin.

Eğer SQL bir iskeleti demek miras değil, daha sonra kendi ihtiyaçlarına göre sorguyu tamamlamak için her bir alt sınıfında bir işlevi kullanmak?

Gerçekten temel bir örneğini kullanarak:

<?php
//our query which could be defined in superclass
$query = "SELECT :field FROM :table WHERE :condition";

//in our subclass
$field = "user, password, email";
$table = "agent";
$condition = "name = 'jim'";

$dbh->prepare($query);
$sth->bindParam(':field', $field);
$sth->bindParam....;//etc

$sth->execute();
?>

Gördüğünüz gibi benim örnek şaşırtıcı değil, ama ben de alıyorum görmek için izin vermelidir. Sorgu alt sınıflar arasında çok benzer ise, benim önerim işe yarayabilir düşünüyorum.

Açıkçası biraz oynanması gerekir ama muhtemelen ben alacağını yaklaşımdır.