Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]Skrypt zacina się, chyba nie łączy z bazą
Forum PHP.pl > Forum > Przedszkole
Herny
Ściągnąłem skrypt stąd: http://compzone.org/art-Licznik+pobran+pliku+w+PHP-54.html
I chciałem zrobić licznik, zwykły prosty licznik pobrań. Męczę się już chyba 5 godzinę z tym i nie ma rozwiązania. Wywala mi taki błąd:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/xxxxxxx/public_html/forum/downloads/download.php on line 35
W bazie danych mam 'download'>'nazwapliku' i drugie pole 'iloscpobran'. Wszystko wg linka wyżej.
Szukałem na forum, w google, nawet gadałem z gościem, który miał podobny problem na gg i nie ma rozwiązania. Panowie pomóżcie, bo strace 5h czasu, a to mnie zmartwi bardziej, niż ten je***y licznik.

Jako, że jestem laikiem, proszę o specjalne nie bluzganie i itp.
download.php
  1. <?php
  2.  
  3. //...
  4. $plik = $_GET['plik']; //pobiera nazwę pliku, który użytkownik chce pobrać
  5.  
  6. $baza_ip = 'localhost'; //adres bazy danych (najlepiej aby był to localhost)
  7. $baza_uzytkownik = 'iiiiiiiiiiiiiiw'; //nazwa użytkownika bazy
  8. $baza_haslo = 'ciiiiiiiiiiiiizV'; //hasło dla danego użytkownika bazy
  9. $baza = 'tiiii_im'; //nazwa bazy glównej
  10. $baza_zrodlo = 'download'; //tabela, w której są zapisywane wpisy o ilości pobrań
  11.  
  12. $folder_z_plikami = 'b871/'; //tutaj będą znajdować się pliki do pobrania
  13. //...
  14. echo 'test0';
  15. //....
  16.  
  17. if ($plik != '') //sprawdzam czy zmienna plik jest pusta, jeżeli jest pusta nie wywołuję dalej kodu tylko informuję o błędzie.
  18. {
  19. if (!file_exists($folder_z_plikami.$plik)) //sprawdzam czy podany plik istnieje na serwerze
  20. {
  21. print "Podany plik: $plik nie istnieje"; //jeżeli plik nie istnieje to nie wykonuję dalszych operacji tylko wyświetlam informację o błedzie
  22. }
  23. else
  24. {
  25. echo 'test01';
  26. $db = mysql_connect($baza_ip, $baza_uzytkownik, $baza_haslo);
  27. /*
  28.  Powyższym kodem łączę się z bazą danych mySQL korzystając ze stałych zdefiniowanych na początku skryptu. Znak małpy przed zmienną $db konieczny jest ze względu na możliwość wystąpienia błędu, który jeżeli i tak zaistnieje to i tak zostanie znaleziony za chwilę.
  29.  */
  30.  
  31. if ($db) //sprawdzam czy zostaliśmy połączeni z bazą
  32. { //Jeżeli tak wykonujemy poniższe czynności
  33. mysql_select_db($baza); //ustawiam nazwę bazy danych
  34. echo 'test1';
  35. $result = mysql_query("SELECT * FROM $baza_zrodlo WHERE nazwapliku='$plik'"); //sprawdzam czy w tabeli $baza_zrodlo istnieje nazwa naszego pliku
  36. $num = mysql_num_rows($result); //sprawdzam ile razy występił wpis o nazwie pliku w $plik
  37. echo $num.'0num';
  38.  
  39. if($num >= 1) //jeżeli występuje jeden plik, lub więcej o tej nazwie to...
  40. {
  41. echo 'test2';
  42. $ile = IleRazyPobrano($plik, $baza, $baza_zrodlo); //...poberam do zmiennej $ile ilość pobrań danego pliku <- w tym miejscy korzystam ze skryptu "pobrano.php"
  43. $nowy = $ile+1; // dodaję jedno pobranie
  44. echo $ile;
  45.  
  46.  
  47. //Tutaj rozpoczyna się już właściwie pobieranie pliku
  48.  
  49. header('Pragma: no-cache'); //ustawiamy: aby zawartość nie była cache'owana,
  50. header('Content-Transfer-Encoding: binary'); //zawartość wysyłanego pliku jest binarna,
  51. header('Content-Type: application/x-unknown'); //aplikacja odpowiedzialna za plik,
  52. header("Content-Disposition: attachment; filename=$plik"); //nazwa pliku,
  53. header("Location: "."/".$folder_z_plikami.$plik); //zródło pliku.
  54. echo $folder_z_plikami.$plik;
  55.  
  56.  
  57. //koniec części odpowieadającej za pobieranie
  58. mysql_query("update $baza_zrodlo set iloscpobran=$nowy where nazwapliku='$plik'"); //wysyłam do bazy prośbę o uaktualnienie wpisu ilości pobrań
  59. }
  60. else // jeżeli nie znaleziono pliku w tabeli o tej nazwie to...
  61. {
  62. mysql_query("insert into $baza_zrodlo values ('$plik', 1)"); //wysyłamy prośbę o dodanie pliku z wartością 1 ściągnięcia
  63. //Poniższe wysyłanie jest identyczne jak w przypadku powyższym
  64.  
  65. echo $folder_z_plikami.$plik;
  66. echo 'test3';
  67.  
  68. //koniec wysyłania
  69. }
  70. mysql_close($db); //kończę połącznie z bazą danych
  71. }
  72. else
  73. {
  74. print "Błąd: Nie mogę połączyć się z bazą danych"; //jeżeli nie można połączyć się z bazą mySQL wyświetl komunikat o błędzie
  75. }
  76. }
  77. }
  78. else
  79. {
  80. print "Błąd wywołania skryptu!!!"; //jeżeli zostały wysłane złe dane do skryptu wyświetl błąd
  81. }
  82. ?>


