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

誰是使用 PHP、MySQL 和 jQuery 的在線小工具

在本週的教程中,我們將查看我們非常有趣的收件箱。這一切都始於幾週前我們的一位讀者的一封信:

泰勒,當我們收到好的教程創意時,我們總是很高興,所以今天我們正在這樣做 - “誰在線 " 帶有 PHP、MySQL 和 jQuery 的小部件。它將顯示當前查看您網站的訪問者數量,並且由於 Hostip 的免費 IP 到位置 API,它甚至能夠檢測您的訪問者來自的國家/地區並將其顯示在滑出面板。

第 1 步 - XHTML

像往常一樣,我們從 XHTML 部分開始。這裡展示的代碼可能看起來不多,但我們需要展示後端完成的所有工作。該小部件具有一個光滑的滑出式面板,其中包含所有地理位置數據,在鼠標懸停時顯示。

demo.html

<div class="onlineWidget">

<div class="panel">

    <!-- Fetched with AJAX: -->

    <div class="geoRow">
    <div class="flag"><img src="who-is-online/img/famfamfam-countryflags/us.gif" width="16" height="11"></div>
    <div class="country" title="UNITED STATES">UNITED STATES</div>
    <div class="people">2</div>
    </div>

    <div class="geoRow">
    <div class="flag"><img src="who-is-online/img/famfamfam-countryflags/uk.gif" width="16" height="11"></div>
    <div class="country" title="UNITED KINGDOM">UNITED KINGDOM</div>
    <div class="people">1</div>
    </div>

</div>

<div class="count">8</div>
<div class="label">online</div>
<div class="arrow"></div>
</div>

正如您從上面的標記中看到的,主容器 div - "onlineWidget " 包含滑出式面板(類名為 "panel 的 div "),在線總人數("count " div), "在線 " 標籤和右側的綠色箭頭。

面板 div 由 AJAX 動態填充當前在線訪問者最多的國家/地區。這個 div 的默認內容是一個旋轉的 gif 預加載器,一旦 AJAX 請求完成(通常不到一秒),它就會被地理數據替換。我們稍後會回到這個話題。

第 2 步 - 數據庫

與通常的例程不同,這裡我們將看一下數據庫的結構,因為它是腳本其餘部分的基礎。

所有小部件數據都存儲在 tz_who_is_online 桌子。它由六個字段(或列)組成。第一個 - ID,是一個標準的主鍵/自動增量字段。之後是存儲訪問者 IP 地址的 IP 字段(預先使用 ip2long 轉換為整數 PHP函數)。

在這之後是 Hostip 的 API 獲取的三個字段 - Country, CountryCode城市 .小部件此時沒有使用 city 字段,但如果有人想要實現它,它會很好。最後是 DT 時間戳字段,在每次頁面加載時都會更新,使我們能夠跟踪誰在線(過去 10 分鐘內沒有加載頁面的用戶可能已經離開了網站)。

第 3 步 - CSS

該小部件(幾乎)沒有圖像,並且僅使用 CSS 進行樣式設置。讓我們看看 styles.css 中定義的樣式 .代碼分為兩部分,比較容易理解。

who-is-online/styles.css - 第 1 部分

.onlineWidget,.panel{

    /* Styling the widget and the sliding panel at once */

    background-color:#F9F9F9;
    border:2px solid #FFFFFF;
    height:25px;
    padding:4px 8px;
    position:relative;
    width:130px;

    cursor:pointer;

    /* CSS3 rules for rounded corners, box and text shadows: */

    -moz-border-radius:6px;
    -webkit-border-radius:6px;
    border-radius:6px;

    -moz-box-shadow:0 0 3px #CCCCCC;
    -webkit-box-shadow:0 0 3px #CCCCCC;
    box-shadow:0 0 3px #CCCCCC;

    text-shadow:0 2px 0 white;
}

.onlineWidget:hover{
    background-color:#fcfcfc;
}

.onlineWidget:hover .arrow{
    /* Changing the background image for the green arrow on hover: */
    background-position:bottom center;
}

.count{
    /* The total number of people online div */

    color:#777777;
    float:left;
    font-size:26px;
    font-weight:bold;
    margin-top:-3px;
    text-align:center;
    width:30px;
}

.label{
    /* The online label */

    float:left;
    font-size:10px;
    padding:7px 0 0 7px;
    text-transform:uppercase;
}

在上面的第一步中,您可以看到我們為 widget 設置了樣式 和滑出式面板 立刻。這是為了確保它們具有一致的樣式,以後很容易更改。不過,有些規則是面板獨有的,因此我們在代碼的第二部分中包含了一組單獨定位的規則。

我們還定義了懸停狀態並為 label 設置樣式 和計數 div。

who-is-online/styles.css - 第 2 部分

