亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 語言 > PHP > 正文

PHP基礎

2024-07-21 02:11:11
字體:
來源:轉載
供稿:網友
    php 的基本功能就是解釋一個腳本,來生成發送到客戶機的web 頁面。具有代表性的是,腳本包括逐字發送到客戶機的html 和作為程序執行的php 代碼的混合編碼。無論代碼生成什么樣的輸出,都會發送到客戶機,因此客戶機永遠不會看到代碼,它只能看結果的輸出。
    當php 開始讀取文件時,假設文件內容表示文字的h t m l,則它僅僅拷貝在那里找到的輸出內容。當php 解釋程序遇到一個特殊的打開標記時,就從html 模式切換到php 代碼模式,而作為要執行的php 代碼也開始解釋文件。代碼的結尾由另一個特殊的標記指出,解
釋絳蛟謖飧鑫恢么喲肽j角謝換豀tml 模式。這就允許將靜態的文本( html 部分)與動態產生的結果( php 代碼部分的輸出)相混合,產生依賴于調用環境變化的頁面。例如,可以使用php 腳本來處理表格的結果,在這個格式中,用戶已經輸入了數據庫搜索的參數。
由于格式填入內容的不同,所以每次搜索的參數可能也不同,因此當腳本執行搜索的時候,每個作為結果的頁面將反映不同的搜索。
    讓我們通過一個非常簡單的php 腳本看一看它是如何工作的:
    <html>
    <body>
    hello,world
    </body>
    </html>
    這個腳本并不很有趣,因為它不包括php 代碼!因此您會問:那它有什么好處?這個問題的回答是:它有時有助于建立包括想要生成頁面的html 框架的腳本,然后再加入php代碼。這是非常有效的,php 解釋程序用于它是沒有問題的。
    為了在腳本中包括php 代碼,您可從用兩個特殊標記(腳本開始處的‘ < ? p h p’和腳本結束處的‘? >’)把它與周圍的文本區分開來。當php 解釋程序遇到開始的‘< ? p h p’標記時,就從html 模式切換到php 模式,并解釋它找到的任何php 代碼,直到看見結束的‘ ? >’標記為止。它產生的所有輸出解釋并替換了兩個標記之間的腳本。將前面的實例再重新編寫一下,它包括了少量的php 代碼,如下所示:

    此時,代碼部分是很小的,由單行組成。當解釋代碼時,產生了輸出“ hello, world”,它作為輸出部分發送到客戶機瀏覽器。這樣,這個腳本產生的web 頁面與前面實例產生的web頁面一樣,前面實例的腳本完全由html 組成。
    可以使用php 代碼產生web 頁面的任何部分。我們已經看到了一個特別的實例,在那里整個腳本都由文字的html 組成,而不包括php 代碼。另一個特別的實例是整個腳本都是php 代碼而不包括文字的h t m l:

    這說明php 在如何產生輸出方面有很大的靈活性。但php 也留下一個問題,那就是確定如何組合html 和php 代碼才是合適的。不必把所有代碼都放在一個地方, php 在這方面也很靈活。只要您高興,就可以通過腳本在html 和php 代碼模式之間進行轉換。
php 腳本標記
    除了本章實例中使用的標記之外, php還支持其他的腳本標記。您可以在其他人編寫的php 代碼中看到它們,或者可以自己使用這些標記。php 識別四種標記風格:
    缺省標記風格。這是php 配置為缺省時使用的風格:
    <?php print ("hello,world/n");?>
    簡潔開標記風格。這個風格除了開標記較簡潔外,其他與缺省風格相類似:
    <? print ("hello,world/n");?>
    兼容asp 的風格。這個風格在active server page 環境內部是通用的:
    <% print ("hello,world/n");%>
    <script> 標記風格。如果使用與其他標記風格不同的html 編輯器,這個風格是有用的。當然,它比較冗長,但是當您使用其他標記風格時,編輯器可能不處理php 代碼,這時您將發現它是必需的:
    <script language="php">print ("hello,world/n");</script>
    缺省時,簡潔開標記風格和兼容asp 風格無效。請參閱附錄h 有關開啟它們的說明。
獨立的php 腳本
    當處理命令解釋程序腳本或perl 腳本時,可以編寫從命令行調用的獨立的php 腳本。這里有一個實例:
    #! /usr/local/bin/php -q
    <?php print ("hello,world/n");?>
    前面的腳本可命名為h e l l o . p h p,利用chmod +x 使之成為可執行的,并從命令解釋程序中調用:
    % hello.php
    hello,world
    本章中我們不編寫任何獨立的腳本。這里編寫的所有實例都期望web 服務器調用它們來生成web 頁面。
    下一個腳本有一些實質性的內容,但仍然相當簡短。它說明了如何較容易地從php 訪問mysql數據庫,并在web 頁面中使用查詢結果。此腳本在第5 章表達得很簡短,它形成了歷史同盟web 站點主頁的基礎。在我們繼續往下做的時候,應該使腳本更精巧一些,但直到
