中級篇項目二內(nèi)容管理系統(tǒng)
《中級篇項目二內(nèi)容管理系統(tǒng)》由會員分享,可在線閱讀,更多相關《中級篇項目二內(nèi)容管理系統(tǒng)(110頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、PHP 【 中級篇 】 項目二:內(nèi)容管理系統(tǒng) 模塊五 后臺功能實現(xiàn) MySQL安裝與使用 HTTP、會話技術 PHP操作數(shù)據(jù)庫 文件、圖像技術 任務一 任務二 任務三 項目準備 管理員登錄 欄目管理 任務四 任務五 文章管理 排序與搜索 任務五 分頁導航 目錄 在項目開發(fā)的初始階段,先進行項目的目錄結構劃分,才能合理、規(guī)范地 管理項目中的各種文件。根據(jù)功能模塊劃分,本項目的目錄結構如下所示。 項目初始化 任務一:項目準備 項目初始化 文件 說明 common 前后臺 公共文件目錄 upload 前后臺 上傳文件目錄 css 前臺 CSS樣式文件目錄 js 前臺 JavaScript文件目錄 i
2、mage 前臺 圖片文件目錄 view 前臺 HTML模板文件目錄 init.php 前臺 初始化文件 index.php 前臺 首頁 文件 說明 admin 后臺 文件目錄 admincss 后臺 CSS樣式文件目錄 adminjs 后臺 JavaScript文件目錄 adminimage 后臺 圖片文件目錄 adminview 后臺 HTML模板文件目錄 admininit.php 后臺 初始化文件 adminindex.php 后臺 首頁 任務一:項目準備 項目初始化 項目首先分成了前臺和后臺兩個平臺 將 common和 upload目錄作為前后臺公共目錄 后臺相關的文件全部放到了 ad
3、min目錄中 從而在目錄結構上對前后臺進行了區(qū)分 任務一:項目準備 項目初始化 在完成目錄劃分后,接下來為項目的前后臺創(chuàng)建初始化文件,為項目定義一 些基礎的常量,方便在項目中使用。 任務一:項目準備 項目初始化 為前臺創(chuàng)建初始化文件 init.php 定義常量 APP_DEBUG,用于表示是否開啟調試,其值可以為 true和 false。 當開啟時將提示完整的錯誤信息以便于調試,否則只進行簡單的錯誤提示。 定義常量 COMMON_PATH和 UPLOAD_PATH,用于表示公共文件目錄和上 傳文件目錄的路徑。 從前臺進行訪問時,從當前目錄“ ./”開始。 任務一:項目準備 項目初始化 為后臺創(chuàng)
4、建初始化文件 admininit.php 定義常量 APP_DEBUG,用于表示是否開啟調試,其值可以為 true和 false。 當開啟時將提示完整的錯誤信息以便于調試,否則只進行簡單的錯誤提示。 定義常量 COMMON_PATH和 UPLOAD_PATH,用于表示公共文件目錄和上 傳文件目錄的路徑。 從后臺進行訪問時,從上級目錄“ ./”開始。 任務一:項目準備 函數(shù)庫與配置文件 函數(shù)庫 在項目開發(fā)時,有許多常用的功能可以通過函數(shù)來完成,因此應該為項目創(chuàng) 建一個函數(shù)庫,保存項目中的常用函數(shù)。 常用函數(shù)的名稱,通過一個大寫字母的命名風格,既書寫方便,又便于程序 閱讀。 任務一:項目準備 函數(shù)
5、庫與配置文件 函數(shù)庫 在 common目錄中創(chuàng)建文件 function.php,編寫一個“ E()”函數(shù)。 函數(shù)名是英文單詞“ error”的首字母縮寫,表示程序遇到錯誤。 該函數(shù)有兩個參數(shù) $msg和 $debug,參數(shù) $debug的默認值為空字符串 該函數(shù)的參數(shù) $msg表示錯誤信息, $debug表示調試信息 當開啟調試時,顯示錯誤信息和調試信息,而關閉調試時,只顯示錯誤信息 在完成編寫函數(shù)庫后,接下來在項目的初始化文件中載入函數(shù)庫 任務一:項目準備 函數(shù)庫與配置文件 配置文件 在項目中通常有一些常用的配置,如數(shù)據(jù)庫連接信息,使用獨立的配置文 件來保存配置可以使代碼更利于維護。 任務一
6、:項目準備 函數(shù)庫與配置文件 配置文件 接下來在 common目錄中創(chuàng)建配置文件 config.php,保存數(shù)據(jù)庫的連接信息。 在 config.php中,直接返回數(shù)組,數(shù)組中的元素用于設置項目的配置信息 DB_CONNECT元素的值是一個數(shù)組,用于保存數(shù)據(jù)庫的連接信息,如 數(shù) 據(jù)庫服務器地址、用戶名、密碼、默認數(shù)據(jù)庫和端口號 。 DB_CHARSET元素用于保存數(shù)據(jù)庫字符集 任務一:項目準備 函數(shù)庫與配置文件 訪問配置文件 完成配置文件 commonconfig.php的創(chuàng)建后,接下來還需要對配置文件進 行訪問。 任務一:項目準備 函數(shù)庫與配置文件 訪問配置文件 在函數(shù)庫文件 commonf
7、unction.php中編寫函數(shù) C()實現(xiàn)此功能。 函數(shù)名是英文字母“ config”的首字母縮寫,表示訪問程序的設置。 參數(shù) $name表示待訪問的數(shù)組元素,如 DB_CONNECT。 在 C()函數(shù)中設置靜態(tài)變量 $config,用于保存項目配置信息 判斷 $config是否為 null,若為 null,則載入配置文件 判斷要獲取的配置信息是否存在,若不存在賦值為空字符串 返回要獲取的配置信息 任務一:項目準備 函數(shù)庫與配置文件 示例演示 在后臺初始化文件 admininit.php中,添加以下代碼用于測試函數(shù)的使用。 /訪問數(shù)據(jù)庫連接信息 $config = C(DB_CONNECT)
8、; echo $confighost; /輸出結果: localhost /訪問數(shù)據(jù)庫字符集 echo C(DB_CHARSET); /輸出結果: utf8 任務一:項目準備 數(shù)據(jù)庫函數(shù) 在基于數(shù)據(jù)庫的項目中,對數(shù)據(jù)庫的操作是非常頻繁的,因此可以利用函數(shù) 將這部分代碼提取出來,以方便后續(xù)的代碼編寫。 接下來在 common目錄中創(chuàng)建 db.php,保存數(shù)據(jù)庫的常見操作函數(shù) 任務一:項目準備 數(shù)據(jù)庫函數(shù) 連接數(shù)據(jù)庫 編寫 db_connect()函數(shù),用于完成數(shù)據(jù)庫連接和設置字符集操作 設置靜態(tài)變量 $link用于保存數(shù)據(jù)庫連接 實現(xiàn) 函數(shù)第一次調用時進行數(shù)據(jù)庫連接 實現(xiàn) 函數(shù)執(zhí)行后返回數(shù)據(jù)庫連
9、接 $link 任務一:項目準備 數(shù)據(jù)庫函數(shù) 執(zhí)行 SQL語句 在完成數(shù)據(jù)庫連接后接下來就可以執(zhí)行 SQL語句。由于 MySQLi擴展提供 的預處理語句更加高效和安全,因此在項目中執(zhí)行 SQL語句時,將通過預處理 來實現(xiàn)。 任務一:項目準備 數(shù)據(jù)庫函數(shù) 執(zhí)行 SQL語句 編寫函數(shù) db_query(),完成 SQL語句的預處理操作 該函數(shù)的 參數(shù)依次為 SQL語句、數(shù)據(jù)格式 和 數(shù)據(jù)內(nèi)容 。其中,數(shù)據(jù)格式的默 認值為空字符串、數(shù)據(jù)內(nèi)容的默認值為空數(shù)組。 獲取數(shù)據(jù)庫連接后,利用 mysqli_prepare()預處理 SQL語句,獲取 $stmt 數(shù)據(jù)內(nèi)容為空,利用 mysqli_stmt_ex
10、ecute()直接執(zhí)行 SQL語句。 數(shù)據(jù)內(nèi)容不為空,則執(zhí)行自定義函數(shù) db_bind_param()進行參數(shù)綁定后,再 執(zhí)行 SQL語句 最后返回預處理結果 $stmt 任務一:項目準備 數(shù)據(jù)庫函數(shù) 執(zhí)行 SQL語句 編寫函數(shù) db_bind_param(),完成 SQL語句的參數(shù)綁定 該函數(shù)的 參數(shù)依次 $stmt、數(shù)據(jù)格式和引用傳遞的數(shù)據(jù)內(nèi)容 利用 $params保存預處理函數(shù) mysqli_stmt_bind_param()需要的每個參數(shù) 首先依次保存前兩個參數(shù) $stmt和數(shù)據(jù)格式 由于 mysqli_stmt_bind_param()的參數(shù)綁定需要引用傳參,因此通過遍歷數(shù) 據(jù)內(nèi)容,
11、為每個參數(shù)創(chuàng)建引用,并依次賦值給 $param 最后調用 mysqli_stmt_bind_param()函數(shù)完成參數(shù)的綁定 任務一:項目準備 數(shù)據(jù)庫函數(shù) 示例演示 /準備 SQL語句 $sql = INSERT INTO cms_category (name, sort) VALUES (?, ?); /執(zhí)行 SQL語句 db_query($sql, si, test, 0); 第二個參數(shù) si,表示插入數(shù)據(jù)的類型 s表示字符串 i表示整型 任務一:項目準備 數(shù)據(jù)庫函數(shù) 批量操作 在 db_query()函數(shù)中,第 3個參數(shù)用于傳入數(shù)據(jù)內(nèi)容,目前只支持一維數(shù)組。 MySQLi擴展的預處理機制
12、還可以實現(xiàn)批量操作。 因此,還可以改進 db_query()函數(shù),當傳入數(shù)據(jù)內(nèi)容是二維數(shù)組時,自動 進行批量操作。 任務一:項目準備 數(shù)據(jù)庫函數(shù) 批量操作 在 db_query()函數(shù)實現(xiàn)參數(shù)綁定的位置進行修改 首先進行預處理操作的參數(shù)綁定并執(zhí)行預處理操作 然后刪除執(zhí)行完的數(shù)據(jù) 最后批量執(zhí)行剩余的其他數(shù)據(jù) 任務一:項目準備 數(shù)據(jù)庫函數(shù) 示例演示 /準備 SQL語句 $sql = INSERT INTO cms_category (name, sort) VALUES (?, ?); /準備數(shù)據(jù) $data = aa, 1, bb, 12, cc, 30; /執(zhí)行 SQL語句 db_query(
13、$sql, si, $data); 任務一:項目準備 數(shù)據(jù)庫函數(shù) 其他數(shù)據(jù)庫操作 在數(shù)據(jù)庫操作中,除了執(zhí)行 SQL語句,還需要處理結果集、獲取受影響行 數(shù)、獲取最后插入的 ID等后續(xù)操作。接下來繼續(xù)完善數(shù)據(jù)庫操作函數(shù) 。 任務一:項目準備 數(shù)據(jù)庫函數(shù) 其他數(shù)據(jù)庫操作 定義常用常量,用于表示后續(xù)的具體操作 定義函數(shù) db_fetch(),處理有結果集的 SQL語句;定義函數(shù) db_exec(),處理 沒有結果集的 SQL語句。 兩個函數(shù)的參數(shù)依次為后續(xù)的操作, SQL語句,數(shù)據(jù)格式和數(shù)據(jù)內(nèi)容 最后結合 switch語句根據(jù)不同的操作,執(zhí)行不同的處理函數(shù) 任務一:項目準備 數(shù)據(jù)庫函數(shù) 示例演示 /
14、 查詢數(shù)據(jù),獲得保存所有結果的關聯(lián)數(shù)組 $data = db_fetch(DB_ALL, SELECT * FROM cms_category); var_dump($data); / 插入數(shù)據(jù),獲得最后插入的 ID $sql = INSERT INTO cms_category (name, sort) VALUES (?, ?); $id = db_exec(DB_LASTID, $sql, si, test, 0); echo $id; 任務一:項目準備 輸入過濾函數(shù) 在項目開發(fā)中,對于 $_GET、 $_POST數(shù)組的訪問是非常頻繁的,但是這兩 個數(shù)組保存的是來自外部提交的數(shù)據(jù),如果直
15、接進行訪問,會帶來安全隱患。 因此,通過函數(shù)來統(tǒng)一接收外部變量,可以使項目代碼更加嚴謹和規(guī)范。接 下來,在 commonfunction.php中編寫 I()函數(shù)用于接收外部變量 。 任務一:項目準備 輸入過濾函數(shù) 該函數(shù)名取自英文單詞“ input”的首字母,表示輸入。 該函數(shù)的參數(shù)依次為需要處理的變量名、接收方法、數(shù)據(jù)類型、默認值 根據(jù)接收方法確定數(shù)據(jù)變量使用哪種接收類型 通過 isset()判斷接收的數(shù)據(jù)變量是否存在,若不存在將其值設為默認值 結合 switch和數(shù)據(jù)類型進行不同的過濾處理,具體有字符串型、 html轉義、整 數(shù)、無符號整數(shù)、頁碼、浮點數(shù)、布爾型、數(shù)組型。 任務一:項目準
16、備 輸入過濾函數(shù) 結合 htmlspecialchars()函數(shù)把一些預定義的 HTML 實體轉換為字符,并設置 第二個參數(shù) ENT_QUOTES完成對單引號和雙引號的轉義操作。 結合 trim()函數(shù)去除字符串首尾處的空白字符(或者其他字符) 結合 str_replace()函數(shù)將字符串中的空格替換成 其中 , 在對數(shù)據(jù)進行 HTML特殊字符轉義時,為方便管理和操作,接下來在 commonfunction.php中實現(xiàn)該函數(shù) toHTML()。具體思路如下: 任務一:項目準備 輸入過濾函數(shù) 示例演示 / POST方式 $_POSTname = 測試 ; $name = I(name, pos
17、t, html); echo $name; /輸出結果:測試 文本 / GET方式 $_GETid = 123abc; $id = I(id, get, id); echo $id; /輸出結果: 123 任務一:項目準備 后臺頁面布局 下面開始進入網(wǎng)站后臺頁面的開發(fā)。在設計后臺頁面時,通常使用“品” 字形的頁面布局,此布局的具體結構如圖 。 t o p n a v c o n t e n t top是頁面的頂部,通常用于顯示系統(tǒng) 名稱、相關鏈接; nav是頁面的左側導航菜單,后臺中的 各個功能模塊通過這個菜單進入; content是頁面內(nèi)容,根據(jù)當前訪問的 功能而改變。 任務一:項目準備 后
18、臺頁面布局 在 adminview目錄中創(chuàng)建后臺的布局文件 layout.html,頁面頂部和 左側導航 標簽中添加響應 ,頁面內(nèi)容部分嵌套一個框架,用于動態(tài)改變內(nèi)容 創(chuàng)建后臺首頁 adminindex.php,載入后臺初始化文件和布局文件 接下來 在當前目錄下, 創(chuàng)建 admincp_index.php文件 ,載入后臺首頁信息 創(chuàng)建文件 adminviewindex.html,該文件是后臺首頁的 HTML模板文件 任務一:項目準備 后臺頁面布局 后臺頁面布局展示圖 任務一:項目準備 實現(xiàn)管理員登錄 添加管理員信息 在管理員表中添加初始數(shù)據(jù),具體字段應包括 ID、用戶名和密碼, SQL 語句如
19、下。 INSERT INTO cms_admin VALUES (1, admin, 123456); 任務二:管理員登錄 實現(xiàn)管理員登錄 創(chuàng)建后臺登錄表單 在后臺 adminview中創(chuàng)建后臺用戶登錄的 HTML表單 login.html。 用戶名: 密 碼: 任務二:管理員登錄 實現(xiàn)管理員登錄 載入數(shù)據(jù)庫操作函數(shù) 修改前后臺的初始化文件 admininit.php,載入數(shù)據(jù)庫操作函數(shù) db.php。 將數(shù)據(jù)庫操作函數(shù)載入后,在項目中就可以使用來自 db.php中的函數(shù)。 任務二:管理員登錄 實現(xiàn)管理員登錄 接收登錄表單 創(chuàng)建后臺登錄文件 adminlogin.php,實現(xiàn)載入 HTML模板
20、顯示登錄頁面,當 接收到提交的登錄表單時處理表單。 任務二:管理員登錄 實現(xiàn)管理員登錄 接收登錄表單 載入后臺初始化文件 init.php和表單模板文件 login.html 通過 if與 $_POST處理提交后的表單內(nèi)容 在處理表單時,先通過 I()函數(shù)接收用戶名和密碼,到數(shù)據(jù)庫中查詢信息,然后取 出密碼后進行驗證。 如果驗證通過,則將用戶登錄信息保存到 Session中,然后利用自定義 redirect() 函數(shù)跳轉到后臺首頁 index.php 如果驗證失敗,則調用 E()函數(shù)停止程序繼續(xù)執(zhí)行。 任務二:管理員登錄 實現(xiàn)管理員登錄 接收登錄表單 接下來在 commonfunction.p
21、hp中編寫用于實現(xiàn)頁面跳轉的 redirect()函數(shù)。 function redirect($url) header(Location:$url); /重定向到目標 URL地址 exit; 任務二:管理員登錄 頁面信息提示 當 PHP處理用戶提交表單時,如果在處理過程中發(fā)生了成功或失敗的信息,應 該以友好的提示信息在頁面中顯示。 為了利于程序的維護,可以將載入 HTML頁面的代碼放到一個函數(shù)中,通過調 用函數(shù)的方式來決定程序在什么情況下顯示頁面。 任務二:管理員登錄 頁面信息提示 編寫顯示頁面的函數(shù) 接下來在 adminlogin.php中編寫 display()函數(shù),將載入 HTML模板的
22、代碼放 到函數(shù)中 。 function display($msg=null) require ./view/login.html; exit; 任務二:管理員登錄 頁面信息提示 在頁面中輸出提示信息 編輯后臺登錄頁面 adminviewlogin.html,在頁面中添加 元素用于 顯示信息提示。 任務二:管理員登錄 頁面信息提示 在頁面中輸出提示信息 在 commonfunction.php中編寫該函數(shù) tips()輸出提示信息。 function tips($msg=null) if(!$msg) return ; /沒有提示信息時直接返回空字符串 return $msg0 ? $msg1
23、: $msg1; tips()函數(shù)的參數(shù) $msg用于傳入一個數(shù)組,數(shù)組的第 1個元素表示成功或失敗 第 2個元素是表示提示信息 當省略參數(shù) $msg,或 $msg為空時,直接返回空字符串,表示沒有提示信息 任務二:管理員登錄 頁面信息提示 顯示頁面并提示信息 在完成信息提示功能后,修改 adminlogin.php中登錄失敗的提示代碼 /修改前的代碼: /E(登錄失?。河脩裘蛎艽a錯誤。 ); /修改后的代碼: display(false, 登錄失?。河脩裘蛎艽a錯誤。 ); 任務二:管理員登錄 頁面信息提示 沒有表單提交時顯示頁面 在完成創(chuàng)建 display()函數(shù)后,當沒有表單提交時,應
24、顯示登錄頁面 if($_POST) /有表單提交時,處理表單 else /沒有表單提交時,顯示登錄頁面 display(); 任務二:管理員登錄 頁面信息提示 效果展示 任務二:管理員登錄 判斷登錄狀態(tài) 在實現(xiàn)了用戶登錄功能后,還需要判斷用戶是否登錄,如果沒有登錄則提 示用戶進行登錄,并阻止用戶訪問本來的功能。 任務二:管理員登錄 判斷登錄狀態(tài) 在后臺中, Session操作是項目中的公共功能,為了更好地維護項目中的 Session,可以在初始化文件中統(tǒng)一開啟 Session,并為項目中的 Session創(chuàng)建前 綴。修改文件 admininit.php,具體如下: 開啟 Session /啟動
25、 session session_start(); /為項目創(chuàng)建 Session,統(tǒng)一保存到 cms中 if(!isset($_SESSIONcms) $_SESSION = cms = ; 任務二:管理員登錄 判斷登錄狀態(tài) 接下來在 admininit.php中繼續(xù)編寫代碼,實現(xiàn)檢查用戶登錄。 檢查用戶登錄 判斷是否已經(jīng)定義了 NO_CHECK_LOGIN常量 如果沒有定義則檢查用戶是否登錄,如果已經(jīng)定義了則不檢查用戶是否登錄 當用戶登錄時,取出用戶信息保存到變量 $user中 如果沒有登錄則跳轉到登錄頁面 login.php并停止腳本繼續(xù)執(zhí)行 當其他腳本載入這個文件時,就會自動判斷用戶是否
26、登錄,而如果不需要判斷 登錄,則在載入 admininit.php之前,先定義 NO_CHECK_LOGIN常量。 任務二:管理員登錄 判斷登錄狀態(tài) 在 adminlogin.php文件中,當用戶登錄成功時,將用戶信息( ID和用戶名)保 存到了 Session中。 在 admininit.php中判斷用戶是否登錄,如果已經(jīng)登錄,則從 Session中取出用 戶信息,保存到 $user中。 當用戶登錄成功后進入后臺首頁時,可通過輸出 $user將用戶名顯示在頁面中。 顯示當前登錄的用戶名 任務二:管理員登錄 判斷登錄狀態(tài) 效果展示 任務二:管理員登錄 登錄驗證碼 在開發(fā)管理員登錄功能時,還要考
27、慮一個問題,就是除了瀏覽器,其他軟 件也可以向服務器提交數(shù)據(jù)。 從系統(tǒng)安全的角度看,如果使用軟件自動大批量向服務器提交表單,那么 管理員的用戶名、密碼將會被窮舉出來,導致管理員賬號被盜取。為此,驗證 碼就是一種防御的手段。 任務二:管理員登錄 登錄驗證碼 通常情況下,驗證碼是一張帶有文字的圖片,要求用戶輸入圖中的文字。 對于圖片中的文字,人類識別非常容易,而軟件識別非常困難。 因此,驗證碼是一種區(qū)分人類和計算機的程序。接下來,就在項目中實現(xiàn) 驗證碼的功能。 任務二:管理員登錄 登錄驗證碼 生成驗證碼文本 在項目中創(chuàng)建 commoncaptcha.php,該文件用于保存驗證碼相關的函數(shù)。 編寫
28、captcha_create()函數(shù) , 用于生成指定位數(shù)的驗證碼 該函數(shù)有一個參數(shù),用于 表示生成 文本的 位數(shù) ,默認值為 5 從 $charset字符串中隨機取出 $count個字符,保存到 $code中 調用該 函數(shù)后,返回生成的驗證碼文本 任務二:管理員登錄 登錄驗證碼 生成驗證碼圖像 通過 PHP提供的 GD庫擴展,可以繪制一張圖片。在繪制圖片時,可以將文 本寫入到圖片中 。 任務二:管理員登錄 登錄驗證碼 生成驗證碼圖像 在 commoncaptcha.php中繼續(xù)編寫代碼,實現(xiàn)輸出驗證碼圖像的函數(shù)。 編寫 captcha_show()函數(shù) , 用于驗證碼圖像 該函數(shù)有一個參數(shù),
29、用于表示驗證碼文本 創(chuàng)建圖片資源,隨機生成背景顏色, 設置字體顏色和樣式 生成指定長度的驗證碼 添加 8個干擾線 和 250個噪點 向瀏覽器輸出 PNG格式的 驗證碼圖片 任務二:管理員登錄 登錄驗證碼 調用驗證碼函數(shù) 在完成了驗證碼文本和圖像生成的函數(shù)后,接下來在后臺中調用函數(shù)顯示 驗證碼。 創(chuàng)建文件 admincaptcha.php,完成驗證碼函數(shù)的調用 載入驗證碼函數(shù) 文件 commoncaptcha.php 生成驗證碼值 輸出驗證碼圖像 , 將驗證碼保存到 Session中 任務二:管理員登錄 登錄驗證碼 顯示驗證碼 在完成驗證碼的調用后,接下來在后臺管理員登錄的表單中顯示驗證碼。修
30、改登錄表單 adminviewlogin.html,在表單中使用 載入驗證碼圖片 。 驗證碼: 任務二:管理員登錄 登錄驗證碼 效果展示 任務二:管理員登錄 登錄驗證碼 判斷驗證碼 在用戶提交表單后,在判斷用戶名和密碼之前,應該先判斷驗證碼是否正確。 如果驗證碼有誤,則沒有必要繼續(xù)判斷用戶名和密碼。 任務二:管理員登錄 登錄驗證碼 判斷驗證碼 通過 I()函數(shù)獲取用戶輸入的驗證碼 載入驗證碼函數(shù) 調用自定義函數(shù) checkCode()驗證用戶輸入的驗證碼是否正確 若驗證錯誤,則顯示驗證碼驗證失敗 若驗證正確,接著繼續(xù)驗證用戶名和密碼是否正確 任務二:管理員登錄 登錄驗證碼 判斷驗證碼 接著自定
31、義函數(shù) checkCode() 該函數(shù)的參數(shù)是用戶輸入的驗證碼 $code 接著取出保存到 Session中的驗證碼 $captcha 在 $captcha 不為空的情況下,為防止重復驗證,清除驗證碼 在不區(qū)分大小寫的情況下,返回 $code和 $captcha 的比較結果 在 $captcha 為空的情況下,直接返回 false 任務二:管理員登錄 退出登錄 在完成管理員登錄功能后,還需要開發(fā)管理員退出功能。 編輯 adminviewlayout.html文件,在顯示用戶信息的位置,添加一個退出登 錄的鏈接 。 您好, 前臺首頁 退出 任務二:管理員登錄 退出登錄 接下來在 adminlog
32、in.php中接收參數(shù),實現(xiàn)退出功能。 /接收操作參數(shù) $action = I(a, get, string); /執(zhí)行操作 if($action=logout) /退出登錄 unset($_SESSIONcmsadmin); /清除 Session display(true, 您已經(jīng)成功退出。 ); 任務二:管理員登錄 讀取欄目 準備測試數(shù)據(jù) 在管理員登錄后,就可以對欄目進行管理。在項目數(shù)據(jù)庫中,為欄目表添 加測試數(shù)據(jù),用于讀取欄目功能的開發(fā)。添加測試數(shù)據(jù)的 SQL語句如下。 INSERT INTO cms_category (id, pid, name, sort) VALUES (1,
33、0, PHP, 0), (2, 0, Java, 1), (3, 1, PHP基礎 , 0), (4, 1, PHP高級 , 1); 任務三:欄目管理 讀取欄目 讀取欄目數(shù)據(jù) 在項目中,讀取欄目數(shù)據(jù)的需求可能會頻繁出現(xiàn),因此將此功能寫在函數(shù)中。 在 common目錄下創(chuàng)建文件 module.php,用于保存和數(shù)據(jù)相關的功能模塊函數(shù)。 任務三:欄目管理 讀取欄目 讀取欄目數(shù)據(jù) 定義函數(shù) module_category(),用于獲取欄目列表 該函數(shù)的參數(shù) $mode表示索引方式: id 或 pid,默認返回兩種格式 定義一個靜態(tài)變量 $result,用于緩存查詢結果 當?shù)谝淮握{用函數(shù)時,到數(shù)據(jù)庫中
34、獲取數(shù)據(jù),并分別根據(jù) id和 pid 創(chuàng)建數(shù)組索引,方便查找。 最后根據(jù)索引方式返回查詢結果 任務三:欄目管理 編輯欄目 輸出已有欄目 在項目中創(chuàng)建 cp_category.php文件,該文件用于讀取欄目數(shù)據(jù)顯示在 HTML模板中。 在該文件中載入初始化文件 接著定義 display()函數(shù),顯示頁面 從數(shù)據(jù)庫中根據(jù) pid取出數(shù)據(jù),載入 HTML模板文 adminviewcateogory.html 調用函數(shù) display() 任務三:欄目管理 編輯欄目 輸出已有欄目 接下來編寫用于顯示欄目的 adminviewcateogory.html文件。為了提高后臺 管理的操作效率,可以將欄目顯示
35、、添加、修改功能都在一個頁面中完成。 pid的頂級分類為 0 外層循環(huán)輸出頂級欄目 接著判斷該分類下是否存在子欄目,若存在則循環(huán)輸出 任務三:欄目管理 編輯欄目 效果展示 任務三:欄目管理 編輯欄目 添加欄目 在完成已有欄目的輸出后,還需要開發(fā)欄目添加功能,在實現(xiàn)欄目添加時,為 了更直觀地在頁面中添加欄目和子欄目,這里通過 jQuery實現(xiàn)了頁面的靈活處理。 編輯 adminviewcp_category.html文件,在頁面底部添加 JavaScript代碼如下。 任務三:欄目管理 編輯欄目 添加欄目 當單擊頁面中的 class屬性為 jq-add的元素時,就會觸發(fā)點擊事件 在該元素的前面添
36、加 HTML內(nèi)容,內(nèi)容是添加新欄目的輸入框 對于添加表單的 name屬性,這里使用了名稱為 add的二維數(shù)組,其外層用于 區(qū)分多個添加的內(nèi)容,內(nèi)層是 sort、 name、 pid三個字段 由于是頂級欄目,所以 pid的值為 0 頂級分類欄目添加 任務三:欄目管理 編輯欄目 添加欄目 當單擊頁面中的 class屬性為 jq-sub-add的元素時,就會觸發(fā)點擊事件 為“添加子欄目”元素添加 data-id屬性,用于保存子欄目的上級欄目 ID。 添加子欄目的事件函數(shù)中應該先獲取到此 ID,然后保存到隱藏域的 pid字段中。 二級分類欄目添加 任務三:欄目管理 編輯欄目 效果展示 任務三:欄目管理
37、 批量保存 接收表單 調用 addData()函數(shù)添加欄目,調用 saveData()函數(shù)修改欄目 實現(xiàn)接收表單并處理 批量添加 添加欄目的信息保存在了 add二維數(shù)組中 利用 I()函數(shù)接收數(shù)組后保存到數(shù)據(jù)庫中即可 批量修改 批量修改的實現(xiàn)方式和批量添加類似 在接收表單時,修改欄目的信息保存在了 save數(shù)組中 任務三:欄目管理 修改層級 添加編輯鏈接 為每個欄目添加“編輯”超鏈接,鏈接到 cp_category_edit.php文件 同時,傳遞參數(shù) ID,表示編輯指定 ID的欄目 取出指定欄目信息 先取出待編輯欄目的信息,然后取出所有頂級欄目信息 保存信息 在 admincp_catego
38、ry_edit.php中 接收表單數(shù)據(jù),將信息保存到數(shù)據(jù)庫中 任務三:欄目管理 刪除欄目 添加刪除鏈接 在開發(fā)刪除功能時,為了防止誤操作,在執(zhí)行操作前進行彈框提示 執(zhí)行操作 判斷 待刪除 欄目下是否有子級欄目, 若 有則不執(zhí)行刪除操作; 若 沒有 則 刪除 任務三:欄目管理 刪除欄目 效果展示 任務三:欄目管理 刪除欄目 令牌保護 在前面實現(xiàn)刪除功能時,通過一個 URL地址直接實現(xiàn)了刪除數(shù)據(jù),然而這 種方式在 Web開發(fā)中存在安全隱患。 當管理員在登錄系統(tǒng)的狀態(tài)下進行其他操作時,如果訪問了其他用戶惡意 構造的危險 URL地址,就會導致后臺的操作被執(zhí)行,這種安全漏洞稱為 CSRF (跨域請求偽造
39、)。 任務三:欄目管理 刪除欄目 令牌保護 防御 CSRF安全問題的一個有效的措施,是為所有涉及更改數(shù)據(jù)的操作加上 令牌保護,該令牌將在用戶登錄時隨機生成,每個更改的操作都附加上令牌, 沒有令牌時將無法執(zhí)行操作。 任務三:欄目管理 刪除欄目 令牌保護 token_get():利用 md5()和 microtime(true)生成令牌, 將其保存在 Session中 token_check():先從 GET參數(shù)中取出 token,然后再與保存到 Session中的 token 進行比較,判斷是否正確。如果令牌有誤,說明用戶當前的操作是非法的。 在 commonfunction.php中,自定義
40、token_get()和 token_check()函數(shù) 任務三:欄目管理 刪除欄目 令牌保護 在 admininit.php中添加代碼實現(xiàn)令牌的自動生成和驗證 對刪除欄目的操作添加令牌驗證 需要注意的是,為了避免項目中頻繁的令牌驗證影響代碼演示,在 本書后面的開發(fā)步驟中并沒有加上令牌驗證功能。同時為了確保項 目的嚴謹性,在本書的配套源代碼中已經(jīng)全部加上了令牌驗證。 任務三:欄目管理 文章列表 準備測試數(shù)據(jù) 在開發(fā)具體功能前,先向數(shù)據(jù)庫中插入測試數(shù)據(jù) 查詢文章列表 通過文章表和欄目表的左連接查詢,從數(shù)據(jù)庫中獲取到文章列表, 在列表中包含了文章所屬欄目的信息 展示文章列表 編寫代碼輸出文章列表
41、任務四:文章管理 文章列表 效果展示 任務四:文章管理 編輯文章 添加編輯鏈接 當單擊“編輯”鏈接時,訪問 cp_article_edit.php并傳入?yún)?shù) id 查詢指定文章信息 接收 文章 id,顯示修改頁面 如果沒有收到,或 id的值為 0時,直接顯示空表單,用于發(fā)布新文章 顯示文章編輯表單 創(chuàng)建一個表單顯示文章編輯內(nèi)容 輸出欄目列表 下面將欄目輸出到一個下拉菜單中 任務四:文章管理 編輯文章 引入在線編輯器 在 CKEditor的官方網(wǎng)站可以下載此編輯器 將編輯器放入到項目的 adminjs目錄中,并將編輯器目錄命名為“ ckeditor” 在文章編輯頁面 adminviewartic
42、le_edit.html的底部編寫 JavaScript代碼, 實現(xiàn)在線編輯器的引入 。 修改容器的 name屬性值 任務四:文章管理 編輯文章 效果展示 任務四:文章管理 保存文章 接收表單 接收用戶填寫的基本信息 接收由在線編輯器提交的內(nèi)容時,沒有進行 HTML轉義,這是因為 編輯器提交內(nèi)容的本來就是 HTML。 從安全角度來說,服務器端不進行 HTML轉義會帶來安全問題,原因是瀏覽 器端任何限制都可以被繞過。 在項目開發(fā)時,可以考慮使用富文本過濾器(如 HTML Purifier)對 HTML內(nèi) 容進行安全過濾,這部分內(nèi)容將在后面的項目中進行講解。 任務四:文章管理 保存文章 實現(xiàn)文章修
43、改 在執(zhí)行接收表單后的操作時,如果接收到文章 ID,就執(zhí)行文章修改操作。 實現(xiàn)文章添加 在處理表單時,如果沒有接收到文章 ID,就執(zhí)行文章添加操作。 任務四:文章管理 上傳封面圖 檢查上傳文件 在進行添加或修改數(shù)據(jù)之前,先處理上傳文件 在 commonfunction.php中,自定義 check_upload()函數(shù) , 用于判斷上傳文 件是否成功,成功時返回 true,失敗時將錯誤信息保存到 $error中 準備縮略圖函數(shù) 為圖片生成縮略圖 image_thumb 根據(jù)原圖文件創(chuàng)建圖像資源 image_create 保存圖像資源 image_save 任務四:文章管理 上傳封面圖 獲取圖片
44、信息 實現(xiàn) image_thumb()函數(shù)的功能,完成縮略圖的生成 實現(xiàn)圖片等比例縮放 通常會保持圖片比例,防止圖片被拉伸或者壓扁,影響圖片的美觀 生成保存路徑 可以根據(jù)日期為圖片生成子目錄,并為文件自動生成文件名,防止文件名沖突 調用縮略圖函數(shù) 在調用時,需要指定原圖路徑、縮略圖寬高、上傳目錄等信息 任務四:文章管理 上傳封面圖 效果展示 任務四:文章管理 刪除文章 添加刪除鏈接 該功能和欄目刪除時的代碼相同 執(zhí)行刪除操作 當用戶單擊刪除鏈接后,就會向 PHP腳本發(fā)送待刪除的文章 ID參數(shù) 在實際進行文章記錄刪除操作之前,需要先判斷文章是否有封面圖。 如果封面圖存在,就先刪除圖片文件,再刪除
45、文章記錄 任務四:文章管理 列表功能區(qū) 準備排序條件 在 admincp_article.php文章列表程序中編寫代碼,獲取列表相關的 GET參 數(shù),并定義排序的 方式以及對應的 SQL語句 顯示列表功能區(qū) 欄目篩選和列表排序功能是兩個下拉菜單 列表搜索功能是一個文本框 三個功能各放在三個表單中,單擊表單提交按鈕即可完成對應的功能操作。 任務五:排序與搜索 列表功能區(qū) 效果展示 任務五:排序與搜索 組合 SQL語句 組合 ORDER和 WHERE子句 在前面的步驟中,已經(jīng)使用 $cid、 $search、 $order三個變量接收了來自表單提 交的數(shù)據(jù)。接下來就可以根據(jù)這些數(shù)據(jù)組合 SQL語句
46、進行查詢。在文章列表功能 admincp_article.php中繼續(xù)編寫代碼,在接收變量后組合 SQL語句。 /拼接排序條件 $sql_order = ORDER BY $sql_order .= isset($order_arr$order) ? $order_arr$ordersql : a.id DESC; /拼接 WHERE條件 $sql_where = WHERE 1=1 ; $sql_where .= $cid ? AND a.cid IN (.module_category_sub($cid).) : ; $sql_where .= AND a.title LIKE ? ; $
47、sql_search = %.db_escape_like($search).%; 任務五:排序與搜索 組合 SQL語句 根據(jù)欄目 ID取出所有子欄目 ID 下面在 commonmodule.php文件中編寫 module_category_sub()函數(shù),實現(xiàn) 根據(jù)欄目 ID取出所有子欄目 ID的功能。 function module_category_sub($id) $data = module_category(pid); $sub = isset($data$id) ? array_keys($data$id) : ; array_unshift($sub, $id); /將 $id
48、放入數(shù)組開頭 return implode(, $sub); 任務五:排序與搜索 組合 SQL語句 轉義 LIKE搜索字符串 接下來在 commondb.php文件中編寫 db_escape_like()函數(shù),用于實現(xiàn)轉義 LIKE搜索字符串中的所有特殊字符。 function db_escape_like($like) return strtr($like, %=%, _=_, =); 在單引號字符串中書寫“ ”字符時,如果一個“ ”后面跟一個單引號,單引 號將會被轉義成字符串中的字符,而非字符串定界符,因此需要在“ ”前面加一 個“ ”進行轉義(字符串中實際只保存了一個“ ”字符)。 任務
49、五:排序與搜索 組合 SQL語句 修改文章列表查詢 SQL 在完成對 ORDER和 WHERE的組合后,接下來繼續(xù)編寫 admincp_article.php, 修改查詢文章列表數(shù)據(jù)的代碼,將篩選和排序條件加入到 SQL語句中。 $data = db_fetch(DB_ALL, SELECT a.id, a.cid, a.title, a.author, a.show, a.time, c.name AS cname FROM cms_article AS a LEFT JOIN cms_category AS c ON a.cid=c.id. $sql_where $sql_order, s
50、, $sql_search); 任務五:排序與搜索 組合 SQL語句 效果展示 任務五:排序與搜索 分頁顯示信息 分頁查詢原理 實現(xiàn)分頁的原理是對 SQL語句中的 LIMIT進行控制,示例代碼如下。 SELECT title FROM cms_article LIMIT 0, 10; # 獲取第 1頁的 10條數(shù)據(jù) SELECT title FROM cms_article LIMIT 10, 10; # 獲取第 2頁的 10條數(shù)據(jù) SELECT title FROM cms_article LIMIT 20, 10; # 獲取第 3頁的 10條數(shù)據(jù) SELECT title FROM cms
51、_article LIMIT 30, 10; # 獲取第 4頁的 10條數(shù)據(jù) 任務六:分頁導航 分頁顯示信息 分頁查詢原理 LIMIT的第 2個參數(shù)“ 10” 表示每次讀取的最大條數(shù);第 1個參數(shù)與頁碼之 間存在一定的數(shù)學關系,具體如下: LIMIT 第 1個參數(shù) = (頁碼 - 1) * 每頁查詢的條數(shù) 任務六:分頁導航 分頁顯示信息 分頁查詢原理 根據(jù)上述條件,接下來在 common目錄中創(chuàng)建 page.php,用于實現(xiàn)分頁功 能。下面在文件中編寫用于生成 LIMIT參數(shù)的函數(shù)。 ?php /獲取 SQL分頁 Limit( $page表示頁碼, $size表示每頁查詢條數(shù)) functio
52、n page_sql($page, $size) return ($page-1) * $size . , . $size; 任務六:分頁導航 分頁顯示信息 實現(xiàn)分頁查詢數(shù)據(jù) 接下來在文章列表功能 admincp_article.php文件中實現(xiàn)分頁查詢,在 display()函數(shù)中查詢文章列表數(shù)據(jù)之前 , 編寫代碼定義每頁顯示的記錄數(shù)和 頁碼,并調用 page_sql函數(shù)生成 LIMIT參數(shù) 。 任務六:分頁導航 分頁顯示信息 實現(xiàn)分頁查詢數(shù)據(jù) $page = I(page, get, page); /獲取頁碼(限制最小值為 1) $page_size = 3; /每頁顯示 3條記錄 req
53、uire COMMON_PATH.page.php; /載入分頁函數(shù) $sql_limit = LIMIT .page_sql($page, $page_size); /拼接 LIMIT /獲取文章列表時,將 LIMIT放入 SQL語句中 $data = db_fetch(DB_ALL, SELECT a.id, a.cid, a.title, a.author, a.show, a.time, c.name AS cname FROM cms_article AS a LEFT JOIN cms_category AS c ON a.cid=c.id. $sql_where $sql_ord
54、er $sql_limit, s, $sql_search); 任務六:分頁導航 生成分頁導航 獲取總頁數(shù) 查詢出符合 $sql_where條件的總記錄數(shù),通過總記錄數(shù)和每頁顯示的記錄數(shù), 即可計算出總頁數(shù),計算公式為“總記錄數(shù)每頁數(shù)量”,然后向上取整。 例如,總記錄數(shù)為 7,每頁顯示 3條,則 7除以 3的結果大于 2且小于 3,超出第 2頁的記錄在第 3頁顯示,因此總頁數(shù)為 3。 任務六:分頁導航 生成分頁導航 生成分頁導航 生成分頁導航的原理是,根據(jù)當前頁碼和總記錄數(shù),計算出“上一頁”、 “下一頁”、“尾頁”的頁碼值。 其中,為了 在輸出分頁鏈接時攜帶 GET參數(shù) ,獲取原來所有的 GET參數(shù), 清 除原來的 page參數(shù) , 重新構造參數(shù)字符串 并返回。 在 commonpage.php中編寫程序,實現(xiàn)分頁導航的自動生成 。 任務六:分頁導航 生成分頁導航 效果展示 任務六:分頁導航
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 6.煤礦安全生產(chǎn)科普知識競賽題含答案
- 2.煤礦爆破工技能鑒定試題含答案
- 3.爆破工培訓考試試題含答案
- 2.煤礦安全監(jiān)察人員模擬考試題庫試卷含答案
- 3.金屬非金屬礦山安全管理人員(地下礦山)安全生產(chǎn)模擬考試題庫試卷含答案
- 4.煤礦特種作業(yè)人員井下電鉗工模擬考試題庫試卷含答案
- 1 煤礦安全生產(chǎn)及管理知識測試題庫及答案
- 2 各種煤礦安全考試試題含答案
- 1 煤礦安全檢查考試題
- 1 井下放炮員練習題含答案
- 2煤礦安全監(jiān)測工種技術比武題庫含解析
- 1 礦山應急救援安全知識競賽試題
- 1 礦井泵工考試練習題含答案
- 2煤礦爆破工考試復習題含答案
- 1 各種煤礦安全考試試題含答案