.arrow{
    /* The green arrow on the right */

    background:url(img/arrow.png) no-repeat top center;
    position:absolute;
    right:6px;

    width:25px;
    height:25px;
}

.panel{
    /* The slideout panel */

    position:absolute;
    cursor:default;

    bottom:50px;
    left:0;
    height:auto;
    display:none;
    margin:-2px;
    z-index:1000;
}

.preloader{
    /* The rotating gif preloader image */
    display:block;
    margin:10px auto;
}

.geoRow{
    /* The div that contains each country */

    height:16px;
    overflow:hidden;
    padding:2px 0;
}

.flag{
    float:left;
    margin:0 4px;
}

.country, .people{
    float:left;
    font-size:10px;
    padding:2px;
}

.country{
    width:85px;
    overflow:hidden;
}

.people{
    font-weight:bold;
}

在文件的第二部分,我們設置了在 jQuery 從後端獲取地理定位數據後在滑出面板中呈現的方式。這樣我們就可以繼續下一步了。

第 4 步 - PHP

這就是魔法發生的地方。 PHP 必須使在線用戶的數據庫保持最新,並從 Hostip 的 API 獲取 IP 到位置的數據 .這稍後會被緩存以供將來在訪問者 PC 上的 cookie 中使用。

誰在線/online.php

require "connect.php";
require "functions.php";

// We don't want web bots altering our stats:
if(is_bot()) die();

$stringIp = $_SERVER['REMOTE_ADDR'];
$intIp = ip2long($stringIp);

// Checking wheter the visitor is already marked as being online:
$inDB = mysql_query("SELECT 1 FROM tz_who_is_online WHERE ip=".$intIp);