現在為止,它所做的只是顯示簡短的歡迎消息和當前同盟會員資格的計數:


    歡迎消息就是一個靜態文本,因此它作為文字的html 是最容易編寫的。另一方面,會員資格的計算是動態的,而且隨時會更改,因此必須在它不工作時通過查詢samp_db 數據庫中的member 表來確定。
    在開和閉腳本標記之間的代碼文本執行一個簡單的任務。首先,它打開了與mysql服務器的連接,并使samp_db 數據庫成為缺省數據庫。然后,它發送一個到服務器的查詢來確定此刻歷史同盟有多少成員(我們將它作為member 表中的行數)。查詢結果將作為包括會員
資格計數消息的一部分顯示出來,然后再做處理。
    在處理過程中,如果任何一點發生錯誤,該腳本都會簡單地退出。它由于太簡單而不產生錯誤輸出,因此把訪問該web 站點的人們搞糊涂了(如果依靠php 代碼生成整個web 頁面,當因錯誤而退出,且不產生任何輸出時,可能會使訪問頁面的人非常惱火,因為有些瀏
覽器將顯示“這個頁面沒有數據”的對話框)。
    讓我們把該腳本分成幾段,看看它是如何工作的。第一步是用mysql_pconnect() 連接到服務器:
    上一篇      目錄      下一篇[email protected]_pconnect ("pit.viper.snake.net","paul","secret")
    or exit ();
    mysql_pconnect() 把主機名、用戶名和口令作為參數。連接建立成功,則返回連接標識符,如果發生錯誤,則返回fa l s e。如果連接失敗,腳本立刻調用exit() 來結束腳本,并且不再產生輸出。
    在mysql_pconnect() 調用前的‘@’字符是什么意思呢?就是“請關閉”的意思。有些php 函數在失敗時除了返回狀態代碼之外還寫出錯誤消息。在mysql_pconnect() 情況下,失敗的連接導致了下面的消息出現在發送到客戶機瀏覽器的web 頁面上:
    warning:mysqlconnection failed:access denied for user:
    'paul0pit-viper.snake.net' (using password:yes)
    這樣很難看,參觀我們站點的人們可能不知道它是如何造成的和該怎樣處理它。把‘ @’字符放到mysql_pconnect() 調用的前面,就可以取消這個錯誤消息,以使我們能在返回值的基礎上自己選擇如何處理錯誤。對于該腳本,如果發生錯誤,最好根本不產生屬于會員資格計數的輸出。這樣,頁面將只包含歡迎消息。
    任何php 函數都可以使用‘@’,但以筆者的經驗來說,初始的mysql_pconnect() 調用是最可能失敗的一個。因此,本章的例子禁止來自該函數中的消息。
    將名稱和口令嵌入到所有人都能看到的腳本中,可能會使您緊張不安。是這樣的,名稱和口令出現在發送到客戶機的web 頁面上是對的,因為該腳本的內容由其輸出的結果替換掉了。然而,如果web 服務器不知何故配置不當,沒有識別出腳本需要由php 代碼來處理,
它就會將腳本以純文本發送出去,且會暴露連接參數。在8 . 2 . 1節“使用函數和include 文件”中,將簡要地處理這類情況。
    mysql_pconnect() 返回的連接標識符可以傳遞到php api 中的幾個與mysql相關的調用中。然而,對于這樣的調用,標識符總是可選擇的。例如,可以使用下列格式之一來調用mysql_ s e l e c t _ db ( ):
    mysql_select_db ($db_name,上一篇      目錄      下一篇);
    mysql_select_db ($db_name);
    mysql_pconnect() 與mysql_connect() 的對比函數mysql_pconnect() 與函數mysql_connect() 相似,都具有主機名、用戶名和口令
參數,并返回連接標識符或false 來說明連接是否成功。兩個調用之間的不同在于:mysql_pconnect() 建立了一個持久的連接,而mysql_connect() 建立了一個非持久的連接。與非持久連接不同,持久連接在腳本終止時不關閉。如果另外一個php 腳本隨后由同一
個apache 子處理執行,并用同樣的參數調用mysql_ p c o n n e c t ( ),將重新使用這個連接。這比關閉后再建立連接的效率要高。
    如果忽略了從一些相關mysql的php 調用中得到的連接參數,調用就會使用最近打開的連接。這樣,如果腳本只打開單個連接,那么在任何mysql調用中永遠不必指定連接參數——即連接是缺省的。這就是c 或dbi api 與mysql程序設計的極大不同之處,因為它
