Funkcja mysql_fetch_array


(Patrol) #1

Witam!

Mam takie problemy:

$querygame1=mysql_query("SELECT game1 FROM users WHERE id='$_SESSION[userid]'") or die(mysql_error());

$rowgame1=mysql_fetch_array($querygame1);


if($rowgame1>0)

{


}

Kod ten ma pobierać wartość pola game1 i jeżeli jest większe od 0 wykonywać instrukcje. Niestety tego nie robi, a w zmiennej $rowgame1 jest napis Array i za każdym razem wykonuje te instrukcje (bez względu na to czy jest większe czy nie) 2 Problem to:

$signin=mysql_query("SELECT id,username,password,lastlogindate FROM users WHERE username='$_POST[username]' AND password='$_POST[passwordmd5]'") or die(mysql_error());

$data=mysql_fetch_array($signin);


if($signin[lastlogindate]!='.date("Y-m-d", time()).')

{


}

Tutaj ma wykonać operacje w klamrach jeśli się jeszcze dzisiaj nie logowaliśmy, lecz nic nie wyświetla, a instrukcje robi za każdym zalogowaniem.

Prosze o pomoc.

Pozdrawiam Patrol13!


(adpawl) #2

1.

$querygame1=mysql_query("SELECT game1 FROM users WHERE id='$_SESSION[userid]'") or die(mysql_error());

if (mysql_num_rows($querygame1)>0)

while ($signin = mysql_fetch_array($querygame1)){

if($signin[lastlogindate]!=date("Y-m-d"))

{


}

}
  1. podobnie

    $signin=mysql_query("SELECT id,username,password,lastlogindate FROM users WHERE username='$POST[username]' AND password='$POST[passwordmd5]'") or die(mysql_error());

    while ($data = mysql_fetch_array($signin)){

    if($data[lastlogindate]!=date("Y-m-d"))

    {

    }

    }

Zaznaczam, że ten kod i tak nie był i nie jest do końca poprawny ...bo część zwyczajnie na szybko przekleiłem.

Tak czy owak poniżej jest info jak poprawić zapytania mysql_query


(pcgyver) #3

Witam!

A nie powinno być przypadkiem:

$signin=mysql_query("SELECT id,username,password,lastlogindate FROM users WHERE username=' ". $_POST[' username '] ."' AND password='".$_POST[' passwordmd5 '] ."'") or die(mysql_error());

$data=mysql_fetch_array($signin);

if($ data [' lastlogindate ']!=date("Y-m-d"))

{

}

Jeśli do date bierzesz obecny czas, to nie musisz podawać parametru time(). date automatycznie weźmie bierzący czas.

Druga sprawa tablice asocjacyjne pisze się $data['index'] lub $data["index"] a nie $data[index] no chyba że wcześniej zdefiniujesz co to jest stała index.

Pozdrawiam


(Patrol) #4

Można pisać bez '', lecz jest to mniej poprawne.

W dniu 17.07.2008 , o godzinie 9:38 został dopisany post przez patryk_patrol

Czemu ty to wsadziłeś w pętle? To ma pobierać jedno pole z kolumny a nie kilka.


(Airborn) #5

nie nie można


(adpawl) #6

W kwestii pętli while, to w czym problem? -wykona się i tak tyle razy ile zapytanie zwróci rekordów.

W kwestii $_POST w zapytaniu, to jak dla mnie jest jakaś calkowita pomyłka.

Najpierw dane zewnętrzne powinny być przefiltrowane, a dopiero potem można ich używać w zapytaniu ...a i problem z zapisem znika -bo zamiast kombinować w zapytaniu ze zmiennymi $_POST i $_SESSION stosowane będą zwykłe zmienne

np.

WHERE username='$username'

(L337 Crew) #7

