[PHP][MySQL] - If działał, działał... i nie działa ;/


(jacko1998) #1
<?phpif((!(@$_POST['username'] == ''))  (!($_POST['password'] == ''))  (!($_POST['password2'] == ''))  ($_POST['password2'] == $_POST['password'])  (!($_POST['mail'] == ''))){        $sql = mysql_query("SELECT * FROM users");        $fetch = mysql_fetch_assoc($sql);        if(!($fetch['username']) == $_POST['username']){            mysql_query("INSERT INTO users (username, password) VALUES ('$_POST[username]', '$_POST[password]')");            $_SESSION['regged'] = false;?                Thank's for th registration ! Now you log in into my Little CMS !

(kostek135) #2

Chyba żartujesz, myśląc, że ktoś sprawdzi ten kod. Po co tyle   wstawiłeś? Wstaw czytelny kod, to porozmawiamy. Po drugie nie wyjaśniłeś jaki masz błąd. To, że według ciebie if "nie działa" nie znaczy, że nagle if przestał działać, tylko coś zmieniłeś i przez ten syf nie jesteś wstanie połapać się o co chodzi. Podaj konkretnie co się dzieje (co jest nie tak) i jaki ma być rezultat.


(jacko1998) #3

Te   dodaja sie czasem jak dodam kod. Nie wiem z jakiego powodu, ale tak sie dzieje.


([alex]) #4
if((!( @ $

(jacko1998) #5

Mialem juz wczesniej z @ i dzialalo, ale mimo tego sprawdzilem i nie dziala, tzn. pokazuje sie komunikat, ze taki username juz istnieje


(kostek135) #6

Gdybyś ty u mnie tak pisał to pracę straciłbyś po 3 dniach...

  1. Obiecałeś, że nie będzie już wyciszania warningów, co robisz... no tak wyciszasz warningi

  2. Wybrałeś wszystkich użytkowników i porównujesz pierwszy element (jeśli PHP domyślnie ustawia iterator kursora na pierwszym elemencie)

  3. To działało prawdopodobnie wttw gdy miałeś jednego użytkownika i próbowałeś zarejestrować się jeszcze raz na ten jedyny login

  4. Zasysać całą tabelę, żeby sprawdzić jeden nick, to chyba jakieś nowe pojęcie skalowalności i wydajności, szczególnie jak mamy miliony rekordów.

  5. To jest ciągle podatne na SQL Injection

    if(jeśli przesłane dane istnieja) {

    if(dane są poprawne) {
    
        rozpocznij transakcję
    
        wykonaj select z WHERE nickname = "pobrany nickname"
    
    
        if(zwróciło jeden wiersz) {
    
            już jest taki user
    
        } else { // Jeśli nickname jest unikalny a powyższy warunek do tego prowadzi tu wejdziemy tylko przy 0 rekordów
    
           wstaw usera
    
        }
    
        commituj transakcje
    
    }

    }

PS Zauważyłem coś jeszcze, zastanów się co tu zrobiłeś...

if(!($fetch['username']) == $_POST['username']){

PS2

SELECT i INSERT powinny być częscią jednej transakcji. Teoretycznie scheduler przy równoległym przetwarzaniu, może ustawić to tak

  1. User1 sprawdza nick "ABC"

  2. User2 sprawdza nick "ABC"

  3. User1 otrzymuje odpowiedź nick unikalny

  4. User2 otrzymuje odpowiedź nick unikalny

  5. User1 rejestruje jako ABC

  6. User2 rejestruje jako ABC

Generalnie szanse są znikome, z technicznego punktu widzenia, ale wraz ze wzrostem osób używających rejestracji w tym samym momencie wzrastają. Dlatego najlepiej objąć takie coś transakcją. Lista kroków została edytowana o wprowadzenie transakcji. Należy pamiętać, aby upewnić się, że jest ustawiony READ COMMITED (czyli zatwierdzenie zwolnienia blokady z tabeli po odczycie w momencie commitu, bo jeśli będzie tylko przy WRITE, to nam nic nie da).


(jacko1998) #7

Tego nie umiem naprawić.

if((!(@$_POST['username']&nbsp;==&nbsp;''))&nbsp;&&&nbsp;(!($_POST['password']&nbsp;==&nbsp;''))&nbsp;&&&nbsp;(!($_POST['password2']&nbsp;==&nbsp;''))&nbsp;&&&nbsp;($_POST['password2']&nbsp;==&nbsp;$_POST['password'])&nbsp;&&&nbsp;(!($_POST['mail']&nbsp;==&nbsp;''))){&nbsp; [/code]

Tylko w tym username występuje błąd. Nie wiem dlaczego z innymi tak się nie dzieje. A co do SQL Injection, to wiem, że wszytko dziurawe, ale postaram się to wszystko naprawić. Na razie muszę uporać się z designem stronki, a potem będę łatał błędy.

-- Dodane 10.11.2013 (N) 18:28 --

PS. Już sobie poradziłem z tą rejestracją.

[code=php]<?php if((!(@$_POST['username'] == '')) && (!($_POST['password'] == '')) && (!($_POST['password2'] == '')) && ($_POST['password2'] == $_POST['password']) && (!($_POST['mail'] == ''))){
        $q = mysql_query("SELECT username FROM users WHERE username = '".mysql_escape_string($_POST['username'])."'");
        $wQ = mysql_fetch_assoc($q);
        $wQr = mysql_num_rows($wQ);
        if($wQr != 1){
            mysql_query("INSERT INTO users (usernamepassword) VALUES ('".mysql_escape_string($_POST['username'])."', '".mysql_escape_string($_POST['password'])."')"); ?
                

Thank's for th registration ! Now you log in into my Little CMS !

Tylko taki warning wyskakuje:

Linia 43:

$wQr = mysql_num_rows($wQ);[/code]

(kostek135) #8

Generalnie ostrzeżenie wynika z jakiejś linijki powyżej (wklej) + komunikat daje na ogół informację co mu nie pasuje (też wklej).

Powiedzmy. Nadal masz niedeterministyczny błąd, który wyjdzie dopiero, jeśli zostanie to kiedykolwiek wykorzystane przez więcej osób (patrz PS2).

Przekazałeś nie to co trzeba jako parametr http://us1.php.net/mysql_num_rows. Poza tym lepiej wykorzystać to http://dev.mysql.com/doc/refman/5.1/en/ ... -rows.html (szczególnie przy wielu wierszach, tu może nie ma to aż takiego znaczenia).


(jacko1998) #9
<?php if((!(@$_POST['username'] == '')) && (!($_POST['password'] == '')) && (!($_POST['password2'] == '')) && ($_POST['password2'] == $_POST['password']) && (!($_POST['mail'] == ''))){$q = sprintf("SELECT username FROM users WHERE username = '".mysql_real_escape_string($_POST['username'])."'"); // pobieram z bazy nick wpisany przez usera$wQ = mysql_query($q); // wykonuje zapytanie do powyższej konstrukcji$wQr = mysql_num_rows($wQ); // Pobieram rekord z nickiem wpisanym przez usera = do tego co jest w bazie

(kostek135) #10

Pogooglaj za słowami: TRASACTION, ROLLBACK, COMMIT, LOCK


([alex]) #11

Po kiego takie komplikacje?!

Ustawiasz przy tworzeniu tablicy users:

create table users

  (

   ...

   username char(...) not null unique key,

   mail char(...) not null unique key,

   ...

  );

Zaś w PHP od razu robisz:

mysql_query
  (
   "INSERT INTO users set ".
   "username='".mysql_real_escape_string($_POST['username'])."', ".
   "password='".mysql_real_escape_string($_POST['password'])."', ".
   "mail='".mysql_real_escape_string($_POST['mail'])."'"
  );[/code]

Po czym analizujesz status.

Jeżeli przeszło to wszystko jest ok.

Jeżeli nie przeszło z komunikatem zawierającym słowo username to znaczy że jest taki użytkownik.

Jeżeli nie przeszło z komunikatem zawierającym słowo mail to znaczy że jest taki mail.

Jeżeli nie przeszło z innym komunikatem to coś się dzieje z bazą.