2012-05-24 11 views
10

Ich bin ein relativer Neuling in PHP, und ich bin der beste Weg, um einige Datenbankzugriffscode zu implementieren. Ich versuche, einige einfache Datenbankzugriffsobjekte zu erstellen - jede Tabelle erhält ihre eigene Klasse, jede Instanz der Klasse repräsentiert eine Zeile in der Tabelle, Sie kennen den Drill.Abstrakte statische Funktion in PHP 5.3

Ich habe Code, der zu funktionieren scheint, aber einige von dem, was ich online gesehen habe, macht mir Sorgen, dass mein Ansatz irgendwie falsch sein könnte. Und seit "Kann ich das tun?" und "SOLL ICH das tun?" sind zwei verschiedene Fragen, ich hatte gehofft, dass einige PHP-Tierärzte hineinspielen könnten.

Meine aktuelle Strategie besteht darin, eine abstrakte Tabellenklasse auf Basisebene zu erstellen, die den allgemeinen Code enthält und dann jede Klasse für eine einzelne Tabelle erweitert.

Mein Hauptanliegen ist dieser Code:


abstract class Table { 
    protected abstract static function get_fields(); 
    protected abstract static function get_primary_key(); 
    protected abstract static function get_table_name(); 

Die Idee ist, dass jede implementierenden Klasse der Feldnamen definieren, die den Primärschlüssel (n), die Tabellennamen usw. und dann der Tabellenklasse werden diese Funktionen in bestimmten Rohlingen wie so füllen: sehen, können


