php伺服器接口

三套方案 mysql mysqli pdo
1、mysql擴展庫 效率不怎麼高的伺服器
2、mysqli擴展庫
3、pdo 可以操作任何一種伺服器
mysql擴展庫和mysqli的擴展庫,擴展庫就是操作伺服器的一個集合
mysql伺服器是用於存放數據的
可以查看php可以使用的擴展庫 phpinfo();
創建新表

CREATE table  user(
  id int primary key auto_increment,
  name varchar(32) not NULL,
  PASSWORD  VARCHAR(64) not NULL,
   emial VARCHAR(128) not NULL,
  age   TINYINT UNSIGNED not NULL
) 

預先加載數據
mysql中密碼的處理,對一個明文加密成一個密文,而且這個過程是不可逆的。由密文推不出明文。
INSERT INTO user(name,password,emial,age) values(‘zs’,MD5(‘123456’),’1051743154@qq.com’,12)其中md5這個函數就是實現對密碼的加密
解決伺服器不能插入中文
INSERT INTO user(name,password,emial,age) values(‘趙文娟’,MD5(‘123432326’),’1051743154@qq.com’,12)
中文在伺服器就不能正常的顯示
新建伺服器的時候一定要選擇正確的編碼格式
php利用擴展庫操作mysql
1、獲取連接
connection=mysqlconnect(“127.0.0.1”,”root”,”“);if(!connection){
die(“連接失敗”.mysql_error);
}
2、選擇伺服器
mysql_select_db(“senjintang”);
3、設置操作編碼
mysql_query(“set names utf8”); 出現中文亂碼的時候可以嘗試使用
4、向伺服器發送指令sql(ddl數據定義語言 創建表 dml數據操作語言 dql數據查詢語句select dtl數據事物語句 rollback commit)
res=mysqlquery(sql,connection);5、接受返回的結果並處理while(row=mysql_fetch_row(res))echo“$row[0]??$row[1]–$row[2]??$row[3]–$row[4]”;mysqlfetchrow(res) 返回一個索引數組
mysql_fetch_assoc(res)返回一個關聯數組mysqlfetcharray(res) 返回索引數組和關聯數組兩套
mysql_fetch_object(res)把一行數據當作一個對象mysqlfetchrow(res)返回的是結果集的下一行,會一次取出結果集中的下一行
但是這資格函數使用完以後,都必須釋放資源
6、釋放資源,關閉連接
mysql_free_result($res); //釋放結果集
mysql_close(); //關閉連接 不是必須的,會在腳本執行完以後自動關閉
mysqli_error() 可以打印連接的錯誤
註意:在對伺服器執行dml(非select的伺服器查詢以後),一定不要再進行釋放資源,也就是 mysql_free_result(res);因為當前的res是一個佈爾值。所以:對數據的操作嚴格的區分有無結果集的的返回。

對mysql伺服器進行crud操作 使用的是mysql_

實現對伺服器的插入操作

 //server的名稱  伺服器的用戶名和密碼
    $connection=mysql_connect("127.0.0.1","root","");
    if(!$connection){
       die("連接失敗".mysql_error);
    }
    mysql_select_db("senjintang");
    mysql_query("set names utf8");
    $sql="insert into user(name,password,emial,age) values ('小敏',md5('123'),'xiaoming',34)";
    //如果是dml操作,調用這個函數以後返回的是一個佈爾值
    $res=mysql_query($sql,$connection);
    $affected_number=mysql_affected_rows($connection);
    if(!$res){
       die("操作失敗".mysql_error());
    }
     if($affected_number>0){
           echo "對伺服器的影響為$affected_number";
         }else{
           echo "操作沒成功";
         }
    mysql_close($connection);

實現對伺服器刪除數據的操作

 //server的名稱  伺服器的用戶名和密碼
    $connection=mysql_connect("127.0.0.1","root","");
    if(!$connection){
       die("連接失敗".mysql_error);
    }
    mysql_select_db("senjintang");
    mysql_query("set names utf8");
    $sql="delete from user where id=5";
    //如果是dml操作,調用這個函數以後返回的是一個佈爾值
    $res=mysql_query($sql,$connection);
    $affected_number=mysql_affected_rows($connection);
    if(!$res){
       die("操作失敗".mysql_error());
    }
     if($affected_number>0){
           echo "對伺服器的影響為$affected_number";
         }else{
           echo "操作沒成功";
         }
    mysql_close($connection);

