Zum Forum springen
PHP Entwickler, bit...
 
Benachrichtigungen
Alles löschen

PHP Entwickler, bitte helft mir

24 Beiträge
5 Benutzer
2 Reactions
1,505 Ansichten
0815pokerpr0
Beigetreten: 03.06.2012

Folgendes Problem:

ich habe eine Datenbank mit 2 Tabellen Benutzer und Adresse.
Der Primärschlüssel der Tabelle Adresse ist in der Tabelle Benutzer vorhanden.

Nun will ich einen neuen Benutzer + Adresse hinzufügen und brauche dazu die ID des Adressrecords, um ihn in die Benutzertabelle zu schreiben.
Aktuell habe ich folgenden Code der leider nicht funktioniert.

(Benutzer und Adresse wird angelegt, aber der Fremdschlüssel des Adressrecords in der Tabelle Benutzer ist null)

//Adressrecord schreiben
        if ($insert_stmt1 = $mysqli->prepare("INSERT INTO Adresse (Strasse,PLZ,Ort,Hausnr) VALUES (?, ?, ?, ?)")){
           $insert_stmt1->bind_param('ssss', $strasse, $plz, $ort, $hausnr);
            //Führe die vorbereitete Anfrage aus.
            if (!$insert_stmt1->execute()) {
             //  header('Location: ../error.php?err=Registration failure: INSERT2');
            }
       }    
        
        

//Maximale ID auslesen
        $sql  = "SELECT MAX(BenutzerId) b FROM Benutzer";
        $stmt->prepare($sql);
        $stmt->execute();
        $row  = $stmt->fetch();
        
        echo $row[1];
        
       
//Benutzer hinzufügen
if ($insert_stmt2 = $mysqli->prepare("INSERT INTO Benutzer(Benutzername,Vorname,Nachname,Telefonnummer,Handynummer,Mailadresse,Passwort,Profilbild,istAdmin,istAktiv,Salt,Adresse_idAdresse) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")){
            $insert_stmt2->bind_param('ssssssssssss', $username, $vorname, $nachname, $telefon, $handy, $email, $passwort, $bild, $admin, $aktiv, $random_salt, $row[b]);
            // Führe die vorbereitete Anfrage aus.
            if (!$insert_stmt2->execute()) {
             //  header('Location: ../error.php?err=Registration failure: INSERT2');
            }
        }  
        //success beider Statements
        // header('Location: ../Anmeldung.php');

Antwort
Zitat
23 Antworten
Greenplanet90
Beigetreten: 06.08.2008

ohne jetzt viel ahnung von php zu haben, in zeile 18 gibst du die id der adresse aus ($row[1]) und ich gehe mal davon aus dass hier der wert stimmt. In zeile 23 setzt du dann die parameter für das insert statement, aber hier verwendest du als wert $row[b]. Ersetze mal $row[b] durch $row[1] und schau was passiert.

Außerdem finde ich dass die Adresse einen Fremschlüssel auf den Benutzer haben sollte und nicht andersrum. Eine Adresse alleine macht ja wenig Sinn.


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

was genau macht der interpreter denn?!? irgend wirres zeug oder steigt er mit ner fehlermeldung aus?!? vieleicht auch mal in die logdatein kucken. moeglich, dass dein code richtig ist, aber die datenbank rumzickt(rechte z.b.)


Antwort
Zitat
bastimw
Beigetreten: 07.10.2008

Original von Greenplanet90
Außerdem finde ich dass die Adresse einen Fremschlüssel auf den Benutzer haben sollte und nicht andersrum. Eine Adresse alleine macht ja wenig Sinn.

this - so kann ein Benutzer auch mehrere Adressen haben, außer die Adresse hat mehrere Nutzer ^^
was ist

$row[b]

? Bei Php bin ich nicht so bewandert aber normalerweise ist das ein Integer oder Bigint/ Long Wert.
Also entweder: $row[0-xxx] oder wenn du Klarnamen verwendest dann eher $row["NamedeinerZelle"] also meist irgendwie mit Anführungszeichen.

  $insert_stmt2->bind_param('ssssssssssss', $username, $vorname, $nachname, $telefon, $handy, $email, $passwort, $bild, $admin, $aktiv, $random_salt, $row[b]);

