摘要
在此記錄一下阿里百秀專案的教學視訊的學習筆記,部分頁面被我修改了,某些頁面效果會不一樣,基本操作是一致的,好記性不如爛筆頭,加油叭!!!
step 1 : 整合全部靜態頁面
-
將靜態頁面全部拷貝到 admin 目錄中。
-
將副檔名由 .html 改為 .php ,頁面中的 a 連結也需要調整。
-
調整頁面檔案中的靜態資源路徑,將原本的相對路徑調整為絕對路徑。
在 sublime 工具中選中資料夾 admin 右擊 --> 查詢&&替換
step 2 : 抽離公共部分
由於每一個頁面中都有一部分程式碼(側邊欄和頭部)是相同的,分散到各個檔案中,不便於維護,所以應該分別抽象到一個公共的檔案中。
- 在 admin 目錄中建立一個 com (common 的簡稱)的資料夾
- 在這個目錄裡建立一個 sidebar.php 和 nav.php 文 件
- 隨便在一個檔案中(eg: index.php)找到側邊欄和頭部的程式碼片段將程式碼抽離出來
com / sidebar.php
<div class="aside">
<div class="profile">
<img class="avatar" src="../uploads/avatar.jpg">
<h3 class="name">布頭兒</h3>
</div>
<ul class="nav">
<li class="active">
<a href="index.php"><i class="fa fa-dashboard"></i>儀表盤</a>
</li>
<li>
<a href="#menu-posts" class="collapsed" data-toggle="collapse">
<i class="fa fa-thumb-tack"></i>文章<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-posts" class="collapse">
<li><a href="posts.php">所有文章</a></li>
<li><a href="post-add.php">寫文章</a></li>
<li><a href="categories.php">分類目錄</a></li>
</ul>
</li>
<li>
<a href="comments.php"><i class="fa fa-comments"></i>評論</a>
</li>
<li>
<a href="users.php"><i class="fa fa-users"></i>使用者</a>
</li>
<li>
<a href="#menu-settings" class="collapsed" data-toggle="collapse">
<i class="fa fa-cogs"></i>設定<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-settings" class="collapse">
<li><a href="nav-menus.php">導航選單</a></li>
<li><a href="slides.php">圖片輪播</a></li>
<li><a href="settings.php">網站設定</a></li>
</ul>
</li>
</ul>
</div>
com/nav.php
<nav class="navbar">
<button class="btn btn-default navbar-btn fa fa-bars"></button>
<ul class="nav navbar-nav navbar-right">
<li><a href="profile.html"><i class="fa fa-user"></i>個人中心</a></li>
<li><a href="login.html"><i class="fa fa-sign-out"></i>退出</a></li>
</ul>
</nav>
- 在每一個需要這個模組的頁面中通過 include 載入 sidebar.php
<?php include 'com/sidebar.php' ;?>
- 在每一個需要這個模組的頁面中通過 include 載入 nav.php ,載入到 main 中
<div class="main">
<?php include 'com/nav.php';?>
</div>
step 3 : 實現側邊欄對應到相應頁面顯示高亮
由於側邊欄在不同頁面時, active class name 出現的位置不盡相同,所以我們需要區分當前 sidebar.php 檔案是 在哪個頁面中載入的,從而明確焦點狀態。
每一個選單項 li <元素:
<li<?php echo $current_page == 'dashboard' ? ' class="active"' : ''; >>
<a href="index.php"><i class="fa fa‐dashboard"></i>儀表盤</a> </li>
對於有子選單的選單項,有一點例外:
<li <?php echo in_array($current_page,$menu_posts) ? 'class="active" ': ''?>>
<a href="#menu-posts" class="collapsed" data-toggle="collapse">
<i class="fa fa-file-text"></i>文章管理<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-posts" class="collapse<?php echo in_array($current_page, array('posts', 'post-add', 'categories')) ? ' in' : ''; ?>">
<li<?php echo $current_page == 'posts' ? ' class="active"' : ''; ?>><a href="posts.php">所有文章</a></li>
<li<?php echo $current_page == 'post-add' ? ' class="active"' : ''; ?>><a href="post-add.php">寫文章</a></li>
<li<?php echo $current_page == 'categories' ? ' class="active"' : ''; ?>><a href="categories.php">分類目錄</a></li>
</ul>
</li>
sliderbar.php
//php部分
$current_page = isset($current_page) ? $current_page : '';
//html部分
<div class="aside">
<div class="profile">
<img class="avatar" src="/static/uploads/avatar.jpg">
<h3 class="name">布頭兒</h3>
</div>
<ul class="nav">
<li<?php echo $current_page == 'dashboard' ? ' class="active"' : ''; ?>>
<!-- fa fa-dashboard -->
<a href="index.php"><i class="fa fa-list"></i>Home</a>
</li>
<?php $menu_posts = array('posts','post-add','categories');?>
<li <?php echo in_array($current_page,$menu_posts) ? 'class="active" ': ''?>>
<a href="#menu-posts" class="collapsed" data-toggle="collapse">
<i class="fa fa-file-text"></i>文章管理<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-posts" class="collapse<?php echo in_array($current_page, array('posts', 'post-add', 'categories')) ? ' in' : ''; ?>">
<li<?php echo $current_page == 'posts' ? ' class="active"' : ''; ?>><a href="posts.php">所有文章</a></li>
<li<?php echo $current_page == 'post-add' ? ' class="active"' : ''; ?>><a href="post-add.php">寫文章</a></li>
<li<?php echo $current_page == 'categories' ? ' class="active"' : ''; ?>><a href="categories.php">分類目錄</a></li>
</ul>
</li>
<li<?php echo $current_page == 'comments' ? ' class="active"' : ''; ?>>
<a href="comments.php"><i class="fa fa-comments"></i>評論管理</a>
</li>
<li<?php echo $current_page == 'users' ? ' class="active"' : ''; ?>>
<a href="users.php"><i class="fa fa-user-circle-o"></i>使用者管理</a>
</li>
<?php $menu_settings = array('nav-menus','slides','settings');?>
<li <?php echo in_array($current_page,$menu_settings) ? 'class="active" ': ''?>>
<a href="#menu-settings" class="collapsed" data-toggle="collapse">
<i class="fa fa-wrench"></i>系統設定<i class="fa fa-angle-right"></i>
</a>
<ul id="menu-settings" class="collapse<?php echo in_array($current_page, array('nav-menus', 'slides', 'settings')) ? ' in' : ''; ?>">
<li<?php echo $current_page == 'nav-menus' ? ' class="active"' : ''; ?>><a href="nav-menus.php">導航選單</a></li>
<li<?php echo $current_page == 'slides' ? ' class="active"' : ''; ?>><a href="slides.php">圖片輪播</a></li>
<li<?php echo $current_page == 'settings' ? ' class="active"' : ''; ?>><a href="settings.php">網站設定</a></li>
</ul>
</li>
</ul>
</div>
comments.php
<?php $current_page='comments';?>
users.php
<?php $current_page = 'users'; ?>
settings.php
<?php $current_page='settings';?>
.....
所有需要跳轉頁面顯示高亮狀態的頁面以此類推都加上 $current_pag 變數
step 4 : 處理登入頁面
調整HTML頁面
- 將 login.php 中的登入連線換成 button 按鈕
<a class="btn btn-primary btn-block btn-login" href="index.php">登 錄</a>
<button class="btn btn-primary btn-block btn-login">登入</button>
- 往表單元素中新增相應的屬性 method 與 action
<form class="login-wrap">
<form class="login-wrap" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>" >
- 給郵箱和密碼框新增 name 屬性
<input id="email" name="email" type="email" class="form-control" placeholder="郵箱" autofocus>
<input id="password" name="password" type="password" class="form-control" placeholder="密碼">
處理執行PHP指令碼
- 專案配置檔案
由於在接下來的開發過程中,肯定有一部分公共的成員,例如資料庫名稱,資料庫主機,資料庫使用者名稱密碼等,這些資料應該放到公共的地方,抽象成一個配置檔案 config.php 放到專案根目錄下。
這個配置檔案採用定義常量的方式定義配置成員:
config.php
<?php
define('DB_HOST','127.0.0.1');
/**
* 資料庫使用者名稱
*/
define('DB_USER','root');
/**
* 資料庫密碼
*/
define('DB_PASS', '');
/**
* 資料庫名稱
*/
define('DB_NAME', 'demo');
- 載入 config.php 檔案
require_once '../config.php';
- 合法化校驗及錯誤資訊展示
if(empty($_POST['email'])){
$GLOBALS['message'] = '請輸入郵箱';
return;
}
if(empty($_POST['password'])){
$GLOBALS['message'] = '請輸入密碼';
return;
}
- 接收資料
$email = $_POST['email'];
$password = $_POST['password'];
5.校驗郵箱與密碼(假資料)
if($email !== 'admin@qx.com'){
$GLOBALS['message'] = '密碼與郵箱不匹配';
return;
}
if($password !== '123'){
$GLOBALS['message'] = '密碼與郵箱不匹配';
return;
}
- 表單狀態保持
在輸出 時為其新增一個 value 屬性,值就是 $_POST['email']
<input id="email" name="email" type="email" class="form‐control" value="<?php echo isset($_POST['email']) ? $_POST['email'] : ''; ?>" placeholder="郵箱" autofocus>
step 5 : 錯誤訊息的呈現
當驗證郵箱與密碼不匹配時,頁面彈出錯誤資訊
- 引入 bootstarp 樣式檔案
<link rel="stylesheet" href="/static/assets/vendors/bootstrap/css/bootstrap.css">
- 判斷資訊是否呈現
login.php
<?php if (isset($message)) : ?>
<div class="alert alert-danger">
<strong>錯誤!</strong><?php echo $message; ?>
</div>
<?php endif; ?>
<!-- 有錯誤資訊時展示 -->
<!-- <div class="alert alert-danger">
<strong>錯誤!</strong> 使用者名稱或密碼錯誤!
</div> -->
step 6 : 錯誤資訊呈現的動畫效果
- 官網下載動畫樣式檔案 https://animate.style/#migration
- 引入 animate.css 檔案
<link rel="stylesheet" href="/static/assets/vendors/animate/animate.css">
- 選擇錯誤資訊呈現的動畫效果
<h1 class="callout-title">Animate.css</h1>
//當選擇任意一個動畫效果時,會發現中有動畫效果的類名新增
栗子:當點選 rubberBand 這個動畫時,會在class中新增相應的動畫效果的類名
animate__animated animate__rubberBand
- 在表單中判斷是否加入產生動畫效果的類
<form class="login-wrap <?php echo isset($message) ?
'animate__animated animate__rubberBand' : ''; ?>"
method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>"
novalidate autocomplete="off">
//novalidate取消瀏覽器自定義的資訊提示
//autocomplete="off"取消歷史記錄客戶端自動完成功能提示
step 7 : 登入功能的實現
來吧展示:
資料庫連線查詢
- 連線資料庫
// 連線資料庫
$conn = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
mysqli_query($conn,'set names utf8');
if(!$conn){
exit('<h1>連線資料庫失敗</h1>');
}
- 根據郵箱查詢使用者
// 根據郵箱查詢使用者資訊,limit 是為了提高查詢效率
$query = mysqli_query($conn, "select * from users where email = '{$email}' limit 1;");
if (!$query) {
$GLOBALS['message'] = '登入失敗,請重試!';
return;
}
- 使用者密碼比對
其中,密碼在資料庫中儲存的時候要進行加密,百度搜md5線上加密
網址:https://md5jiami.51240.com/
將資料庫中的密碼換成自己在 md5 加密的 32位 密文
login.php
// 獲取登入使用者
$user = mysqli_fetch_assoc($query);
if (!$user) {
// 使用者名稱不存在
$GLOBALS['message'] = '郵箱與密碼不匹配';
return;
}
// 一般密碼是加密儲存的
if ($user['password'] !== md5($password)) {
// 密碼不正確
$GLOBALS['message'] = '郵箱與密碼不匹配';
return;
}
- 訪問控制及登陸狀態保持 (用來防止使用者不登陸直接跳轉到其他頁面)
// 將使用者資訊存放在session中
$_SESSION['current_login_user'] = $user;
header('Location:/admin/');
}
- 將之前的(1~4步驟)使用者密碼驗證封裝成一個 login 函式, 如果是 POST 提交則處理登入業務邏輯
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
login();
}
- 整合程式碼
login.php
require_once '../config.php';
// 判斷使用者是否登入,防止使用者不登陸直接跳轉到其他頁面
session_start();
function login(){
if(empty($_POST['email'])){
$GLOBALS['message'] = '請輸入郵箱';
return;
}
if(empty($_POST['password'])){
$GLOBALS['message'] = '請輸入密碼';
return;
}
$email = $_POST['email'];
$password = $_POST['password'];
// 連線資料庫
$conn = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
//防止頁面出現亂碼(中文顯示帶?問號)
mysqli_query($conn,'set names utf8');
if(!$conn){
exit('<h1>連線資料庫失敗</h1>');
}
$query = mysqli_query($conn, "select * from users where email = '{$email}' limit 1;");
if (!$query) {
$GLOBALS['message'] = '登入失敗,請重試!';
return;
}
// 獲取登入使用者
$user = mysqli_fetch_assoc($query);
if (!$user) {
// 使用者名稱不存在
$GLOBALS['message'] = '郵箱與密碼不匹配';
return;
}
// 一般密碼是加密儲存的
if ($user['password'] !== md5($password)) {
// 密碼不正確
$GLOBALS['message'] = '郵箱與密碼不匹配';
return;
}
//假資料
// if($email !== 'admin@qq.com'){
// $GLOBALS['message'] = '密碼與郵箱不匹配';
// return;
// }
// if($password !== '123'){
// $GLOBALS['message'] = '密碼與郵箱不匹配';
// return;
// }
// 將使用者資訊存放在session中
$_SESSION['current_login_user'] = $user;
header('Location:/admin/');
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 如果是 POST 提交則處理登入業務邏輯
login();
}
- 在每個頁面開頭部分加入session狀態的判斷
栗子: index.php
session_start();
if(empty($_SESSION['current_login_user'])){
header('Location:/admin/login.php');
}
step 8 : 封裝公共函式
由於接下來的操作(開發)過程中會有很多需要查詢資料庫和判斷使用者是否登入的地方。如果每次都按照最原始的方法去寫過於麻煩。 我們應該將重複的地方提取出來,封裝一個公共的函式,方便後期呼叫和維護。
functions.php
<?php
require_once 'config.php';
//1. 封裝判斷使用者是否登入資訊,防止使用者不登陸直接跳轉到其他頁面
session_start();
function get_userinfo(){
if(empty($_SESSION['current_login_user'])){
header('Location:/admin/login.php');
exit();
}
return $_SESSION['current_login_user'];
}
//2.封裝資料庫查詢,簡化每次查詢次數麻煩
// 得先引入config.php檔案,在檔案開頭引入
// 封裝多條資料
function mysql_all($sql){
$conn = mysqli_connect(DB_HOST,DB_USER,DB_PASS,DB_NAME);
// $conn -> query("set names utf8");
mysqli_query($conn,'set names utf8');
if(!$conn){
exit('連線失敗');
}
$query = mysqli_query($conn,$sql);
if(!$query){
return false;
}
$result = array();
while ($row = mysqli_fetch_assoc($query)) {
$result[] = $row;
}
mysqli_free_result($query);
mysqli_close($conn);
return $result;
}
// 封裝單條資料
function mysql_one ($sql) {
$res = mysql_all($sql);
return isset($res[0]) ? $res[0] : null;
}
// 封裝增刪改資料
function mysql_change ($sql) {
$conn = mysqli_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
mysqli_query($conn,'set names utf8');
if (!$conn) {
exit('連線失敗');
}
$query = mysqli_query($conn, $sql);
if (!$query) {
// 查詢失敗
return false;
}
// 對於增刪修改類的操作都是獲取受影響行數
$affected_rows = mysqli_affected_rows($conn);
mysqli_close($conn);
return $affected_rows;
}