Licznik pobrań pliku przy użyciu bazy MySQL

PcSA

Do napisania licznika będę potrzebować dwóch skryptów: pierwszy będzie pobierał ilość ściągnięć, a drugi będzie
zapisywać do bazy, który to już raz plik został pobrany. Zacznę od pierwszego, chociaż będzie on wyglądać na
taki, który działa jakoś nie logicznie.

Skrypt pierwszy
Licznik pobrań

Aby móc sprawdzić ile osób pobrało nasz program musimy najpierw połączyć się z bazą danych, a następnie pobrać ile razy został ściągnięty dany plik. Aby łatwiej było nam korzystać później korzystać z tego skryptu to zastosuję funkcje.

Funkcje nazwałem "IleRazyPobrano" do tej prawidłowego funkcjonowania potrzebować będziemy pewnych danych, czyli: nazwę pliku, nazwę tabeli z której pobieramy dane oraz nazwę bazy danych. Zminną przechowującą nazwę pliku nazwałem $plik , bazę nazwałem $baza , a nazwę tabeli $baza_zrodlo. Funkcja teraz przedstawia się następująco:

<?php
//...
function IleRazyPobrano($plik, $baza, $baza_zrodlo)
//...
?>

Teraz wystarczy tylko połączyć się z odpowiednią bazą danych, pobranie ilości pobrań danego pliku oraz zwrócenie wyniku. Wygląda to następująco:

<?php
//...
mysql_select_db($baza); //wybieram bazę
//wysyłam zapytanie do bazy o liczbę ściągnięć
$ilerazy = mysql_query("SELECT iloscpobran FROM $baza_zrodlo WHERE nazwapliku = '$plik'");  
//pobieram wynik w komórki, którą otrzymałem w zmiennej $ilerazy
$wynik = mysql_fetch_row($ilerazy);
/zwracam pierwszy wynik ponieważ zmienna $wynik jest typu array
return $wynik[0];
?>

Cały skrypt prezentuje się następująco:

<?php
function IleRazyPobrano($plik, $baza, $baza_zrodlo)
{
//wybieram bazę
mysql_select_db($baza); 
//wysyłam zapytanie do bazy o liczbę ściągnięć
$ilerazy = mysql_query("SELECT iloscpobran FROM $baza_zrodlo WHERE nazwapliku = '$plik'");
//pobieram wynik w komórki, którą otrzymałem w zmiennej $ilerazy
$wynik = mysql_fetch_row($ilerazy);
//zwracam pierwszy wynik ponieważ zmienna $wynik jest typu array
return $wynik[0];
}
?>

Plik ze skryptem zapisujemy pod nazwą "pobrano.php".

Drugi skrypt już będzie bardzie skomplikowany. Będziemy musieli w nim nawiązać kontakt z bazą danych, sprawdzić czy dany plik istnieje,czy użytkownik z zewnątrz nie "kombinował" ze skryptem, dodać nazwę pliku to tabeli jeżeli nie istnieje zwiększyć ilość pobrań i zainicjować pobieranie. No więc zaczynamy :)

Skrypt drugi
Zwiększanie oraz pobieranie

Teraz zacznę od zmiennych, które będą mi potrzebne:

<?php 
//...
  $plik = $_GET['plik']; //pobiera nazwę pliku, który użytkownik chce pobrać
  
  $baza_ip = 'localhost'; //adres bazy danych (najlepiej aby był to localhost)
  $baza_uzytkownik = 'userbazy'; //nazwa użytkownika bazy
  $baza_haslo = 'haslousera'; //hasło dla danego użytkownika bazy
  $baza = 'stronaglowna'; //nazwa bazy glównej
  $baza_zrodlo = 'download'; //tabela, w której są zapisywane wpisy o ilości pobrań
  
  $folder_z_plikami = 'download/'; //tutaj będą znajdować się pliki do pobrania
//...
?>

Teraz przedstawię resztę kodu wraz z opisem:

