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

使用 PHP、JS 和 MySQL 的簡單書籤應用程序

開發人員生活的一部分,就是在工作的各個方面都力求簡單。在尋找常見問題的解決方案時,您可以選擇將自己鎖定在各種第三方服務和 API 中,或者抓住機會自己開發功能。

在本週的教程中,我們正在製作一個簡單的鏈接共享應用程序。此應用程序將使您能夠立即共享任何網頁,只需單擊書籤欄中的書籤,並將其顯示在您網站上的小部件中。

想法

單擊小書籤會在您正在查看的頁面中包含一個 PHP 腳本(評估為 JavaScript 文件),標題和 URL 作為 GET 傳遞 參數。 PHP腳本將頁面數據寫入MySQL數據庫,並輸出成功消息,該消息被視為JavaScript代碼並由瀏覽器執行。

數據庫架構

在進行任何開發工作之前,我們需要創建將保存所有書籤的數據庫表。表定義存儲在 table.sql 在下載 zip 中。您可以在 phpMyAdmin 的 SQL 部分運行它以在您的服務器上重新創建表。在此之後記得更改 connect.php 中的 MySQL 登錄詳細信息 .

注意 HASH 列。這是存儲 md5() 的唯一字段 URL 字段的總和。我們使用它來確保數據庫中沒有重複的鏈接。插入一個已經存在的鏈接,將導致查詢失敗並且 mysql_affected_rows() 函數將返回 0。我們在 tut 的 PHP 部分使用它來確定將向用戶顯示什麼消息,稍後您將看到。

第 1 步 - XHTML

XHTML 標記由 PHP 動態生成。只有在您的網站上顯示共享鏈接時才需要它。它基本上是一個簡單的無序列表,每個共享頁面都是其中的一個 li 元素。

demo.php

<ul class="latestSharesUL">

      <!-- The LI elements are populated by PHP -->

      <li>
          <div class="title"><a href="http://perfectionkills.com/" class="bookmrk">Perfection kills</a></div>
          <div class="dt">36 seconds ago</div>
      </li>
      <li>
          <div class="title"><a href="http://html5test.com/" class="bookmrk">The HTML5 test - How well does your browser support HTML5?</a></div>
          <div class="dt">2 minutes ago</div>
      </li>
</ul>

元素是在 PHP 對數據庫運行查詢以獲取最新書籤後生成的,正如您將在第 3 步中看到的那樣。每個 li 包含頁面的標題和自添加書籤以來的相對時間。我們將在教程的 PHP 部分返回。

第 2 步 - CSS

同樣,CSS 代碼僅在演示部分中需要。您可以修改樣式以匹配站點的其餘部分或完全忽略此代碼。此外,此處並未給出所有樣式。您可以在 styles.css 中查看其餘部分 在下載存檔中。

styles.css

ul.latestSharesUL{
    /* The bookmark widet */
    background-color:#f5f5f5;
    margin:0 auto;
    padding:10px;
    width:280px;
    border:1px solid #e0e0e0;
    text-shadow:1px 1px 0 white;

    font-size:13px;
    color:#666;
    font-family:Arial, Helvetica, sans-serif;
}

ul.latestSharesUL li{
    /* Each bookmark entry */
    background-color:#FAFAFA;
    border:1px solid #EAEAEA;
    border-bottom:none;
    list-style:none;
    padding:12px;
}

ul.latestSharesUL li:last-child{
    /* Targeting the last element of the set */
    border-bottom:1px solid #EAEAEA;
}

ul.latestSharesUL,
ul.latestSharesUL li{
    /* Adding regular and inset shadows */
    -moz-box-shadow:1px 1px 0 white inset, 0 0 2px white;
    -webkit-box-shadow:1px 1px 0 white inset, 0 0 2px white;
    box-shadow:1px 1px 0 white inset, 0 0 2px white;
}

.dt{
    /* The date time field */
    font-size:10px;
    padding-top:10px;
    color:#888;
}

a.bookmrk,
a.bookmrk:visited{
    /* The bookmark title in the widget */
    color:#666;
}

通過使用 box-shadow 和 border-radius CSS3 屬性,我們減少了實現相同設計所需的 div 數量。還要注意 :last-child 的使用 選擇器,它以無序列表中的最後一個 li 為目標,並添加一個底部邊框。

第 3 步 - PHP

首先讓我們看一下鏈接是如何保存的。如前所述,單擊書籤包括 bookmark.php 作為當前頁面頭部的腳本。由於它以 JavaScript 內容類型提供服務,因此瀏覽器會將其評估為常規 JS 文件。