們沒有這樣的缺省。
    筆者使用上一篇      目錄      下一篇 變量在簡單的主頁上編寫了下面的連接代碼,使mysql_pconnect() 返回哪種類型的值更加清晰:
    上一篇      目錄      下一篇[email protected]_pconnect("pit-viper.snake.net","paul","secret")
    or exit();
    然而,實際上,我們在腳本的其他地方都沒有使用$ l i n k,因此代碼可更簡單地寫成:
    @mysql_pconnect("pit.viper.snake.net","paul","secret")
    or exit();
    假設連接建立成功,則下一步是選擇一個數據庫:
    mysql_select_db("samp_db")
    or exit();
    如果mysql_select_db 失敗,我們將會默默地退出。如果我們能夠連接到服務器,并且數據庫存在,那么似乎不可能發生錯誤,但是仍然要嚴格地檢查問題并采取相應的行動。選擇數據庫之后,可將查詢發送到服務器,提取結果,加以顯示,然后釋放結果集:
    $result=mysql_query("select count(*) from member
    or exit();
    if ($row = mysql_fetch_array ($result))
        echo "<p>the league currently has ". $row[0] . "members";
    mysql_free_result($result);
    mysql_query() 函數將查詢發送到服務器中去執行。查詢不用分號或者‘ / g’終止。如果查詢非法或因為某些原因不能執行,則mysql_query() 返回fa l s e,否則返回一個結果集標識符。該標識符是我們能用來獲得有關結果集信息的值。對于查詢,該結果集由表示會員資格計數的單列值的單行組成。為得到這個值,我們可以把結果集標識符傳給mysql_ f e t c h _ r o w ( )
來獲取行,將此行賦給變量$ r o w,并以$row[0] 形式訪問第一個元素(只有一個元素時也是這樣)。
    當處理完結果集時,將結果集傳遞給mysql_free_result() 進行釋放。實際上這種調用在我們的腳本中是不必要的,因為當腳本結束時, php 會自動地釋放所有活動的結果集。
    mysql_free_result() 有助于執行大型查詢或大量查詢的腳本。它防止大量內存的使用。
    為了使用腳本,需要在某處安裝它。本章將采用這樣的約定:美國歷史同盟在apache 文檔樹的最高一級中有自己的目錄,稱為us h l,因此主頁面腳本作為該樹的ushl/index.php 進行安裝。我們也將為學分保存方案開發腳本,因此給出目錄g p。如果web 站點主機是pit-viper.snake.net,那么這兩個目錄中的頁面將有如下開頭的url:
    http://pit-viper.snake.net/ushl/
    http://pit-viper.snake.net/gp/
    例如,每個目錄的主頁面都可稱為i n d e x . p h p,并以如下方式進行訪問:
    http://pit-viper.snake.net/ushl/index.php
    http://pit-viper.snake.net/gp/index.php

使用函數和include 文件

    php 腳本與dbi 腳本的不同之處在于, php 腳本位于web 服務器文檔樹的內部,而dbi 腳本位于cgi-bin 目錄中,這個目錄在文檔樹的外部。這就提出了一個安全性問題:服務器配置不當的錯誤可能導致位于文檔樹內部的頁面會以純文本方式泄露給客戶機。這意味著
建立與mysql服務器連接的用戶名和口令如果在php 腳本而非dbi 腳本中使用,則將處于暴露給外界的很高的危險之中。
    php 中的變量
    在php中,可以通過簡單地使用變量而使它們存在。主頁腳本使用了三個變量:$ l i n k、$result 和$ r o w,沒有一個變量會在所有地方都聲明(聲明變量的地方有上下文,如在函數內部引用全局變量時,我們隨后會談到這個問題)。
    變量由美元符號(‘$’)為開頭的標識符表示。無論它表示什么類型的值都是正確的,盡管對于數組和對象要添加一些額外內容來訪問值的單個元素。如果變量$x 表示單個值,例如,數字或字符串,則可以寫成$x 來訪問它。如果$x 表示有數字索引的數組,則可
以寫成$ x [ 0 ]、$x[1] 等等來訪問它的元素。如果$x 表示有關聯索引的數組,如“ y e l l o w”或者“l a rg e”,則可以寫成$ x [“y e l l o w”]、$ x [“l a rg e”] 來訪問它的元素。
    php 數組可以同時擁有數字索引的元素和相關索引的元素。例如, $x[1] 和 $ x [“ l a rg e”] 都能作為同一數組的元素。如果$x 代表一個對象,則可寫成$ x ->property_name 來訪問它所具有的屬性。例如, $x->yellow 和$ x - > l a rge 都是$x 的屬性。
作為屬性名,數字是不合法的,因此$x->1在php 中是不合法的。
    初始的歷史同盟主頁腳本也存在這個問題,因為它包括mysql用戶名和口令的直接值。讓我們用兩個php 性能:函數和include 文件,把這些連接參數移到腳本外面。我們將編寫函數samp_db _ c o n n e c t ( )來建立這個連接,并把函數放到一個include 文件中—不是主腳本部分的,但可以從腳本中引用的文件。這種方法的優點如下:
    編寫連接建立代碼比較容易。不需要寫出所有參數,就可以在連接后用samp_db _connect() 選擇數據庫,使一個函數可以進行兩個php 函數的工作。由于你可以將精力集中于腳本的獨特標記,而不必為連接建立代碼分心,因此也使得腳本更加易于理解。
    可從腳本中訪問include 文件,但可移到apache 文檔樹的外面。這使它的內容對于客戶機來說是不可訪問的,即使web 服務器配置不當,連接參數也不會暴露給它們。使用include 文件,對于隱藏不想由web 服務器發送到站點的任何類型的敏感信息都是個良策。
    雖然如此,但這并不意味著用戶名和口令在任何意義上說都是安全的。如果沒有采取預防措施,在web 服務器主機上注冊的用戶,能夠直接讀取include 文件。請參閱7 . 4 . 3節“從web 腳本連接到mysql服務器”關于安裝dbi 配置文件所描述的預防措施,它們用于保護口令和用戶名不受其他用戶侵害。對php 的include 文件也要應用同樣的防范措施。
    php 語言上的影響
    如果有c 程序設計經驗,則可能注意到:腳本中許多語法的結構與c 程序設計中的非常類似。實際上, php 語法很大程度上來自于c,因此這種相似處并不是巧合。如果有些c 的背景知識,就可以將它的許多內容轉換到php。事實上,如果不能確信如何用php 編寫表達式或控制結構,則可以試用c 中編寫它們的方法,這很可能也是正確的。雖然php 的基本部分主要在c 中,但也包含了使用java 和perl 的成分??梢栽谧⑨屨Z法中查看它,在那里允許以下形式:
    # perl-style comment from '#' to end of line
    //c++ or java-style comment from '//' to end of line
    //* c-style comment between slash-star to star-slash */
    perl 的其他相似性包括‘ .’字符串連接操作符(包括‘ . =’作為額外的連接),變量引用和轉義序列的方法是在雙引號內而非單引號內解釋的。
    include 文件可以由多個腳本使用。這提高了代碼的可重用性,使代碼更加可維護。同時也允許對訪問這個文件的每個腳本不費力地做出全局性的更改。例如,如果我們將數據庫samp_db 從pit-viper 移動到b o a,則不必更改一簇單個腳本,而只要更改包含
samp_db_connect() 函數的include 文件中mysql_pconnect() 調用的主機名參數即可。
    為了使用include 文件,必須有存放它們的地方,而且必須使php 找到它們。如果系統已經有了這樣一個位置,則可以使用。如果沒有,則使用下面的過程建立一個include 文件的位置:
    1) 創建一個目錄來存放php 的include 文件。該目錄不能位于web 服務器文檔樹內部!筆者使用/usr/local/apache/php 的php include 目錄,它與我的文檔樹在同一層次上(/ us r / l o c a l / a p a c h e / h t d o c s),而不是在其內部。
    2) 通過完整的路徑名或者告訴php 在搜索時尋找哪個目錄來引用include 文件。后者的方法更方便些,因為如果我們使用了文件的基名, php 就會找到它( php include 文件與c頭文件有些類似,其中包括的php 將在多個目錄中搜尋include 文件,就像c 預處理程序在多個目錄中搜尋c 頭文件一樣)。為了告訴php 去哪里查看,修改php 初始化文件(系統上的/ us r / l o c a l / l i b / p h p 3 . i n i)來改變include_path 的值。如果它沒有值,可以將它設置為新的包含路徑的完整路徑名:
    include_path="current_value:/usr/local/apache/php"
    如果include_path 已經有值了,則把新的目錄加到那個值中:
    include_path="current_value:/usr/local/apache/php"
    3) 創建想使用的include 文件并將它放到i n c l ud e目錄中。文件應該有一些有特點的名稱,為了這個目的,這里我們使用samp_db . i n c。它的內容將在下面列出。對于我們這里開發的腳本,當連接到mysql服務器上時,會一直使用samp_db 數據庫,因此連接函數samp_db_connect() 也可以為我們選擇samp_db 數據庫。如果連接成功并選擇了這個數據庫,這個函數就返回一個連接標識符;如果發生錯誤,則返回fa l s e。發生錯誤時將不打印消息,并且允許調用者靜靜地退出,或者在環境允許時再打印消息。

    觀察一下,samp_db.inc 文件的內容由‘< ? p h p’和‘? >’括在一起。這是因為php 是在html 模式中開始讀取文件的。如果沒有這些標記php 會把文件以純文本發送出去,而不是作為php 代碼解釋。如果想在文件中包含文字的html 是很好的選擇。但是,如果文件包含php 代碼,就必須在腳本標記內部封閉代碼。
    4) 使用下面的行從腳本中引用文件:
    include("samp_db.inc");
    當php 看到這一行時,就搜尋文件并讀取內容。對于腳本的下列部分,文件中的任何事物都變成可訪問的。
    在建立了我們的include 文件samp_db.inc 之后,就可以修改歷史同盟主頁來引用i n c l ud e文件,并通過調用samp_db_connect() 函數連接到mysql服務器上:

    include( ) 與require( ) 的對比
    php 的require() 性能與include() 相類似。不同之處在于,對include() 來說,在include() 執行時文件每次都要進行讀取和評估;而對于require() 來說,文件只處理一次(實際上,文件內容替換了require() 語句)。這意味著如果有包含這些指令之一的代碼和