if(!mysql_num_rows($inDB))
{
    // This user is not in the database, so we must fetch
    // the geoip data and insert it into the online table:

    if($_COOKIE['geoData'])
    {
        // A "geoData" cookie has been previously set by the script, so we will use it

        // Always escape any user input, including cookies:
        list($city,$countryName,$countryAbbrev) = explode('|',mysql_real_escape_string(strip_tags($_COOKIE['geoData'])));
    }
    else
    {
        // Making an API call to Hostip:

        $xml = file_get_contents('http://api.hostip.info/?ip='.$stringIp);

        $city = get_tag('gml:name',$xml);
        $city = $city[1];

        $countryName = get_tag('countryName',$xml);
        $countryName = $countryName[0];

        $countryAbbrev = get_tag('countryAbbrev',$xml);
        $countryAbbrev = $countryAbbrev[0];

        // Setting a cookie with the data, which is set to expire in a month:
        setcookie('geoData',$city.'|'.$countryName.'|'.$countryAbbrev, time()+60*60*24*30,'/');
    }

    $countryName = str_replace('(Unknown Country?)','UNKNOWN',$countryName);

    mysql_query("   INSERT INTO tz_who_is_online (ip,city,country,countrycode)
                    VALUES(".$intIp.",'".$city."','".$countryName."', '".$countryAbbrev."')");
}
else
{
    // If the visitor is already online, just update the dt value of the row:
    mysql_query("UPDATE tz_who_is_online SET dt=NOW() WHERE ip=".$intIp);
}

// Removing entries not updated in the last 10 minutes:
mysql_query("DELETE FROM tz_who_is_online WHERE dt<SUBTIME(NOW(),'0 0:10:0')");

// Counting all the online visitors:
list($totalOnline) = mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM tz_who_is_online"));

// Outputting the number as plain text:
echo $totalOnline;

這個 PHP 腳本最初由 jQuery 調用,以便用當前在線人數填充 count div。然而,在幕後,這個腳本將訪問者的 IP 寫入數據庫並解析他們的 IP 到位置的數據。

這是組織後端的最佳策略,因為我們會在每個用戶第一次訪問該站點時將 API 調用(這非常耗時)分發給他們。

另一種選擇是僅存儲訪問者的 IP,並在顯示面板後對地理位置數據進行排隊。這意味著要同時解析大量 IP,這會使腳本無響應並將我們從 API 中列入黑名單。完全不酷。

您可以通過打開與類似以下 URL 的連接來排隊 Hostip 的 API:http://api.hostip.info/?ip=128.128.128.128 .它返回一個有效的 XML 響應,其中包含各種數據,包括 country 城市 與 IP 關聯的名稱,國家 縮寫 甚至是絕對坐標 .我們正在使用 PHP file_get_contents() 獲取這些數據 函數並提取我們需要的信息。

誰在線/geodata.php

require "connect.php";
require "functions.php";

// We don't want web bots accessing this page:
if(is_bot()) die();

// Selecting the top 15 countries with the most visitors:
$result = mysql_query(" SELECT countryCode,country, COUNT(*) AS total
                        FROM tz_who_is_online
                        GROUP BY countryCode
                        ORDER BY total DESC
                        LIMIT 15");

while($row=mysql_fetch_assoc($result))
{
    echo '
    <div class="geoRow">
        <div class="flag"><img src="who-is-online/img/famfamfam-countryflags/'.strtolower($row['countryCode']).'.gif" width="16" height="11" /></div>
        <div class="country" title="'.htmlspecialchars($row['country']).'">'.$row['country'].'</div>
        <div class="people">'.$row['total'].'</div>
    </div>
    ';
}

地理數據.php 由 jQuery 獲取以使用位置數據填充滑出面板。該文件基本上使用 GROUP BY 對數據庫進行排隊 查詢,該查詢按國家/地區對各個用戶進行分組,並按降序排列結果行,最受歡迎的國家位於頂部。

對於標誌圖標,我們使用的是作為公共領域發布的 famfamfam 標誌圖標集。 Hostip API 的一大優點是它以標準的兩個字母格式返回國家代碼,famfamfam 圖標集也共享該格式。這意味著在 while 循環中,很容易找到要顯示的適當標誌,只需降低存儲在數據庫中的國家/地區縮寫的大小寫並添加 gif 擴展名。

第 5 步 - jQuery

JavaScript 管理 AJAX 請求並滑動面板。僅使用純 JS 這將是一項艱鉅的任務,這就是我們使用最新版本的 jQuery 庫的原因。

現在讓我們看看代碼是什麼樣子的。

誰在線/widget.js

$(document).ready(function(){
    // This function is executed once the document is loaded

    // Caching the jQuery selectors:
    var count = $('.onlineWidget .count');
    var panel = $('.onlineWidget .panel');
    var timeout;

    // Loading the number of users online into the count div with the load AJAX method:
    count.load('who-is-online/online.php');

    $('.onlineWidget').hover(
        function(){
            // Setting a custom 'open' event on the sliding panel:

            clearTimeout(timeout);
            timeout = setTimeout(function(){panel.trigger('open');},500);
        },
        function(){
            // Custom 'close' event:

            clearTimeout(timeout);
            timeout = setTimeout(function(){panel.trigger('close');},500);
        }
    );

    var loaded=false;   // A flag which prevents multiple AJAX calls to geodata.php;

    // Binding functions to custom events:

    panel.bind('open',function(){
        panel.slideDown(function(){
            if(!loaded)
            {
                // Loading the countries and the flags
                // once the sliding panel is shown:

                panel.load('who-is-online/geodata.php');
                loaded=true;
            }
        });
    }).bind('close',function(){
        panel.slideUp();
    });

});

你可能對 setTimeout 的使用有點困惑 在菜單中。這樣就完成了,所以我們在鼠標懸停和滑出面板的實際打開之間有一點延遲。這樣,鼠標光標在窗口小部件上的無意移動不會觸發 open 事件,並且一旦打開,就不會關閉 一旦鼠標離開它就立即。

有了這個,我們的小部件就準備好了!

設置演示

此時,您可能想要獲取小部件並將其放在您的網站上。要使其工作,您需要執行 table.sql 中的 SQL 代碼 在下載存檔中。它將創建 tz_who_is_online 小部件使用的數據庫中的表。稍後您需要將文件上傳到您的服務器並包含 widget.js 到頁面的頭部(連同 jQuery 庫)。在此之後,您必須在 connect.php 中填寫您的 MySQL 登錄詳細信息 最後從 demo.html 添加標記 到你的網頁。

結論

訪問您網站用戶群的實時數據是任何網站管理員的夢想。像 Google Analytics 這樣的工具可以很好地了解您網站的覆蓋面,但缺乏像這樣的簡單小部件可以提供的實時感覺。

你怎麼看?您將如何修改此代碼?


Tutorial JavaScript 教程
  1. 檢索百分比 CSS 值(在 Firefox 中)

  2. 控制你的 Monorepo 🗄️

  3. 打開此鏈接並查看我的一個 javascript 應用程序。

  4. 在 JAVASCRIPT 中從數組中刪除項目的現代方法

  5. 使用 Packer CLI 像專業人士一樣構建節點模塊

  6. 航站樓徽章

  7. JavaScript 數組每個方法 |檢查所有元素是否通過測試

  1. 反應保存可能性以使用重新渲染組件選擇文本

  2. jQuery函數從數組中獲取所有唯一元素?

  3. 你好 Treacker,一個 React 的跟踪庫

  4. jQuery 基礎

  5. 🚀 GitHub 上面向 Web 開發人員的 10 個熱門項目 - 2021 年 1 月 29 日

  6. Chartjs 漸變背景

  7. 您將什麼稱為現代(前端?)依賴架構?

  1. 使用 Express 作為 Node.js 框架構建服務器的初學者指南

  2. Reactjs JWT 身份驗證示例

  3. Leetcode - 合併兩個排序列表(使用 JavaScript)

  4. 有沒有辦法限制 javascript 性能來模擬慢速客戶端