bookmark.php

// Setting the content-type header to javascript:
header('Content-type: application/javascript');

// Validating the input data
if(empty($_GET['url']) || empty($_GET['title']) || !validateURL($_GET['url'])) die();

// Sanitizing the variables
$_GET['url'] = sanitize($_GET['url']);
$_GET['title'] = sanitize($_GET['title']);

// Inserting, notice the use of the hash field and the md5 function:
mysql_query("   INSERT INTO bookmark_app (hash,url,title)
                VALUES (
                    '".md5($_GET['url'])."',
                    '".$_GET['url']."',
                    '".$_GET['title']."'
                )");

$message = '';
if(mysql_affected_rows($link)!=1)
{
    $message = 'This URL already exists in the database!';
}
else
$message = 'The URL was shared!';

文檔標題和 URL 由小書籤傳遞給此腳本,並在 $_GET 中可用 大批。使用我們定制的 sanitize() 對數據進行清理和驗證 函數,然後將其插入數據庫。然後,檢查 mysql_affected_rows() 的狀態後 函數,我們分配給 $message 變量將要顯示給用戶的適當狀態消息。

我建議快速瀏覽一下 bookmark.php 在下載 zip 中,查看 PHP 和 JavaScript 如何協同工作以成功插入書籤並輸出結果。

現在讓我們繼續看看書籤是如何在一個簡單的小部件中顯示的。

demo.php

$shares = mysql_query("SELECT * FROM bookmark_app ORDER BY id DESC LIMIT 6");

while($row=mysql_fetch_assoc($shares))
{
    // Shortening the title if it is too long:
    if(mb_strlen($row['title'],'utf-8')>80)
        $row['title'] = mb_substr($row['title'],0,80,'utf-8').'..';

    // Outputting the list elements:
    echo '
    <li>
        <div class="title"><a href="'.$row['url'].'" class="bookmrk">'.$row['title'].'</a></div>
        <div class="dt">'.relativeTime($row['dt']).'</div>
    </li>';
}

此代碼從數據庫中選擇最後 6 個共享鏈接,生成包含標題的適當 LI 元素作為書籤頁面的超鏈接,並使用我們的自定義 relativeTime() 功能。

我們使用的自定義函數在 functions.php 中定義 .

functions.php

/* Helper functions */

function validateURL($str)
{
    return preg_match('/(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/i',$str);
}

function sanitize($str)
{
    if(ini_get('magic_quotes_gpc'))
        $str = stripslashes($str);

    $str = strip_tags($str);
    $str = trim($str);
    $str = htmlspecialchars($str);
    $str = mysql_real_escape_string($str);

    return $str;
}

function relativeTime($dt,$precision=2)
{
    if(is_string($dt)) $dt = strtotime($dt);

    $times=array(   365*24*60*60    => "year",
                    30*24*60*60     => "month",
                    7*24*60*60      => "week",
                    24*60*60        => "day",
                    60*60           => "hour",
                    60              => "minute",
                    1               => "second");

    $passed=time()-$dt;

    if($passed<5)
    {
        $output='less than 5 seconds ago';
    }
    else
    {
        $output=array();
        $exit=0;

        foreach($times as $period=>$name)
        {
            if($exit>=$precision || ($exit>0 && $period<60)) break;

            $result = floor($passed/$period);
            if($result>0)
            {
                $output[]=$result.' '.$name.($result==1?'':'s');
                $passed-=$result*$period;
                $exit++;
            }
            else if($exit>0) $exit++;
        }

        $output=implode(' and ',$output).' ago';
    }

    return $output;
}

構建 Web 應用程序時的指導原則之一是“不要信任您的用戶”。這意味著所有輸入數據都必須正確轉義。這正是 sanitize() 功能正在執行 - 它可以防止可能的 XSS 攻擊,剝離任何 HTML 標記並轉義所有可能在顯示時破壞您的標記的 HTML 字符。

另一個有趣的函數是 relativeTime() ,它將時間戳字段分配給每個書籤,並將其轉換為用戶友好的相對時間字符串。它還接受一個可選的第二個參數,它限制返回的時間單位的數量(將精度設置為 1 將返回 1 小時前 , 而不是 1 小時 10 分鐘 以前)。

第 4 步 - JavaScript

由於腳本是動態包含在第三方頁面中的,因此依賴第三方庫(如 jQuery)並不是一個好主意。這就是為什麼,為了改變,我們將使用純 JavaScript。

首先,讓我們看一下書籤代碼。

書籤代碼

(function () {
    var jsScript = document.createElement('script');

    jsScript.setAttribute('type', 'text/javascript');
    jsScript.setAttribute('src', '/bookmark.php?url=' + encodeURIComponent(location.href) + '&title=' + encodeURIComponent(document.title));

    document.getElementsByTagName('head')[0].appendChild(jsScript);
})();

小書籤只是一個常規超鏈接,上面的代碼以 javascript: 開頭 協議作為它的 href 屬性。單擊時,該片段會創建一個新的腳本元素,設置 bookmark.php 作為其 URL(以及當前活動頁面的編碼標題和 URL),並將其附加到文檔的頭部部分。它不像我們使用 jQuery 庫那樣漂亮,但它完成了工作。

現在讓我們回到 bookmark.php .

bookmark.php

function displayMessage(str)
{
    // Using pure JavaScript to create and style a div element

    var d = document.createElement('div');

    with(d.style)
    {
        // Applying styles:

        position='fixed';
        width = '350px';
        height = '20px';
        top = '50%';
        left = '50%';
        margin = '-30px 0 0 -195px';
        backgroundColor = '#f7f7f7';
        border = '1px solid #ccc';
        color = '#777';
        padding = '20px';
        fontSize = '18px';
        fontFamily = '"Myriad Pro",Arial,Helvetica,sans-serif';
        textAlign = 'center';
        zIndex = 100000;

        textShadow = '1px 1px 0 white';

        MozBorderRadius = "12px";
        webkitBorderRadius = "12px";
        borderRadius = "12px";

        MozBoxShadow = '0 0 6px #ccc';
        webkitBoxShadow = '0 0 6px #ccc';
        boxShadow = '0 0 6px #ccc';
    }

    d.setAttribute('onclick','document.body.removeChild(this)');

    // Adding the message passed to the function as text:
    d.appendChild(document.createTextNode(str));

    // Appending the div to document
    document.body.appendChild(d);

    // The message will auto-hide in 3 seconds:

    setTimeout(function(){
        try{
            document.body.removeChild(d);
        }   catch(error){}
    },3000);
}

上面的 JavaScript 代碼就在將書籤插入到 bookmark.php 中的數據庫的 PHP 邏輯下方。 displayMessage() JavaScript 函數創建一個 div 元素,為其設置樣式並將其顯示在頁面中心。

作為 bookmark.php 被評估為 JS 文件,它輸出的每個文本都被視為常規 JavaScirpt 代碼。正如我們在 PHP 步驟中提到的,bookmark.php 接收文檔標題和 URL,將它們插入到數據庫中,並創建 $message 多變的。這稍後會作為對 displayMessage() 的調用輸出 函數,它執行上面的代碼並顯示消息:

// Adding a line that will call the JavaScript function:
echo 'displayMessage("'.$message.'");';

有了這個我們簡單的書籤應用程序就完成了!

結論

如果您打算使用此小部件與訪問者共享鏈接(或為自己保存鏈接),請務必將腳本上傳到具有隨機名稱的目錄,因為此腳本不提供身份驗證。這也是它設置和使用如此簡單的原因。

你怎麼看?你打算用它做什麼?


Tutorial JavaScript 教程
  1. [Gatsby] 無法獲取此 StaticQuery 的結果的解決方案。

  2. 在 ES6 和 Canvas 上一步一步的俄羅斯方塊

  3. Javascript:從變量本身引用變量名

  4. 1行代碼:如何獲取數組的最高數字項

  5. 在 Javascript 中處理二進製文件

  6. 固態菜單、英雄介紹、倒計時 |模塊星期一 59

  7. 由 onload 事件調用的警報未運行? [關閉]

  1. 建立投資組合網站 - DO Hackathon

  2. 在 JavaScript 中解決 Code 2021 出現的第 16 天

  3. 使用 useReducer、memo 和 useCallback 優化重新渲染的長列表。

  4. 使用 Graphql 爬行 - 基礎知識

  5. Satha - 本地存儲包裝器

  6. 我想在我的平台中集成一個代碼編輯器

  7. 通用片段 - DOM 元素創建

  1. 使用 React 和 CSS 構建這個很酷的彈出窗口/模態框

  2. 讓我們為自己寫一個片段!

  3. 使用 nodeJS - HTTP Trigger 使用 Azure Functions 創建無服務器 REST API

  4. 如何使用 BMFont 為 Phaser JS 創建位圖字體