可能執行多次的代碼,則使用require() 的效率比較高。另一方面,如果每次執行代碼時想讀取不同的文件,或者有通過一組文件迭代的循環,就使用i n c l ud e ( ),因為可以給想要包括的文件名設置一個變量,當參數為include() 時使用這個變量。
    samp_db.inc 文件對其他函數也是有用的,我們可以將它作為各種其他事物的儲藏庫。實際上,還可以再創建兩個函數放入到文件中。我們編寫的每個腳本在頁面的開頭都會產生一組相當醒目的html 標記,而另一組在結尾。不必在每個腳本中將它們逐字地寫出,我們可以通過編寫函數html_begin() 和html_end() 來做這些事。函數html_begin() 能夠提取幾個指定了頁面標題和頭的參數。兩個函數的代碼如下:

    然后我們可以修改歷史同盟主頁來使用這兩個新函數,如下所示:

    請注意代碼被分成了兩塊,兩塊代碼之間出現了歡迎消息的文字html 文本。
    產生頁面開始和最后部分的函數用法給了我們一個重要的能力。如果想改變使用這些函數的頁面頭和尾的外觀,可以在函數中包含一些代碼。使用它們的每個腳本也都將自動地受到影響。例如,您可以把消息“ copyright ushl”放在每個歷史同盟頁面的底部。頁面尾部函數html_end() 會很容易地做到這一點。

