JavaScript >> Javascript 文檔 >  >> Tags >> CSS

PHP &MySQL 文件下載計數器

我們已經有一段時間沒有在 Tutorialzine 上完成適當的 PHP 和 MySQL 教程了,所以今天我們要創建一個簡單但功能強大的文件下載跟踪器。

每個文件在數據庫中都有對應的行,其中保存了下載總數。 PHP 將更新 MySQL 數據庫並將訪問者重定向到適當的文件。

要跟踪下載次數,您只需將文件上傳到 files 文件夾,並使用特殊的 URL 來訪問它們。

第 1 步 - XHTML

第一步是設置跟踪器的 XHTML 標記。這很簡單——我們有 file-manager div,其中包含一個無序列表 每個文件作為 li 元素。

將被跟踪的文件被放入 files 腳本根目錄中的文件夾(您可以在演示 zip 文件中看到文件結構是如何組織的)。然後 PHP 循環遍歷所有文件並將每個文件添加為單獨的 li 元素添加到無序列表中。

demo.php

<div id="file-manager">

    <ul class="manager">

        <!-- The LI items are generated by php -->
        <li><a href="download.php?file=photoShoot-1.0.zip">photoShoot-1.0.zip
            <span class="download-count" title="Times Downloaded">0</span> <span class="download-label">download</span></a>
        </li>
    </ul>

</div>

注意 href 超鏈接的屬性 - 它將文件名作為參數傳遞給 download.php .這是下載跟踪發生的地方,稍後您會看到。

為了提供下載跟踪,您不僅限於此界面 - 您只需將鏈接發佈到 download.php 在您的博客文章或網站頁面中,所有下載都將被正確跟踪。

第 2 步 - CSS

有了 XHTML 標記,我們現在可以專注於腳本的表示方面。下面的 CSS 規則針對 file-managerid 劃分 (帶有哈希符號 ),因為它在頁面中只出現一次,其餘元素按 類名 .

styles.css

#file-manager{
    background-color:#EEE;
    border:1px solid #DDD;
    margin:50px auto;
    padding:10px;
    width:400px;
}

ul.manager li{
    background:url("img/bg_gradient.gif") repeat-x center bottom #F5F5F5;
    border:1px solid #DDD;
    border-top-color:#FFF;

    list-style:none;
    position:relative;
}

ul.manager li a{
    display:block;
    padding:8px;
}

ul.manager li a:hover .download-label{
    /* When a list is hovered over, show the download green text inside it: */
    display:block;
}

span.download-label{
    background-color:#64B126;
    border:1px solid #4E9416;
    color:white;
    display:none;
    font-size:10px;
    padding:2px 4px;
    position:absolute;
    right:8px;
    text-decoration:none;
    text-shadow:0 0 1px #315D0D;
    top:6px;

    /* CSS3 Rounded Corners */

    -moz-border-radius:3px;
    -webkit-border-radius:3px;
    border-radius:3px;
}

span.download-count{
    color:#999;
    font-size:10px;
    padding:3px 5px;
    position:absolute;
    text-decoration:none;
}

這裡有趣的部分是下載標籤默認是隱藏的 display:none .它以 display:block 顯示 僅當我們將鼠標懸停在其父級 上時 元素,因此無需使用 JavaScript 即可顯示正確的標籤。一點CSS3 也用於圓角下載標籤。

第 3 步 - PHP

如前所述,PHP 循環遍歷 文件 文件夾,並將每個文件輸出為 li 無序列表中的元素。現在讓我們仔細看看這是如何發生的。

demo.php - 頂部

// Error reporting:
error_reporting(E_ALL^E_NOTICE);

// Including the DB connection file:
require 'connect.php';

$extension='';
$files_array = array();

/* Opening the thumbnail directory and looping through all the thumbs: */

$dir_handle = @opendir($directory) or die("There is an error with your file directory!");

while ($file = readdir($dir_handle))
{
    /* Skipping the system files: */
    if($file{0}=='.') continue;

    /* end() returns the last element of the array generated by the explode() function: */
    $extension = strtolower(end(explode('.',$file)));

    /* Skipping the php files: */
    if($extension == 'php') continue;

    $files_array[]=$file;
}

/* Sorting the files alphabetically */
sort($files_array,SORT_STRING);

$file_downloads=array();

$result = mysql_query("SELECT * FROM download_manager");

if(mysql_num_rows($result))
while($row=mysql_fetch_assoc($result))
{
    /*  The key of the $file_downloads array will be the name of the file,
        and will contain the number of downloads: */

    $file_downloads[$row['filename']]=$row['downloads'];
}

請注意我們如何從 download_manager 中選擇所有行 帶有 mysql_query() 的表 ,然後將它們添加到 $file_downloads 以文件名作為下載次數的鍵的數組。這樣,在後面的代碼中,我們可以編寫 $file_downloads['archive.zip'] ,並輸出這個文件被下載了多少次。

你可以看到我們用來生成li的代碼 下面的項目。

demo.php - 中間部分

foreach($files_array as $key=>$val)
{
    echo '<li><a href="download.php?file='.urlencode($val).'">'.$val.'
        <span class="download-count" title="Times Downloaded">'.(int)$file_downloads[$val].'</span> <span class="download-label">download</span></a>
    </li>';
}

就這麼簡單——一個 foreach $files_array 上循環 數組,以及一個將所有標記打印到頁面的 echo 語句。

現在讓我們仔細看看到底是如何跟踪下載的。

下載.php

// Error reporting:
error_reporting(E_ALL^E_NOTICE);