對伺服器的更新操作

 //server的名稱  伺服器的用戶名和密碼
    $connection=mysql_connect("127.0.0.1","root","");
    if(!$connection){
       die("連接失敗".mysql_error);
    }
    mysql_select_db("senjintang");
    mysql_query("set names utf8");
    $sql="update user set age=100  where id=4";
    //如果是dml操作,調用這個函數以後返回的是一個佈爾值
    $res=mysql_query($sql,$connection);
    $affected_number=mysql_affected_rows($connection);
    if(!$res){
       die("操作失敗".mysql_error());
    }
     if($affected_number>0){
           echo "對伺服器的影響為$affected_number";
         }else{
           echo "操作沒成功";
         }
    mysql_close($connection);

上面可見代碼的復用性不高,所以將對伺服器的操作封裝成一個工具類。
mysqltool.php

conn=mysql_connect($this->host,$this->user,$this->password);
       if(!($this->conn)){
          die("連接伺服器發生錯誤".mysql_error());
       }
       mysql_select_db($this->db,$this->conn);
       mysql_query("set names utf8");
     }
     //完成slect
     public  function execute_dql($sql){
     //失敗的時候就退出瞭
        $res=mysql_query($sql) or die(mysqli_error());
        return $res;
     }
     //完成dml
     public  function execute_dml($sql){
       $b=mysql_query($sql,$this->conn);
       if(!$b){
         return 0;   //表示失敗
       }else{
         if(mysql_affected_rows($this->conn)>0){
            return 1;//表示成功
         }
         else{
            return 2;  //表示沒有對伺服器影響
         }
       }
     }
  }
?>

使用mysqli(improvement)來操作伺服器

相當於上面的mysql的擴展庫的一個增強版
mysql和mysqli的比較
1、穩定性、安全性、效率有所提高
2、mysqli提供瞭面向對象的編程思想。
mysqli有兩套編程風格
面向對象
1、創建mysqli對象

$mysqli=new MySQLi("127.0.0.1","root","","senjintang");
     //按章是否ok
     if($mysqli->connect_error){
        die("連接失敗".$mysqli->connect_error);
     }
     else{
       echo  "連接成功";
     }

2、操作伺服器

 $sql="select * from user";
     $res=$mysqli->query($sql);

3、處理結果

  while($row=$res->fetch_row()){
        foreach($row as $key=>$val){
           echo $val;
        }
        echo  "
";
     }

4、關閉資源

  //關閉資源   這一個步驟是必須的
     $res->free();
     //斷開連接
     $mysqli->close();

使用面向對象的方式,實現利用擴展庫對伺服器的操作

connect_error){
        die("連接失敗".$mysqli->connect_error);
     }
     else{
       echo  "連接成功";
     }
      $mysqli->query("set names utf8");
     $sql="select * from user";
     $res=$mysqli->query($sql);
     //返回的是一個對象  mysqliResult
      echo "
";
     var_dump($res);
      echo "
";
     //fetch_row這是mysqliResult的一個方法
     while($row=$res->fetch_row()){
        foreach($row as $key=>$val){
           echo $val;
        }
        echo  "
";
     }
     //關閉資源   這一個步驟是必須的
     $res->free();
     //斷開連接
     $mysqli->close();
     //對於這種面向對象的方式,
?>

註意:防亂碼
//防止亂碼
header(“Content-type:text-html;charset=utf-8”);
可以保證往伺服器裡邊插入正確的漢字
$mysqli->query(“set names utf8”);
mysql中sql語句的特別說明:
如果操作的字段類型是字符串類型的則要求我們要使用”包括,
如果操作的字段是數值型的,則可以用”包括,也可以不使用

分裝mysqli的操作,實現對伺服器的crud