一個簡單的查詢頁面

    已經嵌入到歷史同盟主頁中的腳本運行了一個只返回單個行的查詢。下一個腳本介紹了如何處理多行的結果集。它獲取并顯示了member 表中的內容。這就是第7 章開發的dump_members dbi 腳本的php 等價物,因此稱它為d um p _ member s . p h p。它與dbi 版本的不同之處在于,它希望在web 環境中使用而不是在命令行中使用。由于這個原因,它需要產生html 輸出而不是簡單地寫出制表符分隔的文本。為了使行和列漂亮地排列,我們將以html 表形式編寫會員資格記錄。腳本如下:

    這個腳本使用了die() 函數來打印消息,如果發生錯誤則退出( die() 函數與exit() 函數相類似,但是它在退出之前打印消息)。與我們在歷史同盟主頁中使用的靜靜地退出方法相比,這是一種不同的錯誤處理方法。在dump_membes.php 中,我們希望看到一個特殊的結果,因此打印錯誤消息來說明發生的問題是有道理的。
    腳本可以安裝在ushl 目錄并用http://pit-viper.snake.net/ushl/dump_members.php 訪問??梢栽跉v史同盟主頁的新腳本中增加一個連接,以便人們了解它:



處理查詢結果

    在這一節中,我們將更細致地檢查如何執行mysql查詢并處理結果集。在php 中,所有的查詢都通過調用mysql_query() 函數來發布,這個函數提取查詢字符串和連接標識符作為參數。連接標識符是可選的,因此可以用下面任意一種形式調用mysql_query():
    $result=mysql_query($query,上一篇      目錄      下一篇); # use explicit connection
    $result=mysql_query($query); # use default connection
    對于不返回行的查詢(非select 的查詢,如d e l e t e、insert、replace 和update),mysql_query() 返回true 或者false 說明查詢成功或者失敗。為了獲得成功的查詢,可以調用mysql_ a ffected_rows() 找出有多少行被改變(可能是刪除、插入、替換或者更新)。
    對于select 語句,mysql_query() 返回結果集標識符或者false 說明查詢是成功或是失敗。為了獲得成功的查詢,使用結果集標識符可以獲得更多的有關結果集的信息。例如,可以找出結果集有多少行或列,或者提取這個結果集內部包括的行。
    當mysql_query() 返回fa l s e(也就是零)時,意味著查詢失敗—換句話說就是發生一些錯誤而不能執行查詢。查詢失敗可能有下面幾個原因:
    查詢可能是畸形的并包含語法錯誤。
    查詢依照語法可能是正確的,但是在語義上卻是無意義的,例如要從不包含列的表中選擇列時。
    沒有充分的權利執行查詢。
    由于網絡問題,可能已經連接不到mysql服務器主機。
    在以上每種情況中(還有其他情況),mysql_query() 都返回fa l s e。如果要想知道錯誤的詳細原因,就調用mysql_error() 或者mysql_errno() 獲得錯誤消息字符串或者數字錯誤代碼(請參閱8 . 2 . 4節“處理錯誤”一節)。
    考慮mysql_query() 造成的兩種最常見的錯誤,返回值是行計數,或者它包含查詢返回的數據,兩者都是錯誤的。
    1. 處理不返回結果集的查詢
    下面的代碼使用delete 說明了如何處理不返回任何行的查詢:
    $result=mysql_query("delete from member where member_id=149");
    if (!$result)
        print ("query failed/n");
    else
        printf("number of rows deleted:%d/n",mysql_affected_rows());
    如果有一個id 號為149 的成員,mysql就刪除記錄,且mysql_query() 返回t r u e。如果沒有這樣的成員呢?這種情況下mysql_query() 仍然返回t r u e!這使將精力耗在誤解mysql_query() 的返回值是行計數的人們非常驚訝。兩種情況都返回t r u e,是因為不管實際上是否刪除了一些行,查詢都是合法的。由查詢作用的行的數目則是完全不同的事。若要在查詢成功之后提取值,可調用mysql_ a ff e c t e d _ r o w s ( )。
    2. 處理返回結果集的查詢
    下面的實例提供了select 查詢處理的大致概況:

    不要假設mysql_query() 會成功
    在php 郵件發送清單中,新的php 用戶會共同詢問:執行腳本時為什么會發生下面的錯誤消息:
    warning:0 is not a mysqlresult index in file on line n
    這個消息將為零的結果集標識符的值傳遞給了期望有效結果集的一些函數(如提取行的函數)。這意味著早時的mysql_query() 調用返回了零值—就是fa l s e。換句話說就是mysql_query() 失敗,并且在由其他函數使用它之前,腳本編寫程序對檢查返回值并不煩惱。在使用mysql_query() 時,要一直檢測返回值。
    如果查詢失敗,結果將為fa l s e,對這個結果我們只是打印一條消息(取決于環境,其他對錯誤的反應可能更合適)。如果查詢成功,則mysql_query() 返回結果集標識符。這個返回值在許多方法中是有用的(但不是作為行計數!)。結果集標識符可用于下列目標:
    將它傳遞給mysql_ n um _ r o w s ( ),來確定結果集中的行數。
    將它傳遞給mysql_ n um _ f i e l d s ( ),來確定結果集中的列數。
    將它傳遞給提取行的例程,來提取結果集的連續行。這個實例使用了mysql_ f e t c h _r o w ( ),但是還有其他的選擇,我們馬上就會看到它們。
    將它傳遞給mysql_ f r e e _ r e s ul t ( ),來釋放結果集并允許php 處理一些與之相關的源文件。
    在mysql_query() 成功地執行s e l e c t查詢之后(請參見表8 - 1),php 為檢索結果集提供了幾個提取行的函數。當不再有行時,每個函數都得到一個結果集標識符作為參數并返回fa l s e。