// Including the connection file:
require('connect.php');

if(!$_GET['file']) error('Missing parameter!');
if($_GET['file']{0}=='.') error('Wrong file!');

if(file_exists($directory.'/'.$_GET['file']))
{
    /* If the visitor is not a search engine, count the downoad: */
    if(!is_bot())
    mysql_query("   INSERT INTO download_manager SET filename='".mysql_real_escape_string($_GET['file'])."'
                    ON DUPLICATE KEY UPDATE downloads=downloads+1");

    header("Location: ".$directory."/".$_GET['file']);
    exit;
}
else error("This file does not exist!");

/* Helper functions: */

function error($str)
{
    die($str);
}

function is_bot()
{
    /* This function will check whether the visitor is a search engine robot */

    $botlist = array("Teoma", "alexa", "froogle", "Gigabot", "inktomi",
    "looksmart", "URL_Spider_SQL", "Firefly", "NationalDirectory",
    "Ask Jeeves", "TECNOSEEK", "InfoSeek", "WebFindBot", "girafabot",
    "crawler", "www.galaxy.com", "Googlebot", "Scooter", "Slurp",
    "msnbot", "appie", "FAST", "WebBug", "Spade", "ZyBorg", "rabaz",
    "Baiduspider", "Feedfetcher-Google", "TechnoratiSnoop", "Rankivabot",
    "Mediapartners-Google", "Sogou web spider", "WebAlta Crawler","TweetmemeBot",
    "Butterfly","Twitturls","Me.dium","Twiceler");

    foreach($botlist as $bot)
    {
        if(strpos($_SERVER['HTTP_USER_AGENT'],$bot)!==false)
        return true;    // Is a bot
    }

    return false;   // Not a bot
}

檢查訪問者是否是掃描您的鏈接的搜索引擎機器人而不是真實的人,這一點很重要。機器人是一件好事,因為它們可以讓您加入 Google 搜索等服務,但在這種情況下,可能會扭曲您的下載統計信息。這就是為什麼只有在訪問者通過 is_bot() 之後才更新數據庫行 驗證。

第 4 步 - MySQL

如上一步所述,下載計數在 download_manager 中存儲為一行 MySQL 數據庫中的表。首先,讓我們解釋一下這個特定的查詢是如何工作的:

下載.php

INSERT INTO download_manager SET filename='filename.doc'
ON DUPLICATE KEY UPDATE downloads=downloads+1

它告訴 MySQL 在 download_manager 中插入一個新行 表,並設置文件名 該行的字段為所請求下載文件的值。但是,文件名 字段被定義為唯一索引 在表中。這意味著一行只能插入一次,否則會出現重複鍵錯誤 會發生的。

這是查詢的第二部分開始的地方 - ON DUPLICATE KEY UPDATE 如果文件已存在於數據庫中,將告訴 MySQL 將下載列加一。

這樣新文件在第一次下載時會自動插入到數據庫中。

第 5 步 - jQuery

為了讓下載跟踪感覺幾乎是實時的,一旦用戶開始下載,更新文件名旁邊的計數器將是一個很好的補充。否則,他們將不得不啟動頁面刷新,以便顯示計數器的新統計信息。

我們將通過一個 jQuery 小技巧來實現這一點:

script.js

$(document).ready(function(){
    /* This code is executed after the DOM has been completely loaded */

    $('ul.manager a').click(function(){

        var countSpan = $('.download-count',this);
        countSpan.text( parseInt(countSpan.text())+1);
    });
});

我們只是為指向文件的鏈接分配一個點擊處理程序,每次點擊其中一個時,我們都會增加 counter span 標籤內的數字。

第 6 步 - htaccess

在我們收工之前,我們還需要做一件事。什麼download.php 所做的是將訪問者重定向到作為參數傳遞的請求文件。但是您可能已經註意到,對於某些文件類型,默認瀏覽器行為是直接打開它們。我們想開始下載。這是通過 .htacess 內的幾行來實現的 文件,在 files 中找到 目錄:

<Files *.*>
ForceType application/octet-stream
</Files>

這樣我們的文件下載計數器就完成了!

結論

要在您自己的服務器上運行演示,您需要重新創建 download_manager 您有權訪問的 MySQL 數據庫中的表。你可以找到需要的SQL 將在 table.sql 中為您創建表的代碼 ,您可以在下載存檔中找到。

之後,只需將數據庫的登錄詳細信息(由您的網絡主機提供)添加到 configuration.php .

你怎麼看?您將如何改進此示例?


Tutorial JavaScript 教程
  1. 在 JavaScript 對像中創建 setter 函數

  2. JavaScript 設計模式

  3. Node.js - 最佳實踐

  4. Web 的可訪問性 - ARIA 簡介

  5. AlpineJs 從 select[option] 中提取值

  6. NodeJs 的最小授權策略構建器

  7. Firefox 擴展來找出哪個 Javascript 事件綁定到一個被檢查的元素?

  1. 如何修復手機上 HTML 畫布上的模糊文本

  2. Angular 作為你的第一個 JavaScript 框架?

  3. Angular:單元測試模擬服務

  4. 如何在不污染全局範圍的情況下使用 p5.js?

  5. LaraCRUDJS

  6. JS 中的事件委託

  7. 方括號 Javascript 對象鍵

  1. NPM 幕後和發布指南

  2. 2022 年 Remix 和 JavaScript 的 10 個最佳代碼片段

  3. 使用 AWS CloudFront 的多租戶多區域 React 應用程序的動態路由

  4. 使用 Pino 在 Papertrail 上記錄 Node.js 日誌