it-swarm.com.de

Ist es eine schlechte Praxis, während der Entwicklung eines Plugins direkt zur MySQL-Datenbank zu wechseln?

Dies ist ein Beispiel des Vote Up Plugins:

//Run this to create an entry for a post in the voting system. Will check if the post exists. If it doesn't, it will create an entry.
function SetPost($post_ID) {
    global $wpdb;

    //prevents SQL injection
    $p_ID = $wpdb->escape($post_ID);

    //Check if entry exists
    $id_raw = $wpdb->get_var("SELECT ID FROM ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    if ($id_raw != '') {
        //entry exists, do nothing
    } else {
        //entry does not exist
        $wpdb->query("INSERT INTO ".$wpdb->prefix."votes (post, votes, guests, usersinks, guestsinks) VALUES(".$p_ID.", '', '', '', '') ") or die(mysql_error());
    }
}

//Run this to create an entry for a user in the voting system. Will check if the user exists. If it doesn't, it will create an entry.
function SetUser($user_ID) {
    global $wpdb;

    //prevents SQL injection
    $u_ID = $wpdb->escape($user_ID);

    //Check if entry exists
    $id_raw = $wpdb->get_var("SELECT ID FROM ".$wpdb->prefix."votes_users WHERE user='".$u_ID."'");
    if ($id_raw != '') {
        //entry exists, do nothing
    } else {
        //entry does not exist
        $wpdb->query("INSERT INTO ".$wpdb->prefix."votes_users (user, votes, sinks) VALUES(".$u_ID.", '', '') ") or die(mysql_error());
    }
}