statt

$row[b]

würde ich eher sowas schreiben:

if (is_numeric($row[1])) {intval($row[1]);}else{Nothing;}


Antwort
Zitat
sarc
Beigetreten: 06.06.2008

fetch() liefert nur nen booleschen Wert, ob das Abrufen geklappt hat. Die Variablen, in denen gespeichert werden soll, müssen zunächst mit bin_result() festgelegt werden. Siehe Beispiele hier: http://php.net/manual/de/mysqli-stmt.fetch.php

Wer hat noch mal behauptet, PHP wär angenehm zu nutzen?

@Basti: $row wird als Zugriff auf ein Element eines assoziativen Arrays interpretiert. Dazu geht PHP erst mal davon aus, dass "b" eine Konstante ist, die nicht gefunden wird. Damit wird das dann durch 'b' ersetzt. (Außer natürlich, $row ist innerhalb eines mit " eingeleiteten Strings, dann wär das korrekte Syntax...) Allerdings liefert das normalerweise ne Notice, genauso wies ne Fehlermeldung geben sollte, weil das Element nicht existiert. OP, eventuell error_reporting ausgeschaltet? Würde das Debugging deutlich vereinfachen.


Antwort
Zitat
sarc
Beigetreten: 06.06.2008

Ach ja, und noch ein paar Anmerkungen:

1. Wie schon gesagt wurde, Adresse sollte auf den Benutzer verweisen, nicht andersrum.

2. Warum liest du die maximale ID der Benutzer aus? Sieht mir danach aus, als hättest du da irgendwo Code genommen, der von Hand die nächste ID ermitteln will? Dafür hat mysql das herrliche Schlüsselwort auto_increment für Tabellen... Die automatisch generierten IDs kannst du dann über insert_id abfragen. ( http://us.php.net/mysqli_insert_id)

3. Dein select Statement musst nicht als prepared Statement machen, kannst auch direkt als query rausjagen. Da sind weder Parameter drin noch wird es häufiger aufgerufen, also sollte das keinen Unterschied machen.

Und, willst du jetzt zwar nicht hören, aber: Für mich sieht das danach aus, als hättest du dir da halt ein Registrationsscript aus verschiedenen Schnipseln zusammenkopiert. Zum Lernen in Ordnung, aber wenn du das irgendwo nutzen willst, würde ich dir empfehlen, dich vorher mehr mit PHP zu beschäftigen. PHP ist beliebt weil einige Sachen sehr schnell gehen, aber genauso schnell reißt man sich gewaltige Sicherheitslücken. Du solltest also zumindest ein grobes Verständnis davon haben, was du tust (wobei die Benutzung von prepared Statements schon mal sehr gut ist :f_thumbsup:).


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

Original von sarc
(wobei die Benutzung von prepared Statements schon mal sehr gut ist :f_thumbsup:).

ist das nicht mittlerweile standard(in der lehre)?


Antwort
Zitat
0815pokerpr0
Beigetreten: 03.06.2012

Original von sarc
Ach ja, und noch ein paar Anmerkungen:

1. Wie schon gesagt wurde, Adresse sollte auf den Benutzer verweisen, nicht andersrum.

2. Warum liest du die maximale ID der Benutzer aus? Sieht mir danach aus, als hättest du da irgendwo Code genommen, der von Hand die nächste ID ermitteln will? Dafür hat mysql das herrliche Schlüsselwort auto_increment für Tabellen... Die automatisch generierten IDs kannst du dann über insert_id abfragen. ( http://us.php.net/mysqli_insert_id)

3. Dein select Statement musst nicht als prepared Statement machen, kannst auch direkt als query rausjagen. Da sind weder Parameter drin noch wird es häufiger aufgerufen, also sollte das keinen Unterschied machen.

Und, willst du jetzt zwar nicht hören, aber: Für mich sieht das danach aus, als hättest du dir da halt ein Registrationsscript aus verschiedenen Schnipseln zusammenkopiert. Zum Lernen in Ordnung, aber wenn du das irgendwo nutzen willst, würde ich dir empfehlen, dich vorher mehr mit PHP zu beschäftigen. PHP ist beliebt weil einige Sachen sehr schnell gehen, aber genauso schnell reißt man sich gewaltige Sicherheitslücken. Du solltest also zumindest ein grobes Verständnis davon haben, was du tust (wobei die Benutzung von prepared Statements schon mal sehr gut ist :f_thumbsup:).

Danke schonmal für eure Antowrten!
Ich habe bereits versucht mit mysqli_insert_id zu arbeiten. Allerdings hat das nicht funktioniert. Ich habe da gestern mindestens 4h dran rumprobiert...-.-

Kannst du die paar Zeilen mal als Code posten, wie es funktionieren sollte?

zu Punkt 1. Das ist okay so. Jeder Benutzer hat maximal eine Adresse


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

ist zwar ne recht unsaubere loesung aber wenn die ids autoincrementet sind.
dann select id from table und das array nach dem max abfragen.

wie gesagt, sehr dirty loesung aber du willst ja vorran kommen


Antwort
Zitat
0815pokerpr0
Beigetreten: 03.06.2012

Original von flowIIpoker
ist zwar ne recht unsaubere loesung aber wenn die ids autoincrementet sind.
dann select id from table und das array nach dem max abfragen.

wie gesagt, sehr dirty loesung aber du willst ja vorran kommen

ja, aber das soll schon sauber sein. Ist ja schwachsinn dann bei gewisser größe ein Array zu haben das hunderttausend Werte beinhaltet.

AI ist aktiviert. Ich will nur wissen wie ich mysqli_insert_id nutzen kann, damit ich die letzte ID des AdressRecords bekomme...


Antwort
Zitat
sarc
Beigetreten: 06.06.2008

Original von flowIIpoker

Original von sarc
(wobei die Benutzung von prepared Statements schon mal sehr gut ist :f_thumbsup:).

ist das nicht mittlerweile standard(in der lehre)?

Wenn du halbwegs aktuell Sachen anschaust wohl schon, aber man findet auch noch Schnipsel, da stellen sich einem die Haare auf.

zu Punkt 1. Das ist okay so. Jeder Benutzer hat maximal eine Adresse

Warum dann nicht einfach die Adressdaten mit in die Benutzertabelle packen?

Und, zu insert_id: Machst halt nach dem ersten execute noch ein $id = $mysqli->insert_id;


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

ot: erlaubt denn mysqli ueberhaupt nen anderen query als prepaired? oder wurde mir das nur ausgetrieben, als ich php gelernt hatte vor jahren

edit naja was heisst gelernt. kamm in eine firma die da mit ner vierer php rumgewundert sind. als konnte ich damals gleich mal wieder die haelfte vergessen


Antwort
Zitat
0815pokerpr0
Beigetreten: 03.06.2012

okay, also sollte es so theoretisch funktionieren?

//Adressrecord schreiben
        if ($insert_stmt1 = $mysqli->prepare("INSERT INTO Adresse (Strasse,PLZ,Ort,Hausnr) VALUES (?, ?, ?, ?)")){
           $insert_stmt1->bind_param('ssss', $strasse, $plz, $ort, $hausnr);
            //Führe die vorbereitete Anfrage aus.
            $success = $insert_stmt1->execute();
if ($success) {
             $id = $mysqli->insert_id; 
            }
else{
             //  header('Location: ../error.php?err=Registration failure: INSERT1');
}
       }    
        
        

        
       
//Benutzer hinzufügen
if ($insert_stmt2 = $mysqli->prepare("INSERT INTO Benutzer(Benutzername,Vorname,Nachname,Telefonnummer,Handynummer,Mailadresse,Passwort,Profilbild,istAdmin,istAktiv,Salt,Adresse_idAdresse) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")){
            $insert_stmt2->bind_param('ssssssssssss', $username, $vorname, $nachname, $telefon, $handy, $email, $passwort, $bild, $admin, $aktiv, $random_salt, $id);
            // Führe die vorbereitete Anfrage aus.
            if (!$insert_stmt2->execute()) {
             //  header('Location: ../error.php?err=Registration failure: INSERT2');
            }
        }  
        //success beider Statements
        // header('Location: ../Anmeldung.php');

Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

sieht erstmal fuer mich vernuenftig aus, aber wozu brauchst du denn die last id?!?
mit der erfolgreichen anmeldung kann dir doch die id egal sein. mmn.


Antwort
Zitat
0815pokerpr0
Beigetreten: 03.06.2012

last id? Was meinst du genau?
welche Zeile?


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

if ($success) {
$id = $mysqli->insert_id;
}
else{
// header('Location: ../error.php?err=Registration failure: INSERT1');
}
}
warum du dein else auskommentierst, ist auch nen bisle komisch fuer mich. da musste ja laufend auf die db schauen beim debuging

naja jeder hat sein eigene vorgehensweise beim debug, aber genau "diesen" fehler willst du doch erzwingen


Antwort
Zitat
sarc
Beigetreten: 06.06.2008

Natürlich erlaubt mysqli auch normale Querys. Ist halt nur ein modernerer Wrapper als das Standard mysql Zeug. Als ob PHP irgendwas, das mit den drunterliegenden Bibliotheken möglich wäre, verbieten würde... ;)

Er braucht die ID als Fremdschlüssel. Warum das jetzt unbedingt n Fremdschlüssel sein muss (und dann auch noch sorum) steht auf nem anderen Blatt... ;)

