飛機的 PHP 學習筆記之資料庫篇

飛機飛過天空發表於2020-01-30

前言

最近在系統的學習 PHP ,參考的資料是《PHP程式設計》+ 官方文件(如果你有好的學習資料,歡迎推薦給我)。雖然這本《PHP程式設計》是基於 PHP5 的,但我筆記裡的程式碼,全部在 PHP 7.2 的環境裡測試過,是能夠執行的。另,本筆記中只記錄我模糊不清的知識。

訪問資料庫

在 PHP 中訪問資料有兩種方法:

  • 使用資料庫特定的擴充
  • 使用不受資料庫約束的 PDO ( PHP 資料物件)庫

如果使用資料庫特定的擴充套件,你的程式碼會和你所使用的資料庫密切相關。也就是說你先把資料庫從 MySQL 遷移到 PostgreSQL ,會引起程式碼的重大改動。而 PDO ,用一個抽象層為你隱藏了資料庫特定的函式,因此在資料庫系統間進行遷移,改變程式或 php.ini 檔案中的一行程式碼這麼簡單。但是這種可移植性也是有代價的。使用 PDO 的程式碼會比使用原生資料庫特定擴充套件的程式碼在執行速度上慢一點。

需要注意的是,抽象層並不能保證你的 SQL 語句是真正可移植的。如果你的應用使用了任何非泛型的 SQL ,那麼在資料庫遷移時你不得不對 SQL 語句進行重大改造。

PDO ( PHP 資料物件)

連線

$db = new PDO($dsn, $username, $password);

$db = new PDO("mysql:host=localhost;bdname=text", "username", "password");

資料庫互動

使用 query() 函式

$db = new PDO("mysql:host=localhost;dbname=laravelblog", 'root', 'root');

$result = $db->query("select * from users");

foreach($result as $row){
    print_r($row);
}

$result = null; // 釋放結果集物件

預處理語句

先使用預處理函式 prepare() ,在執行執行函式 execute()

$db = new PDO("mysql:host=localhost;dbname=laravelblog", 'root', 'root');

$result = $db->prepare("select * from users");
$result->execute();

while ($row = $result->fetch()) {
  print_r($row);
}

$result = null; // 釋放結果集物件

利用佔位符來進行重複插入

$db = new PDO("mysql:host=localhost;dbname=laravelblog", 'root', 'root');

$statement = $db->prepare("insert into posts (title, body) values (:title, :body)");
$statement->execute([
  'title' => 'What is PHP?',
  'body' => 'best language'
]);

$db = null;

也可以使用位置佔位符(不命名),用 ? 標誌。

$db = new PDO("mysql:host=localhost;dbname=laravelblog", 'root', 'root');

$statement = $db->prepare("insert into posts (title, body) values (?, ?)");
$statement->execute(['What is PHP?', 'best language']);

$db = null;

事務

使用函式 beginTransaction() 開始事務, commit() 提交事務, rollback() 取消事務。

try {
  $db = new PDO("mysql:host=localhost;dbname=laravelblog", 'root', 'root');
  echo "Connected\n";
} catch (Exception $e) {
  die("Unable to connect: " . $e->getMessage());
}