<?php
//....
//sprawdzam czy zmienna plik jest pusta, jeżeli jest pusta nie wywołuję 
//dalej kodu tylko informuję o błędzie.
if ($plik != '')
  {
    //sprawdzam czy podany plik istnieje na serwerze
    if (!file_exists($folder_z_plikami . $plik))
    {
     //jeżeli plik nie istnieje to nie wykonuję dalszych operacji tylko 
     //wyświetlam informację o błedzie
      print "Podany plik: $plik nie istnieje"; 
    }
    else
    {
      @$db = mysql_connect($baza_ip, $baza_uzytkownik, $baza_haslo);
      /*
        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ę.
      */
      if ($db) //sprawdzam czy zostaliśmy połączeni z bazą
      { //Jeżeli tak wykonujemy poniższe czynności
       mysql_select_db($baza); //ustawiam nazwę bazy danych
       
       //sprawdzam czy w tabeli $baza_zrodlo istnieje nazwa naszego pliku
       $result = mysql_query("SELECT * FROM $baza_zrodlo WHERE nazwapliku='$plik' "); 
       //sprawdzam ile razy występił wpis o nazwie pliku w $plik
       $num = mysql_num_rows($result);

       if($num >= 1) //jeżeli występuje jeden plik, lub więcej o tej nazwie to...
       {
       //...poberam do zmiennej $ile ilość pobrań danego pliku <- w tym miejscy
       // korzystam ze skryptu "pobrano.php"
       $ile = IleRazyPobrano($plik, $baza, $baza_zrodlo); 
       $nowy = $ile+1; // dodaję jedno pobranie 
       
       
       //Tutaj rozpoczyna się już właściwie pobieranie pliku
       

       header('Pragma: no-cache'); //ustawiamy: aby zawartość nie była cache'owana, 
       header('Content-Transfer-Encoding: binary'); //zawartość wysyłanego pliku jest binarna,
       header('Content-Type: application/x-unknown'); //aplikacja odpowiedzialna za plik,
       header("Content-Disposition: attachment; filename=$plik"); //nazwa pliku,
       header("Location: "."/".$folder_z_plikami.$plik); //zródło pliku.

       //koniec części odpowieadającej za pobieranie

       //wysyłam do bazy prośbę o uaktualnienie wpisu ilości pobrań
       mysql_query("update $baza_zrodlo set iloscpobran=$nowy where nazwapliku='$plik'"); 
       }
       else // jeżeli nie znaleziono pliku w tabeli o tej nazwie to...
       {
       //wysyłamy prośbę o dodanie pliku z wartością 1 ściągnięcia
       mysql_query("insert into $baza_zrodlo values ('$plik', 1)"); 
       //Poniższe wysyłanie jest identyczne jak w przypadku powyższym
       header('Pragma: no-cache');
       header('Content-Transfer-Encoding: binary');
       header('Content-Type: application/x-unknown');
       header("Content-Disposition: attachment; filename=$plik");
       header("Location: "."/".$folder_z_plikami.$plik);
       //koniec wysyłania
       }
       mysql_close($db); //kończę połącznie z bazą danych
      }
      else
      {
       //jeżeli nie można połączyć się z bazą mySQL wyświetl komunikat o błędzie
        print "Błąd: Nie mogę połączyć się z bazą danych"; 
      }
    }
  }
  else
  {
    //jeżeli zostały wysłane złe dane do skryptu wyświetl błąd
    print "Błąd wywołania skryptu!!!"; 
  }
?>

Powyższy kod nie nadaje się do pobierania plików typu txt, pas oraz podobnych - można to jednak poprawić korzystając ze wskazówek które znajdują się artykule piechnata pod adresem: http://4programmers.net/article.php?id=534

Pełny listnik skryptu drugiego znajduje się w załączniku do artykułu.

Ustwienie bazy danych
W bazie danych będziemy potrzebować tabeli o polach: "nazwapliku" o typie VarChar i długości 30 znaków oraz pola o nazwie "iloscpobran" o typie Int i wartością domyślną "0"

Korzystanie ze skryptów

Korzystanie ze skryptów jest bardzo proste, należy jednak pamiętać aby plik "pobrano.php" znajdował się w folderze z plikami do sciągnięcia.

Korzystanie z skryptu "download.php"

Aby użyć skryptu download.php musimy go odpowiedni wywołać np. w taki sposób
twójadres.pl/download.php?plik=nazwapliku

Korzystanie z skryptu "pobrano.php"
Niestety korzystanie z tego pliku jest już trochę bardziej skomplikowane. Przykład skryptu jaki trzeba dodać do pliku html znajduje się w załączniku do artykułu ile.txt

12 komentarzy

za każdym razem jak odwiedzam stronę pisze: Błąd wywołania skryptu!!! a jak klikam na odnośnik pisze że pliku nie ma :/ nie wiem co jest nie tak. proszę o pomoc.

i co się znajduje w pliku "ile.txt" ? nie podałeś żadnego załącznika.

wszystko ladnie ale trzeba ZAWSZE pamietac o walidacji danych pobieranych od usera, w tym wypadku zmienna $plik musi byc zbadana (wystarczy ze jakis plik bedzie w folderze pobran ktory niekoniecznie chcemy poslac odbiorcy a on zmieni sobie nazwe i pojawi sie problem)
w mojej opinii trzeba zrobic to w ten sposob ze przy dodawaniu pliku do uploadu powinnismy automatycznie dodawac nazwe pliku do bazy i walidowac zmienna $plik przez obecnosc tego w bazie, dopiero po tym zmieniac sobie licznik przy pliku i wysylac go do usera

I albo nie wiedze albo tu nie ma tego załącznika

jak ten skrypt na stronie ma sie prezentowac !! Pomocy nie wiem jak to mam zrobic.

Czy nie szybciej i łatwiej było by tak:

mysql_query("update $baza_zrodlo set iloscpobran=iloscpobran+1 where nazwapliku='$plik'");

?

a nie domyślna wartość "0" ? przecież na początku jest 0 pobrań a nie 1 :)

A co to za róźnica :)
//po namyśle faktycznie powinno być "0" - już poprawiłem
Dzięki :)

oraz pola o nazwie "iloscpobran" o typie Int i wartością domyślną "1"

a nie domyślna wartość "0" ? przecież na początku jest 0 pobrań a nie 1 :)

No ja nie wiem, kod jest chyba poprawny. A ten komunikat o dostales to mowi, ze jest to nieprawidlowy wynik(ale nie, ze mysql cos skopalo, cos w kodzie jest nie tak)

hmm,a ja otrzymuje takowy blad:

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /usr/home/admins/karol/public_html/index.php on line 30

art bardzo dobry - jasny i rzeczowy -, jedna tylko uwaga: pisze się "ze skryptu" a nie "z skryptu"

lofix: nie wiem czemu ten błąd ci wyskakuje, ale jak na moje to serwer na którym masz skrypt nie obsługuje mySQL, albo taka baza nie istnieje ;/ ale jeśli uruchamiasz sobie skrypt w domu (bardziej prawdopodobne), to nie wiem... Zakładam, że inne skrypty ci chodzą (z MySQL).

Dziwne ;-/
Raczej na pewno nie ma błedu, bo ja korzystam z tych skryptów i wszystko działa.