表8-1php 行提取函數

函數名返回值
mysql_ f e t c h _ r o w ( )一個數組,由數字索引訪問其元素
mysql_ f e t c h _ a r r a y ( )一個數組,由數字索引或相關索引訪問其元素
mysql_ f e t c h _ o b j e c t ( )一個對象,作為屬性訪問其元素

    最基本的調用是mysql_ f e t c h _ r o w ( ),它返回結果集的下一行作為一個數組。數組的元素通過從0 到mysql_ n um _ f i e l d s ( )-1范圍內的數字索引訪問。下面的實例說明了如何在每一行都提取和打印值的簡單循環中使用mysql_ f e t c h _ r o w ( ):

    變量$row 是一個數組。可用$row[$i] 訪問它, $ i在這里是數字列索引。如果熟悉php count() 函數,可以試著用它而不要用mysql_num_fields() 來確定每一行的列數。count() 只計算這個數組中已設置值的元素的數量, php 不是與null 列值相對應的元素設置值。count ( ) 對返回列數的度量是不可靠的,因為那不是它想要的。它還用于另外兩種提取行的函數。
    第二個提取行的函數mysql_fetch_array() 在表8 - 1中列出,它與mysql_fetch_row() 相類似,但是由數字索引和相關索引返回的數組元素都是可靠的。換句話說,可以通過數字或名稱訪問元素:

    由mysql_fetch_array() 返回的信息是mysql_fetch_row() 返回的信息的擴展集。除此之外,兩個函數之間的不同性能是可以忽略不記的,調用mysql_ f e t c h _ a r r a y ( )可以無特殊性能損耗。
    第三個提取行的函數mysql_ f e t c h _ o b j e c t ( ),返回結果集的下一行作為對象,這意味著用$row->col_name 語法訪問行的元素。例如,如果從president 表中檢索last_name 和first_name 值,可以用$row->last_name 和$row->first_name 訪問那些列:

    在查詢結果中測試null 值
    可以使用isset() 函數測試select 查詢返回的列值是否為null。例如,如果行包含在$row 數組中,那么如果$row[$i] 對應于null 值,則isset($row[$i]) 就為fa l s e,如果$row[$i] 為非null 值,則isset($row[$i]) 就為t r u e。相關的函數是e m p t y ( ),但是對于null 和空字符串,empty() 返回的結果都是一樣的,因此作為null 值測試而言,這個函數是無用的。
    如果查詢包括計算的列怎么辦?例如,發布一個作為表達式結果計算的返回值的查詢:
    select concat(first_name," ",lsat_last_name)from president
    這樣編寫的查詢不適于使用mysql_ f e t c h _ o b j e c t ( )。選擇的列名本身就是表達式,它不是合法的屬性名。然而,可以通過給列賦予一個別名來提供合法的名稱。下面的查詢將列的別名命名為f ul l _ name,如果用mysql_fetch_object() 提取結果,就允許它以$row->full_name 形式來訪問:
    select concat(first_name," ",lsat_last_name) as full_name from president

