28. oktober 2005 - 09:17Der er
5 kommentarer og 1 løsning
php og mysql, kun en kørsel af insert into
Jeg har et system hvor det på mystisk vis sker (heldigvis sjældent) at brugere bliver oprettet 2 gange.
Hvordan kan jeg sikre at det ikke sker ?
Koden virker sådan her: Form med knap og textinput: [opret bruger knap] [bruger navn] 1) kontroller om brugernavn allerede eksisterer i db. 2) hvis ikke -> opret brugernavn.
Så.. mit spørgsmål er så hvordan i alverden kan det så være at der aligevel findes enkelte brugere (samme brugernavn) to gange???
Jeg kunne sikkert lave brugernavn som UNIQUE, men.... jeg vil hellere vide hvorfor og hvordan jeg sikre min kode!
Det er som om at brugeren "når" at eksekverer to create_user() og disse ikke kører sekventielt .. og altså begge svarer 0 i exists_username, hvilket kan tillade dobbelt oprettelse :(
simplificeret kode:
<?php class User {
function exists_username($user_name) { $query = "SELECT user_name FROM Users "; $query .= "WHERE user_name='$user_name'"; if ($this->num_results($query)== 0) {$result = 0;} else {$result = 1; } return $result; }
function create_user($user_name){ if ($this->exists_username($user_name)) { $result = 0; } else { $query = "INSERT INTO Users (user_name)"; $query .= "VALUES ('$user_name')"; $this->query($query); $result = 1; } }
Hvordan dubletterne er opstået kan være svært at sige efterfølgende. Det kan sagtens ske, hvis du tidligere har haft fejl i koden, eller der er kommet to brugere på samme tid, der vil have samme navn. De laver "samtidig" en select, der siger ok, og efterfølgede begge en insert.
Løsningen kan være een af: 1) At lave din kode i en transaktion - hvis din database understøtter det 2) At gøre dit "user_name" til primær nøgle, og lave testet for om brugeren findes ved simpelthen at lave din insert. Er der fejl, fordi brugernavnet er optaget, indsættes ingenting, og det kan du se med mysql_affected_rows.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.