Navigation
 Startseite
 Fachbücher
 Anzeigenmarkt
 Forum
 Webmaster News
 Script Newsletter
 Push Meldungen
 Kontakt
 Script Installation
 Php
 Php Tutorials
 Lernpfade
 Webhoster Vergleich
 Impressum

Community-Bereich
 kostenlos Registrieren
 Anmelden
 Benutzerliste

Script Datenbank
 Script Archiv
 Script Top 20
 Screenshots
 Testberichte

Suche
 

Unsere Php Scripts
 Counter Script
 Umfrage Script
 Bilder Upload Script
 Terminverwaltung
 Simple PHP Forum
 RSS Grabber

Tools und Generatoren
 .htpasswd Generator
 md5 Generator
 base64 Generator
 Markdown to HTML
 Colorpicker
 Unix timestamp Tool
 Unit Test Generator
 TLD Liste
 Webkatalog‑Verzeichnis

Artfiles.de
Bietet Serviceorientierte...
https://www.Artfiles.de
Hosterplus.de
Bekommen Sie Speicherplatz (Webspace), Domains...
https://www.Hosterplus.de
 
 
 

PHP mysqli_fetch_field() Function: Spalten-Metadaten lesen

Sie befinden sich: Home > Php Tutorial > PHP mysqli_fetch_field() Fu...

PHP mysqli_fetch_field() Function: Spalten-Metadaten lesen
Veröffentlicht am:
03.10.2026
Hits / Besucher:
8
Sprache:
  Deutsch
Tutorial Art:
eigenes
Eingetragen von:
Merkliste:
 
Beschreibung

Ein internes Werkzeug soll das Ergebnis beliebiger SELECT-Abfragen anzeigen, auch solcher, die jemand gerade erst ins Eingabefeld tippt. Die Kopfzeile aus dem ersten Datensatz abzuleiten liegt nahe und geht genau dann schief, wenn die Abfrage keine einzige Zeile zurückgibt. Dann steht die Tabelle ohne Überschriften da und sieht nach einem Fehler aus, obwohl alles richtig lief. PHP mysqli_fetch_field löst das sauber, denn die Spalteninformation hängt am Ergebnis und nicht an den Daten darin. Der Weg zum Ergebnis, also Verbindung, Platzhalter und get_result(), steht im Tutorial zu Prepared Statements und wird hier vorausgesetzt.

Illustration zum Tutorial: PHP mysqli_fetch_field() Function: Spalten-Metadaten lesen

An jeder Spalte einer Ergebnismenge hängt eine Karte mit Name, Typ, Länge und Flags, unabhängig davon, ob auch nur eine Zeile zurückkommt. Diese Karte ist das Feldobjekt.

Was PHP mysqli_fetch_field() liefert

PHP mysqli_fetch_field() gibt ein Objekt heraus, das eine einzelne Spalte der Ergebnismenge beschreibt. Ein Aufruf, ein Feldobjekt, und der interne Feldzeiger rückt dabei eine Position weiter. Am schnellsten begreift man den Umfang, indem man das erste Objekt einmal vollständig ausgibt.

<?php

$sql = 'SELECT id, name FROM kunden';
$res = $mysqli->query($sql);

$feld = $res->fetch_field();
print_r($feld);

/* stdClass Object (
[name] => id
[orgname] => id
[table] => kunden
[orgtable] => kunden
[def] =>
[db] => shop
[catalog] => def
[max_length] => 0
[length] => 11
[charsetnr] => 63
[flags] => 49667
[type] => 3
[decimals] => 0
) */

Dreizehn Eigenschaften, von denen im Alltag etwa fünf gebraucht werden. Die wichtigsten stehen in der Tabelle, zusammen mit dem, was bei einer berechneten Spalte wie SELECT COUNT(*) AS anzahl davon übrig bleibt. Diese dritte Spalte ist kein Detail: Wer blind auf orgtable zugreift, baut sich eine Stelle, die später still einen leeren String liefert. PHP mysqli_fetch_field() meldet dabei keinen Fehler, es steht schlicht nichts darin.

Eigenschaft Was darin steht Bei COUNT(*) AS anzahl
name Spaltenname, bei einem Alias der Alias anzahl
orgname Name der Spalte im Schema, ohne Alias leer
table Tabellenname oder der Alias aus dem JOIN leer
orgtable Tabelle im Schema, ohne Alias leer
type Typnummer des Datentyps, siehe unten 8
length die im Schema festgelegte Größe 21
max_length längster Wert, der im Ergebnis vorkam, nur bei gepuffertem Ergebnis gesetzt je nach Datenlage
flags Bitmaske mit den Eigenschaften der Spalte Zahlenbits, kein Schlüsselbit
decimals Nachkommastellen bei Dezimalzahlen 0
charsetnr Nummer der Kollation, 63 steht für binary und kennzeichnet damit Zahl- und BLOB-Spalten 63
def Standardwert der Spalte bleibt leer, mysqli füllt dieses Feld nie

