用PHP和MySQL構建一個資料庫驅動的網站(六)

來源:互聯網
上載者:User
mysql|資料|資料庫 摘要

  在這一章內我們會學習到如何在一個Web頁面中向資料庫中儲存資訊並顯示它。

(2002-08-29 14:11:25)

--------------------------------------------------------------------------------
By Wing, 出處:Linuxaid


第四章: 用PHP訪問MySQL資料庫

  在這一章內我們會學習到如何在一個Web頁面中向資料庫中儲存資訊並顯示它。之前我們已經安裝了MySQL這個關係型資料庫引擎以及PHP這個伺服器端指令碼語言,並學習了有關它們的基本知識。在學完這一章後,我們將明白如何綜合利用這兩個新的工具來構建一個資料庫驅動的網站!

對前一部分的回顧

  在我們往下繼續之前,回顧一下我們學習的目的應該是件有價值的事。現在有我們的系統中有了兩個強有力的新的工具:指令碼語言PHP和資料庫引擎MySQL。搞清楚兩者是如果協同工作是很重要的。

  資料庫驅動的網站的實質就是允許網站的內容存在於一個資料庫中,並且可以通過這個資料庫來動態地產生Web頁面來讓我們的訪問者通過標準的Web瀏覽器來顯示它。所以在你的系統的一端是一個訪問你的網站的瀏覽者,他通過訪問http://www.yoursite.com/來獲得一個標準的HTML格式的Web頁面並在Web瀏覽器中顯示它。在你的系統的另一端是通過一個或幾個資料表格儲存體在一個只理解如何響應SQL查詢(命令)的MySQL資料庫中的你的網站的內容。

  PHP指令碼語言承擔了兩者之間的聯絡員的角色,使用PHP,你可以編寫一個標準HTML的“模板”,這個“模板”決定了你的網站的外觀(包括圖畫和頁面設計)。這時內容是屬於這個“模板”的,你可以使用一些PHP代碼來串連MySQL資料庫並且使用SQL查詢來獲得資料並在其相應位置顯示它,這裡的SQL查詢是和我們在第二章中用來建立笑話資料表時一樣的。

  現在對於訪問者在訪問你的資料庫驅動的網站的一個頁面時,到底會發生什麼事,你應該有個明確的認識了:

  訪問者的Web瀏覽器使用一個標準的URL請求這個頁面。

  Web伺服器軟體(Apache、IIS或其他)認定被請求的頁面是一個PHP指令碼,因而在響應這個頁面請求之前用它的PHP外掛程式來解釋它。

  一些PHP命令(我們還沒學到)會串連MySQL資料庫並向資料庫請求屬於這個Web頁面的內容。

  MySQL資料庫作出響應並且向PHP指令碼發出被請求的內容。

  PHP指令碼將內容儲存到一個或幾個PHP變數中,並使用我們熟悉的echo函數將其作為Web頁面的一部分輸出。

  PHP外掛程式完成處理並將產生的HTML副本返回到Web伺服器。

  Web伺服器將這個HTML副本發送到Web瀏覽器,這將是一個標準的HTML檔案,只不過它不是直接來自於一個HTML檔案,而是來自於PHP外掛程式提供的輸出。

用PHP串連MySQL

  在我們從我們的MySQL資料庫中擷取我們的Web頁面所包含的內容之前,我們首先必須知道如何建立與MySQL的串連。在第二章中,我們使用了一個叫mysql的程式來做這樣的串連。PHP不需要這樣的一個程式,對串連MySQL的支援是語言內建的。下面的這個函數用來建立這樣的串連:

mysql_connect(<address>, <username>, <password>);


  在這裡,<address>是MySQL服務軟體在其上啟動並執行電腦的IP地址或主機名稱(如果這與運行Web服務軟體的電腦是同一台,你可以使用"localhost"),<username>和<password>就是你在第二章中用來串連到MySQL伺服器的使用者名稱及口令。

  你可能還記得PHP中的函數在被調用時往往會返回(輸出)一個值。請不要擔心我們沒有提醒你,我們在最初接觸一個函數時都會為你詳細詳細它。絕大多數的函數在被調用後,都會返回一個可以在儲存在變數中的值以備下次使用。例如我們上面介紹的mysql_connect函數,會返回一個數字來標識已經建立的串連。因為我們會要使用這個串連,所以我們必須儲存這個值。下面是一個關於如何串連我們的MySQL資料庫的一個執行個體:

$dbcnx = mysql_connect("localhost", "root", "mypasswd");


  需要說明的是,對於你的MySQL伺服器,上面這個函數中的三個參數的值可能是不同的。你應該注意到在這兒我們的mysql_connect 返回了一個值(我們稱之為一個串連標識),這個值被我們儲存在變數$dbcnx中。

  因為MySQL是一個完全分布式的軟體,我們必須考慮到這些可能性:服務不可用、網路堵塞或者是我們的使用者名稱及口令不匹配。在這些情況下,mysql_connect函數不能返回一個串連標識(因為串連未被建立)。這時,會返回一個邏輯假。這使得我們可以用一個if語句來處理串連的情況: $dbcnx = @mysql_connect("localhost", "root", "mypasswd");


if (!$dbcnx) {
  echo( "<P>Unable to connect to the " .
        "database server at this time.</P>" );
  exit();
}



  在上面的程式碼片段中出現了三個新的東西,首先,我們在mysql_connect函數前加了一個@符號。包括mysql_connect在內的許多函數會在失敗後顯示難看的錯誤資訊。在函數名前加一個@符號可以告訴這個函數當執行失敗時,允許我們顯示我們自己友好的出錯資訊。

  其次,在我們的if語句的條件中,$dbcnx變數前面加了一個驚歎號。這個驚歎號是PHP中的“否運算子”。也就是說將邏輯真變為邏輯假,將邏輯假變為邏輯真。這樣,如果這個串連是失敗的,mysql_connect會返回一個邏輯假,!$dbcnx將等於邏輯真,這樣我們的if語句將被執行。相反,如果這個串連是成功的,儲存在$dbcnx 中的串連標識將等於邏輯真(在PHP中,任何非零的數字都被認為是邏輯真),所以!$dbcnx會等於邏輯假,if語句將不會被執行。

  最後一個是exit函數,這是我們遇到的第一個沒有參數的函數。這個函數的全部作用就是導致PHP停止對本頁的閱讀。如果資料庫連接失敗這是一個很好的響應,因為絕大多數情況下,如果不能串連到資料庫,這一頁不會顯示任何有用的資訊。

  和我們在第二章做過的一樣,串連被建立後下一步就是選擇工作的資料庫。我們將要在第二章中所建立的笑話資料庫中工作。這個資料庫被命名為jokes。在PHP中用來選擇資料庫的另外一個函數:

mysql_select_db("jokes", $dbcnx);


  請注意我們在這兒使用了$dbcnx變數來指出了這個函數所使用的串連標識。這個參數實際上是可省略的。當省略這個參數時,函數會自動使用最後開啟的那一個串連。這個函數成功後返回邏輯真,失敗後返回邏輯假。為了謹慎起見,我們也用了一個if語句來處理錯誤:


if (! @mysql_select_db("jokes") ) {
  echo( "<P>Unable to locate the joke " .
        "database at this time.</P>" );
  exit();
}



  當建立了串連並選擇了資料庫之後,我們可以開始使用儲存在資料庫中的資料了。

在PHP中執行SQL查詢

  在第二章中,我們使用一個叫mysql的程式來串連到MySQL資料庫伺服器,在這個程式中,我們可以輸入SQL查詢(命令)並立即顯示查詢結果。在PHP中,有著類似的機制:mysql_query函數。

mysql_query(<query>, <connection id>);


  在這兒,<query>是一個包含將執行的SQL命令的字串。和mysql_select_db一樣,串連標識這個參數也是可選的。

  這個函數的返回決定於發出的查詢的類型。對於絕大多數的SQL命令來說,mysql_query返回邏輯真或邏輯假來標明執行是否成功。請參看下面這個例子,這是用來建立我們在第二章中建立的Jokes資料表的:


$sql = "CREATE TABLE Jokes ( " .
       "ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY, " .
       "JokeText TEXT, " .
       "JokeDate DATE NOT NULL " .
       ")";
if ( mysql_query($sql) ) {
  echo("<P>Jokes table successfully created!</P>");
} else {
  echo("<P>Error creating Jokes table: " .
       mysql_error() . "</P>");
}



  這兒使用的mysql_error將以字串的形式返回MySQL伺服器最後發出的錯誤資訊。

  對於DELETE、 INSERT以及UPDATE(用來修改儲存的資料),MySQL可以知道有多少資料行被這個查詢影響。參看下面的SQL命令,這個命令我們曾在第二章中用來設定所有包含單詞“chicken”的笑話的日期:


$sql = "UPDATE Jokes SET JokeDate='1990-04-01' " .
       "WHERE JokeText LIKE '%chicken%'";
    當我們執行這個查詢時,我們可以使用mysql_affected_rows函數來顯示這個修改所影響的資料行的數目:
if ( mysql_query($sql) ) {
  echo("<P>Update affected " .
        mysql_affected_rows() . " rows.</P>");
} else {
  echo("<P>Error performing update: " .
       mysql_error() . "</P>");
}



  SELECT命令會有一些不同,因為它會得到許多資訊,而PHP必須提供方法來處理這些資訊。

處理SELECT結果集

  對於絕大多數的SQL查詢來說,mysql_query函數僅僅返回邏輯真或邏輯假。而對於SELECT查詢來說,僅僅這樣顯然是不夠的。你應該還記得SELECT查詢是用來顯示資料庫中儲存的資料的。除了指出查詢成功還是失敗之外,PHP還必須得到查詢的結果。作為一個結果,當我們執行一個SELECT查詢的時候,mysql_query會返回一個標識“結果集”的數字,這將包含了這個查詢返回的所有行的列表。如果查詢失敗,函數仍然是返回一個邏輯假。


$result = mysql_query("SELECT JokeText FROM Jokes");
if (!$result) {
  echo("<P>Error performing query: " .
       mysql_error() . "</P>");
  exit();
}



  假定在執行查詢時沒有遇到錯誤,上面的代碼會定位一個有關儲存在笑話庫中所有笑話的本文的結果集,這個定位被儲存在變數$result中。因為資料庫中的笑話的數目是沒有限制的,這個結果集可能非常龐大。

  我們之前曾經提到過while迴圈對於處理大量的資料來說是一個非常有用的控制語句,這是我們逐個處理結果集中資料行的代碼的基本格式:


while ( $row = mysql_fetch_array($result) ) {
  // process the row...
}



  在這個while迴圈中的條件可能看上去與我們曾經使用過的有所不同,所以我們有必要在這裡解釋它的工作機理。你可以先把這個條件看成一個獨立的語句:

$row = mysql_fetch_array($result);


  mysql_fetch_array函數以一個參數(對於這個例子來說是儲存在$result變數中)接受到一個結果集,並以一個資料的形式返回結果集中的下一行。如果你還不熟悉數組的概念,不要擔心,我們會在下面詳細討論它。如果在這個結果集中不再有其它資料行時,mysql_fetch_array返回邏輯假。

  現在,我們上面的語句定義了一個值到$row變數中,與此同時,整個語句也獲得了同樣的值。這就是我們在while迴圈的條件中使用這個語句的原因,因為while迴圈會一直執行迴圈直到條件等於邏輯假,結果集有幾行,這個迴圈就會執行幾次,每一次$row都會得到一個下一行的值,現在剩下的就是如何在迴圈中從$row變數中獲得相應的值了。

  結果集中的行被描述成一個數組。數組是一個特殊類型的變數,這個變數可以包含多個值,如果你把一個變數看成是值的容器,你可以把數組看成是有間隔的容器,在每一個間隔中可以儲存一個單獨的值。對於我們的資料行來說,這個間隔是以資料表的列名命名的。如果$row是我們結果集中的一行,那麼$row["JokeText"]就是這一行中JokeText列的值。所以如果我們想要顯示我們的資料庫中所在笑話的本文,while迴圈應該是這樣的:


while ( $row = mysql_fetch_array($result) ) {
  echo("<P>" . $row["JokeText"] . "</P>");
}



  最後,作為一個總結,這是一段完整的PHP的Web頁面的代碼,它用來串連我們的資料庫,取出資料庫中所有笑話的本文,並將其在HTML中顯示出來:


<HTML>
<HEAD>
<TITLE> Our List of Jokes </TITLE>
</HEAD>
<BODY>
<?php

  // Connect to the database server
  $dbcnx = @mysql_connect("localhost",
           "root", "mypasswd");
  if (!$dbcnx) {
    echo( "<P>Unable to connect to the " .
          "database server at this time.</P>" );
    exit();
  }

  // Select the jokes database
  if (! @mysql_select_db("jokes") ) {
    echo( "<P>Unable to locate the joke " .
          "database at this time.</P>" );
    exit();
  }

?>
<P> Here are all the jokes in our database: </P>
<BLOCKQUOTE>

<?php
    // Request the text of all the jokes
  $result = mysql_query(
            "SELECT JokeText FROM Jokes");
  if (!$result) {
    echo("<P>Error performing query: " .
         mysql_error() . "</P>");
    exit();
  }

  // Display the text of each joke in a paragraph
  while ( $row = mysql_fetch_array($result) ) {
    echo("<P>" . $row["JokeText"] . "</P>");
  }
?>
</BLOCKQUOTE>
</BODY>
</HTML>



向資料庫中插入資料

  在這一節裡,我們會看到我們會如何綜合利用這些工具來讓我們網站的訪問者向資料庫中添加他們自己的笑話。如果你喜歡挑戰,你可以試試在向下看之前想想大致上應該怎麼做。在這一節裡只有很少新的東西。對於我們學過的東西來說,這隻是一個簡單的應用。

  如果我們想要讓訪問者能夠輸入新的笑話,我們首先需要一個表單,這兒是這個表單的代碼:


<FORM ACTION="<?php echo($PHP_SELF); ?>" METHOD=POST>
<P>Type your joke here:<BR>
<TEXTAREA NAME="joketext" ROWS=10 COLS=40 WRAP></TEXTAREA><BR>
<INPUT TYPE=SUBMIT NAME="submitjoke" VALUE="SUBMIT">
</FORM>



  正如我們上面看到的那樣,這個表單在提交時會載入同一個頁面(因為我們在表單的ACTION屬性中使用了$PHP_SELF變數),但是在再次載入時請求中包含了兩個變數,首先是$joketext,這是在text域中輸入的笑話的本文,另一個是$submitjoke,這個變數的值將始終是"SUBMIT",這用來標誌笑話已被提交。

   要將已提交的笑話添加到資料庫中,我們需要用mysql_query來運行一個INSERT查詢,這個查詢中將包含已經提交的$joketext變數的值:


if ("SUBMIT" == $submitjoke) {
  $sql = "INSERT INTO Jokes SET " .
         "JokeText='$joketext', " .
         "JokeDate=CURDATE()";
  if (mysql_query($sql)) {
    echo("<P>Your joke has been added.</P>");
  } else {
    echo("<P>Error adding submitted joke: " .
         mysql_error() . "</P>");
  }
}



  在全部的內容中只有SQL代碼中出現了一個新的東西。在這裡我們使用了一個MySQL函數CURDATE()來將新插入資料庫的笑話的JokeDate列的值置為當前日期。事實上,MySQL有很多這樣的函數,但是我們只會在使用到他們時才會介紹他們,要得到一個完整的函數的說明,你可以參看MySQL參考手冊。

  

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.