Frage

Meine Frage ist, wie kann man abstrakte Datenbankverbindung aus der Modellschicht einer Anwendung? Das Hauptanliegen ist es, auf einfache Weise aus verschiedenen Arten von Datenbanken zu ändern. Vielleicht beginnen Sie mit einer flachen Datei, durch Komma getrennte Datenbank. Dann möchten Sie zu einer SQL-Datenbank verschieben. Dann später Sie eine LDAP-Implementierung entscheiden, wäre besser. Wie kann eine Person leicht für so etwas planen?

Für ein einfaches Beispiel: Angenommen, Sie einen Benutzer mit einem Vornamen haben, Nachnamen und E-Mail. Eine sehr einfache PHP-Klasse es darstellen könnte wie folgt aussehen (bitte, die Probleme mit dem öffentlichen Instanzvariablen ignorieren):

<?php

class User {
  public $first;
  public $last;
  public $email;
}

?>

Ich habe oft gesehen, wo Menschen eine DAO-Klasse haben, die die SQL-in als solche eingebettet hat:

<?php

class UserDAO {
  public $id;
  public $fist;
  public $last;
  public $email;

  public function create( &$db ) {
    $sql = "INSERT INTO user VALUES( '$first', '$last', '$email' )";
    $db->query( $sql );
  }
}

?>

Mein Problem mit Strategien wie das ist, wenn Sie Ihre Datenbank ändern mögen, müssen Sie jede DAO Klasse ändern erstellen, zu aktualisieren, zu laden, löschen Funktionen mit Ihrer neuen Art von Datenbank zu beschäftigen. Auch wenn Sie ein Programm automatisch generieren sie für Sie haben (was ich bin nicht besonders ein Fan von), würden Sie dieses Programm bearbeiten, um es jetzt arbeiten.

Was sind Ihre Vorschläge, wie dies zu umgehen?

Meine aktuelle Idee ist, eine Superklasse zu schaffen für DAO mit seiner eigenen Objekte erstellen, löschen, aktualisieren, Ladefunktionen. Allerdings würden diese Funktionen Arrays von den Attributen des DAO und erzeugen die Abfrage selbst. Auf diese Weise ist die einzige SQL in der SuperDAO Klasse statt über mehrere Klassen gestreut zu werden. Dann, wenn Sie Ihre Datenbank-Layer ändern wollten, würden Sie nur ändern müssen, wie die SuperDAO Klasse die Abfragen generiert. Vorteile? Nachteile? Vorhersehbare Probleme? Zwei glorreiche Halunken?

War es hilfreich?

Lösung

ORM ist in der Regel der bevorzugte Weg, um die Datenbank zu abstrahieren. Eine unvollständige Liste von PHP-Implementierungen ist auf Wikipedia .

Andere Tipps

Sie verschiedene Frameworks wie PDO verwenden können, PEAR :: MDB2 oder Zend_Db, aber in 12 Jahren PHP-Entwicklung, ehrlich zu sein, ich habe noch nie von einer Art von Datenspeicher-Infrastruktur zu einem anderen wechseln.

Sein äußerst selten sogar von etwas geht ganz ähnlich wie SQLite zu MySQL. Wenn Sie das tun tat mehr als das, würden Sie weit größere Probleme sowieso haben.

kam ich mit einem interessanten Konzept auf den Entwickler erlauben würde, Datenbank-agnostisch Code zu erstellen, aber im Gegensatz zu ORM wird nicht opfern Leistung :

  • einfach zu bedienen (wie ORM)
  • db-agnostisch: arbeitet mit SQL, NoSQL, Dateien usw.
  • immer Abfragen optimieren, wenn Anbieter erlaubt (sub-select, Karten reduzieren)

Das Ergebnis ist Agile Daten - Datenbank Access Framework (Video zur detaillierten Erläuterung siehe).

Lösen von realer Aufgabe mit DB-agnostisch Code und Agile Daten

  1. Starten von beschreibt Geschäftsmodelle .
  2. Erstellen Persistenz Treiber $db (ein ausgefallenes Wort für DB-Verbindung), die CSV-Datei, SQL oder LDAP sein könnte.
  3. Partner-Modell mit $db und drücken Sie Ihre Action
  4. Ausführen Action

An diesem Punkt Rahmen wird beste Strategie bestimmt die Fähigkeiten der Datenbank gegeben, Ihre Felder Erklärung Karte, Vorbereitung und Durchführung von Abfragen für Sie, so dass Sie nicht auf sie schreiben.

Code-Beispiel

Mein nächster Code-Schnipsel löst ein ziemlich komplexes Problem zu bestimmen, was die aktuelle Gesamtverschuldung aller unseren VIP-Kunden ist . Schema:

Als nächstes ist der herstellerunabhängige Code:

$clients = new Model_Client($db);
// Object representing all clients - DataSet

$clients -> addCondition('is_vip', true);
// Now DataSet is limited to VIP clients only

$vip_client_orders = $clients->refSet('Order');
// This DataSet will contain only orders placed by VIP clients

$vip_client_orders->addExpression('item_price')->set(function($model, $query){
    return $model->ref('item_id')->fieldQuery('price');
});
// Defines a new field for a model expressed through relation with Item

$vip_client_orders->addExpression('paid')
  ->set(function($model, $query){
    return $model->ref('Payment')->sum('amount');
});
// Defines another field as sum of related payments