mysqli=new MySQLi(self::$host,self::$user,self::$password,self::$db);
            if($this->mysqli->connect_error){
                die("連接失敗").$this->mysqli->connect_error;
            }
            //設置訪問伺服器的字符集
            //這句話的作用是保證php是以utf8的方式來操作mysql伺服器
            $this->mysqli->query("set names utf8");
         }

         public function execute_dql($sql){
             $res=$this->mysqli->query($sql) or die("操作dql".$this->mysqli->error);
             return $res;
        }
          public function execute_dml($sql){
            $res=$this->mysqli->query($sql) or die("操作dql".$this->mysqli->error);
                 if(!$res){
                    return 0;  //表示失敗
                 }
                 else if($this->mysqli->affected_rows>0){
                     return 1;   //表示成功執行
                 }
                 else{
                     return 2;   //表示沒有收影響的行數
                 }
        }
      }

?>

mysqli的增強

mysql可以批量執行sql語句
1、批量執行dml語句
基本語法:
sqls="sql1;sql2…..”;mysqli::multiquery(sqls);
批量添加、更新、刪除

connect_error){
     die("連接錯誤".$mysqli->connect_error);
   }
    $mysqli->query("set names utf8");
   $sqls=" insert into  user (name,password,emial,age) values('松江',md5('aaa'),'1051743154@qqq.com',21);";
   $sqls.="insert into  user (name,password,emial,age) values('盧俊義',md5('aaa'),'1051743154@qqq.com',21);";
      $sqls.="insert into  user (name,password,emial,age) values('趙文娟',md5('aaa'),'1051743154@qqq.com',21);";
    $b=$mysqli->multi_query($sqls);
    if(!$b){
       echo  "執行失敗".$mysqli->error;
    }
    else{
       echo  "執行成功";
    }
?>

這裡的$sqls可以是增加、更新、刪除這三種語句,但是最好不要使用select語句,接下來就是批量的執行dql語句
2、批量執行dql語句
批量執行select語句、可以一次性的返回多個結果集

connect_error){
     die("連接錯誤".$mysqli->connect_error);
   }
    $mysqli->query("set names utf8");
    //這裡的sqls可以是多個sql語句但是必須用;隔開
   $sqls=" select * from user;";
   $sqls.="select * from users;";  
   //如果就會取出至少一個結果集
    if($res=$mysqli->multi_query($sqls)){
    do{
           //從mysqli連接取出第一個結果集  也就是結果集的第一行
           $result=$mysqli->store_result();
           //顯示mysqli result對象
           while($row=$result->fetch_row()){
              foreach($row as $key=>$val)
              {
                 echo "$key.$val
";
              }
             echo "
";

           }
           $result->free();
           if(!$mysqli->more_results()){
               break;
           }
           echo "新的結果集
";
    }while($mysqli->next_result());
     $mysqli->close();

    };
?>

mysql的事務處理

應用場景:有一張銀行賬號表,id balance一段php程式來實現轉賬
1號賬戶10 元轉到2號賬戶

connect_error){
     die("連接錯誤".$mysqli->connect_error);
   }
   $sql1="update account set balance=balance-2 where id=1";
   $sql2="update account set balance=balance+2 where id=2";
     $b1=$mysqli->query($sql1);
     $b2=$mysqli->query($sql2);
     if(!$b1||!$b2){
        echo "轉賬失敗".$mysqli->error;
     }else{
        echo "轉賬成功";
     }
?>

這種情況貌似是正確的,但是現在假設一種情況,假設我們執行瞭第一個query以後,第二個query沒有執行,這時我們需要有一種方法來控制兩個query必須同時成功執行或者同時失敗,
事務:用於保證數據的一致性,它由一組相關的dml語句組合成,該組的dml語句要麼全部成功,要麼全部失敗。
1、將提交設為false
2、其中一句失敗,執行回滾。兩句都沒有錯誤,實現提交
實現代碼

