>以下文章摘自PHP&MySQL:新手到Ninja,第7版,這是學習所有工具,原理和技術的動手指南,以構建專業的Web應用程序。在該系列的最後一個教程中,您將學習如何將存儲在MySQL數據庫中的信息並在網頁上顯示供所有人查看。 。
到目前為止,您已經編寫了第一個PHP代碼,並了解了MySQL(關係數據庫引擎)的基礎知識,而PHP是服務器端腳本語言。
>現在,您已經準備好學習如何一起使用這些工具來創建一個網站,用戶可以從數據庫中查看數據,甚至添加自己的數據。>
注意:如第3章所示,我在這裡使用“ mysql”來參考數據庫協議。您的PHP腳本也會做同樣的事情。本章中有許多參考文獻 - 在您將編寫的PHP代碼中,即使我們實際上是連接到MariadB數據庫的“ MySQL”。。
大圖
>在我們飛躍之前,值得一試,以清楚地了解我們的最終目標。我們可以使用兩個強大的工具:PHP腳本語言和MySQL數據庫引擎。重要的是要了解這些將如何融合在一起。 >
>如上圖所示,PHP腳本語言是說兩種語言的介於之間。它處理頁面請求並使用SQL查詢從MySQL數據庫中獲取數據,就像您用來在第3章中創建笑話表的數據庫一樣。然後,它隨著瀏覽器期望的良好格式的HTML頁面而動態地吐出它。 >
>使您清楚地清楚,這是當您網站上的訪問者的訪問者時,會發生什麼:
> >您應該創建一個新的用戶帳戶,只有在您的網站依賴的IJDB數據庫上使用的特定特權。讓我們現在就這樣做。
創建用戶,打開MySQL Workbench並連接到您的服務器。然後運行以下查詢:CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
第一個查詢是相當自我解釋的:它創建了一個名為ijdbuser的用戶,並使用密碼myPassword。用戶名之後的%符號表示數據庫可以從任何位置連接到。第二個查詢可為用戶提供完整的IJDB架構,因此該用戶可以在IJDB架構中查看並修改所有表,列和數據,但無法訪問其外部任何內容。
>現在已經創建了用戶ijdbuser,我們可以使用它連接到數據庫。可以與此用戶在MySQL Workbench中建立連接,但是由於權限有限,因此最好使用V.JE帳戶來保持MySQL Workbench。相反,我們將在從PHP腳本連接時使用新用戶。>使用php
連接到mySQL 在您可以從MySQL數據庫中檢索內容以包含在網頁中之前,您必須知道如何從PHP腳本內部建立與MySQL的連接。到目前為止,您已經使用了一個名為MySQL Workbench的應用程序來連接到您的數據庫。就像MySQL Workbench可以直接連接到運行的MySQL Server一樣,您自己的PHP腳本也可以。>客戶端提供了標準化的方法
,因此,為了保持簡單,我將在本章中使用術語
> mysql來參考數據庫。 有三種從php連接到MySQL Server的方法:> mysql庫
> mysqli庫pdo庫
>儘管大多數開發人員在發布PHP 5.0後立即看到了發生變化的原因,但儘管有實際上已經有效地是MySqli,但現在使用這些現在不存在的MySQL_*功能,網絡上仍有數百個文章和代碼示例。首選的圖書館已有十五年。
>遇到一個包含LINE MYSQL_CONNECT()的代碼示例,請檢查文章的日期。大概是從2000年代初開始,在編程中,您永遠不應該相信任何古老的東西。事情一直在改變 - 這就是為什麼這本書在其第七版中!
> 在PHP 5.0中,MySQLI庫(代表“ MySQL改進”)被釋放,以解決原始MySQL庫中的某些局限性。您可以輕鬆地識別MySQLI的使用,因為代碼將使用諸如mysqli_connect()和mysqli_query()。 在PHP 5.0中發布MySQLI庫後不久,PHP 5.1發行了,並進行了大量更改,有助於塑造我們今天編寫PHP的方式(主要是針對對象的編程,您會看到的本書的後期很多) 。 PHP 5.1的主要變化之一是它引入了第三個庫PDO(PHP數據對象),用於連接MySQL數據庫。 PDO和MySQLI之間存在幾個區別,但主要的是您可以使用PDO庫將幾乎所有數據庫服務器連接到任何數據庫服務器(例如Oracle Server或Microsoft SQL Server)。對於開發人員而言,這種通用方法的最大優勢是,一旦您學習瞭如何使用庫與MySQL數據庫進行交互,那麼與另一家數據庫服務器進行交互非常簡單。 可以說,為PDO編寫代碼更簡單,並且有些細微差別可以使PDO代碼更可讀性 - 準備好語句中的參數為主要好處。 (不用擔心,我將稍後解釋這意味著什麼。)>
由於這些原因,最近的PHP項目使用PDO庫,這是我將向您展示如何在本書中使用的庫。有關差異的更多信息,請查看SitePoint文章“重新引入PDO - 正確訪問PHP數據庫的正確方法”。>在那段小歷史課之後,您可能渴望回到編寫代碼。這是您使用PDO建立與MySQL Server的連接的方式:
>>目前,將新的PDO視為內置功能,就像我們在第2章中使用的RAND函數一樣。如果您在想“嘿,函數在他們的範圍內就不可能具有
名字!”,您比普通的熊聰明,我將在稍後確切地說明這裡發生了什麼。無論如何,它需要三個參數:
>您可能可以查看最後兩個參數的情況:它們是您本章之前創建的用戶名和密碼。
>CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
架構
),稱為ijdb。從PHP運行的任何查詢都將默認為該模式中的表。從笑話中選擇 * *將從ijdb架構中的笑話表中選擇記錄。> >即使您已經熟悉PHP,PDO和MySQL,主機= mysql部分看起來令人困惑。通常,這將是host = localhost(參考本地計算機,運行php的同一台計算機)或指向數據庫所在的特定域名,例如host = sitepoint.com。 為什麼它是主機= mysql,MySQL在這裡指的是什麼?在docker中,每個
>服務被賦予一個名稱。如果您檢查配置服務器的Docker-compose.yml文件,則數據庫服務稱為MySQL,在Docker中,一個服務可以使用另一個服務的名稱連接到另一個服務。 除了參數之外,這裡重要的是,新PDO返回的值存儲在名為$ pdo的變量中。
> MySQL Server是與Web服務器完全獨立的軟件。因此,我們必須考慮由於網絡中斷而導致服務器可能無法使用或無法訪問的可能性,或者因為您提供的用戶名/密碼組合被服務器拒絕,或者是因為您只是忘記啟動MySQL Server!在這種情況下,新的PDO不會運行,並且會拋出PHP例外。 > >
注意:至少在默認情況下,可以配置PHP,以使其無例外,並且根本不會連接。這通常不是理想的行為,因為它使得弄清楚出了什麼問題變得更加困難。>如果您想知道“拋出PHP例外”意味著什麼,請自己做好準備!您將要發現PHP語言的更多功能。
> php例外是當您告訴PHP執行任務並且無法執行任務時,會發生什麼。 PHP會嘗試做所講的事情,但會失敗;為了告訴您失敗,它會給您帶來例外。一個例外僅僅是PHP僅帶有特定的錯誤消息崩潰。當拋出例外時,PHP停止。將執行錯誤之後沒有代碼行。
>作為負責任的開發人員,您的工作是捕獲該異常並做些事情以使程序可以繼續。
>注意:如果您沒有捕獲異常,則PHP將停止運行您的PHP腳本並顯示出驚人的醜陋錯誤消息。該錯誤消息甚至會揭示腳本的代碼,這些代碼引發了錯誤。在這種情況下,該代碼包含您的MySQL用戶名和密碼,因此避免用戶看到的錯誤消息尤其重要! 為了捕獲異常,您應該包圍可能會嘗試嘗試的代碼。
>您可以嘗試一個嘗試…像if…else語句一樣捕獲語句,除了第二個代碼塊是第一個代碼無法運行的情況。>困惑了嗎?我知道我正在向您扔很多新概念(沒有雙關語),但是如果我把它們放在一起並向您展示我們擁有的東西,那將是更有意義的:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
>重要的是,在嘗試……捕獲語句中,拋出異常後的任何代碼都不會被執行。在這種情況下,如果連接到數據庫會引發異常(也許密碼是錯誤的,或者服務器未響應),則$輸出變量永遠不會設置為“已建立數據庫連接”。
如果我們的數據庫連接嘗試失敗,PHP將拋出PDOException,這是新PDO投擲的例外類型。因此,我們的捕獲塊說,它將捕獲PdoException(並將其存儲在名為$ e的變量中)。在該塊內部,我們設置了變量$輸出以包含有關出了什麼問題的消息。> 但是,此錯誤消息並不是特別有用。它告訴我們的只是PDO無法連接到數據庫服務器。最好有一些有關為什麼這樣的信息 - 例如,因為用戶名和密碼無效。
>new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
>注意:$ e變量不是字符串,而是對象。我們將不久的將來意味著什麼。但是,目前,您需要知道的是,代碼$ e-> getMessage()基於發生的特定異常獲取錯誤消息。 > if…else語句,一個嘗試的兩個分支之一…catch語句可以運行。 TRY塊中的代碼將成功執行,或者捕獲塊中的代碼將運行。不管數據庫連接是否成功,$輸出變量中都會有一條消息 - 錯誤消息或說明連接成功的消息。
>最後,無論嘗試塊是成功的還是捕獲塊運行,都包括模板輸出。 html.php。這是一個通用模板,僅在頁面上顯示一些文本:>
可以在示例中找到完整的代碼:mysql-connect。
>new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
我希望上述代碼現在對您有意義。隨意回到本節的開始,如果您迷路了,請再次閱讀全部,因為其中有一些棘手的概念。但是,一旦您對代碼有堅定的抓地力,您可能會意識到,我仍然留下了一個無法解釋的神秘:PDOS。新的PDO到底是什麼,當我說它返回一個“ PDO對象”時,一個對像到底是什麼?
>>
注意:所有下載的示例代碼都包含一個名為ijdb_sample的架構和一個稱為ijdb_sample的用戶,以便您能夠運行它,無論您所謂的架構和用戶如何。將包含數據庫的文件作為數據庫.sql提供,您可以導入。>
如果您使用提供的基於Web的示例代碼查看器,則在加載示例時將創建IDBJ_Sample數據庫,但是當您查看另一個示例時,該模式的任何更改都將丟失。 (您可以弄亂事情,然後切換到另一個樣本並將其重置,但是如果要保留任何更改,請將它們製作在您創建的模式中。) 如果要使用MySQL Workbench將示例數據加載到您的架構中,請通過選擇數據導入/還原來從項目目錄中導入database.sql。然後從獨立文件中選擇導入,瀏覽到database.sql,然後在默認目標架構中選擇您的架構名稱。如果您創建了任何具有相同名稱的表格,它們將被覆蓋並且所有記錄都丟失了。>面向對象的編程中的速成課程 >您可能已經註意到“對象”一詞開始在上一節中滲入我的詞彙。 PDO是php數據
對象擴展,而新的PDO返回PDO對象。在本節中,我想解釋哪些對像是有意義的。
>>也許您在自己的PHP或編程中遇到了術語面向對象的編程(OOP)。 OOP是一種先進的編程風格,特別適合用很多部分構建真正複雜的程序。當今有效使用中的大多數編程語言都支持OOP。他們中的一些人甚至需要
創建對像很像調用函數。實際上,您已經看過如何做:
> >新關鍵字告訴PHP您要創建一個新對象。然後,您離開空間並指定一個類名稱,該名稱告訴PHP您要創建哪種類型的對象。一類是PHP將遵循的一組指令來創建對象。您可以將班級視為食譜,例如蛋糕,而物體是遵循食譜產生的實際蛋糕。不同的類可以產生不同的物體,就像不同的食譜可以產生不同的菜餚一樣。 當PHP帶有可以調用的一堆內置功能時,PHP帶有可以從中創建對象的類庫。因此,新的PDO告訴PHP創建一個新的PDO對象 - 即內置PDO類的新對象。
在PHP中,對像是一個值,就像字符串,數字或數組一樣。您可以將對象存儲在變量中,也可以將其作為參數傳遞給函數 - 所有與其他PHP值相同的事情。但是,對象具有一些有用的其他功能。>
首先,一個對象的行為與數組相似,因為它充當了其他值的容器。正如我們在第2章中看到的那樣,您可以通過指定其索引來訪問數組內部的值(例如,$生日['Kevin'])。當涉及對象時,概念相似,但名稱和代碼不同。我們不是訪問存儲在數組索引中的值,而是說我們正在訪問對象的屬性。我們使用箭頭符號( - >) - 例如,$ myObject-> someproperty:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
值的列表(例如生日的數組),而對象則用於存儲>相關>值的列表(例如,例如,數據庫連接的屬性)。不過,如果這是所有對像都可以的,那麼它們對它們沒有太大的意義:我們可能會使用一個數組來存儲這些值,對嗎?當然,對象會做更多的。 除了存儲屬性及其值集合外,對像還可以包含一組函數,旨在帶來更多有用的功能。存儲在對像中的函數稱為一種方法(如果您問我,編程世界中更令人困惑的名稱之一)。方法只是類中的功能。更令人困惑的是,當我們開始編寫自己的課程時,使用函數關鍵字定義方法!即使是經驗豐富的開發人員,也經常錯誤地使用函數
和方法互換。
要調用一種方法,我們再次使用箭頭符號 - $ myobject-> somemethod():
> 但是,目前,我們將堅持使用PHP隨附的類。讓我們繼續使用我們創建的PDO對象,並通過調用其方法之一來查看我們可以做什麼。
>new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
到目前為止,我向您展示瞭如何創建PDO對像以與您的MySQL數據庫建立連接,以及當出現問題時如何顯示有意義的錯誤消息:
但是,假設連接成功,則需要在使用之前對其進行配置。您可以通過調用新PDO對象的某些方法來配置連接。>在將查詢發送到數據庫之前,我們需要配置數據庫連接的字符編碼。正如我在第2章中簡要提到的那樣,您應該在網站中使用UTF-8編碼的文本,以最大程度地提高用戶在填寫網站上表格時可以使用的字符範圍。默認情況下,當PHP連接到MySQL時,它使用更簡單的ISO-8859-1(或Latin-1)編碼而不是UTF-8。如果我們要保持原樣,我們將無法輕易插入中文,阿拉伯語或大多數英語角色。
>
>即使您100%確定您的網站只能由英語說話者使用,但沒有設置角色集引起的其他問題。如果您的網頁未設置為UTF-8,那麼當人們將某些字符(例如捲曲引號)寫入文本框時,您會遇到問題,因為它們會以不同的字符出現在數據庫中。因此,我們現在需要設置我們的新PDO對像以使用UTF-8編碼。
>我們可以指示PHP通過附加; charset = utf8mb4詢問數據庫時使用UTF-8。只要您的PHP腳本也以UTF-8發送到瀏覽器(這是最近的PHP版本中的默認值):
>
注意:如果您去搜索,您會找到不同的方法來設置Charset,並且本書的早期版本指示您使用此代碼:CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
這是因為在PHP 5.3.6之前,PHP無法正確應用Charset選項。由於您實際上要使用的任何PHP版本都解決了這一點,因此將Charset設置為連接字符串的一部分是首選選項。 我們用來連接到mySQL的完整代碼,然後配置該連接,如下所示。
>new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
>在您的瀏覽器中啟動此示例。 (如果您將數據庫代碼放入index.php中的public Directory和output.html.php文件中的模板目錄中,則頁面的URL為https://v.je/。)
>如果您的服務器啟動並運行,並且一切正常,則應看到一條表示成功的消息。>
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword');
>多虧了我們的捕獲塊,數據庫中的錯誤消息已包含在頁面上:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
方法getMessage()返回一條消息,描述發生的異常。還有一些其他方法(包括getFile()和getline())用於返回拋出異常的文件名和行號。您可以生成一個非常詳細的錯誤消息:
new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
>如果您有一個包含數十個文件的大型網站,這將非常有用。錯誤消息將準確地告訴您要查看哪個文件以及錯誤在哪一行中。
如果您很好奇,請嘗試在數據庫連接代碼中插入其他一些錯誤(例如,拼寫錯誤的數據庫名稱),並觀察結果的詳細錯誤消息。完成後,數據庫連接正常工作,請返回簡單的錯誤消息。這樣,如果您的數據庫服務器出現了真正的問題,您的訪問者就不會被技術gobbledygook轟炸。>
>有了建立的連接並選擇了數據庫,您就可以開始使用存儲在數據庫中的數據。>
>您可能想知道腳本完成執行後,與MySQL Server的連接會發生什麼。如果您真的願意,則可以通過丟棄代表您連接的PDO對象來強迫PHP與服務器斷開連接。您可以通過設置包含對象為null的變量來做到這一點:> 也就 >使用php
發送SQL查詢 在第3章中,我們使用MySQL Workbench連接到MySQL數據庫服務器,這使我們能夠鍵入SQL查詢(命令)並立即查看這些查詢的結果。 PDO對象提供了類似的機制 - EXEC方法:$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword');
>在這裡,$ QUERY是一個字符串,包含您要執行的任何SQL查詢。 > 如您所知,如果執行查詢存在問題(例如,如果您在SQL查詢中犯了打字錯誤),則此方法將為您添加PDOException供您捕獲。 >
考慮以下示例,該示例試圖產生我們在第3章中創建的笑話表請注意,我們使用相同的嘗試…捕獲語句技術來處理查詢產生的可能的錯誤。可以使用多次嘗試…捕獲塊顯示不同的錯誤消息 - 一條用於連接,其中一條用於查詢 - 但這可能會導致相當多的額外代碼。
try { ⋮ do something risky } catch (ExceptionType $e) { ⋮ handle the exception }
>這種方法使我們對顯示的錯誤消息的控制權更少,但是節省了每個數據庫操作的鍵入語句。在本書的稍後,我們將將它們分解為不同的塊,但就目前而言,將所有數據庫操作保留在同一嚐試塊中。
此示例還使用GetMessage方法從MySQL Server檢索詳細的錯誤消息。下圖顯示了例如,笑話表已經存在時顯示的錯誤。>
對於刪除,插入和更新查詢(用於修改存儲的數據),EXEC方法返回受查詢影響的表行(條目)的數量。考慮以下SQL命令,我們在第3章中使用的命令來設置包含“程序員”一詞的所有笑話的日期。
>示例:mysql-update
>通過存儲從$ aventedrows中的Exec方法返回的值,我們可以在$ output變量中使用變量在模板中打印。
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
>如果您刷新頁面以再次運行相同的查詢,則應看到消息更改,如下圖所示。這表明沒有排的更新,因為將新日期應用於笑話與現有日期相同。
>選擇的查詢對待有所不同,因為它們可以檢索大量數據,而PHP提供了處理該信息的方法。
>
>處理選擇結果集
對於大多數SQL查詢,EXEC方法工作正常。該查詢對您的數據庫有所作為,您會從方法的返回值中獲得受影響的行(如果有)。但是,選擇查詢需要比執行更奇特的東西。您會記得,精選查詢用於在數據庫中查看存儲的數據。 SELECT查詢不僅只影響數據庫,還具有結果 - 我們需要一種返回它們的方法。
查詢方法看起來就像EXEC一樣,因為它接受SQL查詢作為要發送到數據庫服務器的參數。但是,它返回的是一個pdostatement對象,它表示一個結果集,其中包含從查詢中返回的所有行(條目)的列表:提供處理查詢時沒有遇到錯誤,該代碼將將結果集(以Pdostatement對象的形式)存儲到變量$結果中。此結果集包含笑話表中存儲的所有笑話的文字。由於數據庫中的笑話數量沒有實際限制,因此結果集可能很大。
>>我在第2章中提到,當我們需要循環時,while循環是一個有用的控制結構,但不知道多少次。我們不能將循環使用,因為我們不知道返回的查詢有多少記錄。實際上,您可以在此處使用一段時間循環來處理結果的行一次設置:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
> not 。 現在,上面的語句將值分配給$ ROW變量,但同時,該語句總體上具有相同的值。這就是讓您在循環中使用該語句作為條件的原因。由於段循環將繼續循環直到其條件評估為false,因此此循環將與結果集中的行一樣多次發生,每次循環執行時,$ row都會佔據下一行的值。每次循環運行時,剩下的所有要弄清楚的是如何從$行變量中檢索值。
> 由Fetth返回的結果集的行表示為關聯陣列,其指數以結果集中的表列命名。如果我們的結果集中$ row是一行,則$ row ['joketext']是該行的joketext列中的值。
>我們在此代碼中的目標是存儲所有笑話的文本,以便我們可以將其顯示在PHP模板中。最好的方法是將每個笑話作為新項目存儲在數組中,
>隨著笑話從數據庫中撤出,我們現在可以將它們傳遞到PHP模板笑話.html.php。
總而言之,這是到目前為止的控制器的代碼:$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword');
$笑話變量是存儲笑話列表的數組。如果您在PHP中寫下了數組的內容,則看起來像這樣:
但是,數據已從數據庫中檢索到數據,而不是在代碼中手動輸入。
>您會注意到,設置了兩個不同的變量 - $笑話和$錯誤 - 具體取決於是否成功執行了Try Block。 在jokes.html.php模板中,我們需要顯示$ jokes數組的內容或$錯誤變量中包含的錯誤消息。>檢查是否已分配了一個變量,我們可以使用以前使用的ISSET函數來檢查是否已提交表單。該模板可以包括一個if語句以確定是顯示錯誤還是笑話列表:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';
>
處理PHP中數組的最常見方法是使用循環。我們已經在循環和循環時已經看到。 foreach循環特別有助於處理數組:
new PDO('mysql:host=hostname;dbname=database', 'username', 'password')
>
>通常,在php模板中使用foreach循環依次顯示陣列的每個項目。這可能是如何尋找我們的$笑話陣列的方式:
$pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword');
>
try { ⋮ do something risky } catch (ExceptionType $e) { ⋮ handle the exception }
> if語句可以完成同樣的事情,通過避免括號來查看內部HTML模板內部更好。
try { $pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', ’mypassword’); $output = 'Database connection established.'; } catch (PDOException $e) { $output = 'Unable to connect to the database server.'; } include __DIR__ . '/../templates/output.html.php';
>使用這些新工具,我們可以編寫模板以顯示笑話的列表。
try { $pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword'); $output = 'Database connection established.'; } catch (PDOException $e) { $output = 'Unable to connect to the database server: ' . $e->getMessage(); } include __DIR__ . '/../templates/output.html.php';
$要么在頁面上顯示$錯誤文本,要么在塊引用(
)中顯示的每個笑話都顯示在段落()中,因為我們在此中有效地引用了每個笑話的作者頁。
>由於笑話可能包含可以解釋為HTML代碼的字符(例如,或&),因此我們必須使用htmlspecialchars來確保它們被翻譯成HTML字符實體(即,&lt;&gt;&gt;&gt; &gt;&gt; ;<!doctype html> <html> <head> <meta charset="utf-8"> <title>Script Output</title> </head> <body> <?php echo $output; ?> </body> </html>登入後複製下面的圖像顯示了此頁面一旦您在數據庫中添加了幾個笑話後的外觀。
>
記得我們如何在控制器中使用一個時循環以一次設置一個行中的行中的行?
事實證明,pdostatement對象的行為就像陣列一樣,當您將它們傳遞到foreach循環時。因此,您可以使用foreach循環而不是while循環稍微簡化數據庫處理代碼:CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製>
>我將在本書的其餘部分中使用此整形詞。 PHP提供的另一種整潔的工具是調用Echo命令的速記方式,如您已經看到的那樣,我們需要經常使用。我們的迴聲陳述看起來像這樣:new PDO('mysql:host=hostname;dbname=database', 'username', 'password')登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製>我們可以使用以下方式:
>這完全是相同的。 $pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', 'mypassword'); 這是一個使用速記迴聲的更新模板。
>示例:mysql-listjokes-shorthand
try { ⋮ do something risky } catch (ExceptionType $e) { ⋮ handle the exception }登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製>從此適用時,我將使用速記符號。
> 注意:在5.4之前的PHP版本中,此速記符號需要啟用相當不常見的PHP設置,因此出於兼容的原因而勸阻它。使用速記符號可能會導致您的代碼從啟用的服務器移動到沒有的服務器時停止工作。 >截至PHP 5.4(因此,您實際上將遇到這些天的任何版本),無論PHP設置如何。try { $pdo = new PDO('mysql:host=mysql;dbname=ijdb', 'ijdbuser', ’mypassword’); $output = 'Database connection established.'; } catch (PDOException $e) { $output = 'Unable to connect to the database server.'; } include __DIR__ . '/../templates/output.html.php';登入後複製登入後複製登入後複製提前思考 在我們剛剛查看的示例中,我們創建了一個模板jokes.html.php,其中包含顯示頁面所需的所有HTML。但是,隨著我們網站的增長,我們將添加更多頁面。當然,我們當然希望人們能夠在網站上添加笑話,我們還需要一個帶有一些介紹性文本的主頁,一個帶有所有者的聯繫方式的頁面,並且隨著網站的增長,也許甚至可能人們可以登錄到網站的頁面。
>>我在這裡跳了很多,但是考慮到項目的發展始終值得一提。如果我們應用方法,我們只是將jokes.html.php用於其餘模板- addjoke.html.php,home.html.php,contact.html.php,login.html.php等等- 我們'最終有很多重複的代碼。 > 網站上的每個頁面都需要一個模板,看起來像這樣的模板:
>作為程序員,重複代碼是您可以做的最糟糕的事情之一。實際上,程序員通常是指乾燥原則,該原則代表“不要重複自己”。如果您發現自己重複了代碼的部分,幾乎可以肯定有一個更好的解決方案。
>所有最好的程序員都是懶惰的,重複代碼意味著重複工作。使用此副本/粘貼方法作為模板,該網站非常難以維護。想像一下,我們要在每個頁面上出現一個頁腳和一個導航部分。現在,我們的模板看起來像這樣:
CREATE USER 'ijdbuser'@'%' IDENTIFIED BY 'mypassword'; GRANT ALL PRIVILEGES ON `ijdb`.* TO 'ijdbuser'@'%';登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製>我們將在2022年遇到問題!如果網站上所有頁面的模板- 例如,jokes.html.php addjoke.html.php,home.html.php,contact.html.php andlogin.html.php-將版權通知中的年份更新為“ 2022”,您需要打開每個模板並更改日期。
>我們可能會很聰明,並從服務器的時鐘(echo date('y');如果您很好奇!)動態讀取日期,以避免此問題,但是如果我們想添加<script> tag,該怎麼辦每個頁面都包含在內嗎?還是向菜單添加新鏈接?我們仍然需要打開每個模板文件並將其更改! </script>
>更改五個或六個模板可能有點煩人,但這不會帶來很多問題。但是,如果網站生長到數十個或數百頁,該怎麼辦?每次您想添加鏈接到菜單時,您都必須打開每個模板並更改它。
這個問題可以用一系列包含語句來解決。例如:
>但是,這種方法需要千里眼:我們需要準確地預測將來可能需要進行的更改,並且使用相關的陳述包括我們預見的更改的位置。 例如,在上面的示例中,通過將它們添加到nav.html.php中添加新的菜單條目很容易,但是在每個頁面中添加new PDO('mysql:host=hostname;dbname=database', 'username', 'password')登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製登入後複製作者最新文章
最新問題function_exists()無法判定自訂函數 function test() { return true; } if (function_exists('TEST')) { ech...來自於 2024-04-29 11:01:01032724父視窗沒有輸出 document.onclick = function(){ window.opener.document.write('我是子視窗的輸出'); ...來自於 2024-04-18 23:52:34012300