MySQL-Sicherheitshandbuch (2)
2.1.3 Datenbank- und Tabellenberechtigungen
Die folgenden Berechtigungen gelten für Vorgänge an Datenbanken und Tabellen.
ALTER
ermöglicht Ihnen die Verwendung von ALTER
TABLE-Anweisung, dies ist eigentlich eine einfache Berechtigung der ersten Ebene. Sie müssen über andere Berechtigungen verfügen, je nachdem, welche Vorgänge Sie in der Datenbank ausführen möchten.
Mit
CREATE
können Sie Datenbanken und Tabellen erstellen, jedoch keine Indizes. Mit
LÖSCHEN
können Sie vorhandene Datensätze aus einer Tabelle löschen.
Mit
DROP
können Sie Datenbanken und Tabellen löschen (wegwerfen), nicht jedoch Indizes. Mit
INDEX
können Sie Indizes erstellen und löschen.
REFERENZEN
Derzeit nicht verwendet.
Mit
SELECT
können Sie mithilfe der SELECT-Anweisung Daten aus einer Tabelle abrufen. Für SELECT-Anweisungen, die keine Tabellen beinhalten, wie z. B. SELECT NOW() oder SELECT 4/2, ist dies nicht erforderlich.
Mit
UPDATE
können Sie vorhandene Datensätze in der Tabelle ändern.
2.1.4
Administrative Berechtigungen
Die folgenden Berechtigungen werden für administrative Vorgänge verwendet, die den Betrieb des Servers oder Benutzerautorisierungsfunktionen steuern. Mit
DATEI
können Sie den Server anweisen, Dateien auf dem Server-Host zu lesen oder zu schreiben. Diese Erlaubnis sollte nicht leichtfertig erteilt werden, sie ist gefährlich, siehe „Vermeiden von Risiken durch Autorisierungstabellen“. Der Server achtet darauf, diese Berechtigung in Grenzen zu halten. Sie können nur Dateien lesen, die von jedem gelesen werden können. Die Datei, die Sie schreiben, darf nicht existieren. Dies verhindert, dass Sie den Server zwingen, wichtige Dateien wie /etc/passwd oder Datenverzeichnisse, die zur Datenbank einer anderen Person gehören, neu zu schreiben.
Wenn Sie FILE-Berechtigungen erteilen, stellen Sie sicher, dass Sie den Server nicht als UNIX-Root-Benutzer ausführen, da Root überall im Dateisystem neue Dateien erstellen kann. Wenn Sie den Server als unprivilegierter Benutzer ausführen, kann der Server Dateien nur in Verzeichnissen erstellen, auf die der Benutzer zugreifen kann. Mit
GRANT
können Sie Ihre eigenen Berechtigungen an andere erteilen, einschließlich GRANT.
PROCESS
ermöglicht Ihnen die Verwendung von SHOW
PROCESS-Anweisung oder mysqladmin-Prozessbefehl, um Informationen zu Threads (Prozessen) anzuzeigen, die auf dem Server ausgeführt werden. Mit dieser Berechtigung können Sie auch die KILL-Anweisung oder mysqladmin verwenden
Der Kill-Befehl beendet Threads.
Sie können jederzeit Ihre eigenen Threads sehen oder beenden. Die PROCESS-Berechtigung gibt Ihnen die Möglichkeit, diese Dinge in jedem Thread zu tun.
RELOAD
ermöglicht Ihnen die Durchführung einer Vielzahl von Serververwaltungsvorgängen. Sie können die FLUSH-Anweisung ausgeben und sich auch auf die Befehle reload,fresh,flush-hosts,flush-logs,flush-privileges undflush-tables von mysqladmin beziehen.
Mit
SHUTDOWN
können Sie den Server mit mysqladmin Shutdown herunterfahren.
In den Benutzer-, Datenbank- und Hosttabellen wird jede Berechtigung als separate Spalte angegeben. Diese Spalten sind alle als ENUM-Typ („N“, „Y“) deklariert, sodass der Standardwert jeder Gewichtung „N“ ist. Berechtigungen in tables_priv und columns_priv werden durch ein SET dargestellt, das die Angabe von Berechtigungen in beliebiger Kombination mit einer einzelnen Spalte ermöglicht. Diese beiden Tabellen sind neuer als die anderen drei Tabellen, weshalb sie eine effizientere Darstellung verwenden. (Es ist möglich, dass in Zukunft auch die Benutzer-, Datenbank- und Hosttabellen durch einen SET-Typ dargestellt werden.)
Die Table_priv-Spalte in der tables_priv-Tabelle ist definiert als:
SET („Select“, „Insert“, „Update“, „Delete“, „Create“, „Drop“, „Grant“, „References“, „Index“, „Alter“)
Die Column_priv-Spalte im coloums_priv Tabelle ist definiert als:
SET('Select','Insert','Update','References')
Spaltenberechtigungen sind geringer als Tabellenberechtigungen, da Berechtigungen mit weniger Spaltenebenen sinnvoll sind. Sie können beispielsweise eine Tabelle erstellen, aber keine isolierte Spalte.
Die Benutzertabelle enthält bestimmte Berechtigungsspalten, die in anderen Berechtigungstabellen nicht vorhanden sind: File_priv, Process_priv, Reload_priv und Shutdown_priv. Diese Berechtigungen gelten für Vorgänge, die Sie vom Server ausführen lassen und die sich nicht auf eine bestimmte Datenbank oder Tabelle beziehen. Es macht keinen Sinn, einem Benutzer das Schließen einer Datenbank basierend auf dem aktuellen Inhalt der Datenbank zu erlauben.
2.2
So steuert der Server den Client-Zugriff
Wenn Sie MySQL verwenden, gibt es zwei Stufen der Client-Zugriffskontrolle. Die erste Phase findet statt, wenn Sie versuchen, eine Verbindung zum Server herzustellen. Der Server sucht in der Benutzertabelle nach einem Eintrag, der Ihrem Namen, dem Host, von dem aus Sie eine Verbindung herstellen, und dem von Ihnen angegebenen Passwort entspricht. Wenn es keine Übereinstimmung gibt, können Sie keine Verbindung herstellen. Wenn es eine Übereinstimmung gibt, stellen Sie die Verbindung her und fahren Sie mit der zweiten Phase fort. In dieser Phase überprüft der Server für jede von Ihnen gestellte Abfrage die Autorisierungstabelle, um festzustellen, ob Sie über ausreichende Berechtigungen zum Ausführen der Abfrage verfügen. Die zweite Phase wird bis zum Ende Ihrer Konversation mit dem Server fortgesetzt.
In diesem Abschnitt werden die Prinzipien beschrieben, die der MySQL-Server verwendet, um Autorisierungstabelleneinträge mit eingehenden Verbindungsanforderungen oder Abfragen abzugleichen. Dazu gehören die Arten von zulässigen Werten in den Bereichsspalten der Autorisierungstabelle, kombiniert mit den Berechtigungsinformationen in die Berechtigungstabelle. Der Modus und die Reihenfolge, in der Einträge in der Tabelle überprüft werden.
2.2.1
Inhalt der Bereichsspalte
Einige Bereichsspalten erfordern Literalwerte, die meisten erlauben jedoch Platzhalter oder andere Sonderwerte.
Gastgeber
Ein Host-Spaltenwert kann ein Hostname oder eine IP-Adresse sein. Der Wert „localhost“ bedeutet „localhost“, aber er stimmt nur überein, wenn Sie einen „localhost“-Hostnamen verwenden, nicht, wenn Sie einen „Hostnamen“ verwenden. Wenn Ihr lokaler Hostname pit.snake.net lautet und in der Benutzertabelle zwei Datensätze für Sie vorhanden sind, einer mit einem Hostwert oder „localhost“ und der andere mit „pit.snake.net“, wird der Datensatz mit „localhost“ nur als behandelt Es stimmt überein, wenn Sie eine Verbindung zu localhost herstellen, und andere stimmen nur überein, wenn Sie eine Verbindung zu pit.snake.net herstellen. Wenn Sie möchten, dass Clients auf zwei Arten eine Verbindung herstellen können, müssen Sie zwei Datensätze in der Benutzertabelle haben.
Sie können auch Platzhalter verwenden, um den Host-Wert anzugeben. Die SQL-Musterzeichen „%“ und „_“ können verwendet werden und haben dieselbe Bedeutung wie bei Verwendung des LIKE-Operators in einer Abfrage (der Regex-Operator ist nicht zulässig).
SQL-Musterzeichen können sowohl für Hostnamen als auch für IP-Adressen verwendet werden. Beispielsweise stimmt %wisc.edu mit jedem Host in der wisc.edu-Domäne überein und %.edu mit jedem Host der Hochschule für Pädagogik. Ebenso stimmt 192.168.% mit allem in 192.168 überein
Hosts im Subnetz der Klasse B und 192.168.3.% stimmt mit allem auf 192.168.3 überein
Hosts in Subnetzen der Klasse C.
%-Wert entspricht allen Hosts und kann verwendet werden, um einem Benutzer die Verbindung von überall aus zu ermöglichen. Ein leerer Host-Wert entspricht %. (Ausnahme: In der DB-Tabelle bedeutet ein leerer Host-Wert „Weitere Überprüfung der Host-Tabelle“. Dieser Prozess wird in „Abfragezugriffsüberprüfung“ eingeführt.)
Von MySQL
Ab 3.23 können Sie auch eine IP-Adresse mit Angabe der für die Netzwerkadresse verwendeten Netzmaske angeben, z. B. 192.168.128.0/17, die eine 17-Bit-Netzwerkadresse angibt und jedem Host entspricht, dessen IP-Adresse aus den ersten 17 Ziffern besteht von 192.168128.
Benutzer
Der Benutzername muss Text oder leer sein. Ein leerer Wert entspricht jedem Benutzer. % als Benutzerwert bedeutet nicht, dass es leer ist, sondern entspricht einem wörtlichen %-Namen, was wahrscheinlich nicht das ist, was Sie wollen.
Wenn eine eingehende Verbindung über die Benutzertabelle authentifiziert wird und der übereinstimmende Datensatz einen leeren Benutzerwert enthält, wird der Client als anonymer Benutzer betrachtet.
Passwort
Der Passwortwert kann leer oder nicht leer sein, Platzhalter sind nicht zulässig. Ein leeres Passwort bedeutet nicht, dass irgendein Passwort abgeglichen wird; es bedeutet, dass der Benutzer kein Passwort angeben darf.
Passwörter werden als verschlüsselter Wert und nicht als wörtlicher Text gespeichert. Wenn Sie in der Spalte „Passwort“ ein wörtliches Passwort speichern, können Benutzer keine Verbindung herstellen! GRANT-Anweisung und mysqladmin
Der Passwortbefehl verschlüsselt Passwörter automatisch für Sie, wenn Sie jedoch Befehle wie INSERT, REPLACE, UPDATE oder SET verwenden
Stellen Sie bei Befehlen wie PASSWORD sicher, dass Sie zur Angabe des Passworts PASSWORD("new_password") anstelle von einfach "new_password" verwenden.
Db
In den Tabellen columns_priv und tables_priv muss der Db-Wert (wörtlich) der echte Datenbankname sein, Muster und Leerzeichen sind nicht zulässig. In db und host kann der Db-Wert wörtlich angegeben werden oder ein Platzhalter kann mit den SQL-Musterzeichen „%“ oder „_“ angegeben werden. Ein „%“ oder ein Leerzeichen entspricht einer beliebigen Datenbank.
Tabellenname, Spaltenname
Die Werte in diesen Spalten müssen literale Tabellen- oder Spaltennamen sein, Muster und Leerzeichen sind nicht zulässig.
Bei einigen Bereichsspalten berücksichtigt der Server die Groß-/Kleinschreibung, bei anderen nicht. Diese Grundsätze sind in der folgenden Tabelle zusammengefasst. Beachten Sie insbesondere, dass bei Table_name-Werten immer die Groß-/Kleinschreibung beachtet wird, auch wenn die Groß-/Kleinschreibung von Tabellennamen in Abfragen vom Dateisystem des Hosts abhängt, auf dem der Server ausgeführt wird (bei UNIX wird die Groß-/Kleinschreibung beachtet, bei Windows nicht). ).
Tabelle 3
Groß- und Kleinschreibung der Bereichsspalten der Grant-Tabelle
Spalte
Host
Benutzer
Passwort
Datenbank
Tabellenname
Spaltenname
Groß-/Kleinschreibung
Nein
Ja
Ja
Ja
Ja
Nein
2.2.2
Überprüfung des Abfragezugriffs
Jedes Mal, wenn Sie eine Abfrage stellen, prüft der Server, ob Sie über ausreichende Berechtigungen zum Ausführen verfügen. Er überprüft die Reihenfolge Benutzer, Datenbank, Tabellen_Privat und Spalten_Privat, bis er feststellt, dass Sie über den entsprechenden Zugriff verfügen oder alle durchsucht hat Zuschauen und nichts bekommen. Genauer gesagt:
Der Server überprüft die Benutzertabelle auf Datensätze, die mit denen übereinstimmen, von denen aus Sie die Verbindung gestartet haben, um festzustellen, über welche globalen Berechtigungen Sie verfügen. Wenn ja und diese für die Abfrage ausreichen, führt der Server sie aus.
Wenn Ihre globalen Berechtigungen nicht ausreichen, durchsucht der Server die Datenbanktabelle für Sie und fügt die Berechtigungen im Datensatz zu Ihren globalen Berechtigungen hinzu. Reichen die Ergebnisse für die Abfrage aus, führt der Server diese aus.
Wenn Ihre kombinierten globalen Berechtigungen und Berechtigungen auf Datenbankebene nicht ausreichen, sucht der Server weiterhin zunächst in der Tabelle tables_priv und dann in der Tabelle columns_priv.
Wenn Sie nach Überprüfung aller Tabellen immer noch keine Berechtigung haben, lehnt der Server Ihren Versuch ab, die Abfrage auszuführen.
Boolesch ausgedrückt werden die Berechtigungen in der Autorisierungstabelle vom Server wie folgt verwendet:
Benutzer ODER
tables_priv ODER
columns_priv
Sie fragen sich vielleicht, warum sich die vorherige Beschreibung nur auf 4 Berechtigungstabellen bezieht, es aber tatsächlich 5 sind. Tatsächlich prüft der Server Zugriffsberechtigungen wie folgt:
Benutzer
ODER (Datenbank UND Host) ODER tables_priv ODER
columns_priv
Der erste einfachere Ausdruck besteht darin, dass die Hosttabelle nicht von GRANT- und REVOKE-Anweisungen betroffen ist. Wenn Sie zur Verwaltung von Benutzerberechtigungen immer GRANT und REVOKE verwenden, müssen Sie sich nie Gedanken über die Hosttabelle machen. Aber Sie sollten wissen, wie es funktioniert:
Wenn der Server die Berechtigungen auf Datenbankebene überprüft, sucht er in der Datenbanktabelle für den Client. Wenn die Spalte „Host“ leer ist, bedeutet dies „Überprüfen Sie die Hosttabelle, um herauszufinden, welcher Host auf die Datenbank zugreifen kann.“
Der Server sucht in der Host-Tabelle nach demselben Db-Spaltenwert wie der Datensatz aus der Db-Tabelle. Wenn kein Hostdatensatz mit dem Host des Clients übereinstimmt, werden keine Berechtigungen auf Datenbankebene gewährt. Wenn einer dieser Datensätze über einen Host-Spaltenwert verfügt, der mit dem Host des verbundenen Clients übereinstimmt, werden der Datenbanktabellendatensatz und der Hosttabellendatensatz kombiniert, um die Berechtigungen auf Datenbankebene des Clients zu erzeugen.
Berechtigungen werden jedoch mit einem logischen UND verknüpft, was bedeutet, dass der Client nicht über diese Berechtigung verfügt, sofern eine bestimmte Berechtigung nicht in beiden Tabellen vorhanden ist. Auf diese Weise können Sie einen grundlegenden Satz an Berechtigungen in der Datenbanktabelle erteilen und diese dann mithilfe der Hosttabelle selektiv für bestimmte Hosts deaktivieren. Sie können beispielsweise den Datenbankzugriff von allen Hosts in Ihrer Domäne zulassen, Datenbankberechtigungen jedoch für Hosts in weniger sicheren Zonen deaktivieren.
Die vorherige Beschreibung lässt die Zugriffsprüfung zweifellos wie einen ziemlich komplizierten Prozess erscheinen, insbesondere wenn Sie denken, dass der Server bei jeder von Ihnen gestellten Abfrage eine Berechtigungsprüfung durchführt. Dieser Vorgang ist jedoch sehr schnell, da der Server dies tatsächlich tut Es sucht nach Informationen aus der Grant-Tabelle für jede Abfrage, liest den Inhalt der Tabelle beim Start in den Speicher und überprüft dann, ob die Abfrage eine speicherinterne Kopie verwendet. Dadurch wird die Leistung von Zugriffsüberprüfungsvorgängen erheblich verbessert. Aber es gibt einen ganz offensichtlichen Nebeneffekt. Wenn Sie den Inhalt der Autorisierungstabelle direkt ändern, erfährt der Server nichts von den Berechtigungsänderungen.
Wenn Sie beispielsweise eine INSERT-Anweisung verwenden, um einen neuen Datensatz zur Benutzertabelle hinzuzufügen, um einen neuen Benutzer hinzuzufügen, kann der im Datensatz genannte Benutzer keine Verbindung zum Server herstellen. Dies war für neue Administratoren (und manchmal auch für erfahrene Veteranen) sehr verwirrend, und die Lösung war damals einfach: Weisen Sie den Server an, den Inhalt der Autorisierungstabelle neu zu laden, nachdem Sie ihn geändert haben. Sie können einen FLUSH senden
PRIVILEGES oder führen Sie mysqladmin aus
Flush-Privilegien (oder wenn Sie eine ältere Version haben, die Flush-Privilegien nicht unterstützt, verwenden Sie mysqladmin
neu laden. ).
2.2.3
Reihenfolge der Bereichsspaltenübereinstimmung
Der MySQL-Server sortiert die Datensätze in der Autorisierungstabelle auf eine bestimmte Weise und ordnet dann eingehende Verbindungen zu, indem er die Datensätze der Reihe nach durchsucht. Die erste gefundene Übereinstimmung bestimmt, welcher Datensatz verwendet wird. Es ist wichtig, die von MySQL verwendete Sortierreihenfolge zu verstehen, insbesondere für die Benutzertabelle.
Wenn der Server den Inhalt der Benutzertabelle liest, sortiert er die Datensätze nach den Werten in den Spalten Host und Benutzer. Der Host-Wert spielt eine entscheidende Rolle (es werden die gleichen Host-Werte angeordnet). zusammengefügt und dann nach dem Benutzerwert sortiert). Beim Sortieren handelt es sich jedoch nicht um eine allodische Ordnung (Ordnung nach Wörtern), sondern nur teilweise. Denken Sie daran, dass wörtliche Wörter Vorrang vor Mustern haben. Das heißt, wenn Sie über client.your.net eine Verbindung zum Server herstellen und Host zwei Werte hat, client.your.net und %.your.net, wird der erste zuerst ausgewählt. Ebenso hat %.your.net Vorrang vor %.net, dann %. Das Gleiche gilt für den IP-Adressabgleich.
Kurz gesagt: Je spezifischer die Priorität. Beispiele finden Sie im Anhang dieses Artikels.
2.3
Risiken durch Autorisierungstabellen vermeiden
In dieser Sitzung werden einige Vorsichtsmaßnahmen bei der Autorisierung sowie die Risiken vorgestellt, die durch die Auswahl unbekannter Werte entstehen. Im Allgemeinen sollten Sie bei der Erteilung von Superuser-Berechtigungen sehr „geizig“ sein, dh keine Berechtigungen für Einträge in der Benutzertabelle aktivieren, sondern andere Autorisierungstabellen verwenden, um Benutzerberechtigungen auf die Datenbank, Tabelle oder Spalte zu beschränken. Berechtigungen in der Benutzertabelle ermöglichen den Zugriff auf jede Tabelle in jeder Datenbank, die sich auf Ihren Serverbetrieb auswirkt.
Gewähren Sie der MySQL-Datenbank keine Berechtigungen. Ein Benutzer mit Berechtigungen für die Datenbank, die die Autorisierungstabelle enthält, kann die Tabelle ändern, um Berechtigungen für jede andere Datenbank zu erhalten. Durch die Erteilung von Berechtigungen, die es einem Benutzer ermöglichen, MySQL-Datenbanktabellen zu ändern, erhält der Benutzer effektiv auch eine globale GRANT-Berechtigung. Wenn der Benutzer die Tabelle direkt ändern kann, ist dies gleichbedeutend damit, dass er jede erdenkliche GRANT-Anweisung ausgeben kann.
Die FILE-Berechtigung ist besonders gefährlich. Erteilen Sie sie nicht einfach. Folgendes kann eine Person mit FILE-Berechtigung tun:
ERSTELLEN
TABLE etc_passwd (pwd_entry TEXT);
LOAD DATA INFILE „/etc/passwd“ in
TABLE etc_passwd;
SELECT * FROM
etc_passwd;
Nachdem der Benutzer diese Anweisungen ausgegeben hat, verfügt er bereits über den Inhalt Ihrer Passwortdatei. Tatsächlich können Benutzer mit FILE-Berechtigungen über das Netzwerk auf den Inhalt jeder öffentlich lesbaren Datei auf dem Server zugreifen.
DATEI-Berechtigungen können auch ausgenutzt werden, um Datenbanken auf Systemen zu kompromittieren, auf denen keine ausreichend restriktiven Dateiberechtigungen festgelegt sind. Aus diesem Grund sollten Sie das Datenverzeichnis so einrichten, dass es nur vom Server gelesen werden kann. Wenn die den Datenbanktabellen entsprechenden Dateien für jedermann lesbar sind, nicht nur für Benutzer mit dem Serverkonto des Benutzers, kann auch jeder Benutzer mit FILE-Berechtigungen eine Verbindung über das Netzwerk herstellen und sie lesen. Dieser Vorgang wird unten demonstriert:
Erstellen Sie eine Tabelle mit einer LONGBLOB-Spalte:
USER-Test;
TABELLE ERSTELLEN tmp (b
LONGBLOB);
Verwenden Sie diese Tabelle, um den Inhalt jeder Datei zu lesen, die der Datenbanktabelle entspricht, die Sie stehlen möchten, und schreiben Sie dann den Tabelleninhalt in eine Datei in Ihrer eigenen Datenbank:
LOAD
DATEN-INFILE „./other_db/x.frm“ IN TABLE tmp
FELDER, DIE DURCH „“-ZEILEN VERSCHLOSSEN WERDEN
TERMINATED BY „“;
SELECT * FROM tmp INTO OUTFILE „y.frm“
FIELDS
ESCAPED BY „“ LINES TERMINATED BY „“;
DELETE FROM tmp;
LOAD DATA INFILE
„./other_db/x.ISD“ INTO TABLE tmp
FIELDS ESCAPED BY „“ LINES TERMINATED
BY „“;
SELECT * FROM tmp INTO OUTFILE „y.ISD“
FIELDS ESCAPED BY „“
ZEILEN BEENDET MIT „“;
LÖSCHEN AUS tmp;
DATEN-INDATEI LADEN
„./other_db/x.ISM“ INTO TABLE tmp
FIELDS ESCAPED BY „“ LINES TERMINATED
BY "";
SELECT * FROM tmp INTO OUTFILE
„y.ISM“
Jetzt haben Sie eine neue Tabelle y, die den Inhalt von other_db.x enthält, und Sie haben vollen Zugriff darauf.
Um zu verhindern, dass andere auf die gleiche Weise angreifen, heißt es in „Teil 1
Befolgen Sie die Anweisungen unter „Interne Sicherheit – Schützen Sie Ihr Datenverzeichnis“, um Berechtigungen für Ihre Datenverzeichnisse festzulegen. Sie können beim Starten des Servers auch die Option --skip-show-database verwenden, um Benutzer auf Datenbanken zu beschränken, auf die sie nicht zugreifen können Zugriffsberechtigungen
DATENBANKEN und SHOW
TABELLEN. Dadurch wird verhindert, dass Benutzer Informationen zu Datenbanken und Tabellen finden, auf die sie keinen Zugriff haben.
ALTER-Berechtigungen können auf unbeabsichtigte Weise verwendet werden. Angenommen, Sie möchten, dass Benutzer1 Zugriff auf Tabelle1, aber nicht auf Tabellen2 hat. Ein Benutzer mit ALTER-Berechtigung kann ALTER verwenden
TABLE benennt Tabelle2 in Tabelle1 um, um die Spalte zu ändern.
Vorsicht bei GRANT-Berechtigungen. Zwei Benutzer mit unterschiedlichen Berechtigungen, aber beide mit GRANT-Berechtigungen, können die Rechte des anderen stärken.
Das Obige ist der Inhalt des MySQL-Sicherheitshandbuchs (2) (nachgedruckt). Weitere verwandte Artikel finden Sie auf der chinesischen PHP-Website (www.php.cn).