W tym pliku nie wyświetla się "test2", tak jakby tam się zacinał czy coś. No i nie ma co mówić o wywołaniu pliku do pobrania, bo nic się nie dzieje po prostu.

I plik pobrano.php
  1. <?php
  2. function IleRazyPobrano($plik, $baza, $baza_zrodlo)
  3. {
  4. mysql_select_db($baza); //wybieram bazę
  5. $ilerazy = mysql_query("SELECT iloscpobran FROM $baza_zrodlo WHERE nazwapliku = '$plik'"); //wysyłam zapytanie do bazy o liczbę ściągnięć
  6. $wynik = mysql_fetch_row($ilerazy); //pobieram wynik w komórki, którą otrzymałem w zmiennej $ilerazy
  7. return $wynik[0]; //zwracam pierwszy wynik ponieważ zmienna $wynik jest typu array
  8. }
  9. ?>
barcisz
Ten błąd oznacza, że najprawdopodobniej mysql_query zwraca false ze względu na błąd w zapytaniu. Po zapytaniu wstaw linijkę:

Kod
echo mysql_error();


aby zobaczyć jaki błąd zwraca mysql. Ja bym stawiał właśnie na jakąś niezgodność nazwy tabeli lub kolumny z tym, co masz w bazie.
Magic WWW
Zmień instrukcje warunkową dla sprawdzania ilości wystąpień na coś prostszego:
  1. if($num != 0)

Innym problemem może być małe przeoczenie, po prostu nie podałeś argumentu w linku.

index.php?plik=nazwapliku

Pomijając ten fakt z problemem, skrypt będzie bardzo podatny na ataki typy SQL Injection, poczytaj o funkcji mysql_real_escape_string() lub o wyrażeniach regularnych.
memphis8332
a jakiej funkcji uzywac w PDO zamiast mysql_real_escape_string ?
Magic WWW
Poczytaj o PDO-Prepared-Statement.
memphis8332
czyli to jest tam tak jakby automatycznie robione?
Magic WWW
No mniej więcej, mam nadzieję, że ktoś korzystający z PDO się wypowie bo na co dzień nie korzystam z tego wink.gif
barcisz
PDO wykonuje to automatycznie pod warunkiem, że korzystasz odpowiednio - tzn. nie sklejasz "ręcznie" zapytania, tylko używasz tak, jak w podanym przez Magic WWW przykładzie.
memphis8332
dzieki za odpowiedz panowie smile.gif
Herny
Spróbowałem obydwu rad(barcisza i MagicWWW), ale żadna nie dała rezultatu. Nie wywyala żadnych errorów, a po zmianie porównywania wartości dalej nie dochodzi do "echo 'test2'".