Syntax: die Signatur im Original

PHP mysqli_fetch_field() nimmt einen einzigen Parameter und antwortet mit einem Objekt oder mit false:

<?php

mysqli_fetch_field(
mysqli_result $result
): object|false

/* result: a result set returned by
mysqli_query(), mysqli_store_result(),
mysqli_use_result() or get_result()
returns an object holding the definition
of the NEXT column and advances the
internal field pointer, or false when
no column is left
object style: $result->fetch_field() */

Das Wort next im Handbuch trägt mehr Gewicht, als es aussieht. PHP mysqli_fetch_field() ist keine Abfragefunktion, die immer dasselbe liefert, sondern eine Lesefunktion mit Zustand. Der Rückgabewert false bedeutet deshalb nicht, dass es keine Spalten gibt, sondern nur, dass keine mehr übrig ist.

Der Feldzeiger von PHP mysqli_fetch_field() und field_seek()

Diese Eigenheit kostet Zeit, wenn man sie nicht kennt, denn sie meldet sich nirgends. Jeder Aufruf rückt den Feldzeiger eine Position weiter, nach dem letzten Feld bleibt er am Ende stehen. Eine zweite Schleife über dieselbe Ergebnismenge läuft dann sofort ins Leere, ohne dass irgendetwas meldet, warum.

flowchart TD
    A[Abfrage ausführen] --> B[Ergebnis]
    B --> C[Zeiger auf Feld 0]
    C --> D{Noch ein Feld?}
    D -- ja --> E[Feldobjekt lesen]
    E --> D
    D -- nein --> F[false, Zeiger am Ende]
    F --> G[field_seek 0]
    G --> C
<?php

$res = $mysqli->query('SELECT id, name FROM kunden');

while ($f = $res->fetch_field()) {
echo $f->name, ' ';
}
/* id name */

while ($f = $res->fetch_field()) {
echo $f->name, ' ';
}
/* keine Ausgabe, der Zeiger steht am Ende */

$res->field_seek(0);
while ($f = $res->fetch_field()) {
echo $f->name, ' ';
}
/* id name */

Es gibt drei Wege durch die Felder, und sie schließen sich nicht aus. fetch_fields() holt alle Feldobjekte auf einmal in ein Array, das sich beliebig oft durchlaufen lässt. fetch_field_direct($index) greift ein einzelnes Feld über seine Position heraus und bewegt den Zeiger nicht. Und PHP mysqli_fetch_field() geht Feld für Feld vor, was sich lohnt, wenn die Schleife vorzeitig abbrechen soll.

<?php

$felder = $res->fetch_fields();

foreach ($felder as $f) {
echo $f->name, PHP_EOL;
}
foreach ($felder as $f) {
echo $f->type, PHP_EOL;
}

$zweites = $res->fetch_field_direct(1);
echo $zweites->name, PHP_EOL;

Im Normalfall ist fetch_fields() die bequemere Wahl, weil das Ergebnis mehrfach gelesen werden kann und kein Zeiger im Weg steht. Wer stattdessen PHP mysqli_fetch_field() nimmt und später noch einmal von vorn anfangen muss, setzt field_seek(0) davor. Das kostet nichts und erspart die Fehlersuche.

Praxis: ein generischer Tabellen-Renderer

Der erste Baustein nimmt ein beliebiges Ergebnis entgegen und gibt HTML zurück. Die Kopfzeile stammt aus den Feldnamen, die Datenzeilen aus fetch_row(). Entscheidend ist, was passiert, wenn kein Datensatz zurückkommt: Die Kopfzeile steht trotzdem, und die Tabelle bleibt leer statt kaputt.

Die Metadaten aus PHP mysqli_fetch_field() sind hier die einzige Quelle für die Überschriften, und das ist Absicht. Eine Kopfzeile aus array_keys() des ersten Datensatzes sieht kürzer aus und bricht bei jedem leeren Ergebnis. Der Aufruf von htmlspecialchars() auf dem Feldnamen wirkt an dieser Stelle übervorsichtig, weil Spaltennamen aus dem Schema stammen. Bei einem Alias jedoch steht dort, was der Benutzer in die Abfrage geschrieben hat.

<?php

