Fájl letöltések számolása PHP-vel
2021-05-12T19:35:05+02:00
2021-05-13T12:19:45+02:00
2022-08-12T02:40:29+02:00
*deleted_23419333
Sziasztok!

Hogyan tudnám számolni a Honlapkészítés honlap minta, honlap minták alapján fájl letöltések számát?

Lehetőleg PHP-vel, később MySQL táblába szeretném gyűjteni az adatokat. Lehetőleg a letöltő IP-címére és egyéb adataira is kíváncsi lennék.

Azért is lenne ez fontos mert ha esetleg észrevennék olyat, hogy valaki másodpercenként (kártékonyan) töltögetné le a fájlt megállás nélkül, akkor azt szeretném tiltani, blokkolni.
Mutasd a teljes hozzászólást!
Eddig mivel próbálkoztál? Van bármi olyan amit megpróbálsz önállóan megoldani kérdezés előtt? Csak egy ötletet szeretnék adni, létezik olyan dolog hogy kereső:

https://lmgtfy.app/?qtype=search&q=PHP+count+file+download

Nézegesd a kapott találatokat. A lényeg az, hogy a letölteni kívánt fájlt nem direktben töltöd le, hanem "átfuttatod" egy PHP fájlon. Ez Apache webszerver esetén mehet egy htaccess szabállyal is, ha "szép" hivatkozásokat szeretnél. Ha megvan a fájl, akkor lenaplózod mikor, milyen IP címről és mit töltött le. Ügyelj arra hogy ne lehessen akárhonnan, másik mappából, nem engedélyezett fájlokat letölteni. Ha megvan a naplózás akkor már mehet a letöltés korlátozása. Arra is ügyelj hogy az IP címet nem tárolhatod el a felhasználó előzetes beleegyezése nélkül.
Mutasd a teljes hozzászólást!

  • Köszönöm a hozzászólást. Olvasgattam, illetve eddig el is jutottam:

    .htaccess

    <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule>

    index.php

    <?php if ( $_SERVER [ 'REQUEST_URI' ] == '/latest.zip' ) { if ( $mysqli-> query ( "INSERT INTO `downloads` ( `filename` ) VALUES ( 'latest.zip' )" ) === TRUE ) { // a letöltés elkezdődhet. } else { print 'Hiba.'; } } else {} ?>

    Innentől te hogyan csinálnád? A latest.zip az ~/uploads mappában van xyz.zip fájl néven.



    Az is megoldható, hogy a fájl ne legyen elérhető a Honlapkészítés honlap minta, honlap minták alapján címen, tehát hogy valóban minden megkezdett letöltést tudjak számolni?
    Mutasd a teljes hozzászólást!
  • Több sebből vérzik:

    - Miért csak egy fájlra akarod megírni? Nem lenne jobb, ha több fájlt kezelne?
    - Ha csak egy fájlra akarod megírni, akkor miért tárolod el annak a nevét?
    - Miért nem tárolod el az időbélyeget és az IP címet?
    - Hol van a "fllod" ellenőrzés? (Mondjuk ezt hagyd a végére.)

    Ha ezek megvannak, akkor:

    Alap megoldás: PHP: readfile - Manual
    Egy szerver kímélőbb megoldás: mod_xsendfile for Apache2/Apache2.2

    Ha azt akarod hogy ne legyen direkt linken elérhető:

    - Korlátozd le mappa szinten htaccess-el (deny all). Ez a gyorsabb megoldás.
    - Tedd a fájlokat document root-on kívülre. Ez a korrekt és biztonságos megoldás.
    Mutasd a teljes hozzászólást!
  • downloads adatbázisba 3 tábla `ip` <-- varcar 15 karakteres primary (elsődleges) `filename` <-- varcar 200 Index `count` <-- int 20 ---------download.php--------------- <? $file="latest.zip"; $host=$_SERVER["REMOTE_ADDR"]; header("Content-Type: application/zip"); header("Content-Transfer-Encoding: Binary"); header("Content-Length: ".filesize($file)); header("Content-Disposition: attachment; filename="".basename($file)."""); readfile($file); $query = "INSERT INTO `downloads` (`ip`,`filename`,`count`) VALUES ('".$host."','".$file."','1') ON DUPLICATE KEY UPDATE `count`=`count`+1"; $mysqli-> query($query); exit; ?> ------------------------------------
    Mutasd a teljes hozzászólást!
  • Hibakezelés és IP-cím tárolás nélkül eddig így néz ki. Véleményeznéd? Száz éve programozgatok már, de mindig csak hobbi szinten és örök kezdő vagyok. A flood ellenőrzést ebbe hogyan tudnám beépíteni és pontosan mit értesz alatta?

    `versions` tábla

    CREATE TABLE `versions` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `upload` timestamp NOT NULL DEFAULT current_timestamp(), `filename` varchar(100) NOT NULL, `md5` text NOT NULL, `sha1` text NOT NULL, `stable` tinyint(1) NOT NULL ); INSERT INTO `versions` (`id`, `upload`, `filename`, `md5`, `sha1`, `stable`) VALUES (1, '2021-05-13 06:59:35', 'valami-0.1.zip', '60e2a630d079ad5bf4b51106e073c60d', '0067ec574bd83bdbc0ad6cc7687d20ebefd935e4', 0), (2, '2021-05-13 07:00:29', 'valami-0.2.zip', '57417729e40e6d82738ee94f871883a5', 'd6304aafa479ed06430feb8cdb04870ce3a5fa98', 1);

    `downloads` tábla

    CREATE TABLE `downloads` ( `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, `download` timestamp NOT NULL DEFAULT current_timestamp(), `filename` varchar(100) NOT NULL );

    index.php

    if ( preg_match ( '/\/(?<filename>.*?)\.zip/', $_SERVER [ 'REQUEST_URI' ], $matches ) ) { $filename = $matches [ 'filename' ] . '.zip'; if ( $filename == 'latest.zip' ) { $query = "SELECT * FROM `versions` WHERE `stable`=1 ORDER BY `id` DESC LIMIT 1"; } else { $query = "SELECT * FROM `versions` WHERE `filename`='" . $filename . "'"; } if ( $result = $mysqli-> query ( $query ) ) { $row_cnt = $result-> num_rows; if ( $row_cnt == 1 ) { $file = $result-> fetch_assoc (); $f = __DIR__ . '/../' . $filename; if ( file_exists ( $f ) ) { if ( $mysqli-> query ( "INSERT INTO `downloads` ( `filename` ) VALUES ( '" . $filename . "' )" ) === TRUE ) { header ( 'Content-Description: File Transfer' ); header ( 'Content-Type: application/octet-stream' ); header ( 'Content-Disposition: attachment; filename="' . basename ( $f ) . '"' ); header ( 'Expires: 0' ); header ( 'Cache-Control: must-revalidate' ); header ( 'Pragma: public' ); header ( 'Content-Length: ' . filesize ( $f ) ); readfile ( $f ); exit; } else {} } else {} } else {} } else {} } else {}
    Mutasd a teljes hozzászólást!
  • Köszönöm neked is hozzászólást!

    Tiéd:

    $file; header("Content-Type: application/zip"); header("Content-Transfer-Encoding: Binary"); header("Content-Length: ".filesize($file)); header("Content-Disposition: attachment; filename="".basename($file).""");

    Enyém (php.net-ről):

    $f; header ( 'Content-Description: File Transfer' ); header ( 'Content-Type: application/octet-stream' ); header ( 'Content-Disposition: attachment; filename="' . basename ( $f ) . '"' ); header ( 'Expires: 0' ); header ( 'Cache-Control: must-revalidate' ); header ( 'Pragma: public' ); header ( 'Content-Length: ' . filesize ( $f ) );

    Melyik a jobb, ajánlottabb?
    Mutasd a teljes hozzászólást!
  • ezt használd.

    $f; header ( 'Content-Description: File Transfer' ); header ( 'Content-Type: application/octet-stream' ); header ( 'Content-Disposition: attachment; filename="' . basename ( $f ) . '"' ); header ( 'Expires: 0' ); header ( 'Cache-Control: must-revalidate' ); header ( 'Pragma: public' ); header ( 'Content-Length: ' . filesize ( $f ) );


    Ez nem csak zip-re jó.
    Mutasd a teljes hozzászólást!
  • Csináld meg úgy a letöltés vezérlőt, hogy csak akkor írjon az adatbázisba, ha már ténylegesen letöltődött a fájl.

    $local_file = "latest.zip"; $download_rate = 200.5; // kbyte $filesize = filesize($local_file); $letoltve = $filesize/$download_rate; if(file_exists($local_file) && is_file($local_file)) { header('Cache-control: private'); header('Content-Type: application/octet-stream'); header('Content-Length: '.$filesize); header('Content-Disposition: filename='.basename($local_file)); flush(); $file = fopen($local_file, "r"); while(!feof($file)) { print fread($file, round($download_rate * 1024)); flush(); sleep(1); } fclose($file); /* Ide jön az adatbázisba írás. */ }else{ die('Hiba: A fájl '.$local_file.' nem található!'); }
    Mutasd a teljes hozzászólást!
  • Köszönöm, de nekem elég az is, ha csak a megkezdett letöltések vannak számolva. Az már, hogy letöltötte-e, kicsomagolta-e, használta-e, az nem számít. Valamint kis fájlokról van szó, kevesebb, mint 1 MB-k.
    Mutasd a teljes hozzászólást!
  • Szia!

    Én csak a következő kiegészítést, vagy javaslatot tenném a témában.
    Én általában nem vagyok híve a közvetlen fájl eléréseknek a weboldalon, főleg ha htaccess beállításokkal egyébként blokkolod a közvetlen hívásokat biztonsági okokból.

    Az én logikám ilyenkor a következő:
    - állomány feltöltésekor átnevezem az állományt az upload mappában egy véletlen hash-re (hash1) és ezen a néven tárolom fizikailag. Az eredeti fájlnevet és a hash1-et is eltárolom DB_ben.
    - feltöltés során generálok egy letöltési hasht, ami eltérő az előzőtől (hash2 -> DB)
    - letöltés ágon a letöltési link egy hasht kap, nem állomány nevet (hash2), amelyet ha közvetlenül meghívnak az upload mappára, akkor sem találnak semmit, mivel nem ilyen néven van az állomány, hanem hash1 néven.
    - a letöltést kezelő metódus ellenőrzi a hash1-et és a jogosultságot (belépett-e, elérheti-e az adott állományt, stb.), és ha minden rendben van, akkor a header az hash1 állományt eredeti fájlnéven szolgálja ki, tehát a mentés vagy megnyitás ablakban az eredeti állománynév jelenik meg. A letöltés kezelése során elvégzem a szükséges logolási műveleteket és a kiszolgálás csak ezután történik meg. Ha nagyon fancy kell, akkor a letöltés tényleges megtörténtét (header eredeti fájlnévre sikeres) külön jelzem a DB-ben.

    A fentiek alapján az alábbi releváns adatokat tárolom egy állományról (meg még ami kell):
    - id
    - filename -> eredeti fájlnév
    - size
    - phyHash -> hash1
    - dlHash -> hash2
    - uploader ->user
    - uploadTime -> timestamp

    A letöltési adatokat egy külön táblában files.id=downloads.fileId logikával kezelném (itt tárolnám az IP-t, időbélyegeket, stb.), ahogyan a jogosultságokat is (files.id=access.fileId, userGroup.id = access.groupId, stb...).

    A fenti megoldás sem teljesen bulletproof, de több erőfeszítés kell a tárhely feltáráshoz.

    Üdv, L
    Mutasd a teljes hozzászólást!
  • Heló. Összeraktam számodra egy kis script részt, hogy nagyjából én hogyan oldanám meg a file letöltését.

    File dowload count - Pastebin.com

    Az indok, hogy miért url query-be tenném, mert így könnyen megfogható, és a file-od oda teszed a szerveren belül, ahova csak szeretnéd. Így hiába próbálják a szervered végigpásztázni a file-okért 404-re futnak a scope miatt.

    Persze ezt szétszervezném osztályokra, de szemléltetni a folyamatot megteszi. :)
    Mutasd a teljes hozzászólást!
  • Nem rossz.

    Én így szoktam megoldani a titkosítást.

    <? session_start(); if(isset($_GET["f"])){ $f=$_GET["f"]; print $_SESSION[$f]; unset($_SESSION[$f]); } $hash=md5(date("YmdHis")); $_SESSION[$hash]="latest.zip"; ?> <a href="?f=<?= $hash; ?>">lat</a>
    Mutasd a teljes hozzászólást!
  • Ami fontos, hogy a honlap kezdőlapján lesz egy letöltés gomb, ami mindig a Honlapkészítés honlap minta, honlap minták alapján hivatkozásra kell, hogy mutasson és ez a fájl bárki számára elérhető, tehát nincs szükség bejelentkezésre, regisztrációra stb.

    A fájlok jelenleg így néznek ki:

    /home/********/public_html/.htaccess /home/********/public_html/index.php /home/********/valami-0.1.zip /home/********/valami-0.2.zip

    A valami-0.1.zip fájlt valóban átnevezhetném d16fb36f0911f878998c136191af705e.zip-re például és csinálhatnék adatbázisban ezekre a fájlokra hivatkozásokat, de lehet, hogy így fölösleges lenne, mivel a document root-on kívülre esnek a letölthető fájlok.

    A SEO barát URL-ek miatt a .htacccess amúgy is kellene:

    <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule>
    Mutasd a teljes hozzászólást!
  • <IfModule mod_rewrite.c>
     RewriteEngine On
     RewriteRule ^(.*).zip$ download.php?f=$1 [L]
     RewriteRule ^ index.php [L]
    </IfModule>
    Mutasd a teljes hozzászólást!
abcd