Benutzerdefinierte Datenbanktabellen: API erstellen
German (Deutsch) translation by Wei Zhang (you can also view the original English article)
Im ersten Teil dieser Serie haben wir die Nachteile der Verwendung eines benutzerdefinierten Tisches untersucht. Eine der wichtigsten ist das Fehlen einer API: In diesem Artikel wird erläutert, wie eine erstellt wird. Die API fungiert als Schicht zwischen dem Umgang mit Daten in Ihrem Plug-In und der tatsächlichen Interaktion mit der Datenbanktabelle. Sie soll vor allem sicherstellen, dass solche Interaktionen sicher sind, und einen "benutzerfreundlichen" Wrapper für Ihre Tabelle bereitstellen. Daher benötigen wir Wrapper-Funktionen zum Einfügen, Aktualisieren, Löschen und Abfragen von Daten.
Warum sollte ich eine API erstellen?
Es gibt mehrere Gründe, warum eine API empfohlen wird - die meisten lassen sich jedoch auf zwei verwandte Prinzipien beschränken: Reduzierung der Codeduplizierung und Trennung von Problemen.
Es ist sicherer
Mit den oben genannten vier Wrapper-Funktionen müssen Sie lediglich sicherstellen, dass Ihre Datenbankabfragen an vier Stellen sicher sind. Dann können Sie die Desinfektion vollständig vergessen. Sobald Sie sicher sind, dass Ihre Wrapper-Funktionen die Datenbank sicher handhaben, müssen Sie sich keine Sorgen um die Daten machen, die Sie ihnen geben. Sie können die Daten auch überprüfen - einen Fehler zurückgeben, wenn etwas nicht stimmt.
Die Idee ist, dass Sie ohne diese Funktion sicherstellen müssen, dass jede Instanz der Interaktion mit Ihrer Datenbank sicher funktioniert. Dies erhöht nur die Wahrscheinlichkeit, dass Sie in einem dieser Fälle etwas verpassen und eine Schwachstelle in Ihrem Plug-In verursachen.
Reduziert Fehler
Dies bezieht sich auf den ersten Punkt (und beide beziehen sich auf die Code-Duplizierung). Durch das Duplizieren von Code besteht ein größerer Spielraum für das Durchsuchen von Fehlern. Umgekehrt wissen Sie durch die Verwendung von Wrapper-Funktionen - wenn ein Fehler beim Aktualisieren oder Abfragen der Datenbanktabelle vorliegt - genau, wo Sie suchen müssen.
Es ist einfacher zu lesen
Dies mag als "weicher" Grund erscheinen - aber die Lesbarkeit von Code ist unglaublich wichtig. Lesbarkeit bedeutet, dem Leser die Logik und die Aktionen des Codes verständlich zu machen. Dies ist nicht nur wichtig, wenn Sie als Teil eines Teams arbeiten oder wenn jemand Ihre Arbeit erbt: Sie wissen vielleicht, was Ihr Code jetzt tun soll, aber in sechs Monaten werden Sie es wahrscheinlich vergessen haben. Und wenn Ihr Code schwer zu befolgen ist, ist es einfacher, einen Fehler einzuführen.
Wrapper-Funktionen bereinigen Ihren Code, indem Sie die internen Abläufe einiger Vorgänge (z. B. Erstellen eines Beitrags) buchstäblich vom Kontext dieser Vorgänge trennen (z. B. die Bearbeitung eines Formulars). Stellen Sie sich vor, dass Sie den gesamten Inhalt von wp_insert_post() anstelle jeder Instanz verwenden, die Sie wp_insert_post() verwenden.
Fügt eine Abstraktionsebene hinzu
Das Hinzufügen von Abstraktionsschichten ist nicht immer eine gute Sache - aber hier ist es zweifellos. Diese Wrapper bieten nicht nur eine benutzerfreundliche Methode zum Aktualisieren oder Abfragen der Tabelle (stellen Sie sich vor, Sie müssen SQL zum Abfragen von Posts verwenden, anstatt das weitaus prägnantere WP_Query() - und alle damit zusammenhängenden SQL-Formulierungen und -Desitierungen) Außerdem werden Sie und andere Entwickler vor Änderungen an der zugrunde liegenden Datenbankstruktur geschützt.
Durch die Verwendung von Wrapper-Funktionen können Sie, wie auch Dritte, diese verwenden, ohne befürchten zu müssen, dass sie unsicher sind oder brechen. Wenn Sie sich entscheiden, eine Spalte umzubenennen, eine Spalte an eine andere Stelle zu verschieben oder sogar zu löschen, können Sie sicher sein, dass der Rest Ihres Plug-Ins nicht beschädigt wird, da Sie lediglich die erforderlichen Änderungen an den Wrapper-Funktionen vornehmen. (Dies ist übrigens ein zwingender Grund, direkte SQL-Abfragen von WordPress-Tabellen zu vermeiden: Wenn sie sich ändern, ändern sie das Plug-In.) Auf der anderen Seite hilft eine API, Ihr Plug-In stabil zu erweitern.
Konsistenz
Ich bin vielleicht schuld daran, hier einen Punkt in zwei Teile zu teilen - aber ich glaube, dass dies ein wichtiger Vorteil ist. Bei der Entwicklung von Plug-Ins gibt es wenig Schlimmeres als Inkonsistenzen: Es fördert nur unordentlichen Code. Wrapper-Funktionen bieten eine konsistente Interaktion mit der Datenbank: Sie geben Daten an und geben true (oder eine ID) oder false (oder ein WP_Error-Objekt zurück, wenn Sie dies vorziehen).
Die API
Hoffentlich bin ich jetzt von der Notwendigkeit einer API für Ihre Tabelle überzeugt. Bevor wir jedoch weitergehen, definieren wir zunächst eine Hilfsfunktion, die die Desinfektion ein wenig vereinfacht.
Die Tabellenspalten
Wir definieren eine Funktion, die die Tabellenspalten mit dem erwarteten Datenformat zurückgibt. Auf diese Weise können wir die zulässigen Spalten einfach auf die Positivliste setzen und die Eingabe entsprechend formatieren. Wenn wir außerdem Änderungen an den Spalten vornehmen, müssen wir nur die Änderungen hier vornehmen
1 |
|
2 |
function wptuts_get_log_table_columns(){ |
3 |
return array( |
4 |
'log_id'=> '%d', |
5 |
'user_id'=> '%d', |
6 |
'activity'=>'%s', |
7 |
'object_id'=>'%d', |
8 |
'object_type'=>'%s', |
9 |
'activity_date'=>'%s', |
10 |
);
|
11 |
}
|
Daten einfügen
Die einfachste Wrapper-Funktion "insert" nimmt nur ein Array von Spalten-Wert-Paaren und fügt diese in die Datenbank ein. Dies muss nicht der Fall sein: Sie können sich dafür entscheiden, mehr "benutzerfreundliche" Tasten anzugeben, die Sie dann den Spaltennamen zuordnen. Sie können auch entscheiden, dass einige Werte basierend auf den übergebenen Werten automatisch generiert oder überschrieben werden (z. B. Status in wp_insert_post()).
Möglicherweise müssen die * Werte * zugeordnet werden. Das Format, in dem die Daten am besten gespeichert werden, ist nicht immer das geeignetste Format. Zum Beispiel ist es für Datumsangaben möglicherweise einfacher, ein DateTime-Objekt oder einen Zeitstempel zu behandeln - und dies dann in das gewünschte Datumsformat zu konvertieren.
Die Wrapper-Funktion kann einfach oder kompliziert sein - die Eingabe sollte jedoch mindestens bereinigt werden. Ich empfehle außerdem das Whitelisting für die erkannten Spalten, da der Versuch, Daten in eine nicht vorhandene Spalte einzufügen, einen Fehler auslösen kann.
In diesem Beispiel ist die Benutzer-ID standardmäßig die des aktuellen Benutzers. Alle Felder werden durch ihren Spaltennamen angegeben. Dies ist die Ausnahme des Aktivitätsdatums, das als "Datum" übergeben wird. Das Datum sollte in diesem Beispiel ein lokaler Zeitstempel sein, der vor dem Hinzufügen in die Datenbank konvertiert wird.
1 |
|
2 |
/**
|
3 |
* Inserts a log into the database
|
4 |
*
|
5 |
*@param $data array An array of key => value pairs to be inserted
|
6 |
*@return int The log ID of the created activity log. Or WP_Error or false on failure.
|
7 |
*/
|
8 |
function wptuts_insert_log( $data=array() ){ |
9 |
global $wpdb; |
10 |
|
11 |
//Set default values
|
12 |
$data = wp_parse_args($data, array( |
13 |
'user_id'=> get_current_user_id(), |
14 |
'date'=> current_time('timestamp'), |
15 |
));
|
16 |
|
17 |
//Check date validity
|
18 |
if( !is_float($data['date']) || $data['date'] <= 0 ) |
19 |
return 0; |
20 |
|
21 |
//Convert activity date from local timestamp to GMT mysql format
|
22 |
$data['activity_date'] = date_i18n( 'Y-m-d H:i:s', $data['date'], true ); |
23 |
|
24 |
//Initialise column format array
|
25 |
$column_formats = wptuts_get_log_table_columns(); |
26 |
|
27 |
//Force fields to lower case
|
28 |
$data = array_change_key_case ( $data ); |
29 |
|
30 |
//White list columns
|
31 |
$data = array_intersect_key($data, $column_formats); |
32 |
|
33 |
//Reorder $column_formats to match the order of columns given in $data
|
34 |
$data_keys = array_keys($data); |
35 |
$column_formats = array_merge(array_flip($data_keys), $column_formats); |
36 |
|
37 |
$wpdb->insert($wpdb->wptuts_activity_log, $data, $column_formats); |
38 |
|
39 |
return $wpdb->insert_id; |
40 |
}
|
wp_insert_post() zum Beispiel erfordert ein gewisses Maß an Eindeutigkeit, um Slugs zu posten. Bei Konflikten wird automatisch ein eindeutiger erzeugt. wp_insert_term gibt hingegen einen Fehler zurück, wenn der Begriff bereits existiert. Dies liegt an einer Mischung aus der Art und Weise, wie WordPress diese Objekte verarbeitet, und der Semantik.Daten aktualisieren
Das Aktualisieren von Daten ähnelt in der Regel dem Einfügen von Daten - mit der Ausnahme, dass ein Zeilenbezeichner (normalerweise nur der Primärschlüssel) zusammen mit Daten bereitgestellt wird, die aktualisiert werden müssen. Im Allgemeinen sollten die Argumente mit der Einfügungsfunktion übereinstimmen (aus Gründen der Konsistenz). In diesem Beispiel wird 'date' anstelle von 'activity_date' verwendet.
1 |
|
2 |
/**
|
3 |
* Updates an activity log with supplied data
|
4 |
*
|
5 |
*@param $log_id int ID of the activity log to be updated
|
6 |
*@param $data array An array of column=>value pairs to be updated
|
7 |
*@return bool Whether the log was successfully updated.
|
8 |
*/
|
9 |
function wptuts_update_log( $log_id, $data=array() ){ |
10 |
global $wpdb; |
11 |
|
12 |
//Log ID must be positive integer
|
13 |
$log_id = absint($log_id); |
14 |
if( empty($log_id) ) |
15 |
return false; |
16 |
|
17 |
//Convert activity date from local timestamp to GMT mysql format
|
18 |
if( isset($data['activity_date']) ) |
19 |
$data['activity_date'] = date_i18n( 'Y-m-d H:i:s', $data['date'], true ); |
20 |
|
21 |
|
22 |
//Initialise column format array
|
23 |
$column_formats = wptuts_get_log_table_columns(); |
24 |
|
25 |
//Force fields to lower case
|
26 |
$data = array_change_key_case ( $data ); |
27 |
|
28 |
//White list columns
|
29 |
$data = array_intersect_key($data, $column_formats); |
30 |
|
31 |
//Reorder $column_formats to match the order of columns given in $data
|
32 |
$data_keys = array_keys($data); |
33 |
$column_formats = array_merge(array_flip($data_keys), $column_formats); |
34 |
|
35 |
if ( false === $wpdb->update($wpdb->wptuts_activity_log, $data, array('log_id'=>$log_id), $column_formats) ) { |
36 |
return false; |
37 |
}
|
38 |
|
39 |
return true; |
40 |
}
|
Daten abfragen
Eine Wrapper-Funktion zum Abfragen von Daten ist oft ziemlich kompliziert - zumal Sie alle Arten von Abfragen unterstützen möchten, die nur bestimmte Felder auswählen, die durch AND- oder OR-Anweisungen eingeschränkt werden, nach einer von mehreren möglichen Spalten sortieren usw. (siehe hierzu auch die Klasse WP_Query ).
Das grundlegende Prinzip der Wrapper-Funktion zum Abfragen der Daten besteht darin, dass sie ein "Abfrage-Array" benötigen, es interpretieren und die entsprechende SQL-Anweisung bilden sollten.
1 |
|
2 |
/**
|
3 |
* Retrieves activity logs from the database matching $query.
|
4 |
* $query is an array which can contain the following keys:
|
5 |
*
|
6 |
* 'fields' - an array of columns to include in returned roles. Or 'count' to count rows. Default: empty (all fields).
|
7 |
* 'orderby' - datetime, user_id or log_id. Default: datetime.
|
8 |
* 'order' - asc or desc
|
9 |
* 'user_id' - user ID to match, or an array of user IDs
|
10 |
* 'since' - timestamp. Return only activities after this date. Default false, no restriction.
|
11 |
* 'until' - timestamp. Return only activities up to this date. Default false, no restriction.
|
12 |
*
|
13 |
*@param $query Query array
|
14 |
*@return array Array of matching logs. False on error.
|
15 |
*/
|
16 |
function wptuts_get_logs( $query=array() ){ |
17 |
|
18 |
global $wpdb; |
19 |
/* Parse defaults */
|
20 |
$defaults = array( |
21 |
'fields'=>array(),'orderby'=>'datetime','order'=>'desc', 'user_id'=>false, |
22 |
'since'=>false,'until'=>false,'number'=>10,'offset'=>0 |
23 |
);
|
24 |
|
25 |
$query = wp_parse_args($query, $defaults); |
26 |
|
27 |
/* Form a cache key from the query */
|
28 |
$cache_key = 'wptuts_logs:'.md5( serialize($query)); |
29 |
$cache = wp_cache_get( $cache_key ); |
30 |
|
31 |
if ( false !== $cache ) { |
32 |
$cache = apply_filters('wptuts_get_logs', $cache, $query); |
33 |
return $cache; |
34 |
}
|
35 |
|
36 |
extract($query); |
37 |
|
38 |
/* SQL Select */
|
39 |
//Whitelist of allowed fields
|
40 |
$allowed_fields = wptuts_get_log_table_columns(); |
41 |
|
42 |
if( is_array($fields) ){ |
43 |
//Convert fields to lowercase (as our column names are all lower case - see part 1)
|
44 |
$fields = array_map('strtolower',$fields); |
45 |
|
46 |
//Sanitize by white listing
|
47 |
$fields = array_intersect($fields, $allowed_fields); |
48 |
}else{ |
49 |
$fields = strtolower($fields); |
50 |
}
|
51 |
|
52 |
//Return only selected fields. Empty is interpreted as all
|
53 |
if( empty($fields) ){ |
54 |
$select_sql = "SELECT* FROM {$wpdb->wptuts_activity_log}"; |
55 |
}elseif( 'count' == $fields ) { |
56 |
$select_sql = "SELECT COUNT(*) FROM {$wpdb->wptuts_activity_log}"; |
57 |
}else{ |
58 |
$select_sql = "SELECT ".implode(',',$fields)." FROM {$wpdb->wptuts_activity_log}"; |
59 |
}
|
60 |
|
61 |
/*SQL Join */
|
62 |
//We don't need this, but we'll allow it be filtered (see 'wptuts_logs_clauses' )
|
63 |
$join_sql=''; |
64 |
|
65 |
/* SQL Where */
|
66 |
//Initialise WHERE
|
67 |
$where_sql = 'WHERE 1=1'; |
68 |
|
69 |
if( !empty($log_id) ) |
70 |
$where_sql .= $wpdb->prepare(' AND log_id=%d', $log_id); |
71 |
|
72 |
if( !empty($user_id) ){ |
73 |
|
74 |
//Force $user_id to be an array
|
75 |
if( !is_array( $user_id) ) |
76 |
$user_id = array($user_id); |
77 |
|
78 |
$user_id = array_map('absint',$user_id); //Cast as positive integers |
79 |
$user_id__in = implode(',',$user_id); |
80 |
$where_sql .= " AND user_id IN($user_id__in)"; |
81 |
}
|
82 |
|
83 |
$since = absint($since); |
84 |
$until = absint($until); |
85 |
|
86 |
if( !empty($since) ) |
87 |
$where_sql .= $wpdb->prepare(' AND activity_date >= %s', date_i18n( 'Y-m-d H:i:s', $since, true)); |
88 |
|
89 |
if( !empty($until) ) |
90 |
$where_sql .= $wpdb->prepare(' AND activity_date <= %s', date_i18n( 'Y-m-d H:i:s', $until, true)); |
91 |
|
92 |
/* SQL Order */
|
93 |
//Whitelist order
|
94 |
$order = strtoupper($order); |
95 |
$order = ( 'ASC' == $order ? 'ASC' : 'DESC' ); |
96 |
|
97 |
switch( $orderby ){ |
98 |
case 'log_id': |
99 |
$order_sql = "ORDER BY log_id $order"; |
100 |
break; |
101 |
case 'user_id': |
102 |
$order_sql = "ORDER BY user_id $order"; |
103 |
break; |
104 |
case 'datetime': |
105 |
$order_sql = "ORDER BY activity_date $order"; |
106 |
default: |
107 |
break; |
108 |
}
|
109 |
|
110 |
/* SQL Limit */
|
111 |
$offset = absint($offset); //Positive integer |
112 |
if( $number == -1 ){ |
113 |
$limit_sql = ""; |
114 |
}else{ |
115 |
$number = absint($number); //Positive integer |
116 |
$limit_sql = "LIMIT $offset, $number"; |
117 |
}
|
118 |
|
119 |
/* Filter SQL */
|
120 |
$pieces = array( 'select_sql', 'join_sql', 'where_sql', 'order_sql', 'limit_sql' ); |
121 |
$clauses = apply_filters( 'wptuts_logs_clauses', compact( $pieces ), $query ); |
122 |
foreach ( $pieces as $piece ) |
123 |
$$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : ''; |
124 |
|
125 |
/* Form SQL statement */
|
126 |
$sql = "$select_sql $where_sql $order_sql $limit_sql"; |
127 |
|
128 |
if( 'count' == $fields ){ |
129 |
return $wpdb->get_var($sql); |
130 |
}
|
131 |
|
132 |
/* Perform query */
|
133 |
$logs = $wpdb->get_results($sql); |
134 |
|
135 |
/* Add to cache and filter */
|
136 |
wp_cache_add( $cache_key, $logs, 24*60*60 ); |
137 |
$logs = apply_filters('wptuts_get_logs', $logs, $query); |
138 |
return $logs; |
139 |
}
|
In dem obigen Beispiel gibt es einiges zu sagen, da ich versucht habe, einige Funktionen einzubeziehen, die bei der Entwicklung Ihrer Wrapper-Funktionen berücksichtigt werden könnten, die wir in den folgenden Abschnitten behandeln.
Zwischenspeicher
Sie können Ihre Abfragen für ausreichend komplex halten oder regelmäßig wiederholen, sodass es sinnvoll ist, die Ergebnisse zwischenzuspeichern. Da unterschiedliche Abfragen zu unterschiedlichen Ergebnissen führen, möchten wir offensichtlich keinen generischen Cache-Schlüssel verwenden. Wir benötigen einen, der für diese Abfrage eindeutig ist. Genau das macht das Folgende. Es serialisiert das Abfrage-Array und hasst es, um einen für $query eindeutigen Schlüssel zu erzeugen:
1 |
|
2 |
$cache_key = 'wptuts_logs:'.md5( serialize($query)); |
Als Nächstes prüfen wir, ob wir etwas für diesen Cache-Schlüssel gespeichert haben. Wenn dies der Fall ist, geben wir einfach den Inhalt zurück. Wenn nicht, generieren wir die SQL-Anweisung, führen die Abfrage aus und fügen die Ergebnisse (für höchstens 24 Stunden) in den Cache ein und geben sie zurück. Wir müssen bedenken, dass es bis zu 24 Stunden dauern kann, bis Datensätze in den Ergebnissen dieser Funktion angezeigt werden. Normalerweise gibt es Kontexte, in denen der Cache automatisch gelöscht wird. Diese müssten jedoch implementiert werden.
Filter & Aktionen
Hooks wurden kürzlich von Tom McFarlin und Pippin Williamson ausführlich auf WPTuts + behandelt. In seinem Artikel spricht Pippin über die Gründe, warum Sie Ihren Code durch Hooks erweiterbar machen sollten, und Wrapper wie wptuts_get_logs() sind ausgezeichnete Beispiele dafür, wo sie verwendet werden können.
Wir haben zwei Filter in der obigen Funktion verwendet:
-
wptuts_get_logs- filtert das Ergebnis der Funktion -
wptuts_logs_clauses- filtert ein Array von SQL-Komponenten
Dies ermöglicht Drittentwicklern oder auch uns selbst, auf der bereitgestellten API aufzubauen. Wenn wir die Verwendung von Direct SQL in unserem Plug-in vermeiden und nur die von uns erstellten Wrapper-Funktionen verwenden, können Sie das Plug-In sofort erweitern. Insbesondere der Filter wptuts_logs_clauses würde es Entwicklern ermöglichen, jeden Teil der SQL zu ändern - und somit komplexe Abfragen ausführen. Wir werden feststellen, dass jedes Plug-in diese Filter verwendet, um sicherzustellen, dass das zurückgegebene Filter ordnungsgemäß bereinigt wird.
Hooks sind ebenso nützlich, wenn Sie die anderen drei Hauptoperationen ausführen: Einfügen, Aktualisieren und Löschen von Daten. Aktionen ermöglichen Plug-Ins, zu wissen, wann diese ausgeführt werden - also eine Aktion. In unserem Zusammenhang kann dies bedeuten, dass eine E-Mail an einen Administrator gesendet wird, wenn ein bestimmter Benutzer eine bestimmte Aktion ausführt. Filter im Zusammenhang mit diesen Vorgängen sind nützlich, um Daten vor dem Einfügen zu ändern.
Seien Sie vorsichtig, wenn Sie Haken benennen. Ein guter Hakenname bewirkt mehrere Dinge:
- Kommuniziert, wann der Hook aufgerufen wird oder was er tut (z. B. können Sie raten, was
pre_get_postsunduser_has_captun könnten. - Einzigartig sein. Es wird empfohlen, Hooks mit dem Namen Ihres Plug-Ins vorzustellen. Im Gegensatz zu Funktionen gibt es keinen Fehler, wenn zwischen den Namen der Hooks ein Konflikt besteht. Stattdessen werden wahrscheinlich nur ein oder mehrere Plug-Ins "stummgeschaltet".
- Zeigt eine Art Struktur. Machen Sie Ihre Hooks berechenbar und vermeiden Sie die Benennung von Hooks "on the fly", da dies manchmal zu scheinbar zufälligen Hook-Namen Planen Sie stattdessen die Hooks, die Sie verwenden werden, so weit wie möglich im Voraus, und finden Sie eine geeignete Namenskonvention - und halten Sie sich daran.
Daten löschen
Das Löschen von Daten ist oft die einfachste der Umhüllungen - obwohl es möglicherweise erforderlich ist, einige Aufräumarbeiten durchzuführen oder einfach die Daten zu entfernen. wp_delete_post() löscht beispielsweise nicht nur den Beitrag aus der Tabelle *_posts, sondern auch die entsprechenden Post-Meta-, Taxonomiebeziehungen, Kommentare und Revisionen usw.
In Übereinstimmung mit den Kommentaren des vorherigen Abschnitts fügen wir zwei Aktionen ein: eine zuvor ausgelöst und die andere, nachdem ein Protokoll aus der Tabelle gelöscht wurde. Befolgen Sie die Namenskonvention von WordPress für solche Aktionen:
-
_delete_wird vor dem Löschen ausgelöst -
_deleted_wird nach dem Löschen ausgelöst
1 |
|
2 |
/**
|
3 |
* Deletes an activity log from the database
|
4 |
*
|
5 |
*@param $log_id int ID of the activity log to be deleted
|
6 |
*@return bool Whether the log was successfully deleted.
|
7 |
*/
|
8 |
function wptuts_delete_log( $log_id ){ |
9 |
global $wpdb; |
10 |
|
11 |
//Log ID must be positive integer
|
12 |
$log_id = absint($log_id); |
13 |
if( empty($log_id) ) |
14 |
return false; |
15 |
|
16 |
do_action('wptuts_delete_log',$log_id); |
17 |
$sql = $wpdb->prepare("DELETE from {$wpdb->wptuts_activity_log} WHERE log_id = %d", $log_id); |
18 |
|
19 |
if( !$wpdb->query( $sql ) ) |
20 |
return false; |
21 |
|
22 |
do_action('wptuts_deleted_log',$log_id); |
23 |
|
24 |
return true; |
25 |
}
|
Dokumentation
Ich war ein bisschen faul mit der In-Source-Dokumentation der obigen API. In dieser Serie erklärt Tom McFarlin, warum Sie nicht sein sollten. Sie haben möglicherweise viel Zeit damit verbracht, Ihre API-Funktionen zu entwickeln, aber wenn andere Entwickler nicht wissen, wie sie verwendet werden sollen, tun sie dies nicht. Sie helfen sich auch, wenn Sie nach 6 Monaten vergessen haben, wie die Daten übermittelt werden sollen oder was Sie erwarten sollten.
Zusammenfassung
Wrapper für Ihre Datenbanktabelle können von relativ einfach (z. B. get_terms ()) bis zu extrem komplex (z. B. der Klasse WP_Query) reichen. Gemeinsam sollten sie versuchen, als Zugang zu Ihrem Tisch zu dienen: Sie können sich auf den Kontext konzentrieren, in dem sie verwendet werden, und im Wesentlichen vergessen, was sie tatsächlich tun. Die API, die Sie erstellen, ist nur ein kleines Beispiel für den Begriff der "Trennung von Anliegen", der häufig Edsger W. Dijkstra in seinem Artikel zur Rolle des wissenschaftlichen Denkens zugeschrieben wird.
Es ist das, was ich manchmal als "Trennung von Anliegen" bezeichnet habe, was, wenn auch nicht völlig möglich, die einzige verfügbare Technik zur effektiven Anordnung von Gedanken ist, die ich kenne. Ich meine damit "Aufmerksamkeit auf einen Aspekt richten": Es bedeutet nicht, die anderen Aspekte zu ignorieren, es wird nur der Tatsache gerecht, dass der andere Aspekt aus Sicht dieses Aspekts irrelevant ist. Es ist gleichzeitig ein- und mehrspurig.
Sie finden den in dieser Serie verwendeten Code vollständig auf GitHub. Im nächsten Teil dieser Serie werden wir untersuchen, wie Sie Ihre Datenbank verwalten und Upgrades durchführen können.