connect_error){
     die("連接錯誤".$mysqli->connect_error);
   }
   $mysqli->autocommit(false);
   $sql1="update account set balance=balance-2 where id=1";
   $sql2="update account set balance=balance+2 where id=2";
     $b1=$mysqli->query($sql1);
     $b2=$mysqli->query($sql2);
     if(!$b1||!$b2){
        echo "轉賬失敗".$mysqli->error;
        //其中有一個語句沒有執行成功,執行回滾操作
        $mysqli->rollback();
     }else{
        echo "轉賬成功";
          //兩句都成功執行實現提交操作
                $mysqli->commit();   //一旦提交就沒有機會再回滾
        }
?>

在mysql的控制臺中,也可以使用事務:
1、開啟一個事務 : start transaction
2、做保存點 : savepoint
3、操作 : delete insert update
4.1沒有問題做提交操作 commit
4.2有問題做回滾操作 rollback to savepoint
事務的特點:
1、原子性 一個事務不可以分割
2、一致性
3、隔離性
4、持久性 一旦提交,變化永久存在於伺服器中

mysqli的擴展庫增強之處 預處理技術

預處理:代表的是一種處理數據的技術 mysqli_stmt
需要向mysql伺服器添加100個用戶
1、使用for循環,循環100次,向伺服器中添加100個用戶
2、使用批量插入,用.連接100條sql語句,但是隻執行一次sql,使用mysqli?>mutilquery(sql1);
3、使用預編譯技術,該方案還可以防止sql註入攻擊
補充一個關於sql語句原理的知識點:
減少連接的次數可以提高效率、減少編譯的時間來提高效率,提出預編譯的思想。把sql語句預先編譯好,後面隻需程式發送數據即可。、
步驟:
1、創建mysqli對象
2、創建預編譯對象
實現代碼:

prepare($sql) or die($mysqli->error);
    //設置參數
    $name="小倩";
    $password="xiaoqian";
    $emial="1051743154@qq.com";
    $age=20;
    //參數綁定  給?賦值  這裡類型和順序都要對應
    //sssi表示字符串、字符串、字符串、整形類型
    $mysqli_stmt->bind_param("sssi",$name,$password,$emial,$age);
    //執行
    $b=$mysqli_stmt->execute();
    //其中一個不成功,會直接執行下一個
    if(!$b){
       die("操作失敗21".$mysqli->error);
    }
    else{
      echo "操作成功12";
    }
    //釋放資源  因為這裡隻是dml所以隻需關閉
    $mysqli->close();

?>

從伺服器查詢所有id>5的用戶,同時id可能會發生變化

代碼實現

connect_error){
       die($mysqli->connect_error);
    }
    //2、創建預編譯對象
    $sql="select id,name,emial from user where id>?";
    $mysqli_stmt=$mysqli->prepare($sql) or die($mysqli->error);
    //設置參數
    $id=5;
    //參數綁定  給?賦值  這裡類型和順序都要對應
    //sssi表示字符串、字符串、字符串、整形類型
    $mysqli_stmt->bind_param("i",$id);
    //綁定結果集
    $mysqli_stmt->bind_result($id,$name,$emial);
    //取出綁定的結果集
    $mysqli_stmt->execute();
    while($mysqli_stmt->fetch()){
       echo  "
--$id--$name--$emial";
    }
    //釋放資源  1、釋放資源   2、關閉預編譯語句   3、關閉連接
    $mysqli_stmt->free_result();
    $mysqli_stmt->close();
    $mysqli->close();

?>

註入攻擊

預編譯可以自行放置註入攻擊,
萬能密碼:
select * from user where name=”12” and password=’aa’ or 1=’1’;
輸入的密碼為aa’ or 1=’1這樣就會把所有的用戶都查詢到

mysqli擴展庫的其他函數:

編寫一函數,接受一個表名,然後把表頭和數據顯示在頁面
代碼實現

connect_error);
           }
           $sql="select * from $table_name";
           $res=$mysqli->query($sql);
           echo "共有".$res->num_rows."行212";
           echo "共有".$res->field_count."列213";
           //關閉資源
           $res->free();
           $mysqli->close();
     }
     showTable("user");
?>

發佈留言