function tabelle(mysqli_result $res): string
{
$felder = $res->fetch_fields();
$html = '<table><tr>';

foreach ($felder as $f) {
$html .= '<th>'
. htmlspecialchars($f->name)
. '</th>';
}
$html .= '</tr>';

while ($zeile = $res->fetch_row()) {
$html .= '<tr>';
foreach ($zeile as $wert) {
$html .= '<td>'
. htmlspecialchars((string) $wert)
. '</td>';
}
$html .= '</tr>';
}

return $html . '</table>';
}

CSV-Export ohne feste Spaltennamen

Derselbe Gedanke trägt den Export. Die Kopfzeile entsteht aus den Feldnamen, und weil in name der Alias steht, bestimmt die Abfrage die Beschriftung der Datei. Wer SELECT nachname AS Familienname schreibt, bekommt genau das in der ersten Zeile, ohne eine Zuordnungstabelle im Code zu pflegen. Hier schreibt fputcsv() Zeile für Zeile in einen offenen Datenstrom, was bei großen Ergebnissen der richtige Weg ist. Wer die Datei stattdessen am Stück ablegt, findet die Fallstricke im Tutorial zu file_put_contents(). Die erste Zeile stammt in beiden Fällen aus PHP mysqli_fetch_field().

<?php

$datei = fopen('export.csv', 'w');

$kopf = [];
foreach ($res->fetch_fields() as $f) {
$kopf[] = $f->name;
}
fputcsv($datei, $kopf, ';');

while ($zeile = $res->fetch_row()) {
fputcsv($datei, $zeile, ';');
}
fclose($datei);

Typnummern in lesbare Namen übersetzen

In der Eigenschaft type des Objekts, das PHP mysqli_fetch_field() liefert, steht eine Zahl. Die vollständige Liste der Konstanten im Handbuch nachzuschlagen lohnt sich selten, weil im Alltag eine Handvoll Nummern fast alles abdeckt. Nutzbringender als der Name ist ohnehin die Gruppe: Zahlen werden rechtsbündig ausgegeben, Datumswerte ins deutsche Format gebracht, alles andere bleibt linksbündig. Fertige Formatierungsmuster dafür liefert sprintf().

type Konstante Spaltentyp in MySQL
3 MYSQLI_TYPE_LONG INT
8 MYSQLI_TYPE_LONGLONG BIGINT, auch COUNT(*)
10 MYSQLI_TYPE_DATE DATE
12 MYSQLI_TYPE_DATETIME DATETIME
246 MYSQLI_TYPE_NEWDECIMAL DECIMAL, etwa Preise
252 MYSQLI_TYPE_BLOB TEXT und BLOB
253 MYSQLI_TYPE_VAR_STRING VARCHAR

Zwei Spaltentypen verstecken sich hinter einer fremden Nummer. Eine ENUM-Spalte meldet den Typ 254, also MYSQLI_TYPE_STRING, und setzt zusätzlich MYSQLI_ENUM_FLAG. Eine SET-Spalte verhält sich genauso und setzt MYSQLI_SET_FLAG. Wer aus den Metadaten ein Formular baut, erkennt daran die Spalten, aus denen ein Auswahlfeld statt eines Textfelds werden soll. Die erlaubten Werte selbst stehen allerdings nicht im Feldobjekt, dafür führt kein Weg an SHOW COLUMNS vorbei.

<?php

const TYP_GRUPPEN = [
'zahl' => [1, 2, 3, 8, 9, 4, 5, 246],
'datum' => [7, 10, 11, 12, 13, 14],
];

function typgruppe(int $typ): string
{
foreach (TYP_GRUPPEN as $name => $liste) {
if (in_array($typ, $liste, true)) {
return $name;
}
}
return 'text';
}

foreach ($res->fetch_fields() as $f) {
$gruppe = typgruppe($f->type);
$klasse = $gruppe === 'zahl' ? 'rechts' : 'links';
echo $f->name, ': ', $gruppe, ' / ', $klasse;
echo PHP_EOL;
}

Flags auswerten: Primärschlüssel und Pflichtfeld erkennen

Die Eigenschaft flags ist eine Bitmaske, in der mehrere Aussagen zugleich stecken. Sie ist die aufschlussreichste Angabe, die PHP mysqli_fetch_field() mitbringt. Deshalb wird sie mit dem bitweisen Und abgefragt und niemals mit == verglichen. Ein Vergleich $f->flags == 2 schlägt fehl, sobald neben dem Schlüsselbit noch irgendein anderes gesetzt ist, und das ist bei einer Primärschlüsselspalte immer der Fall.