[quote="patryk_patrol"] $querygame1=mysql_query("SELECT game1 FROM users WHERE id='$SESSION[userid]'") or die(mysqlerror());$rowgame1=mysql_fetch_array($querygame1);if($rowgame10){} [/code] Nic nie mówię, ale gdzie tu jakakolwiek logika? Nawet jeśli zmienna $rowgame1 zawiera tablicę z danymi [mysql_fetch_array($querygame1) ], to jak możesz ilość elementów tablicy sprawdzać za pomocą $rowgame10 :?: [-X Czemu ty to wsadziłeś w pętle? To ma pobierać jedno pole z kolumny a nie kilka. Jeżeli już, to jeden wiersz, zawierający cztery pola (id,username,password,lastlogindate)

$signin=mysql_query("SELECT id,username,password,lastlogindate FROM users WHERE username='$_POST[username]' AND password='$_POST[passwordmd5]'") or die(mysql_error()); $data=mysql_fetch_array($signin); if($signin[lastlogindate]!='.date("Y-m-d", time()).') { } czemu funkcję wywołującą datę traktujesz jako string? if($signin[lastlogindate]!='.date("Y-m-d", time()).') 

porawnie: [code=php]if($data['lastlogindate']!=date("Y-m-d", time()))  Jednak cytat z manuala php: date — Formatuje lokalny czas/datę Opis string date ( string $format [, int $znacznik_czasu] ) Zwraca datę sformatowaną zgodnie z szablonem podanym w argumencie jako znacznik_czasu , lub aktualnego czasu w przypadku wywołania jej bez tego argumentu. Innymi słowy, znacznik_czasu jest parametrem opcjonalnym, domyślnie pobierającym wartość funkcji time(). jak zauważył pcgyver - wystarczy if($data['lastlogindate']!=date("Y-m-d")) [/code] BTW. Witam! Mam takie problemy: Ty nie masz problemów, Ty tego nie umiesz. W tak krótkim kodzie narobiłeś tyle błędów (sporo logicznych)... [/quote]


(Krzkaczor) #8

No przecież chłopak się dopiero uczy. Może ma jakieś nie pewnie źródła z netu :wink: Polecam Manuala. Airborn , nie powinno być define()? :stuck_out_tongue:


(Airborn) #9

SyntaxError , oczywiście że powinno :smiley: wpisałem błędnie w wyszukiwarkę zintegrowaną z Fx i poprawiło błąd w locie, o czym nie pomyślałem i spisałem błędną formę z pola wyszukiwarki :stuck_out_tongue:


(pcgyver) #10

Witam!

Kilka rzeczy które mi się nasunęły.

1.

Airborn ma rację: nie nie można. Dam radę na platformie developerskiej ustaw sobie samo E_ALL. Nie wykluczaj E_NOTICE. Dlaczego?

Jeśli popełnisz gdzieś błąd, to to ci podpowie. W językach takich jak Delphi, C++ i innych zmienne trzeba definiować. W PHP użycie zmiennej jest zarazem definicją jej istnienia zatem jeśli użyjesz ustawienia E_ALL & ~E_NOTICE, to jeśli popełnisz literówkę w nawie zmiennej, to może się okazać, że nawet tego początkowo nie wykryjesz.

Druga sprawa co do ''. Czas interpretatora na analizę składni. Jeśli napiszesz $array[index], to analizator musi sprawdzić co to jest index. A jeśli użyjesz apostrofów, to analizator szuka tylko końca tekstu bez analizy jego zawartości. Dlatego przy okazji odradzam używanie w nazwach indeksów "" - cudzysłowów. Tekst zamieszczony w cudzysłowach podlega analizie semantycznej - no i tu tracimy czas procesora.

2.

$signin=mysql_query("SELECT id,username,password,lastlogindate FROM users WHERE username='$_POST[username]' AND password='$_POST[passwordmd5]'") or die(mysql_error());


    while ($data = mysql_fetch_array($signin)){

    if($data[lastlogindate]!='.date("Y-m-d", time()).')

    {


    }

    }

Faktycznie po co pętla!?! Założenie logiczne jest takie że para username i password mogą wystąpić tylko raz. Użycie w tym przypadku while to tylko strata czasu procesora. - while sprawdza warunek - jeśli ok wykonaj zawartośc pętli - po zakończeniu pętli sprawdź warunek ..... Po co drugi raz sprawdzać warunek jeżeli wiadomo że jeśli jest rekord to tylko jeden. Druga rzecz to pomijam już wzięcie tego date w apostrofy, ale tak jak poprzednik odsyłam do manuala do funkcji date. Przeanalizujmy: date("Y-m-d", time()) - znaleziono dwa parametry - 1 Parametr w cudzysłowach - sprawdzić semantycznie (np. "$symbolroku-$symbolmiesiaca-$symboldnia", gdzie do tych trzech zmiennych przypisze się odpowiednie literki) - analizator musi to sprawdzić składniowo żeby ustalić ostateczny string - i znowu tracimy cenny czas - 1 Parametr pierwszy ustalony - sprawdzenie poprawności formatu - istnieje 2 parametr - sprawdzanie analizy semantycznej ...... - znowu tracimy czas. - wykonanie funkcji time(). - wykonanie funkcji date A powinno być:

date('Y-m-d')
  • znaleziono jeden parametr - parametr jest zawarty w cudzysłowach - brak sprawdzania analizy semantycznej - sprawdzenie poprawności formatu - brak drugiego parametru - wykonanie funkcji time() - wykonanie funkcji date Czas czas czas - skróciliśmy wykonanie skryptu o dwie złożone analizy semantyczne. Kolejna rzecz:

    "SELECT id,username,password,lastlogindate FROM users WHERE username='$POST[username]' AND password='$POST[passwordmd5]'"

Pomijam bezpośrednie wsadzenie danych z formularza do query SQL. Wyobraź sobie, że ktoś Ci wpisze jako username string:

';

DELETE FROM users;

SELECT id,username,password,lastlogindate FROM users WHERE username='

Zatem mysql_query ostatecznie wykona zapytanie:

SELECT id,username,password,lastlogindate FROM users WHERE username='';

DELETE FROM users;

SELECT id,username,password,lastlogindate FROM users WHERE username='' AND password='jakieshaslo'

Jak widać (w zależności jakie user łączący się z php do bazy ma prawa) może zrobić małe akuku. Zamiast wmontowania DELETE FROM users może wstawić cokolwiek destrukcyjnego lub lepiej... Może nawet ukraść dane. Hihi. To drugie jest fajniejsze. I gorsze be jeśli system zawiera dane osobowe i odpowiednio nie zabezpieczyłeś systemu....i ktoś je ukradnie i wykorzysta.... oj sprawa w sądzie. Kolejna rzecz do tego query. Załóżmy że z $_POST wydobędziesz i sprawdzisz dane i zapiszesz zmienne do np $username i $passwordmd5. To pisząc "... $username .... $passwordmd5" powodujesz, że całe zapytanie podlega analizie semantycznej PHP. Owszem kod może jest ładniejszy... ale jeśli mamy długie zapytanie.... czas czas..... Pisząc 'SELECT ________'.$username.'_____'.$passwordmd5.'_____'. powodujesz że tekst w apostrofach nie podlega pełnej analizie semantycznej (interpreter nie szuka zmiennych, nie szuka kombinacji typu \n\b\t\s itp.). A nazwy i $username i $password tak czy siak podlegają analizie. Ktoś powie że kropka powoduje dodatkową operacją łączenia tekstu. No ale czy w pierwszym zapisie z cudzysłowami nie dzieje się to samo? Nie upieram się przy tym bo sam z lenistwa tak robię bo mi się kropek nie chce dodatkowych apostrofów i kropek wstawiać. Owszem kod może wydaje się mniej przejrzysty ale czy na pewno? Zapis

"SELECT ..... $username ...$passwordmd5 ...."

zostanie w całości zakolorowany jako tekst (np w Pajączku). Ale zapis:

'SELECT ________'.$username.'_____'.$passwordmd5.' _____'
  • nazwy zmiennych będą już widoczne innym kolorem.

Hmmmm.... chyba na tyle na ten moment. Jeśli ktoś się nie zgadza to z chęcią posłucham.

Pozdrawiam


(Airborn) #11

w zasadzie tylko jedna drobna rzecz

to co tutaj piszesz jest oczywiście prawdziwe, ale rzekomo od php 5.x narzut czasowy na analizę semantyczną takiego tekstu jest praktycznie niezauważalnie dłuższy od tekstu objętego apostrofem. sam nie stosuje i nie polecam ze względów o których wspomniałeś, ale jednak różnica, zwłaszcza przy średniej wielkości skryptach, nie powinna być znacząco zauważalna.


(Patrol) #12

(L337 Crew) #13
$querygame1=mysql_query("SELECT game1 FROM users WHERE id='$_SESSION[userid]'") or die(mysql_error());$rowgame1=mysql_fetch_array($querygame1);