處理錯誤

    php提供了三種處理錯誤的方法:
    ■ 用‘@’取消錯誤消息??梢詫σ恍╋@示消息的函數使用‘ @’。當我們調用mysql_pconnect() 阻止來自于函數的錯誤消息不在發送到客戶機的頁面上出現時,就已經在做這一點了。
    使用error_reporting() 函數。這個函數按下列級別將錯誤報告打開或者關閉:

錯誤級別錯誤報告類型
1正常函數錯誤
2正常警告
4分析程序錯誤
8請注意

    為了控制錯誤報告,可調用error_reporting() 函數,且參數為想要激活的級別的總和。關閉級別1和級別2警告應該完全能夠取消來源于mysql的消息:
    error_reporting(4+8);
    你可能不想關閉有關分析錯誤的級別4警告,如果關掉了,可能要有一段艱難的時間用來調試它對腳本造成的改動!級別8警告常常被忽略,但有時它指出腳本中應該注意的問題,因此您可能也想把它激活。還有16和3 2錯誤級別,它們都來自于php 核心發動機,而非函數,因此通常情況下不必考慮它們。
    使用mysql_error() 和mysql_er r n o ( )。這些函數報告了mysql服務器返回的錯誤信息。它們與相應的c api 調用相類似。mysql_error() 以字符串形式返回錯誤信息(如果不發生錯誤就返回空字符串)。mysql_errno() 返回一個錯誤數字(如果不發生錯誤就返回0)。兩個函數都有指定與mysql服務器連接的連接標識符參數,在返回狀態的連接上都返回最近調用的mysql函數的錯誤信息。連接標識符是可選的,如果缺失,就使用最近打開的連接。例如,可以這樣報告mysql_query() 的錯誤:

    mysql_error() 和mysql_errno() 的php 版本在一個重要方面與c api 中對應的部分不同。在c 中,即使試圖連接服務器失敗,也會得到錯誤信息。相反, php 調用直到連接建立成功,才返回有用的連接信息。換句話說,如果連接失敗,就不能用mysql_error() 和mysql_er r n o ( ) 報告失敗原因。如果要報告連接失敗的特殊原因而不是普通原因,則必須做特殊的考慮。請參閱附錄h“php api 參考”,其中詳細介紹了如何去做。
    當檢測到錯誤時,本章的腳本打印了相當普通的錯誤信息,如“查詢失敗”。然而在開發腳本時,您會發現:加入一個mysql_error() 調用對幫您發現錯誤的特殊原因是很有用的。

引用問題

    在php 中構造查詢字符串時,知道引用問題是必要的,就像在c 和perl 中一樣。雖然函數名在各種語言中是不同的,但處理引用問題的方法卻是類似的。假設正在構造一個,將新的記錄插入到表中的查詢,可以在值的前后加上引號插入到字符串列中:

    這里的問題是引用值的本身還包含著引號(“o’m a l l e y”),如果將查詢發送到mysql服務器會導致語法錯誤。在c 中我們調用mysql_escape_string() 解決這個問題。在perl dbi腳本中則使用quote( ) 。php 有一個addslashes( ) 函數可以完成同樣的事情。例如,調用a d d s l a s h e s(“o’ malley”)返回“o’ malley” 值。將前面的實例做如下編寫來解決引用問題:

    dbi quote( ) 方法是把前后的引號加到字符串中。addslashes( ) 則不是,因此我們仍需在查詢字符串中要插入值的周圍將那些引號顯式地指定出來。
    當編寫信息出現在web 頁面上時也將發生引用問題。如果正在編寫一個將作為html 或u r l的部分出現的字符串,而且這個字符串包含html 或url 內部的特殊字符,最好將它編碼。php 函數htmlspecialchars( ) 和urlencode( ) 可以做到這點,它們與c g i . p m