Zu Debugging würd ich halt empfehlen, jeden Rückgabewert anzeigen zu lassen. Dann hättest auch schnell gemerkt, dass da erst mal keine ID zurückkommt... ;)


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

na du siesht ja an mir, wenns eng wird, dann bin ich ganz schnell auf der"dirty seite".
man kann ja solche probleme spaeter fixen.(als ob jemand im operativem tagesgeschaeft das jemals gemacht haette)

programme rennen und alles ist gut.

um mal eine analogie zu bringen. nicht jeder der nen g22 abfeuern kann ist automatisch nen sicherungsschuetze auf 1800 meter


Antwort
Zitat
0815pokerpr0
Beigetreten: 03.06.2012

Original von flowIIpoker
na du siesht ja an mir, wenns eng wird, dann bin ich ganz schnell auf der"dirty seite".
man kann ja solche probleme spaeter fixen.(als ob jemand im operativem tagesgeschaeft das jemals gemacht haette)

programme rennen und alles ist gut.

um mal eine analogie zu bringen. nicht jeder der nen g22 abfeuern kann ist automatisch nen sicherungsschuetze auf 1800 meter

jap, never change a running system^^

Vielen Dank nochmal für eure nette Hilfe. Es hat funktioniert! :)
Nun aber ein anderes Problem.

        $query = "SELECT BenutzerId FROM seniorchat.Benutzer where Benutzername = ?)";
        if($stmt = $mysqli->prepare($query)){
        $stmt->bind_param('s', $username);  // Bind "$benutzername" to parameter.
        $stmt->execute();    // Führe die vorbereitete Anfrage aus.
        $stmt->store_result();
        // hole Variablen von result.
        $stmt->bind_result($Benutzer_BenutzerId1);
        $stmt->fetch();
            echo $Benutzer_BenutzerId1;
        }

könnt ihr mir sagen, wieso das nicht funktioniert?
Und mir evtl. auch direkt sagen wie ich das ordentlich debuffen kann? Weil das echo wird garnicht ausgegeben -.-


Antwort
Zitat
flowIIpoker
Beigetreten: 14.02.2007

hast du wirklich ein problem, den gesamten code zu posten?
vielleicht programmiert dir hier auf deiner anforderung auch jemand das ganze projekt runter
(hab gerade sowas wie urlaub und auch lust)

ok besser vieleicht comtoolanfrage


Antwort
Zitat