try {  
  $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $dbh->beginTransaction();
  $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
  $dbh->exec("insert into salarychange (id, amount, changedate) 
      values (23, 50000, NOW())");
  $dbh->commit();

} catch (Exception $e) {
  $dbh->rollBack();
  echo "Failed: " . $e->getMessage();
}

MySQLi

MySQLi , MySQL 改進擴充套件( MySQL Improved )。

連線

$db = new mysqli(host, user, password, databaseName);

$db = new mysqli("localhost", "root", "root", "laravelblog");

資料庫互動

$db = new mysqli("localhost", "root", "root", "laravelblog");

$sql = "select * from users";
$result = $db->query($sql);

while ($row = $result->fetch_assoc()) {
  print_r($row);
}

$result->close();
$db->close();

檔案操作

當我們不想使用資料庫時,我們可以用檔案代替它。但是功能有限。

首先我們來看一下 PHP 檔案管理常用函式

函式名 使用說明
mkdir() 用來在伺服器上建立目錄
file_exits() 用來檢測指定位置的檔案或目錄是否存在
fopen() 用來開啟存在的檔案用來讀或寫
fread() 用來讀取檔案內容到一個 PHP 使用的變數
flock() 用來獲得檔案的獨佔寫鎖
fwrite() 用來將變數中的內容寫入到檔案中
filesize() 當讀取檔案時,這個用來檢測一次需要讀取的位元組數
fclose() 用來當檔案的實用性已經過去時,關閉檔案

fopen() 中的引數

引數 說明
r 只讀方式開啟,將檔案指標指向檔案頭
r+ 讀寫方式開啟,將檔案指標指向檔案頭
w 寫入方式開啟,將檔案指標指向檔案頭並將檔案大小截為零,如果檔案不存在則嘗試建立之
w+ 讀寫方式開啟,將檔案指標指向檔案頭並將檔案大小截為零,如果檔案不存在則嘗試建立之
a 寫入方式開啟,將檔案指標指向檔案末尾進行寫入,如果檔案不存在則嘗試建立之
a+ 讀寫方式開啟,通過將檔案指標指向檔案末尾進行寫入來儲存檔案內容
x 建立一個新的檔案並以寫入方式開啟,如果檔案已存在則返回 FALSE 和一個錯誤
x+ 建一個新的檔案並以讀寫方式開啟,如果檔案已存在則返回 FALSE 和一個錯誤

下面我會利用 PHP 的檔案操作來建立一個動態頁面。類似一個問卷調查的形式。

首先要通過唯一標識來區別使用者,這裡我們假定個人郵箱是唯一的(這樣並不安全)。我們一旦獲取使用者的電子郵件地址,需要把資訊存在在一個對每個訪問者不同的位置。為此,我們為每個訪問者在伺服器上建立目錄資料夾。

<?php
session_start();

if (!empty($_POST['posted']) && !empty($_POST['email'])) {
  $folder = "surveys/" . strtolower($_POST['email']);

  //向會話傳送路徑訊息
  $_SESSION['folder'] = $folder;

  if (!file_exists($folder)) {
    //建立目錄並新增檔案
    mkdir($folder, 0777, true);
  }
  header("Location: 08_6.php");
} else {
?>
  <!DOCTYPE html>

  <head>
    <title>Files & folders - On-line Survey</title>
  </head>

  <body bgcolor="white" text="black">

    <h2>Survey Form</h2>

    <p>Please enter your e-mail address to start recording your comments</p>

    <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="POST">
      <input type="hidden" name="posted" value="1">
      <p>Email address: <input type="text" name="email" size="45" /><br />
        <input type="submit" value="Submit" name="submit"></p>
    </form>

  </body>

  </html>
<?php } ?>

向通過電子郵箱建立目錄,進而進行問卷調查。

<?php
session_start();
$folder = $_SESSION['folder'];
$filename = $folder . "/question.txt";

$file_handle = fopen($filename, "a+");
//向判斷檔案中是否有資料
if (filesize($filename) > 0) {
  //獲取檔案中已存在的任何文字
  $comments = fread($file_handle, filesize($filename));
} else {
  $comments = '';
}
fclose($file_handle);
if (!empty($_POST['posted'])) {
  //首次訪問建立檔案,然後儲存 $_POST['question']中的文字
  $question = $_POST['question'];
  $file_handle = fopen($filename, "w+");
  if (flock($file_handle, LOCK_EX)) {
    if (fwrite($file_handle, $question) == false) {
      echo "Cannot write to file {$filename}";
    }
    flock($file_handle, LOCK_UN);
  }
  fclose($file_handle);
  header("Location: thank_your.php");
} else {
?>
  <!DOCTYPE html>

  <head>
    <title>Files & folders - On-line Survey</title>
  </head>

  <body>

    <table border="0">
      <tr>
        <td>
          Please enter your response to the following survey question:
        </td>
      </tr>
      <tr bgcolor="red">
        <td>
          What is your opinion on the state of the world economy><br />
          Can you help us fix it ?
        </td>
      </tr>
      <tr>
        <td>
          <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
            <input type="hidden" name="posted" value="1"> <br />
            <textarea name="question" cols="35" rows="12"><?php echo  $comments ?></textarea>
            <input type="submit" name="submit" value="Submit">
          </form>
        </td>
      </tr>
    </table>

  </body>

  </html>
<?php } ?>

調查開始,通過表單來提交到 PHP ,進而建立相應檔案。如果檔案中存在資料,則列印到對應的 <textarea> 中。這裡還可以繼續往後面寫問卷調查,要注意的是一對一,也就是一個問題一個檔案。

在提交表單這裡,使用了獨佔鎖,則保證當操作它時,沒有其他程式範圍這個檔案。這裡最後我重定向到了感謝頁面,表示調查的結束。

NoSQL

NoSQL , Not Only SQL 。 這裡重點介紹 MongoDB 。

在 PHP 7+ 中, MongoDB 與之前的不太一樣,首先要去這個網站下載 MongoDB 的擴充套件。對應的就是 php_mongodb.dll 。下載到的是一個壓縮包,解壓之後,將裡面的 php_mongodb.dll 檔案放入你的 PHP 目錄下的 ext 檔案中。最後在 php.ini 檔案中寫下 extension=php_mongodb.dll 重啟伺服器就行了。

這裡演示一下插入資料(要保證 MongoDB 在執行中):

$bulk = new MongoDB\Driver\BulkWrite;
$author1 = ['authorid' => 1, 'name' => 'J.R.R. Tolkien'];
$bulk->insert($author1);
$author2 = ['authorid' => 2, 'name' => 'Alex Haley'];
$bulk->insert($author2);
$author3 = ['authorid' => 3, 'name' => 'Tom Clancy'];
$bulk->insert($author3);
$author4 = ['authorid' => 4, 'name' => 'Isaac Asimov'];
$bulk->insert($author4);

$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$writeConcern = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY, 1000);
$result = $manager->executeBulkWrite('test.authors', $bulk, $writeConcern);

更多的操作可以看這篇文章:php7的mongodb基本用法

感謝你看到了這裡。如果文章有錯誤,請評論指正,謝謝!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章