    static function insert($values) { 
     $field_list = array(); 
     $value_list = array(); 
     foreach (static::get_fields() as $field_name) { 
      if (isset($values[$field_name])) { 
       $field_list[] = $field_name; 
       $value_list[] = self::escape($values[$field_name]); 
      } 
     } 
     $field_string = join(", ", $field_list); 
     $value_string = "'" . join("', '", $value_list) . "'"; 

     $sql = "insert into " . static::get_table_name() . " ($field_string) values ($value_string)"; 

wie Sie der Schlüssel ist, dass ich den Zugriff auf diese static abstract Funktionen, indem sie mit static:: prefacing. Und soweit ich das beurteilen kann, funktioniert es!

Die angenommene Antwort auf this question zeigt jedoch an, dass abstract static Funktionen in 5.3 nicht erlaubt sind.

Also, ich versuche herauszufinden, was ich davon halten soll. Ist die Antwort falsch - sind abstract static Funktionen jetzt als völlig legaler PHP-Code betrachtet? Mache ich in meinem Code etwas, das nicht ratsam ist? Gibt es einen anderen Ansatz, den ich berücksichtigen sollte?

+1

Wenn Sie sagen, „Sie wissen, das Geschäft "Ich weiß eine Sache sicher: Der Deal ist, keine statischen Funktionen dafür zu verwenden. Wenn Sie denken, dass es ist, muss es der Null-Checker-Deal sein, da statische Funktionen nicht gut mit Vererbung funktionieren, die Sie gerne nutzen. Zusätzlich empfehle ich Ihnen, das PoEEA zu lesen, ich meine, Sie kennen das Buch, oder? – hakre

+4

@hakre: Woher kommt diese Feindseligkeit und Herablassung? "Sie kennen den Drill" war ein Verweis auf einen ziemlich standardisierten Ansatz zum Modellieren von Datenbankinhalten, von dem ich nicht dachte, dass er es wert wäre, belebt zu werden. – BlairHippo

+0

Bitte geben Sie an, dass das, was Sie beschreiben, ein ziemlich Standardansatz ist. – hakre

Antwort

17

Hier ist Ihr Beispiel

abstract class Table implements iTable { 

    public static function insert() { 
     $class = get_called_class(); 
     $sql = 'INSERT INTO '.$class::get_class_name(); 
     echo $sql; 
    }  

} 

interface iTable { 
    static function get_class_name(); 
}  


class ConcreteTable extends Table 
{ 
    public function ConcreteTable() {} 

    static function get_class_name() { 
     return 'ConcreteTable'; 
    } 

} 

$t = new ConcreteTable(); 
$t::insert(); 

Dieses Beispiel Hinsicht Paradigma-Objekt, und Sie sind sicher, dass es funktioniert sogar, wenn PHP Stop-Support Späte statische Bindung (die eine PHP-Spezifität ist, glaube ich)

Edit: Was beide Antworten zeigen ist, dass es unbekannt ist, dass eine abstrakte Klasse eine Schnittstelle auch für Klassen, die daraus hervorgehen, einführt.Nach dem Template-Muster ist dies in PHP auch mit statischen Funktionen möglich (allerdings aus einem guten Grund, der Ihnen strenge Standardwarnungen gibt). Der Proof of Concept:

abstract class Table 
{ 
    abstract static function get_class_name(); 
    public static function insert() { 
     printf('INSERT INTO %s', static::get_class_name()); 
    }  

} 

class ConcreteTable extends Table 
{ 
    public static function get_class_name() { 
     return 'ConcreteTable'; 
    } 
} 

ConcreteTable::insert(); 

Wenn Sie die statischen Schlüsselwörter hier entfernen, werden Sie tatsächlich nützlich bekommen (und einer Standard Art, die Dinge) Code:

abstract class Table 
{ 
    protected $table = NULL; 
    public function insert() { 
     printf('INSERT INTO %s', $this->table); 
    }  

} 

class ConcreteTable extends Table 
{ 
    protected $table = 'ConcreteTable'; 
} 

$table = new ConcreteTable(); 
... 
$table->insert(); 
+0

Hmm, warum ist dort das offensichtlich überflüssige 'neue' drin - alles was du brauchst ist eine Saite, z. '$ t = 'ConcretTable';' Warum machen Sie das nicht von einem Funktionsnamen abhängig, der mit '__FUNCTION__' gelesen wird? Oder noch häufiger: Fügen Sie den Tabellennamen als geschützte Eigenschaft (oder die SQL-Abfrage) hinzu? – hakre

+0

Das Einladen einer Schnittstelle zu der Partei scheint mir das Verhalten zu geben, nach dem ich suche, ohne irgendwelche logischen Paradoxien, die meinen Code überfluten. Du hast meinen Dank. :-) – BlairHippo

+0

Siehe auch http://en.wikipedia.org/wiki/Template_method_pattern – hakre

6

Eine abstrakte Funktion wird niemals statisch sein, in irgendeiner Art von Sprache.

Eine statische Funktion bietet eine Funktionalität, auch wenn keine Instanz vorhanden ist.

Eine abstrakte Funktion bietet keine Funktionalität.

Logischerweise können Sie keine abstrakte statische Funktion verwenden, die - IMMER und NIE - eine Funktionalitätsfunktion bietet.


B erstreckt A

Wenn Sie eine statische Funktion in B Kontext nennen, wird es in einem Kontext (Ursache statischer Zustand) runned werden.

Aber in einem Kontext ist die gleiche Funktion abstrakt, und Sie dürfen es nicht nennen.

+0

Das wäre also ein "Ja" zur Frage, ob ich etwas nicht ratsam finde. Haben Sie einen Einblick, warum PHP mich irgendwie davonkommen lässt, oder Vorschläge für einen alternativen Ansatz, der weniger paradox ist? – BlairHippo

+0

Sie verwenden das Objektparadigma falsch. Ich stimme dem Schlüsselwort abstract zu, aber diese 3 Funktionen funktionieren immer auf Instanzen, sie sollten nicht statisch sein. – zessx

+0

Warum sollten sie nicht statisch sein? Die Liste der Felder für das Benutzerobjekt bleibt über alle Benutzerobjekte hinweg konsistent. es ist nicht von einer Instanz abhängig. Ähnlich würde ich denken, dass ich in der Lage sein sollte, "insert" oder "select" für die Klasse anstatt für ein instanziiertes Objekt aufzurufen. – BlairHippo