本文章收藏了php開發中常常會碰到的一些疑惑或一些小問題,大家可參考一下。
上面一些函數之間的區別,
1.isset()和empty()的區別
兩者都是測試變數用的。但是isset()是測試變數是否被賦值,而empty()是測試一個已經被賦值的變數是否為空白。如果一個變數沒被賦值就引用在php裡是被允許的,但會有notice提示。如果一個變數被賦空值,$foo=”"或者$foo=0或者$foo=false,那麼empty($foo)返回真,isset($foo)也返回真,就是說賦空值不會登出一個變數。要登出一個變數,可以用 unset($foo)或者$foo=NULL。
2.如何顯示錯誤資訊
當php.ini的display_errors = On並且error_reporting = E_ALL時,將顯示所有的錯誤和提示,調試的時候最好開啟以便錯誤修正,如果你用以前php寫法錯誤資訊多半是關於未定義變數的。變數在賦值以前調用會有提示,解決辦法是探測或者屏蔽
3.單引號 雙引號什麼區別?分別什麼時侯用
單引號中,任何變數($var)、特殊逸出字元(如”t r n”等)不會被解析,因此PHP的解析速度更快,逸出字元僅僅支援”’”和””這樣對單引號和反斜線本身的轉義;雙引號中,變數($var)值會代入字串中,特殊逸出字元也會被解析成特定的單個字元,還有一些專門針對上述兩項特性的特殊功能性轉義,例如”$”和”。這樣雖然程式編寫更加方便,但同時PHP的解析也很慢;數組中,如果下標不是整型,而是字串類型,請務必用單引號將下標括起,正確的寫法為$array['key'],而不是$array[key],因為不正確的寫法會使PHP解析器認為key是一個常量,進而先判斷常量是否存在,不存在時才以”key”作為下標帶入運算式中,同時出發錯誤事件,產生一條Notice級錯誤。因此,在絕大多數可以使用單引號的場合,不要使用雙引號。
4.print,echo,print_r什麼區別?分別什麼時侯用?
echo和print都可以做輸出,不同的是,echo不是函數,沒有傳回值,而print是一個函數有傳回值,所以相對而言如果只是輸出 echo 會更快,而print_r通常用於列印變數的相關資訊,通常在調試中使用
5.在PHP中有些時候需要開啟遠程檔案
開啟遠程檔案函數為:fopen(http://XXX.com/a.php),fsockopen(http://XXX.com/a.php) , file_get_contents(http://XXX.com/a.php)等)
在php5,apache2.2.X環境下,會提示你無法開啟檔案流,http請求失敗(failed to open stream: HTTP request failed!)
在php.ini中,有這樣兩個選項:
allow_url_fopen =on(表示可以通過url開啟遠程檔案),
user_agent=”PHP”(表示通過哪種指令碼訪問網路,預設前面有個 ” ; ” 去掉即可。)
重啟Apache服務即可。
6.如何預先擷取auto_increment的值?
mysql_connect(’localhost’,'root’,'root’) or die(’不能串連到伺服器‘);
mysql_select_db(’test’); //串連資料庫
$sql = “show create table id_user”; //id_userd 為表名
$query = mysql_query($sql);
$arr = mysql_fetch_array($query);
$b = strstr($arr[1],’AUTO_INCREMENT=’); //擷取子字串,包含AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 )
$result = intval(substr($b,15)); //substr()從字串第16個位置擷取字串,再對擷取後的字串進行int類型轉換
echo ‘AUTO_INCREMENT的值’ .$result; //輸出結果:即為下一次插入資料時的ID值
7.利用獲得用戶端資訊
getenv(”REMOTE_ADDR”)可以得到瀏覽者的IP
getenv(”HTTP_USER_AGENT”)可以得到瀏覽者的作業系統類型,瀏覽器類型
getenv能得到所有$_ENV這個全域變數的所有東西
print_r($_ENV)可以看到很多東西
比如
echo getenv(ALLUSERSPROFILE); 可以看到ALLUSERSPROFILE的值
echo getenv(PATHEXT); 可以看到PATHEXT的值
8.mysql_fetch_row()和mysql_fetch_array()的區別
mysql_fetch_array() 是 mysql_fetch_row() 的擴充版本。除了將資料以數字索引方式儲存在數組中之外,還可以將資料作為關聯索引儲存,用欄位名作為鍵名。用 mysql_fetch_array()並不明顯比用 mysql_fetch_row()慢,而且還提供了明顯更多的值。
mysql_fetch_array() 中可選的第二個參數 result_type 是一個常量,可以接受以下值:MYSQL_ASSOC,MYSQL_NUM 和MYSQL_BOTH。本特性是PHP 3.0.7 起新加的。本參數的預設值是 MYSQL_BOTH。
9.EOD的用法和功效
就是比單引號和雙引號好些,能包含換行。EOD可以改成其他字元。
10.用gdate()獲得一長串數字怎麼轉換成正常的時間?
gmdate 返回 GMT 時間,除此以外和 date() 函數完全一樣。如果你需要本地時間,就用 date() 來格式化時間戳記。
11.正則裡面的()//區別何在?
/ / 是模式定界符,代表裡面是一個正則規則。
( ) 代表的是子模式,一個/ /中可以有很多的( )組成,可以用1 2 或 $1 $2來匹配前面子模式的值。
12.require和require_once有啥區別?
require重複調用會多次載入你飲用的檔案;require_once只載入一次,而不管你實際上調用了多少次,主要用於複雜的檔案內含項目關聯性
例如b包含a,c包含a,但同時c又包含了b,那麼如果用require的話可能會導致兩次載入a
13.三個IP地址的擷取有什麼區別?
$_SERVER['REMOTE_ADDR'];
$_SERVER['HTTP_CLIENT_IP'];
$_SERVER['HTTP_X_FORWARDED_FOR'];
$_SERVER['REMOTE_ADDR']; //訪問端(有可能是使用者,有可能是代理的)IP
$_SERVER['HTTP_CLIENT_IP']; //代理端的(有可能存在,可偽造)
$_SERVER['HTTP_X_FORWARDED_FOR']; //使用者是在哪個IP使用的代理(有可能存在,也可以偽造)
14.$_GET和$_POST的區別?
一:get 方法是限制傳值的大小,不能超過2K. 而post不限制傳值的大小.
二:Get是用來從伺服器上獲得資料,而Post是用來向伺服器上傳遞資料。
三:Get將表單中資料的按照variable=value的形式,添加到action所指向的URL後面,並且兩者使用”?”串連,而各個變數之間使用”&”串連;Post是將表單中的資料放在form的資料體中,按照變數和值相對應的方式,傳遞到action所指向URL。
四:Get是不安全的,因為在傳輸過程,資料被放在請求的URL中,而如今現有的很多伺服器、Proxy 伺服器或者使用者代理程式都會將請求URL記錄到記錄檔中,然後放在某個地方,這樣就可能會有一些隱私的資訊被第三方看到。另外,使用者也可以在瀏覽器上直接看到提交的資料,一些系統內部訊息將會一同顯示在使用者面前。Post的所有操作對使用者來說都是不可見的。
15.在類裡面的函數前面可以加public,private,但在函數庫中的函數前面不能加呢?
function自定的隨便你,public是公開使用的類屬性對象,privat是獨立使用的類屬性對象;
類中 public 或 private 是指這個方法(要注意叫”方法”)是對外公開還是是屬於類私人而你指的函數庫,它是”函數”的庫,不屬於類中的方法,所以不必也不能有前置修飾。
16.頁面執行時間怎麼算的?
| 代碼如下 |
複製代碼 |
$mtime = explode(’ ‘, microtime()); $starttime = $mtime[1] + $mtime[0]; …… …… …… $mtime = explode(’ ‘, microtime()); $endtime = $mtime[1] + $mtime[0]; $usedtime = $endtime - $starttime; printf(” %0.4f s”, $usedtime);
|
17. UTF8編碼指令碼session_start(),header(),settcookie()等函數出錯,提示”headers already sent “。
UTF8編碼指令碼通常的編輯器都會在檔案頭部加上三位元組的BOM編碼來識別UTF8編碼格式,這三個位元組是普通檔案編輯器看不到,而輸出時去先行以HTML輸出了。執行以上函數時就會提示以上錯誤。解決辦法:用editplus等可以清除BOM的編輯器,清除BOM(設定為utf8清除BOM)儲存一下即可。
18. PHP中單引號,雙引號,反引號的區別
PHP單引號(’),雙引號(”")反引號(`)都能引用字串。單引號中變數不被轉義,雙引號轉義變數,而反引號中變數轉義作為shell命令被執行。
下成介紹了一些常開發中的問題
下面我們從較輕微的問題開始討論,直至一些致命的錯誤。共分三部分。
第一部分、較輕微的錯誤
一、Printf(),
該函數主要用來格式化顯示資料。當你要改變某個資料的顯示格式時才使用。
例如以不同的精度來顯示PI(3.1415926)的值。
| 代碼如下 |
複製代碼 |
printf ("Pi is: %.2fn n", M_PI); printf ("Pi is also: %.3fn n", M_PI); printf ("Pi is also: %.4fn n", M_PI); ?>
|
但許多程式員僅僅為顯示一些變數值和函數傳回值使用該函數。因為Printf()在顯示資料前要先格式化該資料以速度較慢,因此,僅為了顯示資料時應用print和echo,以提高速度。
二、語意檢查
PHP是一種弱類型語言,也就是說在使用一個變數前不用定義,這樣給編程帶來了很大的方便和靈活,但你自己必須知道該變數到底應該是哪種類型,因為該變數在運行時仍實際對應著某一種類型(各種類型
之間可以自由互相轉換),沒有類型的變數是不存在的。有可能PHP並不能檢查出你的語意錯誤,但由於變數類型的變化,會導致一些潛在的問題的發生。另外一個值得注意的問題是變數的範圍,它也可能會導致
一些潛在的問題的發生。
在PHP中有以下幾種基本變數:
Boolean, resource, integer, double, string, array and object。
三、臨時變數的使用
臨時變數的濫用會導致程式運行效率的降低。何時使用臨時變數可基於以下兩點考慮:
1、該變數是否至少使用兩次。
2、該變數的使用是否會顯著提高程式的可讀性。
如果一條也不滿足,則省略該變數的使用。例如:
| 代碼如下 |
複製代碼 |
$tmp = date ("F d, h:i a"); print $tmp; ?> 就應該改成: print date ("F d, h:i a"); ?> 又如: // string reverse_characters(string str) // Reverse all of the characters in a string. function reverse_characters ($str) { return implode ("", array_reverse (preg_split("//", $str))); } ?> |
的可讀性不強,可改成:
| 代碼如下 |
複製代碼 |
// string reverse_characters(string str) // Reverse all of the characters in a string. function reverse_characters ($str) { $characters = preg_split ("//", $str); $characters = array_reverse ($characters); return implode ("", $characters); } ?> |
網路找到的一些問題
php中常見問題集錦2009-09-10 11:07【1】頁面之間無法傳遞變數
get,post,session在最新的php版本中自動全域變數是關閉的,所以要從上一頁面取得提交過來得變數要使用$_GET['foo'],$_POST['foo'],$_SESSION['foo']來得到
當然也可以修改自動全域變數為開(php.ini改為register_globals = On);考慮到相容性,還是強迫自己熟悉新的寫法比較好。
【2】Win32下apache2 用get方法傳遞中文參數會出錯
test.php?a=你好&b=你也好
傳遞參數是會導致一個內部錯誤
解決辦法:"test.php?a=".urlencode(你好)."&b=".urlencode(你也好)
【3】win32下的session不能正常工作
php.ini預設的session.save_path = /tmp
這顯然是linux下的配置,win32下php無法讀寫session檔案導致session無法使用
把它改成一個絕對路徑就可以了,例如session.save_path = c:windowstemp
【4】顯示錯誤資訊
當php.ini的display_errors = On並且error_reporting = E_ALL時,將顯示所有的錯誤和提示,調試的時候最好開啟以便錯誤修正,如果你用以前php寫法錯誤資訊多半是關於未定義變數的。變數在賦值以前調用會有提示,解決辦法是探測或者屏蔽
例如顯示$foo,可以if(isset($foo)) echo $foo 或者echo @$foo
【5】Win32下mail()不能寄送電子郵件
在linux下配置好的sendmail可以發送,在win32下需要調用smtp伺服器來寄送電子郵件
修改php.ini的SMTP = ip //ip是不帶驗證功能的smtp伺服器(網上很難找到)
php發送郵件的最好解決方案是用socket直接發送到對方email伺服器而不用轉寄伺服器
有個很好的class,不過需要修改一下發信會暴快,修改後版本將在近日推出
【6】header already sent這個錯誤通常會在你使用HEADER的時候出現,他可能是幾種原因:
1,你在使用HEADER前PRING或者ECHO了
2.你當前檔案前面有空行
3.你可能INCLUDE了一個檔案,該檔案尾部有空行或者輸出也會出現這種錯誤。!
還有使用session_register()
【7】初裝的mysql如果沒有設定密碼,應該使用
update mysql.user set password=password("yourpassword") where user="root"
【8】更改php.ini後沒有變化
重新啟動web server,比如IIS,Apache等等,然後才會應用最新的設定
【9】php在2003上面安裝(ISAPI的安裝方法)
PHP4的php4isapi.dll好像和2003有些衝突,只能用CGI模式安裝
步驟一,先去在一個安裝程式,我是裝的是:php-4.2.3-installer.exe,你也可以去找最新的版本,在安裝 php-4.2.3-installer.exe之前保證你的IIS6.0啟動了,並能夠訪問。 安裝好以後,在預設網站-->應用程式配置
步驟二:點擊 web服務擴充 -->建立web服務擴充.
步驟三: 副檔名-->php,然後添加
步驟四:找到php.exe的路徑添加上去。
步驟五: 確定就可以了!
步驟六: 選擇php的服務擴充,然後點擊允許。
【10】有時候sql語句不起作用,對資料庫操作失敗
最簡便的調試方法,echo那句sql,看看變數的值能不能得到
【11】
| 代碼如下 |
複製代碼 |
// 自 PHP 3 起可用 print $HTTP_POST_VARS['username']; // 自 PHP 4.1.0 起可用 print $_POST['username']; print $_REQUEST['username']; import_request_variables('p', 'p_'); print $p_username; // 如果PHP指令 register_globals = on 時可用。不過自PHP 4.2.0 起預設值為 register_globals = off不提倡使用此種方法。 print $username; ?>
|
使用 GET 表單也類似,只不過要用適當的 GET 預定義變數。GET 也適用於 QUERY_STRING(URL 中在“?”之後的資訊)。因此,舉例說,http://www.example.com/test.php?id=3 包含有可用 $_GET['id'] 訪問的 GET 資料。參見 $_REQUEST 和 import_request_variables()。
在 PHP 4.2.0 之前 register_globals 的預設值是 on。在 PHP 3 中其值總是 on。鼓勵大家不要依賴此指令,建議在編碼時假定其為 off。
【12】暫存你的變數到臨時檔案:
| 代碼如下 |
複製代碼 |
if(file_exists('temp.php')) { $x=r('temp.php'); @eval("$a = $x;"); } if(!is_array($a)){ #重新構造數組A $a=array(array("af"=>"fsdf"),"f"=>"df"); } w('temp.php',var_export($a,true)); var_dump($a); 讀取,寫入文檔資料 function r($file_name) { $filenum=@fopen($file_name,"r"); @flock($filenum,LOCK_SH); $file_data=@fread($filenum,filesize($file_name)); @fclose($filenum); return $file_data; } function w($file_name,$data,$method="w") { $filenum=@fopen($file_name,$method); flock($filenum,LOCK_EX); $file_data=fwrite($filenum,$data); fclose($filenum); return $file_data; } |
【13】include和require的區別
兩者沒有太大的區別,如果要包含的檔案不存在,include提示notice,然後繼續執行下面的語句,require提示致命錯誤並且退出;據我測試,win32平台下它們都是先包含後執行,所以被包含檔案裡最好不要再有include或require語句,這樣會造成目錄混亂。或許linux下情況不同,暫時還沒測試;如果一個檔案不想被包含多次可以使用include_once或require_once
【14】session在函數和方法中的應用:你打算註冊進session的變數都必須是全域的。
原因是這樣的:
php的session_register函數只是記住變數的名字,而不會去記變數的值。
真正要在伺服器端記住這個變數的值是在整個指令碼運行結束之後,也就是說變數的值是在指令碼運行結束的時候才會被讀取並儲存入伺服器端的臨時目錄,這樣,在所有函數或方法外的、或在函數或方法內被定義為全域變數的變數才會成功register,而其他的則都會在指令碼運行結束時被unset掉。
【15】PHP中的session由於基於cookie實現,所以在所有會話視窗關閉後並不會馬上消失。這一點和其他指令碼語言不同,同時讓我感到鬱悶。
答:不不不,樓上的朋友沒有把php的session研究透,如果非要說php的session跟cookie有關係,那也就是一個session_id被記錄在了用戶端
而在伺服器端的臨時目錄下,會產生一個跟session_id大致同名的檔案,這個檔案才是真正記錄你成功register過的變數和它們的值。同樣,如果用戶端禁止使用cookie,php會自動以get的方式傳遞session_id的值,使其不會丟失。所以,cookie跟session之間的關係,並不是那麼密不可分。而且,php的session也不能說是基於cookie實現的。
【16】isset()和empty()的區別
如果一個變數沒被賦值就引用在php裡是被允許的,但會有notice提示;
兩者都是測試變數用的,但是isset()是測試變數是否被賦值,而empty()是測試一個已經被賦值的變數是否為空白
如果一個變數被賦空值,$foo=""或者$foo=0或者 $foo=false,那麼empty($foo)返回真,isset($foo)也返回真,就是說賦空值不會登出一個變數。要登出一個變數,可以用 unset($foo)或者$foo=NULL
【17】通過HTTP協議一次上傳多個檔案的方法
有兩個思路,是同一個方法的兩種實現。
1,在form中設定多個檔案輸入框,用數組命名他們的名字,如下:
| 代碼如下 |
複製代碼 |
這樣,在伺服器端做以下測試 echo " "; print_r($_FILES); echo " ";2,在form中設定多個檔案輸入框,但名字不同,如下: 在伺服器端做同樣測試: echo " "; print_r($_FILES); echo " "; |
【18】可以建立一個臨時的PHP格式的檔案,在需要的地方include進來,這樣臨時的PHP檔案中定義的變數就有了,可以取代session。
【19】正如上面說得,現在get,post方式提交的都無法直接使用,有時甚是麻煩,自己寫了段代碼,把他們轉化為全域變數,以便使用,session變數同理可得。
把通過GET或POST方式提交的變數轉化為全域變數:
| 代碼如下 |
複製代碼 |
foreach($_GET as $key=>$value){ $$key=$value; } foreach($_POST as $key=>$value){ $$key=$value; }
|
http://www.bkjia.com/PHPjc/632206.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/632206.htmlTechArticle本文章收藏了php開發中常常會碰到的一些疑惑或一些小問題,大家可參考一下。 上面一些函數之間的區別, 1.isset()和empty()的區別 兩者都是...