$vip_client_orders->addExpression('due')->set(function($model, $query){
    return $query->expr('{item_price} * {qty} - {paid}');
});
// Defines third field for calculating due

$total_due_payment = $vip_client_orders->sum('due')->getOne();
// Defines and executes "sum" action on our expression across specified data-set

Die resultierende Abfrage wenn $db ist SQL:

select sum(
  (select `price` from `item` where `item`.`id` = `order`.`item_id` )
  * `order`.`qty`
  - (select sum(`payment`.`amount`) `amount` 
     from `payment` where `payment`.`order_id` = `order`.`id` )
) `due` from `order` 
where `order`.`user_id` in (
  select `id` from `user` where `user`.`is_client` = 1 and `user`.`is_vip` = 1 
)

Für andere Datenquellen, die Ausführungsstrategie könnte-Schwergutfrachter einige weitere Daten, würde aber konsequent arbeiten.

Ich glaube, mein Ansatz eine gute Möglichkeit, zu abstrahieren Datenbank ist und ich arbeite es unter MIT-Lizenz zu übernehmen:

https://github.com/atk4/data

Sie sollten die PDO-Bibliothek.

  

PDO liefert eine Datenzugriffsabstraktionsschicht, was bedeutet, dass, unabhängig davon, welche Datenbank Sie verwenden, können Sie die gleichen Funktionen verwenden, um Abfragen zu erstellen und Daten zu holen.

     

PDO bietet keine Datenbank Abstraktion; es umschreiben nicht SQL oder fehlende Funktionen emulieren. Sie sollten eine komplette Abstraktionsschicht verwenden, wenn Sie diese Funktionalität benötigen.

Der beste Weg ist ein ORM (Object-Relational Mapping) Bibliothek zu verwenden. Es gibt viele von ihnen für PHP. Ich habe persönlich verwendet und kann Lehre ORM empfehlen (ich habe es benutzt in Kombination mit silex, die ein minimalistischen PHP-Framework ist).

Hier ist ein Stackoverflow Thread über PHP ORMs, wo Sie einige Alternativen finden können, wenn Sie mögen: Gute PHP ORM Bibliothek?

Es klingt in der Theorie gut, aber in allen likelyhood YAGNI .

Sie würden besser sein, eine SQL-Bibliothek wie PDO und sich Gedanken nicht über LDAP, bis Sie man dorthin kommt.

Generell, wenn Sie ihnen die Mühe gehen eine Datenbank verwenden, dann Ihre Anwendung mithilfe von spezifischen Funktionen zu einer „Marke“ der Datenbank profitieren, und wird eine solidere App für sie.

Es ist sehr selten von einem Datenbanksystem zum anderen zu bewegen. Die einzige Zeit, die Sie realistisch, dass aa Feature wert Umsetzung berücksichtigen könnte, ist, wenn Sie irgendeine Art von lose gekoppelten System oder Rahmen für den Massenkonsum bestimmt sind schriftlich (wie Zend Framework oder Django).

ich immer mit ADOdb mag. Von dem, was ich gesehen habe, sieht es aus wie es der Wechsel zwischen sehr unterschiedlichen Plattformen fähig ist.

http://adodb.sf.net

In der Tat Lösung für das Thema „wo Datenzugriffslogik implementieren?“ ist nicht komplex. Alles, was Sie sich zu erinnern ist, dass Ihr Modell Code aus Ihrem Datenzugriffscode getrennt sein muß.

Wie:

Modell Schicht mit einiger Business-Logik User :: name () Methode

class User 
{
  public $first;
  public $last;
  public $email;
  public function name ()
  {
      return $this->first." ".$this->last;
  }
}

Datenzugriffsschicht:

class Link
{
    $this->connection;
    public function __construct ()
    {
        $this->connection = PDO_Some_Connect_Function();
    }
    public function query ($query)
    {
        PDO_Some_Query ($this->connection, $query);
    }

}

class Database
{
    public $link;
    public function __construct ()
    {
        $this->link = new Link();
    }
    public function query ($query)
    {
        $this->link->query ($query);
    }
}

class Users
{
    public $database;
    public function __construct (&$database)
    {
         $this->database = &$database;
    } 
    public save ($user)
    {
        $this->database->link->query ("INSERT INTO user VALUES( '$user->first', '$user->last', '$user->email' ))";
    }

Verbrauch:

$database = new Database();

$users = new Users();

$users->save (new User());

In diesem Beispiel ist es offensichtlich, dass Sie immer Ihre Datenzugriffsklasse Link ändern können, welche Abfragen auf, was laufen wird (es bedeutet, dass Sie Ihre Benutzer auf einem Server speichern können, wie Sie Link ändern).

In der gleichen Zeit, die Sie sauber Modell Schicht-Code haben, die unabhängig lebt und hat keine Ahnung, wer und wo seine Objekte zu speichern.

Auch hier Database-Klasse scheint nicht notwendig, aber es in der Tat kann es die Geburt große Ideen wie das Sammeln viele Links eine Instanz für viele DB-Verbindungen in einem Projekt geben.

Auch gibt es einzelne Datei einfachste und allmächtige Rahmen genannt db.php (

Axon ORM automatisch Änderungen in Ihrem Schema erkennt, ohne dass Sie Ihren Code neu zu erstellen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top