php面試題(實時更新)- 最全
儘量涵蓋,這裡只寫關於php的,基礎肯定是各種字串操作,陣列操作,然後面向物件的理解。其實這裡面好多好多東西都是平時用不到的,但這就是基礎,面試官問到的東西只是你知道的很少很少一部分,但這就是你們交涉的全部所以還你是得讓自己儘可能知道的多。寫這些東西沒有應試教育的意思,雖然有的東西平時不會用,但對你絕對都是有幫助的
1 PHP是用什麼語言編寫的
php是用c寫的
擴充套件:php3 php4 php5的主要區別是什麼,php6的新特徵有哪些?
這個問題真噁心,等我以後心情好了在回答吧
2 目前PHP的最高版本是
2013.9.12現在應該是php5.5
3 PHP的三種註釋方式
天啊,我竟然知道兩種,太可怕了 # 竟然也是 好吧
4 請列出PHP的8種資料型別
字串 陣列 物件 數值型別 整型 xml 浮點 布林值 特殊的有Null和resource(說實話我只用過前五種)
5 PHP中有幾種形式裝載程式碼,並列舉,以包含同目錄下的Config.php檔案為例?
require include require_once include_once
require一般用在檔案的頭部包含檔案,執行php時包含這個檔案使它成為php的一部分
include一般用在流程控制中,用到時再包含
區別是require遇到錯誤不會往下執行,而include會繼續執行
require_once和include_once的作用是避免重複包含,也就是說如果不小心包含了同一個檔案,用這兩個函式會只包含一次
6 PHP中===表示什麼意思,以及與==的區別,什麼情況下==是true,===是false
這個問題也是比較常見的,不過巨簡單。==是比較表示式兩邊的值,而===會比較資料型別,比如$a = 1;$b = '1'; ==的話就為true,但===就為false,因為資料型別不同
7 header的作用是什麼,以及它的限制
sorry,這個需要先看http協議,等有功夫在回答這個問題,目前只知道這是做跳轉用的
8 strstr和stristr的區別
這種字串操作的方法但凡加了i的一般都是不區分大小寫的意思。這裡在普及一下strstr的做用吧,strstr預設返回從指定字元到該字串結束的字元
9 php如何獲得瀏覽器資訊
看吧,php能做的事還是不少的,哎,我這麼說會不會暴露了我的知識面比較窄的缺陷呢,哈哈
$_SERVER
[
'HTTP_USER_AGENT'
];
平時沒用過這些東西
10 什麼是URLRewriteing
說說我自己的理解吧,就是偽靜態嘛!通過隱藏網頁的訪問地址以達到更好收錄的的效果,可能有不對的地方,歡迎拍磚
11 如何遍歷一個資料夾下所有的內容(考中機率非常高)
以前我都嫌麻煩,不去記這些東西,而且平時用的話我都是從網上搜索,但筆試的時候肯定不能讓你從網上搜雖然這東西經常被考到,但我可以確定的是你寫不出來對你影響不會很大,當然寫出來了更好,之前我歐諾個的都是什麼opendir 之類的這些傻×函式,剛才我知道了scandir這個函式,這是迴圈遍歷資料夾的函式,非常實用奧
<?php
$dir = "."; //當前目錄
list_file($dir);
function list_file($dir){
$list = scandir($dir); // 得到該檔案下的所有檔案和資料夾
foreach($list as $file){//遍歷
$file_location=$dir."/".$file;//生成路徑
if(is_dir($file_location) && $file!="." &&$file!=".."){ //判斷是不是資料夾
echo "------------------------sign in $file_location------------------";
list_file($file_location); //繼續遍歷
}
echo "<br/>";
}
}
?>
12 二分法和氣泡排序(為什麼把這倆在一起說呢,因為他倆都是經常被考到的,而且對於我們的思維邏輯很重要)
二分法 array(1,2,3,4,5,6,7)取出其中一個值的鍵名
先說一個網上很常見的方法
function Dichotomy($php,$k,$low=0,$max=0)
{
if(count($php)!= 0 and $max == 0)
{
$max = count($php);
}
if($low <= $max)
{
$mid = intval(($low+$max)/2);
if($php[$mid] == $k)
{
return $mid;
}
else if($k < $php[$mid])
{
return Dichotomy($php,$k,$low,$mid-1);
}
else
{
return Dichotomy($php,$k,$mid+1,$max);
}
}
return -1;
}
$php = array('1','2','3','4','5','6');
echo Dichotomy($php,5);
?>
這個方法確實可以,我也試過。但是,我覺得這種方法不好,確切的說是不準確。因為這種方法是以順序的不間斷的陣列為基礎的,比如上面所說的
$max = count($php);$max很明顯不是最大值,而是陣列的總長度,所以這裡不準確。看看我寫的方法吧
function dis($arr,$var) {
$max = count($arr);
$mid = intval($max/2);
if($arr[$mid-1] == $var){
return $mid;
}
if($arr[$mid-1] >= $var){
$arrs = array_slice($arr,0,$mid);
return dis($arrs,$var);
}else{
$arrs = array_slice($arr,$mid,$mid);
return dis($arrs,$var);
}
}
$arr = array(1,2,3,4,5,6,7,9);
echo $a = dis($arr,2);
這裡我沒有引入最大值最小的概念,只是從陣列的中間開始取值判斷
氣泡排序
$arr = array(1,5,2,23,64,27);
foreach($arr as $key=>$val){
for($i=0;$i<count($arr);$i++){
$var = '';
if($arr[$i] < $arr[$i+1]){
$var = $arr[$i];
$arr[$i] = $arr[$i+1];
$arr[$i+1] = $var;
}
}
}
print_r($arr);
太神奇了,剛才我自己手寫了一下這段程式。我竟然在沒有任何思考的情況下給背下來了,真的是考的多了
這裡最重要的是程式裡的for迴圈,普通的if判斷只是判斷哪個值最大,但這只是比對一遍,外層在加上一個for迴圈的目的是將當前值跟所有值做比較
13 php常用陣列和字串函式(這對於我們來說是最最最基本和常用的,一定要深刻認識並熟練運用)
陣列:這裡說的都是常用的大約有20個
1 in_array 判斷陣列中是否存在某值或某陣列
2 is_array 判斷是否是陣列
3 array_merge 合併陣列
4 array_search 搜尋某值是否存在於陣列中
5 array_slice 分個陣列(從陣列中取出一段)
6 array_values 建立數字索引
7 array_diff 取差集
8 array_keys返回所有鍵名
9 array_unique 移除重複的值
10 array_splice 將陣列中的值用其他值替換
11 sort asort rsort arsort ksort
12 implode
13 print_r
14 foreach
15 count
16 array_shift 將陣列開頭 的單元去掉
另外像array_map使用頻率不是很高,但這些函式你得知道是做什麼的
字串:
1 substr(擷取字串,這是最最常用的)
2 strlen(獲取字串的長度)
3 strpos(查詢字元在字串中首次出現的位置)
4 str_replace(字串替換)
5 explode(按照規律將字串拆分成陣列)
6 strtoupper(將所有字母變成大寫)
7 strtolower
8 ucfirst(將字串的首字母變成大寫)
9 ucwords(將字串中每個單詞的首字母變成大寫)
10 strrev(反轉字串,其實不是很常用)
11 substr_replace(替換字串的子串,注意與str_replace的區別)
12 strip_tags(去除html和php標記,可以選擇保留想要的標籤)
13 trim(去除空格)
14 獲取一個網頁的內容,比如獲取www.sina.com.cn的內容
主要有三種方法,掌握其中兩種就可以
第一種 使用file_get-contents
第二種,使用fopen先開啟一個檔案,然後讀裡面的內容,忽略
第三種使用curl
15 說出php中給變數加密的函式
15.1 md5 單項加密,不能解密。生成32個字元的值
15.2 crypt 單項加密,不能解密。接受兩個引數,不傳第二個引數時生成的值重新整理可變,傳入第二個值salt之後,加密的結果不變。且,在不同的系統上演算法可能不同
15.3 sha1 單項加密,不能解密。和md5很像,不同的是預設生成40個字串的值,
15.4 base64_encode() 為雙向加密,可以解密。使用base64decode()解密
16 原樣輸出使用者輸入的內容,使用哪一個函式?比如使用者輸入'export<br>export'
htmlspecicalchars 把預定義的字元轉換成html實體
17 如何判斷一個字串是否是合法的日期型別如'2017-03-31',要求程式碼不超過5行
運用date和strtototime進行轉換和比較
18 靜態和非靜態的區別
普通意義上認為靜態可以不用例項化就直接呼叫了,這是和靜態的不同。但這是結果,不是原因。為什麼我們要使用靜態,難道僅僅是為了在不例項化的情況下就呼叫它?那和我們例項化之後呼叫有什麼區別。
其實靜態和非靜態的區別在於記憶體。靜態方法在程式開始時生成記憶體,例項方法在程式執行中生成記憶體,所以靜態方法可以直接呼叫,例項方法要先成生例項,通過例項呼叫方法,靜態速度很快,但是多了會佔記憶體。
任何語言都是對記憶體和磁碟的操作,至於是否面向物件,只是軟體層的問題,底層都是一樣的,只是實現方法不同。靜態記憶體是連續的,因為是在程式開始時就生成了,而例項申請的是離散的空間,所以當然沒有靜態方法快。
靜態方法始終呼叫同一塊記憶體,其缺點就是不能自動進行銷燬,而是例項化可以銷燬。
19 require比require_once要快,因為後者要先檢視是否已經包含要引用的路徑
20 如果你需要得到指令碼執行時的時間,$_SERVER['REQUSET_TIME']優於time();
21 str_replace 比preg_replace要快,而strtr比str_replace還要快1/4
另外不要做無謂的替換即使沒有替換,str_replace 也會為其引數分配記憶體。很慢!解決辦法:
用 strpos 先查詢(非常快),看是否需要替換,如果需要,再替換效率:- 如果需要替換:效率幾乎相等,差別在 0.1% 左右。
如果不需要替換:用 strpos 快 200%。
22 $row['id']比$row[id]速度快7倍 建議養成陣列鍵加引號的習慣;
23 不要在迴圈裡計算陣列的長度24 Apache解析一個PHP指令碼的時間要比解析一個靜態HTML頁面慢2至10倍。
25 使用ip2long將ip地址轉化成整形存入資料庫,可節省儲存空間
26 對於比較大的字串在存入資料庫之前可以使用gzcompress先進行壓縮(前提應該是不需要檢索的情況下吧!!!)
27 不要隨意複製變數
BAD:
$description = $_POST['description'];
echo $description;
GOOD:
echo $_POST['description'];
28 使用選擇分支語句 switch case好於使用多個if,else if語句,並且程式碼更加容易閱讀和維護。
29 在可以用file_get_contents替代file、fopen、feof、fgets 它的效果要比其他的高很多
30 用i+=1代替i=i+1
31 對global變數,應該用完就unset()掉;
33 disable_functions 函式,可以禁用某些php內建函式
34 php指令碼最長執行時間 php_execuation_time = 30. 預設是30秒
35 memory_limit 設定php指令碼處理記憶體佔用的最大記憶體
36 upload_file_filezize 上傳檔案的大小限制,預設是2M
37 遮蔽php錯誤的方法
37.1 最簡單的方法,直接在頁面寫入error_reporting(E_ALL^E_NOTICE^E_WARNING); 可以關閉所有notice 和 warning 級別的錯誤。
37.2 修改php.ini,將引數display_errors 的值修改為off
37.3 在可能出錯的語句前加@,棄用此方法
38 合併兩個陣列有幾種方式,試比較它們的異同
array_merge 合併兩個陣列,遇到有相同的鍵名,則第二個鍵名的值會覆蓋第一個
array_merge_recursive 合併陣列,遇到有相同的鍵名的情況,不會覆蓋。而是將相同鍵名的值遞迴成一個數組
array_combine 函式通過合併兩個陣列來建立一個新陣列,其中的一個數組是鍵名,另一個數組的值為鍵值。
39 請寫一個函式來檢查使用者提交的資料是否為整數
function checkType1($var){
if(is_int($var)){
return true;
}else{
return false;
}
}
function checkType2($var){
if(floor($var) == $var){
return true;
}else{
return false;
}
}
40 字元 位元組 漢字 英文字元等等的關係
位元組是計算機中的儲存單位
字元是計算機中使用的文字和符號。如 1 2 3 a b c 漢 字 ! @ # $等
位元組和字元是兩個層面的概念,無法直接比較或區分。不同編碼裡,字元和位元組的對應關係不同
1位元組=8個二進位制位
ASCII中,一個英文字母(不區分大小寫)佔用一個位元組的空間,一個漢字佔用2個位元組的空間
UTF8中,一個英文字母佔用一個位元組,一個漢字(含繁體字)佔用三個位元組
UNICODE中,一個英文字母佔用2個位元組,一個漢字佔用2個位元組
41 如何實現PHP的安全最大化?怎樣避免SQL注入漏洞和XSS跨站指令碼攻擊漏洞?
基本原則:不對外界展示伺服器或程式設計細節(遮蔽錯誤),不相信任何使用者提交的資料(過濾使用者提交)
41.1 遮蔽錯誤,將display_errors 設定為off
41.2 過濾使用者提交引數,這裡需要注意的是不能僅僅通過瀏覽器端的驗證,還需要經過伺服器端的過濾
這裡是需要注意最多的地方,因為所有使用者提交的資料入口都在這裡,這是過濾資料的第一步。
1 考慮是否過濾select,insert,update,delete,drop,create等直接操作資料的命令語句
2 使用addslashes 將所有特殊字元過濾
3 開啟magic_quotes_gpc,開啟該引數數後自動將sql語句轉換,將 ' 轉換成 \'
41.3 可以考慮設定統一入口,只允許使用者通過指定的入口訪問,不能訪問未經許可的檔案等內容
41.4 可以考慮對於安全性要求高的檔案進行來源驗證,比如要想執行b.php必須先執行a.php,可以在b.php中判斷來自a.php的referer,避免使用者直接執行b.php
42 $a++和++$a的區別
前者是先執行表示式,在自增
後者是先自增,在執行表示式
43 合併兩個陣列的方式,並比較它們的一同
這是一個非常基本也比較考驗基礎的問題,正因為基礎,被考中的機率也非常大
array_merge 簡單的合併陣列
array_merge_recursive 合併兩個陣列,如果陣列中有完全一樣的資料,將它們遞迴合併
array_combine 合併兩個陣列,前者的值作為新陣列的鍵
44 請寫一個函式來檢查使用者提交的資料是否為整數(不區分資料型別,可以為二進位制、八進位制、十進位制、十六進位制數字)
45 PHP的strtolower()和strtoupper()函式在安裝非中文系統的伺服器下可能會導致將漢字轉換為亂碼,請寫兩個替代的函式實現相容Unicode文字的字串大小寫轉換
46 PHP處理上傳檔案資訊陣列中的檔案型別$_FILES['type']由客戶端瀏覽器提供,有可能是黑客偽造的資訊,請寫一個函式來確保使用者上傳的影象檔案型別真實可靠
47 PHP通過對資料的URL編碼來實現與Javascript的資料互動,但是對於部分特殊字元的編解碼與Javascript的規則不盡相同,請具體說明這種差異,並針對UTF-8字符集的資料,寫出PHP的編解碼函式和Javascript的編解碼函式,確保PHP編碼資料可以被Javascript正確解碼 、Javascript編碼的資料可以被PHP正確解碼
48
unset銷燬的不是實際存在於記憶體中的物件,銷燬的是指向記憶體中物件的變數
所以說
$a = 123;
$b = $a;
unset($a);
echo $b;
輸出結果123;很明顯這種情況,銷燬$b對$a沒有任何影響,因為$b和$a引用的完全是兩個記憶體中的地址
$a = 123;
$b = &$a;
unset($a);
echo $b;
這種情況,$a和$b指向同一個記憶體地址,因為unset銷燬的是指向記憶體物件的變數,所以銷燬一個對另一個不會產生影響,所以結果扔是123
這是牽扯到php的垃圾回收機制(目前還不太懂)
$a = 123;
$b = &$a;
$a = 456;
echo $b;
這時$b的值是456,因為$a $b兩個變數指向的是同一塊記憶體地址
49 HTTP常見狀態值、作用
200請求成功
401 未授權
403 禁止
404 未找到
500 伺服器內部錯誤
502 閘道器不可用
503 伺服器不可用
504 伺服器請求超時
50 tcp/ip、http、udp和ajax之間的關係
TPC/IP協議是傳輸層協議,主要解決資料如何在網路中傳輸,而HTTP是應用層協議,主要解決如何包裝資料。關於TCP/IP和HTTP協議的關係,網路有一段比較容易理解的介紹:“我們在傳輸資料時,可以只使用(傳輸層)TCP/IP協議,但是那樣的話,如果沒有應用層,便無法識別資料內容,如果想要使傳輸的資料有意義,則必須使用到應用層協議,應用層協議有很多,比如HTTP、FTP、TELNET等,也可以自己定義應用層協議。WEB使用HTTP協議作應用層協議,以封裝HTTP 文字資訊,然後使用TCP/IP做傳輸層協議將它發到網路上。”
“IP”代表網際協議,TCP和UDP使用該協議從一個網路傳送資料包到另一個網路。把IP想像成一種高速公路,它允許其它協議在上面行駛並找到到其它電腦的出口。TCP和UDP是高速公路上的“卡車”,它們攜帶的貨物就是像HTTP,檔案傳輸協議FTP這樣的協議等。
TCP提供有保證的資料傳輸,而UDP不提供。這意味著TCP有一個特殊的機制來確保資料安全的不出錯的從一個端點傳到另一個端點,而UDP不提供任何這樣的保證。
AJAX指代了瀏覽器端通過javascript發起http請求的一系列技術。主要目的是解決之前web網頁無法實現網頁區域性重新整理的問題。
因此說,AJAX的核心就是通過javascrit程式呼叫而發起的一次http請求。
高階面試題
1 isset和empty的區別
isset 檢測變數是否設定
當變數不存在或者存在但值為null的情況下,返回false;否則返回true
empty 檢測變數值是否為空
當變數不存在或者存在,但值為null,'',0,'0',false,array(),var $var或者任務沒有屬性的物件時,返回true.
否則返回false
2 將字串abcdef 翻轉的函式
<?php
$var = 'abcdef';
$len = strlen($var);
$res = '';
for($i=$len-1;$i>=0;$i--){
$res .= $var[$i];
}
echo $res;
?>
3 多維資料$a1,$a2,$a1與$a2比較,得出$a1中的元素在$a2中的不同部分.
4 將一個多維陣列轉化成一維陣列
<?php
function splitArray($array){
static $res = array();
foreach($array as $Key=>$val){
if(is_array($val)){
splitArray($val);
}else{
array_push($res,$val);
}
}
return $res;
}
$array = array(1,2,array(2,array(array(3),array(4),5),6));
$res = splitArray($array);
print_r($res);
?>
5 如何安全的傳送簡訊,(即如何防止惡意刷簡訊)
基本解題思路:定義input.php和send.php,前者允許使用者輸入手機號,然後提交到後者處理髮送行為。
先執行input.php在執行send.php沒有任何問題,但考慮到程式開發中的時序性,我們應該設想多種使用者可能進行的操作或是惡意操作。比如
input->send 按照邏輯順序,先執行input.php在執行send.php
input 只執行input.php,不執行第二步
send 只執行send.php,不執行第一步
send->input 先執行send.php,在執行input.php
因為目前只有兩個執行檔案,所以組合出四種執行方法,即所有使用者有可能進行的操作。
因為目前沒有進行任何安全防範,所以使用者可以迴圈執行input.php->send.php,從而不斷的給使用者發簡訊。
這肯定是錯誤的,那如何安全防範呢?我們可以在input.php中新增一個驗證碼,讓使用者每次都輸入驗證碼通過時才能繼續執行send.php,我們將驗證碼放入到session中,
在send.php中驗證,使用者輸入的驗證碼和session中的驗證碼是否相同,如果相同,就傳送簡訊。
那麼問題來了,如果使用者直接不經過input.php,而直接執行send.php的話呢?因為這時候沒有執行input.php,所以也就沒有生成驗證碼的session,而在send.php中,使用者也
不輸入任何內容,這樣就成了‘’==‘’又繞過了一層過濾。這時候大家肯定會想到除了使用者輸入的驗證碼和存放在session中的驗證碼要相等之外還要判斷驗證碼都不能為空。
6 多伺服器之間Session共享
6.1 通過cookie共享達到session共享的目的。如何實現呢?我們知道,不同的站點下面的cookie是無法直接通過$_COOKIE來同步共享的。但我們可以攻錯curl的cookie共享
來達到共享的目的,做法就是通過curl的引數設定來控制,在點選開啟連結這篇文章中我有詳細介紹。我們通過獲取以登入站點的cookie資訊來達到在其他站點也登入目的。
6.2 伺服器之間Session資料同步的方式
6.3 利用Mysql資料庫共享Session資料的方式
6.4 利用NFS共享Session資料的方式
7 將1234567890轉換成1,234,567,890 每3位用逗號隔開的形式
<?php
$var = '1234567890';
$len = strlen($var);
$res = strrev($var);
$a = '';
for($i=0;$i<$len;$i++){
if(($i%3 == 0) && ($i != 0)){
$a.=',';
}
$a.=$res{$i};
}
$a = strrev($a);
echo $a;
?>
8 一組隨機數學的數列,對其重新進行排序,要求實現:奇數位保持奇數,偶數位保持偶數.我是高階程式設計師的分割線
以下是期望月薪達到15k的phper們必備的知識點。雖然我們是程式設計師,但因為我們是做web的,所以需要掌握的知識點比較多。雖然工作中大多數php程式設計師工作中80%的時間是在做和php有關的工作,但面試的時候大約只有30%是關於php的知識,其他的像資料庫、web伺服器、快取引用、對linux的使用也非常重要,下面是我長時間在面試中積累的經驗教訓,非常客觀,希望對大家有所幫助。
1 對php常用設計模式的理解、應用場景使用及其優勢(考中機率非常大,這其實是在考差面試者對面向物件的理解和使用情況的掌握程度)
2 對高內聚 低耦合的理解(考中機率不是很大,但作為理解面向物件的重要一步,仍然非常重要)
3 php基本的操作字串的函式,運算元組的函式和處理時間的函式(必考,基礎知識不解釋)
4 php的執行原理,包括如何和web伺服器通訊解析,但不是說如何編譯等的問題這個就變態了(考中機率不是很大,不知道面試官問這個的目的是什麼,應該是為了裝逼吧,但瞭解了總是好的嘛)
5 魔術方法(考中機率極大,同時也是個基礎題,目的在於考差面試者對平時基礎的掌握程度)
6 php編碼規範(竟然有個面試官問我這個問題,看來他們專案真的是很大啊,雖然我平時也非常注意命名規範之類的東西,但還真不知php有專門指定的編碼規範)
7 終極殺招:說說你對面向物件的理解(無語,要死)
8說說關於memcache和redis的區別,應用場景,一致性hash問題(必考,每一個面試官不問這個問題)
9 說說對於hash的理解(屬於基礎不加分項,必須掌握)
10 關於佇列的原理和使用場景(基礎不加分項,必須掌握)
11對正則使用的考差(必考,基礎,基礎,基礎)
12 說說你對http協議的掌握程度(考中機率50%以上)
13 關於session cookie,session共享問題(額,大神的話可能不會問你,但這是基礎,不會的話,今天的面試基本就pass了)
14 apache和nginx的區別(考中機率不大,甚至可以說很小,為了考差你對web服務區的掌握程度和使用配置情況)
15 app介面開發安全問題(現在php作為app介面開發的後方支援語言,這個問題必須開始重視起來了)
關於mysql的問題實在太多,好像有點說不過來,我說幾個方面的問題
16 說說你對索引的理解(必考)
17 常用的優化資料庫的方法(必考)
18 常用的linux命令掌握情況以及shell指令碼的掌握情況(加分項)
剩下的說一下下腳料的但也很重要的東西
19 svn和git的區別
20 bug除錯工具,如何xdebug。貌似需要掌握斷點
21 測試用例
22 傳值和傳引用的區別及一些具體的操作(在筆試中考中的機率非常非常大)
吐血製作,絕對超值