//Returns the vote count
function GetVotes($post_ID, $percent = false) {
    global $wpdb;

    //prevents SQL injection
    $p_ID = $wpdb->escape($post_ID);

    //Create entries if not existant
    SetPost($p_ID);

    //Gets the votes
    $votes_raw = $wpdb->get_var("SELECT votes FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    $sinks_raw = $wpdb->get_var("SELECT usersinks FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    $guestvotes_raw = $wpdb->get_var("SELECT guests FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
    $guestsinks_raw = $wpdb->get_var("SELECT guestsinks FROM  ".$wpdb->prefix."votes WHERE post='".$p_ID."'");
/* Deprecated
    $uservotes_raw = $wpdb->get_var("SELECT votes FROM ".$wpdb->prefix."votes_users WHERE user='".$u_ID."'");
    $usersinks_raw = $wpdb->get_var("SELECT sinks FROM ".$wpdb->prefix."votes_users WHERE user='".$u_ID."'");
*/

    //Put it in array form
    $votes = explode(",", $votes_raw);
    $sinks = explode(",", $sinks_raw);
    $guestvotes = explode(",", $guestvotes_raw);
    $guestsinks = explode(",", $guestsinks_raw);
/* Deprecated
    $uservotes = explode(",", $uservotes_raw);
    $usersinks = explode(",", $usersinks_raw);
*/
    $uservotes = 0;
    $usersinks = 0;

    $initial = 0; //Initial no. of votes [will be placed at -1 when all posts receive votes]

(und so weiter...)

Ich habe von vielen Leuten gehört, dass es eine schlechte Praxis ist, direkt zur mysql-Datenbank zu gehen. Dass der Code in zukünftigen Versionen von Wordpress nicht mehr funktionieren kann.

Oder ist es in einigen Plugins wie Vote it Up notwendig?

3
janoChen

Hallo @ janoChen:

Die richtige Antwort lautet: "Es kommt darauf an."

Im Allgemeinen ist es besser, eingebaute WordPress-Funktionen zu verwenden, als Direct SQL zu verwenden, wenn es eingebaute Funktionen gibt, die Ihnen das bieten, was Sie benötigen. Die Antworten auf viele der Die Fragen, die ich hier zu WPSE sehe, lauten (leider) "Sie müssen dafür direktes SQL verwenden, da WordPress einfach keine (n-effiziente) Funktion bietet, um das zu liefern, was Sie benötigen."

Im Fall des Vote It Up-Plugins ist es fraglich, ob die Auswahl von direktem SQL richtig war, da es keinen effizienten Ort zum Speichern von Stimmen in der WordPress-Datenbank gibt. Andererseits gibt es diejenigen, die argumentieren, dass sie wp_postmeta und wp_usermeta hätten verwenden sollen, um diese Informationen zu speichern. Persönlich bin ich auf dem Zaun für ein Abstimmungs-Plugin; Ich müsste tatsächlich eine implementieren (was ich getan habe, aber es war vor fast 2 Jahren und habe seitdem viel gelernt) , um wirklich eine Meinung darüber zu haben, wie das am besten funktioniert.

Eine Sache, die ich sagen werde, ist, dass ich es fast immer bevorzuge, die eingebauten Tabellen mit WordPress zu verwenden, anstatt neue Tabellen hinzuzufügen. Das Hinzufügen einer Tabelle hat größere Auswirkungen als das Hinzufügen von SQL-Code, um auf die vorhandenen Tabellen zuzugreifen. Wenn man bedenkt, dass ich alleine lernen könnte, die Metatabellen für ein Abstimmungs-Plugin zu verwenden, kann ich das ehrlich gesagt nicht eindeutig sagen, es sei denn, ich habe tatsächlich versucht, eine solche Funktionalität zu implementieren.

AKTUALISIEREN

Ich habe gerade den Code von c.bavota gelesen und in gewisser Weise ist es gut, in anderer Hinsicht stört es mich. Ich mag es, dass er Post-Meta verwendet, aber ich mag es nicht, dass er die Liste der durch Kommas getrennten Benutzer-IDs in ein Post-Meta-Feld setzt. Was passiert, wenn ein Beitrag 25.000 Stimmen erhält? Offensichtlich ist sein Code nicht für eine stark frequentierte Site skalierbar. Und sein Code würde es sehr langsam machen, eine Liste aller Beiträge zu erhalten, über die ein bestimmter Benutzer für eine Website mit einer großen Anzahl von Beiträgen abgestimmt hat.

Wenn er alle Benutzer-IDs für Abstimmungen in ein Metafeld packen will, sollte er dies auf eine skalierbarere Weise tun, z. B. das Speichern von Post-IDs in Benutzer-Metas, da die Wahrscheinlichkeit, dass ein Benutzer 25.000 oder sogar 2500 Stimmen abgibt, sehr gering ist. Oder er könnte Stimmen speichern, indem er die Benutzer-ID in den Post-Metaschlüssel einbettet, d. H. "user_vote_{$user_id}" (obwohl möglicherweise 25.000 Metadatensätze eigene Probleme verursachen würden.)

OTOH, wenn Sie wirklich die Abstimmungen nach Benutzern verfolgen müssen, ist dies der Punkt, an dem ich möglicherweise für eine Tabelle argumentiere und Direct SQL möglicherweise sinnvoll ist.

Außerdem rollt er seinen eigenen Webdienst, anstatt die eingebaute AJAX -Funktionalität für Webdienste zu verwenden. Obwohl mir nicht gefällt, dass die eingebaute Funktionalität nicht RESTful ist, halte ich es nicht für eine gute Idee, eine Web-Service-Infrastruktur neu zu erstellen, es sei denn, Sie tun es richtig. Das Richtige zu tun würde eingebaute Sicherheit beinhalten und c.bavotas Code kümmert sich nicht um die Sicherheit. Kein Entkommen von $_POST Werten, keine Verwendung von Nonces, nichts.

Und sein Code könnte Stimmen leicht unterzählen, wenn zwei oder mehr Personen gleichzeitig abstimmen. Etwas beängstigend ist, dass dieser Typ Premium-Themen verkauft und in seinen Artikeln mit Anleitungen ein Code enthalten ist, der gegen mehrere bekannte Best Practices verstößt. Aber ich denke, er ist kaum ein Einzelfall als Theme-Anbieter, der Code mit Sicherheits- oder Skalierbarkeitsproblemen hat. <Seufzer>.

Ich habe einen Kommentar zu diesen Problemen hinterlassen und ihm vorgeschlagen, seine Benutzer sofort zu warnen und mit besseren Techniken zu aktualisieren, aber es ist derzeit in Maßen. Hoffen wir, dass er es veröffentlicht.

UPDATE2

Warum Funktionen wie update_post_meta() verwenden, anstatt die Datenbank direkt zu aktualisieren? Mehrere Gründe, aber viel wichtiger für Plugins oder Themes, die Sie verteilen möchten, als für Code, den Sie für Ihre eigene Site schreiben (obwohl dies im Idealfall auch für letztere hilfreich ist.):

  1. Durch eine kleine Chance kann WordPress die Datenbankstruktur für Meta zufällig verändern. Sie haben es schon einmal gemacht und könnten es noch einmal tun. Wenn Sie anstelle von SQL die integrierten Funktionen verwenden, funktioniert Ihr Code weiterhin, aber der direkte SQL-Code bricht bei einem WordPress-Upgrade offensichtlich ab.

  2. Wenn Sie update_post_meta() verwenden, funktioniert dies für einzelne Sites und Multisite. Direkter SQL-Code funktioniert für den einen, aber nicht für den anderen.

  3. Wenn Sie update_post_meta() verwenden und jemand ein Plugin verwenden möchte, das häufig aufgerufene Werte in MemCached speichert, wird dies von Ihrem Code unterstützt, jedoch nicht, wenn Sie direktes SQL schreiben.

  4. Im Allgemeinen funktioniert der Hook, wenn ein Plugin oder ein Theme die Funktion update_post_meta() hat, wenn Sie die Funktion update_post_meta() verwenden, aber nicht, wenn Sie Direct SQL verwenden.

  5. Und ich bin mir sicher, dass es noch andere Gründe gibt, an die ich im Moment nicht denken kann.

Es genügt zu sagen, dass die Verwendung der integrierten Funktionen Robustheit und Flexibilität bietet, mit denen Direct SQL nicht Schritt halten kann. Verwenden Sie daher nur Direct SQL, wenn Sie dies mit integrierten Funktionen nicht tun können. JMTCW.

6
MikeSchinkel

Für die meisten Plugins ist es ausreichend, die WordPress Options-API zu verwenden. Während dies für Schaltflächen, Zeichenfolgen und andere einfache Dinge gut funktioniert, benötigen komplexere Plugins manchmal ihre eigene Datenbanktabelle. Wenn Sie sich in einer solchen Situation befinden, befolgen Sie die offiziellen Richtlinien auf der Seite Erstellen von Tabellen mit Plugins .

Es ist nichts Falsches daran, direkt in die Datenbank zu gelangen, solange Sie die Eingabe ordnungsgemäß überprüfen und sicherstellen, dass Ihr Code absolut sicher ist. WordPress verfügt über viele Funktionen, die dies erheblich vereinfachen (siehe auch hier: Erstellen von Tabellen mit Plugins ), weshalb ich dies persönlich empfehle.

1