Wrzucam jeszcze eksport z MySQL, może coś pomoże.
  1. --
  2. -- Struktura tabeli dla `download`
  3. --
  4.  
  5. CREATE TABLE IF NOT EXISTS `download` (
  6. `nazwapliku` varchar(30) collate utf8_unicode_ci NOT NULL,
  7. `iloscpobran` int(11) NOT NULL
  8. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9.  
  10. --
  11. -- Zrzut danych tabeli `download`
  12. --
  13.  
  14. INSERT INTO `download` (`nazwapliku`, `iloscpobran`) VALUES
  15. ('plik1', 5);


Może mógłby ktoś tak na szybko sprawdzić kod tych plików, może tam wdarł się jakiś błąd?
Magic WWW
Moim zdaniem ten cały skrypt jest do przerobienia, za moment jak wróce z biura to Ci to zrobie do porządku.
kadlub
  1. $result = mysql_query("SELECT * FROM $baza_zrodlo WHERE nazwapliku='$plik'")or die(mysql_error()) ;

jak dodasz wyświetlanie błędów do zapytania będziesz wiedzieć więcej
Herny
@kadlub
Odzyskałem nadzieję, ze to zadziała smile.gif

Wywala mi "No database selected", chociaż na początku skryptu jest wybieranie bazy.
  1. if ($db) //sprawdzam czy zostaliśmy połączeni z bazą
  2. { //Jeżeli tak wykonujemy poniższe czynności
  3. mysql_select_db($baza); //ustawiam nazwę bazy danych
  4. echo 'test1';
  5. $result = mysql_query("SELECT * FROM $baza_zrodlo WHERE nazwapliku='$plik'") or die(mysql_error()) ;


Jak wchodzę do phpMyAdmin to mam:
* information_schema (17)
* nazwabazy (77)
Więc chyba nie ma problemu z wyborem? Musi być coś z łączeniem, ale gdyby nie łączyło to by wywalił błąd(sprawdzałem wink.gif). Sprawdzałem też, czy nazwa jest poprawna i jest.
kadlub
może złą nazw podałeś sprawdź to dokładnie
daj też wyświetlanie błędów do połączenia
a w zapytaniu niżej daj an sztywno wybór tabeli
  1. $result = mysql_query("SELECT * FROM download WHERE nazwapliku='$plik'") or die(mysql_error()) ;
Herny
Panowie, aż wstyd się przyznać, ale nie ustawiłem uprawnień dla użytkownika bazy danych wstydnis.gif
Sorry wszystkim, że zmarnowaliście tyle czasu :/ Tak mi głupio, bo zmarnowałem tyle swojego i waszego czasu, ehh...

Teraz zostaje tylko:
Warning: Cannot modify header information - headers already sent by (output started at /home/tibiacor/public_html/forum/downloads/download.php:1) in /home/xxxxxxx/public_html/forum/downloads/download.php on line 55

Warning: Cannot modify header information - headers already sent by (output started at /home/tibiacor/public_html/forum/downloads/download.php:1) in /home/xxxxxxx/public_html/forum/downloads/download.php on line 56

Warning: Cannot modify header information - headers already sent by (output started at /home/tibiacor/public_html/forum/downloads/download.php:1) in /home/xxxxxxx/public_html/forum/downloads/download.php on line 57

Warning: Cannot modify header information - headers already sent by (output started at /home/tibiacor/public_html/forum/downloads/download.php:1) in /home/xxxxxxx/public_html/forum/downloads/download.php on line 58

Warning: Cannot modify header information - headers already sent by (output started at /home/tibiacor/public_html/forum/downloads/download.php:1) in /home/xxxxxxx/public_html/forum/downloads/download.php on line 59


I nie uruchamianie pobierania pliku.
Wstawiam jeszcze raz kod pliku download.php:
  1. <?php
  2.  
  3. //...
  4. $plik = $_GET['plik']; //pobiera nazwę pliku, który użytkownik chce pobrać
  5.  
  6. $baza_ip = 'localhost'; //adres bazy danych (najlepiej aby był to localhost)
  7. $baza_uzytkownik = 'xxxxxxx'; //nazwa użytkownika bazy
  8. $baza_haslo = 'xxxxx'; //hasło dla danego użytkownika bazy
  9. $baza = 'xxxxx'; //nazwa bazy glównej
  10. $baza_zrodlo = 'xxxxx'; //tabela, w której są zapisywane wpisy o ilości pobrań
  11.  
  12. $folder_z_plikami = 'xxx/'; //tutaj będą znajdować się pliki do pobrania
  13. //...
  14. echo 'test0';
  15. //....
  16.  
  17. function IleRazyPobrano($plik, $baza, $baza_zrodlo)
  18. {
  19. mysql_select_db($baza); //wybieram bazę
  20. $ilerazy = mysql_query("SELECT iloscpobran FROM $baza_zrodlo WHERE nazwapliku = '$plik'"); //wysyłam zapytanie do bazy o liczbę ściągnięć
  21. $wynik = mysql_fetch_row($ilerazy); //pobieram wynik w komórki, którą otrzymałem w zmiennej $ilerazy
  22. return $wynik[0]; //zwracam pierwszy wynik ponieważ zmienna $wynik jest typu array
  23. }
  24.  
  25. if ($plik != '') //sprawdzam czy zmienna plik jest pusta, jeżeli jest pusta nie wywołuję dalej kodu tylko informuję o błędzie.
  26. {
  27. if (!file_exists($folder_z_plikami.$plik)) //sprawdzam czy podany plik istnieje na serwerze
  28. {
  29. print "Podany plik: $plik nie istnieje"; //jeżeli plik nie istnieje to nie wykonuję dalszych operacji tylko wyświetlam informację o błedzie
  30. }
  31. else
  32. {
  33. echo 'test01';
  34. $db = mysql_connect($baza_ip, $baza_uzytkownik, $baza_haslo);
  35. /*
  36.  Powyższym kodem łączę się z bazą danych mySQL korzystając ze stałych zdefiniowanych na początku skryptu. Znak małpy przed zmienną $db konieczny jest ze względu na możliwość wystąpienia błędu, który jeżeli i tak zaistnieje to i tak zostanie znaleziony za chwilę.
  37.  */
  38.  
  39. if ($db) //sprawdzam czy zostaliśmy połączeni z bazą
  40. { //Jeżeli tak wykonujemy poniższe czynności
  41. mysql_select_db($baza); //ustawiam nazwę bazy danych
  42. echo 'test1';
  43. $result = mysql_query("SELECT * FROM $baza_zrodlo WHERE nazwapliku='$plik'") or die(mysql_error()) ; //sprawdzam czy w tabeli $baza_zrodlo istnieje nazwa naszego pliku
  44. $num = mysql_num_rows($result); //sprawdzam ile razy występił wpis o nazwie pliku w $plik
  45. echo $num.'0num';
  46.  
  47. if($num != 0)//jeżeli występuje jeden plik, lub więcej o tej nazwie to... 1.
  48. {
  49. echo 'test2'; echo mysql_error();
  50. $ile = IleRazyPobrano($plik, $baza, $baza_zrodlo); //...poberam do zmiennej $ile ilość pobrań danego pliku <- w tym miejscy korzystam ze skryptu "pobrano.php"
  51. $nowy = $ile+1; // dodaję jedno pobranie
  52. echo $ile;
  53. //Tutaj rozpoczyna się już właściwie pobieranie pliku
  54.  
  55. header('Pragma: no-cache'); //ustawiamy: aby zawartość nie była cache'owana,
  56. header('Content-Transfer-Encoding: binary'); //zawartość wysyłanego pliku jest binarna,
  57. header('Content-Type: application/x-unknown'); //aplikacja odpowiedzialna za plik,
  58. header("Content-Disposition: attachment; filename=$plik"); //nazwa pliku,
  59. header("Location: "."/".$folder_z_plikami.$plik); //zródło pliku.
  60. echo $folder_z_plikami.$plik;
  61.  
  62.  
  63. //koniec części odpowieadającej za pobieranie
  64. mysql_query("update $baza_zrodlo set iloscpobran=$nowy where nazwapliku='$plik'"); //wysyłam do bazy prośbę o uaktualnienie wpisu ilości pobrań
  65. }
  66. else // jeżeli nie znaleziono pliku w tabeli o tej nazwie to...
  67. {
  68. mysql_query("insert into $baza_zrodlo values ('$plik', 1)"); //wysyłamy prośbę o dodanie pliku z wartością 1 ściągnięcia
  69. //Poniższe wysyłanie jest identyczne jak w przypadku powyższym
  70.  
  71. echo $folder_z_plikami.$plik;
  72. echo 'test3';
  73.  
  74. //koniec wysyłania
  75. }
  76. mysql_close($db); //kończę połącznie z bazą danych
  77. }
  78. else
  79. {
  80. print "Błąd: Nie mogę połączyć się z bazą danych"; //jeżeli nie można połączyć się z bazą mySQL wyświetl komunikat o błędzie
  81. }
  82. }
  83. }
  84. else
  85. {
  86. print "Błąd wywołania skryptu!!!"; //jeżeli zostały wysłane złe dane do skryptu wyświetl błąd
  87. }
  88. ?>
kadlub
nagłówki na ogół przesyła sie na samym początku pliku
Herny
Sprawdziłem w configu i mam ustawione output_buffering na no value. Czy to ma z tym związek?

Tak mi się wydaje, z tego co tu wyczytałem:
http://phpedia.pl/wiki/Cannot_add_header_i...rs_already_sent

Może jest jakiś prostszy sposób na wymuszanie pobrania tego pliku?
barcisz
Chodzi o to, że masz wywołanie funkcji header po echo.

Funkcje header muszą być wykonane jeszcze zanim cokolwiek wypluwasz na ekran.
Herny
Nic się nie zmieniło, wywaliłem wszystkie echo. Przesuwałem headery na początek, zmienia się tylko numer linii w errorze.
barcisz
Cytat
output started at /home/tibiacor/public_html/forum/downloads/download.php:1


Chodzi o pierwszą linię pliku. Nie masz tam czasem jakiejś spacji przed <?php ?
Herny
Była spacja, ale wywaliłem, sprawdziłem i nadal jest to samo :/. Na końcu też sprawdziłem i wywaliłem wink.gif
barcisz
Niemożliwe, żeby po wywaleniu tej spacji i po przesunięciu header na samą górę to się nadal pojawia smile.gif A wklej aktualny kod.
kadlub
pisałem że nagłówki powinny być na samym początku zaraz po <?php
temat na tym forum poruszany kilkanaście razy
Herny
Nie rozumiem, jak ale teraz działa, choć wcześniej nie dzałało biggrin.gif No i znowu mi głupio biggrin.gif Barcisz miałeś rację smile.gif

Teraz już z podłączeniem licznika do kodu html powinienem sobie poradzić wink.gif Dzięki wielkie wszystkim.
Magic WWW
Oto przerobiony przeze mnie skrypt, było w nim cholernie dużo błędów wink.gif

  1. <?php
  2. // Pobieranie nazwy pliku z linku
  3. $file = $_GET['plik'];
  4.  
  5. // Sprawdzanie poprawności nazwy pliku
  6. if(!preg_match('/^[a-z0-9 ]+$/i', $file))
  7. {
  8. exit('Script error, the file name is invalid.');
  9. }
  10.  
  11. // Konfiguracja bazy danych
  12. $mysql['Server'] = 'localhost';
  13. $mysql['Username'] = 'root';
  14. $mysql['Password'] = '';
  15. $mysql['Database'] = 'nazwa_bazy_danych';
  16. $mysql['Table'] = 'Tabela';
  17.  
  18. // Tworzenie ścieżki do folderu z plikami
  19. $file_dir = 'x/';
  20.  
  21. // Sprawdzanie czy nazwa pliku została podana
  22. if(!empty($file))
  23. {
  24. // Sprawdzanie istnienia pliku
  25. if(!file_exists($file_dir.$file))
  26. {
  27. exit("Plik {$file} nie istnieje.");
  28. }
  29. else
  30. {
  31. // Nawiązanie połączenia z bazą danych
  32. $db = mysql_connect($mysql['Server'], $mysql['Username'], $mysql['Password']);
  33.  
  34. // Sprawdzanie czy połączenie powiodło się
  35. if(mysql_errno() != 0)
  36. {
  37. }
  38.  
  39. // Wybiernaie bazy danych
  40. mysql_select_db($mysql['Database']);
  41.  
  42. // Zapytanie do bazy danych
  43. $result = mysql_query("SELECT * FROM `{$mysql['Table']}` WHERE `nazwapliku`='{$file}'", $db);
  44.  
  45. // Wyciąganie rekordu oraz sprawdzanie czy istnieje
  46. if(($row = mysql_fetch_assoc($result)) != 0)
  47. {
  48. // Dodawanie liczby pobrań
  49. mysql_query("UPDATE `{$mysql['Table']}` SET `iloscpobran`=`iloscpobran` + 1 WHERE `nazwapliku`='{$file}'", $db);
  50.  
  51. // Wysyłanie nagłówków
  52. header('Pragma: no-cache');
  53. header('Content-Transfer-Encoding: binary');
  54. header('Content-Type: application/x-unknown');
  55. header("Content-Disposition: attachment; filename={$file}");
  56. header('Location: '.'/'.$file_dir.$file);
  57.  
  58. // Wyświetlenie ścieżki i nazwy pliku
  59. echo $file_dir.$file;
  60. }
  61. else
  62. {
  63. // Dodawanie pliku do bazy
  64. mysql_query("INSERT INTO `{$mysql['Table']}` (`nazwapliku`,`iloscpobran`) VALUES ('{$file}', 1)");
  65.  
  66. // Wyświetlenie ścieżki i nazwy pliku
  67. echo $file_dir.$file;
  68. }
  69.  
  70. // Zamknięcie połączenia z bazą danych
  71. }
  72. }
  73. else
  74. {
  75. exit('Script error, you did not specify a file name.');
  76. }
  77.  
  78. ?>
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.