Konstante Wert Bedeutung
MYSQLI_NOT_NULL_FLAG 1 Spalte erlaubt kein NULL, also Pflichtfeld
MYSQLI_PRI_KEY_FLAG 2 Teil des Primärschlüssels
MYSQLI_UNIQUE_KEY_FLAG 4 Teil eines eindeutigen Index
MYSQLI_BLOB_FLAG 16 TEXT oder BLOB, besser nicht in die Liste
MYSQLI_UNSIGNED_FLAG 32 Zahl ohne Vorzeichen
MYSQLI_AUTO_INCREMENT_FLAG 512 Wert vergibt die Datenbank selbst
MYSQLI_ENUM_FLAG 256 Spalte ist ein ENUM, gemeldet wird trotzdem Typ 254
MYSQLI_SET_FLAG 2048 Spalte ist ein SET
<?php

$bits = [
MYSQLI_NOT_NULL_FLAG => 'Pflichtfeld',
MYSQLI_PRI_KEY_FLAG => 'Primärschlüssel',
MYSQLI_AUTO_INCREMENT_FLAG => 'Autowert',
];

foreach ($res->fetch_fields() as $f) {
$treffer = [];
foreach ($bits as $bit => $text) {
if ($f->flags & $bit) {
$treffer[] = $text;
}
}
echo $f->name, ': ';
echo implode(', ', $treffer), PHP_EOL;
}
/* id: Pflichtfeld, Primärschlüssel, Autowert */
/* name: Pflichtfeld */

Aus diesen drei Zeilen lässt sich ein Formulargenerator bauen, der Pflichtfelder markiert und den Autowert gar nicht erst anbietet. Zusammen mit den Typnummern aus dem Abschnitt davor entsteht daraus ein Eingabefeld, das zur Spalte passt, und zwar ohne eine einzige fest verdrahtete Angabe im Code.

name gegen orgname, table gegen orgtable

Die beiden Paare unterscheiden zwischen dem, was in der Abfrage steht, und dem, was im Schema steht. Bei SELECT k.nachname AS Familienname liefert name den Alias und orgname den echten Spaltennamen. Genauso verhält es sich mit table und orgtable, sobald ein JOIN mit Tabellenaliassen arbeitet. Bei berechneten Spalten bleiben die Herkunftsangaben leer, weshalb der Zugriff einen Rückfall braucht.

<?php

$sql = 'SELECT k.nachname AS Familienname, '
. 'COUNT(b.id) AS anzahl '
. 'FROM kunden k '
. 'LEFT JOIN bestellungen b ON b.kunde = k.id '
. 'GROUP BY k.id';
$res = $mysqli->query($sql);

foreach ($res->fetch_fields() as $f) {
echo $f->name, ' | ';
echo $f->orgname ?: 'berechnet', ' | ';
echo $f->table ?: '-', ' | ';
echo $f->orgtable ?: '-', PHP_EOL;
}
/* Familienname | nachname | k | kunden */
/* anzahl | berechnet | - | - */

Wer eine Bearbeitungsmaske aus einem Ergebnis ableitet, braucht diese Unterscheidung zwingend: Zurückgeschrieben wird nach orgtable und orgname, angezeigt wird name. Und eine Spalte ohne orgtable ist berechnet und damit nicht schreibbar. Eine Zeile Prüfung auf orgtable davor, und ein UPDATE, das nie funktionieren kann, kommt gar nicht erst zustande.

Der Blick zu PDO: getColumnMeta()

In PDO beantwortet PDOStatement::getColumnMeta() dieselbe Frage. Der Unterschied liegt weniger in den Daten als in der Zusage: mysqli sichert die Metadaten fest zu, PDO überlässt sie dem Treiber und bezeichnet die Methode im Handbuch ausdrücklich als nicht überall vorhanden. Dazu kommt, dass ein Array mit anderen Schlüsselnamen zurückkommt statt eines Objekts. Wer auf mysqli setzt, hat mit PHP mysqli_fetch_field() die verlässlichere Auskunft.

Fazit

Das Feldobjekt beantwortet drei Fragen auf einmal: wie die Spalte heißt, welchen Typ sie hat und welche Regeln für sie gelten. Damit lässt sich eine beliebige Abfrage ausgeben, ohne ihre Struktur zu kennen, und die Kopfzeile steht auch bei null Treffern. Der Feldzeiger bewegt sich bei jedem Aufruf, weshalb fetch_fields() im Zweifel der ruhigere Weg ist, und flags ist eine Bitmaske, die man mit dem bitweisen Und liest. Wer das beherzigt, hat mit PHP mysqli_fetch_field() zwei Bausteine, die in jedes eigene Adminwerkzeug passen.

 

Tags:

 

 

Kommentare (0)

Noch keine Kommentare. Sei der Erste!

Melde dich an, um einen Kommentar zu schreiben.
Bücherregal mit drei Büchern: 'PHP 4 - Grundlagen und Profiwissen' von Hanser Verlag, 'Webdesign in a Nutshell' von O'Reilly Verlag, und 'Webgestaltung' von Galileo Computing.