escapehtml( ) 和escape( ) 方法相類似。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美亚洲成人| 亚洲男人av在线| 97在线精品国自产拍中文| 久久久久中文字幕2018| 亚洲精品资源美女情侣酒店| 国产日产久久高清欧美一区| 一区二区三区在线播放欧美| 久久精品中文字幕免费mv| 91精品国产91久久久久久吃药| 欧美激情亚洲综合一区| 欧美黄色www| 亚洲在线一区二区| 中文字幕精品av| 秋霞午夜一区二区| 久久精品99久久久久久久久| 91精品国产精品| 91久久精品国产91久久性色| 国产精品91在线| 亚洲欧美国产制服动漫| 国产精品一区二区久久精品| 久久久亚洲国产| 欧美日本啪啪无遮挡网站| 欧美在线不卡区| 福利一区福利二区微拍刺激| 久久夜精品香蕉| 欧美一级大胆视频| 日韩在线中文视频| 日韩视频亚洲视频| 日韩在线观看网址| 亚洲精品日韩丝袜精品| 国产成人精品av| 久久精品国产91精品亚洲| 亚洲欧美激情另类校园| 国产亚洲欧美日韩美女| 久久99精品国产99久久6尤物| 日韩精品在线影院| 久久久久久久久久久久av| 91影视免费在线观看| 亚洲精品久久久久久久久| 91美女福利视频高清| 久久激情视频免费观看| 久久不射电影网| 亚洲免费av电影| 欧美一级高清免费播放| 在线免费观看羞羞视频一区二区| 国产精品视频yy9099| 性夜试看影院91社区| 国产亚洲一区二区在线| 青青精品视频播放| 国产成人一区三区| 日本最新高清不卡中文字幕| 国内精品国产三级国产在线专| 国产精品18久久久久久麻辣| 国产成人免费av电影| 亚洲人成电影在线观看天堂色| 中文一区二区视频| 中文字幕欧美亚洲| 欧美国产精品va在线观看| 欧美在线观看www| 国产在线a不卡| 国产精品黄色影片导航在线观看| 日韩动漫免费观看电视剧高清| 91亚洲精品久久久久久久久久久久| 亚洲欧美日本精品| 国产精品6699| 久久69精品久久久久久久电影好| 日本精品在线视频| 亚洲性69xxxbbb| 久久精品99久久久久久久久| 国产精品久久久久久久9999| 成人免费视频在线观看超级碰| 91精品国产自产在线| 欧美色视频日本版| 亚洲精美色品网站| 欧美性猛交99久久久久99按摩| 国产一区二区欧美日韩| 一区二区三区www| 91社区国产高清| 91精品国产乱码久久久久久久久| 精品无码久久久久久国产| 欧美精品在线免费观看| 青草青草久热精品视频在线网站| 欧美一乱一性一交一视频| 中文字幕欧美日韩va免费视频| 亚洲综合精品一区二区| 国产成人亚洲综合91| 国产精品亚洲美女av网站| 日本一区二区在线免费播放| 国产精品www网站| 日韩一二三在线视频播| 国产在线观看一区二区三区| 久久伊人91精品综合网站| 久久精品人人爽| 中文字幕亚洲字幕| 日韩有码片在线观看| 中文字幕久久久av一区| 亚洲奶大毛多的老太婆| 久久久精品一区| 韩剧1988在线观看免费完整版| 欧美亚洲国产日本| 久久久久久久久电影| 亚洲精品在线视频| 欧美一乱一性一交一视频| 91精品在线观看视频| 国产精品成人一区二区| 亚洲午夜女主播在线直播| 国产成人精品一区二区在线| 欧美网站在线观看| 中文字幕精品一区二区精品| 欧美韩国理论所午夜片917电影| 日韩电影免费观看在线| 亚洲视频在线观看| 欧美成人免费视频| 亚洲人成在线一二| 亚洲精品wwww| 日韩电影中文 亚洲精品乱码| 国产亚洲精品久久久久动| 亚洲人成电影在线播放| 97在线观看免费高清| 亚洲影院色无极综合| 欧美激情性做爰免费视频| www.国产精品一二区| 中文字幕精品久久| 九九热这里只有精品免费看| 69影院欧美专区视频| 日韩视频在线免费| 久久午夜a级毛片| 国产精品私拍pans大尺度在线| 久久99热这里只有精品国产| 亚洲国产精品成人va在线观看| 国产精品视频999| 精品色蜜蜜精品视频在线观看| 成人网在线观看| 中文字幕在线视频日韩| 久久久亚洲影院| 日韩中文字幕不卡视频| 日韩h在线观看| 亚洲女人天堂av| 中文字幕久久亚洲| 久久亚洲精品中文字幕冲田杏梨| 亚洲国产精品电影| 国产精品日韩在线一区| 日韩成人xxxx| 国产一区香蕉久久| 久久亚洲一区二区三区四区五区高| 亚洲淫片在线视频| 亚洲国产精品久久久| 国产91在线播放精品91| 久久噜噜噜精品国产亚洲综合| 欧美日韩亚洲高清| 成人高清视频观看www| 亚洲直播在线一区| 国产亚洲欧美一区| 亚洲国产欧美一区| 久久国产精品视频| 国产精品视频内| 欧美精品成人在线| 久久久av一区| 亚洲成年人在线播放| 国产91九色视频| 久久网福利资源网站| 欧美一区二区三区……| 亚洲理论在线a中文字幕| 日本亚洲欧美成人|