PHP txt-datei oder mysql?
treziman
- datenbank
Hallo,
ich arbeite gerade an einem Projekt, und dabei bin ich auf ein paar Fragen gestossen, wobei ich hoffe, hier Antworten zu finden. Es geht nicht um programmiertechnische Fragen, sondern um grundsätzliche. Aber schaut mal.
Alle kennen ja txt-Dateien und wissen, dass diese per PHP einfach zu handhaben sind. Irgendwo jedoch stossen diese Dateien an ihre Grenzen, denn wenn sie zu gross sind, dauerts eventuell zu lange bis ein Script sie abgearbeitet hat, und dann kriegt man eine Fehlermeldung. Soweit mein Informationsstand.
Nun gibt es aber Seiten im Net, die mehrere Millionen Mitglieder haben, und diese mit 10 oder 12 verschiedenen Eigenschaften speichern. Also Name, Vorname, Email usw. Facebook wäre z.B. eine solche Seite.
Ich gehe mal davon aus, dass dies mit einer txt-Datei nicht mehr zu realisieren ist. Ist MySql aber für solche Anwendungen schnell genug (habe mit MySql noch keine Erfahrung)? Oder gibt es noch Alternativen? Wie werden solche Massenspeicherungen am besten gemacht, im Hinblick auch auf eine Suchfunktion, die ja jeden Eintrag abfragen muss, um ihn mit einem bestimmten Suchkriterium zu vergleichen?
Ich danke schonmal im Voraus.
treziman
Grüße,
kommt ganz drauf an welche datenart du speichern willst.
für "hausgebackenes" wäre SQL in der einen oder anderen form merh als genug und eifnach zu handhaben. du müsstest keine such und sonstwas funktionen selbst basteln oder suchen.
im allgemeinen ist MySQL&co einfach so bequem und einfach, dass der einzige grund drauf zu verzichten providerlimitierung wäre.
MFG
bleicher
Hallo,
Ich gehe mal davon aus, dass dies mit einer txt-Datei nicht mehr zu realisieren ist. Ist MySql aber für solche Anwendungen schnell genug (habe mit MySql noch keine Erfahrung)? Oder gibt es noch Alternativen? Wie werden solche Massenspeicherungen am besten gemacht, im Hinblick auch auf eine Suchfunktion, die ja jeden Eintrag abfragen muss, um ihn mit einem bestimmten Suchkriterium zu vergleichen?
Selbst bei sehr großen Anwendungen mit Hoch-Last wird sowas eigentlich immer über Datenbank-Systeme (wie MySQL) gemacht. Normale Text-Dateien sind so gut wie nie performanter (Ausnahmen evtl. bei sehr kleinen Datenmengen, die IMMER KOMPLETT ausgelesen werden müssen).
Welche Datenbank man nun benutzt, ist natürlich eine andere Frage:
Anwendungen mit sehr hoher Last und großen Datenmengen benutzen oft Oracle, aber auch MySQL und PostgreSQL kommen immer mehr zum Einsatz.
Facebook konkret setzt glaube ich z.b. MySQL ein.
Unabhängig von der Wahl des Datenbank-Systems wird ein solches System ab einer bestimmten Last zum Flaschenhals. Abhilfe kann dann die Optimierung der Datenbank selbst sein, verschiedene programmiertechnische Massnahmen (z.b. Caching von bereits gelesenen DB-Inhalten) oder das simple Erschlagen mit mehr Hardware (Load-Balancing, schnellere Festplatten, mehr CPU, mehr RAM,...)
Ohne jetzt Deine Anwendung genau zu kennen, behaupte ich aber mal: Ein vernünftiger PHP/MySQL-Server sollte für Deine Zwecke erstmal reichen.
Viele Grüße,
Jörg
hi,
die Performance auf Dateizugriffe ist von vielen Faktoren abhängig, ein paar Anmerkungen zu Textdateien mit der Struktur einer ini:
[section]
attr = property
param = value
Solche Dateien lassen sich vorzüglich von Hand bearbeiten und es gibt in PHP, Perl u.a. Programmiersprachen fertige Funktionen und Module für den Zugriff. Genau hier liegt jedoch das Problem, dass zum Parsen (Lesen) einiges an CPU und RAM gebraucht wird, weil die Strukturierung rein textlicher Natur ist. Kurzum, auf den Systemen, die mir bisher unterkamen, wird das Parsen ab einer Dateigröße von 500 kB...1 MB fürs Web unakzeptabel. Bei CSV-Dateien ist das im Prinzip genauso.
Wesentlich performanter ist das Lesen und Schreiben von Dateien, in denen keine textliche Strukturierung vorliegt, also Dateien, die byteweise bearbeitet werden, hier habe ich die Grenzen einer aktzeptablen Performance noch nicht erreichen können, d.h., beim Einlesen einer Dateien mit 10 MB gibt es für die Maschine einen kurzen Burst und das wars. Ich habe dieses Beispiel bewusst gewählt: in einer 10 MB Binärdatei lässt sich der komplette Content einer Website mit mindestens 500 HTML-Seiten sämtlicher Attribute wie title, descr, author, lastmod usw. unterbringen.
Noch ein Beispiel vielleicht: Eine Tabelle mit 5000 Zeilen und 10 Spalten belegt als binary ca. 1 MB, mein letzter Auftrag beeinhaltete ein Frontend zum Editieren dieser Tabelle (Auftragsverwaltung), diese Anwendung erfreute sich großer Beliebtheit wegen der schönen Performance ;-)
Wenn Du einen DB-Server verwendest: der größte Overhead entsteht beim Aufbau der Verbindung, das lässt sich z.B. dadurch umgehen, dass die Anwendung eine Verbindung dauerhaft aufrechterhält (z.B. ein FastCGI). Ansonsten wirst Du auch hier die Daten zum Bearbeiten in eine programmgerechte Struktur umwandeln, sofern die Daten hingegen aus einer Datei kommen, liegt eine solche Struktur (z.B. ein Array oder Hash) unmittelbar nach dem Parsen der Datei vor.
Als Pro/Kontra DB/Datei ist evntl. die Zeichen- bzw. Byteorientierung auch noch ein Aspekt, mit einer DB bist Du zeichenorientiert abhängig von der Kodierung (utf-8, iso...) und in der Übertragungskette gibt es einige Möglichkeiten, wo sich Fehler einschleichen können (das Forum hier ist voll davon); eine Speicherung und Verarbeitung von Rohdaten ist weit weniger problembehaftet in dieser Hinsicht.
Viele Grüße,
Hotti
Hello,
bei der Betrachtung von Textdatei kontra Datenbank sollte man auch nicht vergessen, dass bei der Verwendung von Textdateien jeder Request die volle Datenmenge selber einlesen muss, wenn er Änderungen in der Textdatei vornhemen will. Bei einer Datenbank macht dies die Datenbankmaschine, aber nicht für jeden Client gesondert, sondern für alle zusammen. Änderungen können koordiniert im Speicher gehalten werden und werden immer erst dann auf die HDD zurückgeschrieben, wenn es sich lohnt... Darum muss man ja einen Datenbankserver auch erst herunterfahren, bevor man die Tabellen-Files anderweitig anfasst.
Es gibt aber über klassische Textdateien hinaus eine Vielzahl anderer Modelle, die einen wesentlich schnelleren Zugriff ermöglichen und es nicht erfoderlich machen, für eine Änderung die gesamte Datei inzulesen.
und diverse komplexere Dtrukturen, die dann aber schon nahe an der Datenbank sind.
PHP unterstützt leider Random Access Dateien nur über einen Umweg. Diese sind aber durchaus eine akzeptable Lösung für kleinere oder vom Datenmodell einfachere Projekte. Sie sind i.d.R. dann merklich schneller, als eine Datenbank.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
bei der Betrachtung von Textdatei kontra Datenbank sollte man auch nicht vergessen, dass bei der Verwendung von Textdateien jeder Request die volle Datenmenge selber einlesen muss, wenn er Änderungen in der Textdatei vornhemen will. Bei einer Datenbank macht dies die Datenbankmaschine, aber nicht für jeden Client gesondert, sondern für alle zusammen. Änderungen können koordiniert im Speicher gehalten werden und werden immer erst dann auf die HDD zurückgeschrieben, wenn es sich lohnt... Darum muss man ja einen Datenbankserver auch erst herunterfahren, bevor man die Tabellen-Files anderweitig anfasst.
Logo, auf einem DB-Server wird auch nur mit Wasser gekocht ;-)
Es gibt aber über klassische Textdateien hinaus eine Vielzahl anderer Modelle, die einen wesentlich schnelleren Zugriff ermöglichen und es nicht erfoderlich machen, für eine Änderung die gesamte Datei inzulesen.
- Textdateien, sequenziell
wird komplett gelesen, der Begriff sequentiell schließt jedoch ein Anhängen nicht aus.
- Textdateien mit fester Satzlänge
bei festen Satzlängen entfällt das Berechnen derer, sehr performant.
- Random Access Dateien, Dateien mit fester Satzlänge und festem Satzaufbau
Ja, sehr performant, es braucht einen Index (Inhaltsverzeichnis) für wahlfreien Zugriff, ggf. entsteht jedoch ein Vakuum, weil gelöschte Sätze immer noch Platz belegen (bei den heutigen Massenspeichern aber auch kein Thema).
- direktgestreute Dateien
kenne ich nicht, haste maln Link?
und diverse komplexere Dtrukturen, die dann aber schon nahe an der Datenbank sind.
Wie schon gesagt, einen Performancegewinn gegenüber DB-Zugriff kriegst Du, weil Du mit einer Datenhaltung in Dateien "näher dran" bist, sofern nach dem Einlesen einer Datei die Daten sofort in einer programmgefälligen Struktur (struct, hash, array...) vorliegen, was natürlich einen geschickten Algorithmus voraussetzt, der beim Lesen (und auch beim Schreiben) Verwendung findet. Perl z.b. unterstützt sowas mit Low-Level-Funktionen wie pack() und unpack(), die byteorientiert arbeiten und sehr schnell sind (Umrechnen von IP-Adressen über bytes mit pack/unpack geht schneller als das Rechnen mit Zahlen und algebraischen Funktionen als Beispiel).
Schöne Grüße,
Horst Hauser
Erstmal allen vielen Dank für die Antworten!
Ich habe selbst weiter im Net recherchiert und tendiere mehr zu MySql. Dies ist nicht zuletzt auch eine Frage der Sicherheit. Wenn man eine Datei mit Kundendaten (Passwort, Name usw.) anlegt, lässt sich diese Datei sicher auch als txt-Datei verwalten, aber ist es nicht verhältnismässig leicht, das Inhaltsverzeichnis einer Website auszulesen und Datein oder Scripte daraus runterzuladen? MySql kann man immerhin mit einem Passwort versehen.
Auch muss ich davon ausgehen, dass eine Datei (Tabelle) mit 5.000 Zeilen und 12 Spalten, was 5.000 Kunden entsprechen würde, irgendwann nicht mehr ausreicht. Dabei fällt mir Ebay ein. Wieviele Mitglieder hat Ebay? Keine Ahnung, aber dies kann doch unmöglich mit txt-Dateien realisiert worden sein?
Auch gibt es Websites, auf denen hat man eine Funktion "Mitglieder suchen". Nun könnte man ca. 25 txt-Dateien anlegen, für jeden Buchstaben eine, und so das ganze für die Suchfunktion nach Anfangsbuchstaben optimieren. Problematisch wirds dann wieder, wenn man nach Anfangsbuchstaben ODER nach z.B. PLZ suchen könnte. Nach PLZ müsste die Suchfunktion trotzdem wieder alle Dateien durchsuchen. Ich glaube, MySql ist da komfortabler.
Wenn ich das richtig verstehe, läuft es mit MySql etwa so:
Kunde 1 loggt sich ein
Datenbank wird geöffnet
es wird nach dem Nicknamen gesucht
wird er gefunden, werden die Passwörter verglichen
stimmen sie überein, ist der Kunde eingeloggt und es wird eine session gestartet
Datenbank schliessen
Für jeden weiteren Kunden wäre es derselbe Vorgang. Theoretisch könnten also tausende von Kunden gleichzeitig auf die Datenbank zugreifen. Ist das überhaupt mit MySql möglich? Mit txt-Dateien geht das. Wenn man diese beim Auslesen nicht mit "flock" sperrt, können viele sie gleichzeitig auslesen. Und mit "$array = file('xxx.txt')" wird die Datei doch nicht automatisch gesperrt, oder?
Gruss
Thorsten
Hi!
aber ist es nicht verhältnismässig leicht, das Inhaltsverzeichnis einer Website auszulesen und Datein oder Scripte daraus runterzuladen?
Jein, kommt auf die Konfiguration des Webservers an. Mit einem Default-Dokument kommt bei .../ immer selbiges. Ein Dateiverzeichnis kommt nur beim Fehlen des Defaultdokuments und wenn das Directory-Listing erlaubt ist. Ansonsten wäre es eine hervorragende Idee, Dateien, die nicht im Web abrufbar sein sollen, außerhalb des DocumentRoot aufzubewahren.
Auch muss ich davon ausgehen, dass eine Datei (Tabelle) mit 5.000 Zeilen und 12 Spalten, was 5.000 Kunden entsprechen würde, irgendwann nicht mehr ausreicht.
Hinzu kommt auch noch, dass du dir um das Schreiben von konkurrenzfähigen Zugriffsmethoden Gedanken machen musst, was beim DBMS bereits erledigt ist.
Dabei fällt mir Ebay ein. Wieviele Mitglieder hat Ebay? Keine Ahnung, aber dies kann doch unmöglich mit txt-Dateien realisiert worden sein?
Darüber musst du dir keine Gedanken machen, so groß wird dein Projekt sicher nicht werden.
Auch gibt es Websites, auf denen hat man eine Funktion "Mitglieder suchen". Nun könnte man ca. 25 txt-Dateien anlegen, für jeden Buchstaben eine, und so das ganze für die Suchfunktion nach Anfangsbuchstaben optimieren. Problematisch wirds dann wieder, wenn man nach Anfangsbuchstaben ODER nach z.B. PLZ suchen könnte. Nach PLZ müsste die Suchfunktion trotzdem wieder alle Dateien durchsuchen. Ich glaube, MySql ist da komfortabler.
Ganz genau, all diese Funktionalität ist schon eingebaut und viele Jahre getestet.
Wenn ich das richtig verstehe, läuft es mit MySql etwa so:
Kunde 1 loggt sich ein
Datenbank wird geöffnet
Datenbank-_Verbindung_ wird hergestellt. Hinzu kommt beispielsweise noch das Aushandeln der zu verwendenden Zeichenkodierung.
es wird nach dem Nicknamen gesucht
wird er gefunden, werden die Passwörter verglichen
Man kann auch nach dem Datensatz in einer einzigen Abfrage suchen, der zum eingegebenen Loginnamen und dem Passwort passt.
stimmen sie überein, ist der Kunde eingeloggt und es wird eine session gestartet
"stimmen überein" äußert sich dann so, dass ein Datensatz gefunden wurde. Dem können nun je nach Bedarf weiter Kundendaten entnommen werden. Gab es keinen Datensatz, so gibt es den Loginnamen nicht oder das Passwort stimmte nicht. Diese beiden Fehler muss man nicht trennen, denn das macht es nur leichter, gültige Kundennamen zu finden.
Datenbank schliessen
Datenbank-_Verbindung_ wird geschlossen. Das macht PHP aber bei jedem Script-Ende von selbst.
Für jeden weiteren Kunden wäre es derselbe Vorgang. Theoretisch könnten also tausende von Kunden gleichzeitig auf die Datenbank zugreifen. Ist das überhaupt mit MySql möglich?
MySQL hat eine begrenzte Anzahl an gleichzeitigen Verbindungen. Da die Requests bei 5000 Kunden jedoch gehörig zeitversetzt ankommen, sollte das kein Problem sein.
Mit txt-Dateien geht das. Wenn man diese beim Auslesen nicht mit "flock" sperrt, können viele sie gleichzeitig auslesen.
Ein exklusives Sperren ist bei Änderungsvorgängen notwendig. Beim Lesen muss ein Shared Lock gesetzt werden, dann können andere Vorgänge ebenfalls lesen.
Und mit "$array = file('xxx.txt')" wird die Datei doch nicht automatisch gesperrt, oder?
Nein. Es wird auch nicht geprüft, ob eine Sperre vorliegt. Jedenfalls erwähnt das Handbuch nichts dergleichen, also muss man davon ausgehen, dass so etwas nicht passiert.
Lo!
Hello,
Hinzu kommt auch noch, dass du dir um das Schreiben von konkurrenzfähigen Zugriffsmethoden Gedanken machen musst, was beim DBMS bereits erledigt ist.
Das stimmt nur bedingt. Spätestens, wenn mehrere Queries Verwendung finden, muss man auch bei Datenbanken anfangen, sich Gedanken über TOCTTOU, refenzielle Integrität, usw. zu machen.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hello,
Nein. Es wird auch nicht geprüft, ob eine Sperre vorliegt. Jedenfalls erwähnt das Handbuch nichts dergleichen, also muss man davon ausgehen, dass so etwas nicht passiert.
Laut POSIX müssen Streams während der Lese-/Schreibvorgänge gesperrt sein.
Ob PHP sich inzwischen daran hält, weiß ich nicht. Ich gehe auch eher davon aus, dass (fast) alle namensbasierten Dateifunktionen von PHP keine Sperren berücksitigen. Das sollten wir nochmal im neuesten Quellcode nachschauen.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Nein. Es wird auch nicht geprüft, ob eine Sperre vorliegt. Jedenfalls erwähnt das Handbuch nichts dergleichen, also muss man davon ausgehen, dass so etwas nicht passiert.
Laut POSIX müssen Streams während der Lese-/Schreibvorgänge gesperrt sein.
Ob PHP sich inzwischen daran hält, weiß ich nicht. Ich gehe auch eher davon aus, dass (fast) alle namensbasierten Dateifunktionen von PHP keine Sperren berücksitigen. Das sollten wir nochmal im neuesten Quellcode nachschauen.
Sollten wir? - Partnerschaftspassiv à la "Jemand müsste mal den Müll runterbringen"?
Du kannst gern genauer nachforschen, wenn du die Muße dazu hast. Es ist nicht so ganz einfach, die relevante Stelle im Code zu finden, weil er aufgrund der Möglichkeit, Wrapper zu verwenden, sich in mehr als eine Richtung verzweigt. Die einfachere Methode ist in dem Fall, alles was nicht dokumentiert ist, als nicht gegeben anzunehmen. Das spart die ansonsten notwendigen Code-Überprüfungen, ob sich da in neuen Versionen nichts geändert hat.
Lo!
Hello,
Sollten wir? - Partnerschaftspassiv à la "Jemand müsste mal den Müll runterbringen"?
Höhöhö. Du bist wirklich ein schlaues Kerlchen :-)
Ich würde ja den Müll gerne runterbringen, wenn dafür jemand anderes dazu bereit wäre, mir anschließend Nachhilfe beim Suchen, Ersetzen und Neucompilieren zu geben.
Du kannst gern genauer nachforschen, wenn du die Muße dazu hast. Es ist nicht so ganz einfach, die relevante Stelle im Code zu finden, weil er aufgrund der Möglichkeit, Wrapper zu verwenden, sich in mehr als eine Richtung verzweigt. Die einfachere Methode ist in dem Fall, alles was nicht dokumentiert ist, als nicht gegeben anzunehmen. Das spart die ansonsten notwendigen Code-Überprüfungen, ob sich da in neuen Versionen nichts geändert hat.
Ich habe das schonmal intensiv nachgeforscht, als damals der Artikel "Sperren von Dateien" anstand. Mit dem hat mich dann Christian Seiler überholt, was ich prinzipiell nicht verkehrt fand ...
Leider bin ich mit meinem persönlichen Anliegen, im PHP-Quellcode etwas finden, ändern und geändert compilieren zu können, dabei auf der Strecke geblieben. Das Finden wird wohl noch möglich sein, aber spätestens fürs Ändern würde ich dann doch lieber Christian fragen ;-))
Damals waren die von POSIX geforderten Locks für die Streamverarbeitung noch nicht vorhanden.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo und nochmals dankeschön für Eure Antworten!
Ich habe mich jetzt auch bei schattenbaum.de ein bisschen tiefer in MySql reingelesen. Ich werde es wohl realisieren, wenn...
Dabei fällt mir Ebay ein. Wieviele Mitglieder hat Ebay? Keine Ahnung, aber dies kann doch unmöglich mit txt-Dateien realisiert worden sein?
Darüber musst du dir keine Gedanken machen, so groß wird dein Projekt sicher nicht werden.
»»
speziell:"...so gross wird dein Projekt sicher nicht werden."
Genau das kann ich nicht im Vorfeld sagen. Ich denke aber, dass man davon ausgehen muss, programmiert man eine für viele User interessante Website, dass sich sehr viele User dort registrieren. Darum nochmal gezielt die Frage - bleiben wir beim Beispiel Ebay mit angenommener Mitgliederzahl von 2 Mio und 50 einzelnen Einträgen pro Mitglied, also tabellenförmig: 2 Mio Zeilen a 50 Spalten - wäre dies mit MySql noch machbar?
Gruss
Thorsten
Hello,
Genau das kann ich nicht im Vorfeld sagen. Ich denke aber, dass man davon ausgehen muss, programmiert man eine für viele User interessante Website, dass sich sehr viele User dort registrieren. Darum nochmal gezielt die Frage - bleiben wir beim Beispiel Ebay mit angenommener Mitgliederzahl von 2 Mio und 50 einzelnen Einträgen pro Mitglied, also tabellenförmig: 2 Mio Zeilen a 50 Spalten - wäre dies mit MySql noch machbar?
Das hängt auch vom OS und Filesystem ab, auf dem der MySQL-Server installiert wird.
bei 2.000.000 Zeilen x 50 Spalten x 20 Bytes kommen schon mal 2.000.000.000 Bytes als Nutzdaten dabei heraus, wenn es denn in einer Tabelle stehen muss. Dazu kommt der Overhead, den das DBMS für sich benötigt.
4GB war lange eine magische Grenze, sowohl für OS als auch für DBMS
Such doch mal nach "MySQL's 4GB Limit" .o.ä.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
bleiben wir beim Beispiel Ebay mit angenommener Mitgliederzahl von 2 Mio und 50 einzelnen Einträgen pro Mitglied, also tabellenförmig: 2 Mio Zeilen a 50 Spalten - wäre dies mit MySql noch machbar?
Grundsätzlich sind DBMS so ausgelegt, dass sie mit einer großen Datenmenge zurechtkommen können. Du musst dir also nicht so sehr um die Menge Gedanken machen, sondern um die Performance und dazu wissen, wie dich das DBMS dabei unterstützen kann.
Aber 50 Spalten in einer Tabelle sind schon recht heftig. Mir fällt da grad kein Anwendungsbeispiel ein, wenn man mit normalisierten Daten arbeitet.
Lo!
Hello,
Ich habe mich jetzt auch bei schattenbaum.de ein bisschen tiefer in MySql reingelesen. Ich werde es wohl realisieren, wenn...
Dann lies doch auch nochmal dort, wo es relevant ist:
http://dev.mysql.com/doc/refman/5.0/en/full-table.html
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
hi,
Ich habe selbst weiter im Net recherchiert und tendiere mehr zu MySql.
Mit meinem Gefühl für Dein Vorhaben: Ja, das ist ok, die Engine ist ausgereift und nimmt Dir Einiges an Entwicklungsarbeit ab, die Du evntl. in eine eigene Datenverwaltung stecken müsstest. _Wie_ MySQL die Daten speichert, darüber musst Du Dir überhaupt keine Gedanken machen, 5000 Records sind ein Furz und es gibt Mechanismen zum Locken (transaktionssichere Tabellen und siehe auch dedlfix).
Viel Erfolg,
Hotti
Hello,
Wenn ich das richtig verstehe, läuft es mit MySql etwa so:
Kunde 1 loggt sich ein
Datenbank wird geöffnet
es wird nach dem Nicknamen gesucht
wird er gefunden, werden die Passwörter verglichen
stimmen sie überein, ist der Kunde eingeloggt und es wird eine session gestartet
Datenbank schliessen
Das sollte bitte ganz anders laufen:
Die Trennung von Abfrage und Vergleich ist also nicht notwendig oder sogar falsch.
[1] Wenn eine "Last-Request"-Tabelle geführt werden soll, sollte man das Insert in diese mit der Abfrage nach Usernamy<->Passwort verbinden, damit man sich kein TOCTTOU-Problem baut
http://en.wikipedia.org/wiki/Time-of-check-to-time-of-use
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo,
ich habe nun meine ersten Gehversuche mit MySql erfolgreich abgeschlossen! DB mit Tabelle erstellen, Daten reinschreiben, ändern und löschen klappt alles wunderbar. Als Vorlage diente schattenbaum.net.
In den Beispielen dort wird die ID mit "auto_increment" gesetzt. Klappt auch. Leider passiert aber folgendes:
Ich habe 3 Zeilen in der Tabelle. 1, 2 und 3 als Index (key). Lösche ich nun die 2. Zeile und schreibe dann eine neue in die Tabelle, fügt MySql den neuen Eintrag wohl an der zweiten Stelle ein, aber mit dem Index 4. Sieht so aus:
1 Eintrag
4 Eintrag
3 Eintrag
Wie erreiche ich, dass der neue Eintrag an der 2. Stelle (Zeile) auch wieder den Index 2 bekommt?
Gruss
Thorsten
Hi!
Wie erreiche ich, dass der neue Eintrag an der 2. Stelle (Zeile) auch wieder den Index 2 bekommt?
Datensätze liegen in einer Abfrage generell unsortiert vor, solange keine explizite Sortierung mit der ORDER-BY-Klausel vorgenommen wird. Es gibt auch die Möglichkeit, die Datensätze physikalisch zu sortieren, aber MySQL garantiert diese Ordnung nur bis zur nächsten Änderung, weswegen du ORDER BY vorziehen und die tatsächliche Anordung unbeachtet lassen solltest. Außerdem ist die ID ein ungeeignetes Sortierkriterium. Sie hat lediglich die Aufgabe hat, die Datensätze zu identifizieren. Nur die Eindeutigkeit ist garantiert, nicht jedoch ein zeitlicher Zusammenhang zwischen den einzelnen IDs. Für eine solche Ordnungsmöglichkeit solltest du dir ein Feld für eine Zeitangabe aufnehmen. Der Typ TIMESTAMP hat eine schöne Automatik, die man nutzen kann, um nicht händisch die Zeit pflegen zu müssen.
Lo!
Hallo Lo!,
danke für Deine Antwort.
Es geht dabei nicht ums Sortieren. Auch wann ein Eintrag stattgefunden hat, ist nicht wichtig. Ich hätte nur gern eine fortlaufende Numerierung.
Gruss
Thorsten
Hi,
Es geht dabei nicht ums Sortieren. Auch wann ein Eintrag stattgefunden hat, ist nicht wichtig. Ich hätte nur gern eine fortlaufende Numerierung.
Ich wiederhole Dedlfix: IDs sind zur Identifizierung. Wenn du eine Nummerierung willst, nimm etwas anderes.
Es hat Vorteile, dass sich IDs nicht ändern. Diese wirst du erst dann merken, wenn du entweder die ID nach außen gegeben hast, von wo sie dann "irgendwann" wieder zurückkommt, oder wenn du andere Daten damit referenzierst (wobei man das mit ein wenig Geschick und Constraints umgehen kann).
Eine wirkliche einfache und leicht verständliche Weise, eine Nummerierung zu erzeugen, fällt mir auf Anhieb nicht ein. Liegt hauptsächlich daran, dass die Spalten ausgewertet werden, bevor die Reihenfolge feststeht.
Da du aber eh die Daten mit einer Programmiersprache weiter verarbeitest, kannst du die Nummerierung einfach dort erzeugen.
Bis die Tage,
Matti
Hello,
Eine wirkliche einfache und leicht verständliche Weise, eine Nummerierung zu erzeugen, fällt mir auf Anhieb nicht ein. Liegt hauptsächlich daran, dass die Spalten ausgewertet werden, bevor die Reihenfolge feststeht.
Das geht unter Zuhilfenahme von User-Variablen relativ einfach.
http://dev.mysql.com/doc/refman/5.1/en/user-variables.html
Diese Numerierung ist dann allerdings wirklich nur optisches Beiwerk, da ja die Identitöät der Datensätze in keiner Weise daran gebunden ist.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hallo,
die Sache mit der Numerierung hat sich soweit erledigt. Meine Denkweise resultiert immernoch aus der Arbeit mit txt-Dateien, wo man, hatte man die Datei mittels array = file ("datei.txt") in ein array geladen, leicht eine fortlaufende Numerierung und auch eine nachträgliche erzeugen konnte.
Dieser einmalige Index diente dazu, eine aus Zeitgründen abgelaufene session wieder herzustellen, indem dieser index per <input type = "hidden"... von Seite zu Seite weitergegeben wurde.
Ich brauche in meiner DB die Spalte mit der id nicht. Offenbar ist sie aber für MySql erforderlich, denn, als ich festgestellt habe, dass ich sie nicht brauche und deswegen gelöscht habe, funktioniert es nicht mehr so mit den Abfragen.
Um abgelaufene sessions wieder herzustellen, kann ich auch die kdnr (Kunden Nr.), bzw. den Nicknamen verwenden. Beides darf nur einmal in der DB vorkommen.
Nochmals dankeschön an alle!
Gruss
Thorsten
Hi!
Ich brauche in meiner DB die Spalte mit der id nicht. Offenbar ist sie aber für MySql erforderlich, denn, als ich festgestellt habe, dass ich sie nicht brauche und deswegen gelöscht habe, funktioniert es nicht mehr so mit den Abfragen.
Eine ID-Spalte ist für MySQL nicht erforderlich. Wenn bei dir ohne diese etwas nicht funktioniert, so liegt es mit Sicherheit am weiterverarbeitenden Programm.
Um abgelaufene sessions wieder herzustellen, kann ich auch die kdnr (Kunden Nr.), bzw. den Nicknamen verwenden. Beides darf nur einmal in der DB vorkommen.
Dann könntest du einen dieser Werte als Identifizierungsmerkmal verwenden. Der Vorteil einer ID ist jedoch, dass sie keine weitere Bedeutung hat, als den Datensatz eindeutig zu kennzeichnen. Verweise auf eine solche ID bleiben auch dann gleich, wenn sich Kundennummer oder Nickname ändern.
Warum aber willst du eine abgelaufene Session wiederherstellen? Wenn sie - warum auch immer - ewig weiterlaufen soll, muss sie einfach nur nicht expirieren.
Lo!
Hi Lo!,
der Vorgang, warum es nicht mehr funktioniert hat:
Meine Test-DB sah wie folgt aus:
1. Spalte: id
2. Spalte: kdnr
3. Spalte: nick
4. Spalte: passwort
Nun hatte ich bemerkt, dass ich die ID nicht brauche und diese Spalte wieder gelöscht. Nun sah meine DB so aus:
1. Spalte: kdnr
2. Spalte: nick
3. Spalte: passwort
Eine Abfrage wie:
<?php
...
$passwort = "testpw";
$ergebnis = mysql_query ("select kdnr from testtab where passwort like '$passwort' ");
...
(es folgt die while-Schleife)
echo $row->kdnr;
?>
funktioniert nicht mehr. Warum auch immer. Nun habe ich in der Abfrage lediglich das "kdnr" gegen "nick" ausgetauscht, und das klappt. Es scheint so, als ob - nach dem Löschen der 1. Spalte (id) - auf die neue 1. Spalte (kdnr) kein Zugriff mehr erfolgt. Keine Ahnung.
Das war aber das einzigste, was nicht ging. Alle anderen Kombinationen mit Abfragen und Ausgaben gingen.
Eine session darf, solange ein Kunde online ist, nicht ablaufen. Auch nicht bei Inaktivität. Es kann ja sein, dass er gerade einen längeren Text liesst und anschliessend ein Formular ausfüllt. Und beim Absenden bekommt er dann die Nachricht, sich neu einzuloggen, da die Zeit abgelaufen ist. Nervig, weil die eingegebenen Daten weg sind. Darum ein session-handler, der etwa so aussieht:
$konstante = $nickname; ($konstante wird von Skript zu Skript weitergegeben, entweder per input-hidden oder an links angehängt)
Zu Beginn eines Skripts frage ich:
<?php
session_start();
if ($konstante != $_session(nickname))
{
session abgelaufen, zuerst neu setzen (Variablen)
}
script...
?>
Wird also die Konstante nicht weitergegeben, könnte der Kunde z.B. den Browser geschlossen haben, ohne sich auszuloggen. Die session wird dann auch nicht erneuert.
Gruss
Thorsten
der Vorgang, warum es nicht mehr funktioniert hat:
Meine Test-DB sah wie folgt aus:
- Spalte: id
- Spalte: kdnr
- Spalte: nick
- Spalte: passwort
Nun hatte ich bemerkt, dass ich die ID nicht brauche und diese Spalte wieder gelöscht. Nun sah meine DB so aus:
- Spalte: kdnr
- Spalte: nick
- Spalte: passwort
Eine Abfrage wie:
<?php
...
$passwort = "testpw";
$ergebnis = mysql_query ("select kdnr from testtab where passwort like '$passwort' ");
...
(es folgt die while-Schleife)
echo $row->kdnr;
?>funktioniert nicht mehr. Warum auch immer. Nun habe ich in der Abfrage lediglich das "kdnr" gegen "nick" ausgetauscht, und das klappt. Es scheint so, als ob - nach dem Löschen der 1. Spalte (id) - auf die neue 1. Spalte (kdnr) kein Zugriff mehr erfolgt. Keine Ahnung.
Das kann nicht sein. Die Reihenfolge der Spalten ist völlig unerheblich und da hier auch nicht auf die id zugegriffen wird ist das fehlen auch unproblematisch.
Trotzdem ist das Löschen der id nicht sinnvoll, da damit der Datensazu identifiziert wird (und falls du dir dadurch Speicherplatz erspranis erhoffst, ist dieser auch nur minimal, da id eine Ganzzahl sein sollte.)
Normalerweise sollte die id als Fremdschlüssel in zur identifizierung in anderen Tabellen dienen - falls es welche welche gibt - und dazu benötigst du diese.
Struppi.
Hallo Struppi,
doch, Tatsache. Nach meinem vorherigen Posting habe ich es nochmal probiert (habe die Testscripte ja fertig). Es geht nicht.
Tabelle:
1.kdnr
2.nickname
3.passwort
Abfrage:
...
$ergebnis = mysql_query("select kdnr from testtab where passwort like '$passwort' ");
...
echo $row->kdnr;
...
Ich bekomme nichts angezeigt!
Dagegen:
...
$ergebnis = mysql_query("select nickname from testtab where passwort like '$passwort' ");
...
echo $row->nickname;
...
gibt mir korrekt den Nicknamen "testnick1" aus.
Die kdnr in der 1. Spalte lautet: "tkn123". Ist also nicht numerisch. Vielleicht liegts daran? Oder weil ich die Spalte "id" nachträglich gelöscht habe?
Ich weiss es nicht. Ich müsste vielleicht eine komplett neue Tabelle erstellen und es dann nochmal versuchen.
Unter phpmyadmin kann ich ja keine neue Spalte VOR der ersten einfügen. Erst ab der 2.
Aber noch etwas bezüglich der id. Wenn ich beim Erstellen einer Tabelle die Länge der id auf 1 setzen würde, heisst das ja Zahlen von 1 - 9. Was passiert aber dann ab dem 10. Eintrag?
Gruss
Thorsten
doch, Tatsache. Nach meinem vorherigen Posting habe ich es nochmal probiert (habe die Testscripte ja fertig). Es geht nicht.
Dann machst du etwas falsch, aber der Code ist richtig und funktioniert auch, mit den von dir gemachten Angaben.
Unter phpmyadmin kann ich ja keine neue Spalte VOR der ersten einfügen. Erst ab der 2.
Wie gesagt, die Reihenfolge der Spalten ist in dem Beispiel unerheblich.
Aber noch etwas bezüglich der id. Wenn ich beim Erstellen einer Tabelle die Länge der id auf 1 setzen würde, heisst das ja Zahlen von 1 - 9. Was passiert aber dann ab dem 10. Eintrag?
Warum willst du sowas machen?
Programmierst du für einen Mikrocomputer, dass du einzelne Bytes sparen möchtest?
Struppi.
»»»» Aber noch etwas bezüglich der id. Wenn ich beim Erstellen einer Tabelle die Länge der id auf 1 setzen würde, heisst das ja Zahlen von 1 - 9. Was passiert aber dann ab dem 10. Eintrag?
Warum willst du sowas machen?
Programmierst du für einen Mikrocomputer, dass du einzelne Bytes sparen möchtest?
(lach) Nein, fiel mir nur während meines Herumprobierens so ein.
Hello,
Abfrage:
...
$ergebnis = mysql_query("select kdnr from testtab where passwort like '$passwort' ");
Warum nimmst Du einen Ähnlichkeitsvergleich mit like? Außerdem ist der unvollständig, aber vermutlich kann Dir jeder ein '%' als Passwort posten?
Das ist dann das Universalpasswort ;-))
Du solltest das Passwort schon genau überprüfen, ggf. die Spalte sogar auf 'binary' setzen, damit auch Groß-/Klienschreibung relevant wird.
Liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Hi!
Abfrage:
...
$ergebnis = mysql_query("select kdnr from testtab where passwort like '$passwort' ");
...
echo $row->kdnr;
...
Ich bekomme nichts angezeigt!
Auch nicht, wenn das error_reporting auf E_ALL steht (und display_errors auf 1)?
Dagegen:
...
$ergebnis = mysql_query("select nickname from testtab where passwort like '$passwort' ");
...
echo $row->nickname;
...
gibt mir korrekt den Nicknamen "testnick1" aus.
Das ist das selbe in grün. Beides muss gehen, da ist vermutlich was anderes die Ursache.
Warum vergleichst du das Passwort mit like? Ein eingegebenes % würde damit immer ein gültiges Passwort ergeben.
Die kdnr in der 1. Spalte lautet: "tkn123". Ist also nicht numerisch. Vielleicht liegts daran? Oder weil ich die Spalte "id" nachträglich gelöscht habe?
Nein.
Ich weiss es nicht. Ich müsste vielleicht eine komplett neue Tabelle erstellen und es dann nochmal versuchen.
Unter phpmyadmin kann ich ja keine neue Spalte VOR der ersten einfügen. Erst ab der 2.
Brauchst du nicht, denn daran liegt es nicht. Die Position der ID ist ebenfalls nicht relevant, solange du nicht nach * abfragst und positioniert auf die Spalten zugreifst. Trotzdem kann man mit dem PMA für das Hinzufügen von Feldern nicht nur nach bestimmten Feldern sondern auch am Ende oder Anfang der Tabelle auswählen.
Aber noch etwas bezüglich der id. Wenn ich beim Erstellen einer Tabelle die Länge der id auf 1 setzen würde, heisst das ja Zahlen von 1 - 9. Was passiert aber dann ab dem 10. Eintrag?
Der Werteumfang wird dadurch nicht eingeschränkt (wenn du einen Zahlentyp und nicht etwa einen String-Typ verwendest). Diese Angabe erscheint nur in den Metadaten des Feldes und kann von Anwendungen ausgewertet werden, muss aber nicht. Wenn du schon die Frage nicht mit dem MySQL-Handbuch beantworten willst, hätte zumindest ein kleiner Test schon eine Teilantwort erbringen können.
Lo!
Hi!
Eine Abfrage wie:
<?php
...
$passwort = "testpw";
$ergebnis = mysql_query ("select kdnr from testtab where passwort like '$passwort' ");
...
(es folgt die while-Schleife)
echo $row->kdnr;
?>
funktioniert nicht mehr. Warum auch immer.
Beschreibe bitte "funktioniert nicht mehr" exakter, sonst kann man damit nichts anfagen.
Nun habe ich in der Abfrage lediglich das "kdnr" gegen "nick" ausgetauscht, und das klappt. Es scheint so, als ob - nach dem Löschen der 1. Spalte (id) - auf die neue 1. Spalte (kdnr) kein Zugriff mehr erfolgt. Keine Ahnung.
Du fragst im Beispiel lediglich eine Spalte ab und verwendest augenscheinlich die Funktion mysql_fetch_object(). Positionen im Abfrageergebnis spielen nur bei mysql_fetch_row() und mysql_fetch_array() eine Rolle.
Das war aber das einzigste, was nicht ging. Alle anderen Kombinationen mit Abfragen und Ausgaben gingen.
Einzig ist schon wenig genug, das kann man sinnvollerweise nicht steigern.
Eine session darf, solange ein Kunde online ist, nicht ablaufen. Auch nicht bei Inaktivität. Es kann ja sein, dass er gerade einen längeren Text liesst und anschliessend ein Formular ausfüllt. Und beim Absenden bekommt er dann die Nachricht, sich neu einzuloggen, da die Zeit abgelaufen ist. Nervig, weil die eingegebenen Daten weg sind.
Dann konfiguriere doch das Session-System so, dass der Garbage Collector nicht oder deutlich später zuschlägt, als die Default-Zeit ist.
Darum ein session-handler, der etwa so aussieht:
$konstante = $nickname; ($konstante wird von Skript zu Skript weitergegeben, entweder per input-hidden oder an links angehängt)
Du brauchst keine Zusatzkonstrukte, die Session-ID ist schon eindutig genug. Konfiguriere die Session einfach nach deinen Bedürfnissen. Beachte, dass du den session.save_path auf ein separates Verzeichnis stellst, wenn auf dem Server mehrere Anwendungen mit Sessions arbeiten, denn bei einem gemeinsamen Verzeichniss räumen die Garbage Collectoren mit anders eingestellten Werten auch deine Sessions vorzeitig weg.
Lo!
Hi Lo!,
Beschreibe bitte "funktioniert nicht mehr" exakter, sonst kann man damit nichts anfagen.
Es wird bei der Ausgabe nichts angezeigt.
Das Testscript sieht so aus:
<?php
mysql_connect("localhost","root") or die ("Keine Verbindung");
mysql_select_db ("test") or die ("Keine DB");
$passwort = "testpw1"; (lediglich für den 1. Eintrag)
$ergebnis = mysql_query("select nickname from testtb where passwort like '$passwort' ");
while ($row = mysql_fetch_object($ergebnis))
{
echo $row->nickname;
}
?>
So gehts auch. Tausche ich aber im script die beiden "nickname" gegen "kdnr" aus, wird nichts mehr angezeigt! Siehe auch mein vorheriges Posting an Struppi.
Als Vorlage dienen die Beispiele bei schattenbaum.net. Es funktioniert auch so und ich erwarte dabei auch nur eine Ausgabe, nämlich eben den Nicknamen.
Vielleicht ist alles noch nicht so, wie es sein sollte. Ich habe gerade erst mit MySql angefangen und probiere noch rum. Bis jetzt bin ich aber zufrieden.
Gruss
Thorsten
Hi!
Beschreibe bitte "funktioniert nicht mehr" exakter, sonst kann man damit nichts anfagen.
Es wird bei der Ausgabe nichts angezeigt.
Verwende für Kontrollausgaben var_dump(), denn das zeigt immer etwas an. Wenn auch dann keine Ausgabe erscheint, wurde das var_dump() gar nicht ausgeführt.
Lo!
Nochmal Hallo an alle,
Ich habe jetzt noch zwei weitere Testtabellen erstellt. Somit habe ich jetzt 3, alle mit phpmyadmin:
testtab1 (die ursprüngliche, 3 Spalten)
testtab2 (wie testtab1, ohne id, 3 Spalten)
testtab3 (mit id, 4 Spalten)
In den Tabellen 1 und 2 steht exakt dasselbe drin; in Tabelle 3 auch, aber erst ab Spalte 2.
Mit den Tabellen 2 und 3 klappt ALLES wunderbar! Ich bekomme mit jeder Kombination eine korrekte Ausgabe. Nur mit Tabelle 1 bekomme ich absolut nicht den Inhalt der 1. Spalte angezeigt!
Dasselbe Skript (siehe ein vorheriges Posting), alles genau dasselbe. Kann möglicherweise die Tabelle beim Löschen der 1. Spalte irgendwie "beschädigt" worden sein? Mir fehlt da das Insiderwissen. Mit den neu erstellten Tabellen gehts ja jetzt.
Warum "like" statt "%"? Weil ich es noch nicht anders kenne. Solche Feinheiten kommen aber noch, sobald ich mich weiter in die Materie reingearbeitet habe.
Ich hoffe, ich bin bald mal soweit, dass ich mal jemandem helfen kann!
Dankeschön nochmal!
Gruss
Thorsten
Hi!
Mit den Tabellen 2 und 3 klappt ALLES wunderbar! Ich bekomme mit jeder Kombination eine korrekte Ausgabe. Nur mit Tabelle 1 bekomme ich absolut nicht den Inhalt der 1. Spalte angezeigt!
Was ergab die Kontrollausgabe mit var_dump() statt echo?
Dasselbe Skript (siehe ein vorheriges Posting), alles genau dasselbe. Kann möglicherweise die Tabelle beim Löschen der 1. Spalte irgendwie "beschädigt" worden sein?
Sicher nicht.
Warum "like" statt "%"? Weil ich es noch nicht anders kenne. Solche Feinheiten kommen aber noch, sobald ich mich weiter in die Materie reingearbeitet habe.
Nicht "LIKE statt %", sondern LIKE ist ein Ähnlichkeitsoperator und % ein Jokerzeichen. Passwörter will man jedoch genau vergleichen, wozu man das = nimmt. Dein WHERE passwort LIKE '$passwort' wird bei einem eingegebenen % zu WHERE passwort LIKE '%' und evaluiert immer zu wahr. Einen exakten Vergleich bekommst du mit WHERE passwort = '$passwort'. Allerdings ist dabei zu beachten, dass das Feld eine BIN-Kollation bekommen muss, sonst wird nicht zwischen Groß- und Kleinschreibung unterschieden. Und natürlich muss der Kontextwechsel beachtet werden, sonst bist du anfällig gegen SQL-Injection. Das sind übrigens keine "Feinheiten" sondern essentiell wichtig, anderenfalls einer der häufigsten Programmierfehler.
Lo!
Hi,
[Umgang mit Passwort-Feldern in Datenbanken]
Es ist auch angebracht, die Passwörter verschlüsselt in der DB zu speichern. Dies bewirkt, dass jemand, der einen lesenden Zugriff auf die Datenbank bekommt, nicht sofort die Passwörter aller Nutzer kennt.
Etwas über den Umgang mit Passwörtern in MySQL erfährst du z.B. in der MySQL-Dokumentation.
Bis die Tage,
Matti
Hallo,
die Ausgabe mit var_dump() ergibt folgendes:
Scriptausschnitt mit Fehler:
...
$passwort = "testpw1";
$ergebnis= mysql_query("select kdnr from testtab1 where passwort like '$passwort' ");
...
var_dump($row->kdnr);
...
Ausgabe = "NULL"
Scriptausschnitt ohne Fehler:
...
$passwort = "testpw1";
$ergebnis= mysql_query("select nickname from testtab1 where passwort like '$passwort' ");
...
var_dump($row->nickname);
...
Ausgabe = "string(8) 'Thorsten'"
In der Tabelle steht sichtbar unter phpmyadmin in der 1. Spalte, 1. Zeile:
kdnr (= Name der Spalte)
tkn121 (= Inhalt)
Ich erwähne es nochmal. Tabelle 1 (testtab1) ist die, in welcher die 1. Spalte mit der id nachträglich gelöscht wurde. Die 2. Tabelle (testtab2) ist neu angelegt, mittels phpmyadmin. Beide Tabellen haben denselben Inhalt und dieselben Attribute. Es ist also nicht z.B. auto_increment gesetzt oder so.
In beiden Tabellen steht sichtbar unter phpmyadmin in der 1. Spalte, 1. Zeile:
kdnr (= Name der Spalte)
tkn121 (= Inhalt)
Während ich dieses Posting schrieb, kam mir die Idee! Ich habe gerade noch eine Tabelle erstellt (testtab4) MIT ID, also 4 Spalten. Wird auch alles korrekt ausgegeben! Dann habe ich die 1. Spalte, die mit der id, wieder nachträglich gelöscht, und siehe da, es geht wieder nicht! Ist vielleicht XAMPP fehlerhaft? Nicht korrekt installiert? Ansonsten klappt aber alles.
Ich habe bei testtab4 zuerst die id ausgeben lassen - geht.
Danach die kdnr - geht.
Spalte id gelöscht, php-script unverändert gelassen.
kdnr - geht nicht mehr. Sobald kdnr durch löschen an die 1. Stelle rückt, gehts nicht mehr.
Gruss
Thorsten
Das ist alles sehr ungewöhnlich und nicht nachvollziehbar.
$passwort = "testpw1";
$ergebnis= mysql_query("select kdnr from testtab1 where passwort like '$passwort' ");
...
var_dump($row->kdnr);
Lass dir doch mal den Inhalt von allen Feldern der Tabelle ausgeben:
$passwort = "testpw1";
$ergebnis= mysql_query("select * from testtab1 where passwort like '$passwort' ");
...
var_dump($row);
Struppi.
Hi!
$ergebnis= mysql_query("select kdnr from testtab1 where passwort like '$passwort' ");
...
var_dump($row->kdnr);
...
Ausgabe = "NULL"
Das deutet darauf hin, dass $row kein kdnr enthält. Genaueres kann man sagen, wenn das error_reporting auf E_ALL (und display_errors auf on) steht und es einem Notice-Meldung gibt. Das sollte man immer machen, damit solche Zugriffsfehler gleich angezeigt werden. Und dann wäre es auch sinnvoll, sich das komplette $row anzeigen zu lassen. Vielleicht kannst du dann einen Tippfehler erkennen oder bei false, dass die Abfrage kein Ergebnis ergab.
Ich erwähne es nochmal. Tabelle 1 (testtab1) ist die, in welcher die 1. Spalte mit der id nachträglich gelöscht wurde.
Egal, wie of du die gelöschte Spalte verdächtigst, es wird nicht relevanter.
Während ich dieses Posting schrieb, kam mir die Idee! Ich habe gerade noch eine Tabelle erstellt (testtab4) MIT ID, also 4 Spalten. Wird auch alles korrekt ausgegeben! Dann habe ich die 1. Spalte, die mit der id, wieder nachträglich gelöscht, und siehe da, es geht wieder nicht! Ist vielleicht XAMPP fehlerhaft? Nicht korrekt installiert? Ansonsten klappt aber alles.
Ganz sicher nicht. Verwende var_dump(), um dir das komplette $row anzuzeigen und möglichst auch alle anderen Zwischenergebnisse der Abfrage, beispielsweise den Rückgabewert von mysql_query()
Lo!
Hallo alle,
es hat etwas gedauert (war am WE unterwegs), melde mich jetzt aber nochmal.
Das Problem ist gelöst! Da Ihr alle sagtet, das Script ist ok und MySql muss auch mit gelöschter erster Spalte funktionieren, habe ich kurzen Prozess gemacht. Ich glaube auch, dass ich MySql beim letzten Neuaufspielen des Betriebssystems nicht installiert, sondern nur kopiert habe (von einer FP auf die andere).
Jedenfalls habe ich xampplite runtergeschmissen und komplett neu installiert. Jetzt geht alles.
Ich danke Euch nochmal für Eure Mühe!
Thorsten