PHP面試整理

zhangrxiang發表於2019-02-16

PHP

HTTP Keep-Alive的作用

作用

Keep-Alive:使客戶端到伺服器端的連線持續有效,當出現對伺服器的後繼請求時,Keep-Alive功能避免了建立或者重新建立連線。Web伺服器,基本上都支援HTTP Keep-Alive

缺點

對於提供靜態內容的網站來說,這個功能通常很有用。但是,對於負擔較重的網站來說,雖然為客戶保留開啟的連 接有一定的好處,但它同樣影響了效能,因為在處理暫停期間,本來可以釋放的資源仍舊被佔用。當Web伺服器和應用伺服器在同一臺機器上執行時,Keep-Alive功能對資源利用的影響尤其突出。

解決

Keep-Alive: timeout=5, max=100

  • timeout:過期時間5秒(對應httpd.conf裡的引數是:KeepAliveTimeout),
  • max:是最多一百次請求,強制斷掉連線。就是在timeout時間內又有新的連線過來,同時max會自動減1,直到為0,強制斷掉。

php陣列函式常見的那些?

陣列遍歷函式

list();  //不是真正的函式,而是PHP的語言結構,用於給一組變數賦值,僅能用於索引陣列
each();  //返回陣列當前元素的鍵值對,並將指標移動到下一個元素位置
while(); //可配合list或each使用:while(list($key, $value) = each($arr)){each $key, $value; }

陣列內部指標控制

current();  //讀取指標位置的內容
key();      //讀取當前指標指向內容的索引值
next();     //將陣列中的內部指標指向下一單元
prev();     //將陣列內部指標倒回一位
end();      //將陣列內部指標指向最後一個元素
reset();    //將目前指標指向第一個索引位置

陣列鍵值操作函式

array_values($arr);       //獲得陣列的值
array_keys($arr);         //獲得陣列的鍵名
array_flip($arr);         //陣列中的值與鍵名互換(如果有重複前面的會被後面的覆蓋)
array_search(`PHP`,$arr); //檢索給定的值,加true則是嚴格型別檢查
array_reverse($arr);      //將陣列中的元素翻轉(前後順序)
in_array("apple", $arr);  //在陣列中檢索apple
array_key_exists("apple", $arr); // 檢索給定的鍵名是否存在陣列中
array_count_values($arr);        // 統計陣列中所有值出現的次數
array_unique($arr);              // 刪除陣列中重複的值

陣列回撥函式

array_filter(); //使用回撥函式過濾陣列中的元素,如果回撥返回true則當前的元素被包含到返回陣列中
array_walk();   //回撥函式處理陣列,自定義函式要有兩個引數,本函式第三個引數可以作為回撥第三個引數返回
array_map();    //可以處理多個陣列,每個陣列的長度應該相同,傳入陣列的個數和回撥函式引數個數應該一致

陣列的分段和填充

array_slice($arr, 0, 3);    //將陣列中的一段取出,此函式忽略鍵名(陣列的分段)
array_splice($arr, 0, 3,array("black","maroon"));    //將陣列中的一段取出,返回的序列從原陣列中刪除
array_chunk($arr, 3, TRUE);   //將一個陣列分割成多個,TRUE為保留原陣列的鍵名(分割多個陣列)

陣列與棧,列隊

array_push($arr, "apple", "pear");    //將一個或多個元素壓入陣列棧的末尾(入棧),返回入棧元素的個數
array_pop($arr);    // 將陣列棧的最後一個元素彈出(出棧)
array_shift($arr);   //陣列中第一個元素移出並返回(長度減1,其他元素向前移動一位,數字鍵名改為從零計數,文字鍵名不變)
array_unshift($arr,"a",array(1,2));  //在陣列的開頭插入一個或多個元素

陣列的排序

sort($arr);      //由小到大,忽略鍵名
rsort($arr);     //由大到小,忽略鍵名
asort($arr);     //由小到大,保留鍵名
arsort($arr);    //由大到小,保留鍵名
ksort($arr);     //按照鍵名正序排序
krsort($arr);    //按照鍵名逆序排序

陣列的計算

array_sum($arr);   //對陣列內部的所有元素做求和運算(陣列元素的求和)
array_merge($arr1, $arr2); //合併兩個或多個(相同字串鍵名,後面覆蓋前面,相同的數字鍵名,後面的附加到後面)
 
array_diff($arr1, $arr2);       //返回差集結果陣列   
array_diff_assoc($arr1, $arr2, $arr3);  //返回差集結果陣列,鍵名也做比較
array_intersect($arr1, $arr2);  //返回交集結果陣列    
array_intersect_assoc($arr1, $arr2);   //返回交集結果陣列,鍵名也做比較 

其他的陣列函式

array_unique($arr);   //移除陣列中重複的值,新的陣列中會保留原始的鍵名
shuffle($arr);        // 將陣列的順序打亂

PHP中幾個輸出函式echoprint()print_r()sprintf()var_dump()的區別

  • echo:是語句不是函式,沒有返回值,可輸出多個變數值,不需要圓括號。不能輸出陣列和物件,只能列印簡單型別(如int,string)。
  • print:是語句不是函式,有返回值 1 ,只能輸出一個變數,不需要圓括號。不能輸出陣列和物件,只能列印簡單型別(如int,string)。
  • print_r:是函式,可以列印複合型別,例如:stirngintfloatarrayobject等,輸出array時會用結構表示,而且可以通過print_r($str,true)來使print_r不輸出而返回print_r處理後的值
  • printf:是函式,把文字格式化以後輸出(參看C語言)
  • sprintf:是函式,跟printf相似,但不列印,而是返回格式化後的文字(該函式把格式化的字串寫寫入一個變數中,而不是輸出來),其他的與printf一樣。
$str = "Hello";    
$number = 123; 
$txt = sprintf("%s world. Day number %u",$str,$number);
//輸出: Hello world. Day number 123 
var_dump():函式,輸出變數的內容、型別或字串的內容、型別、長度。常用來除錯。

可以通過function_exists(`函式名稱`)進行測試

var_dump(function_exists(`print`));  //bool(false)
var_dump(function_exists(`echo`));  //bool(false)
var_dump(function_exists(`print_r`)); //bool(true

heredoc

Heredoc在正規的PHP文件中和技術書籍中一般沒有詳細講述。他是一種Perl風格的字串輸出技術。使用heredoc技術可以實現介面與程式碼的準分離,比如phpwind模板。
heredoc的語法是用”<<<”加上自己定義成對的標籤,在標籤範圍內的文字視為一個字串

  • <<<End開始標記開始,以End結束標記結束,結束標記必須頂頭寫,不能有縮排和空格,且在結束標記末尾要有分號。開始標記和開始標記相同,比如常用大寫的EOTEODEOF來表示,也可以使用其他標記,只要保證開始標記和結束標記不在正文中出現就行。
  • 位於開始標記和結束標記之間的變數可以被正常解析,但是函式則不可以。在heredoc中,變數不需要用連線符 ., 來拼接,比如:
$a=2;
$b= <<<EOF
"zing"$a
"zing"
EOF;
echo $b; //結果連同雙引號一起輸出:"zing"2 "zing"

heredoc常用在輸出包含大量HTML語法文件的時候。他要比傳統的echo輸出精煉很多,如下所示:

function getHtml(){
    echo "<html>";
    echo "<head><title>Title</title></head>";
    echo "<body>Content</body>";
    echo "</html>";
}

function getHtml(){
    echo <<<EOT
    <html>
    <head><title>Title</title></head>
    <body>Content</body>
    </html>
EOT;
}

禁掉cookiesession使用方案,設定session過期的方法,對應函式

通過url傳值,把session id附加到url上(缺點:整個站點中不能有純靜態頁面,因為純靜態頁面session id 將無法繼續傳到下一頁面)
通過隱藏表單,把session id放到表單的隱藏文字框中同表單一塊提交過去(缺點:不適用<a>標籤這種直接跳轉的非表單的情況)
直接配置php.ini檔案,將php.ini檔案裡的session.use_trans_sid= 0設為1,(好像在win上不支援)
用檔案、資料庫等形式儲存Session ID,在跨頁過程中手動呼叫

// 第一種  setcookie() 直接用setcookie設定session id的生命週期。
    $lifetime=60; //儲存1分鐘 
    session_start(); 
    setcookie(session_name(), session_id(), time()+$lifetime, "/");
// 第二種  session_set_cookie_params()    
    $lifetime=60;//儲存1分鐘
    session_set_cookie_params($lifetime);
    session_start();
    session_regenerate_id(true);
    // 其中session_regenerate_id();方法用於改變當前session_id的值,並保留session中陣列的值。引數預設為 false,如果設定為true則改變session_id的值,並清空當前session陣列。

json格式資料有哪些特點

JSON一種輕量級的資料交換格式(JavaScript Object Notation, JS 物件標記)。它基於ECMAScript的一個子集。 JSON採用完全獨立於語言的文字格式,但是也使用了類似於C語言家族的習慣(包括CC++C#JavaJavaScriptPerlPython等)。這些特性使JSON成為理想的資料交換語言。 易於人閱讀和編寫,同時也易於機器解析和生成(網路傳輸速率)。

  • "名稱/值"對的集合 不同語言中,它被理解為物件(object),記錄(record),結構(struct),字典(dictionary),雜湊表(hash table),鍵列表(keyed list)等
  • 值的有序列表 多數語言中被理解為陣列(array)

php獲取檔案內容的方法,對應的函式

  • file_get_contents得到檔案的內容(可以以getpost的方式獲取),整個檔案讀入一個字串中
  • fopen開啟url, 以get方式獲取內容(藉助fgets()函式)
  • fsockopen函式開啟url(可以以getpost的方式獲取),以get方式獲取完整的資料,包括headerbody
  • 使用curl庫獲取內容,使用curl庫之前,需要檢視php.ini,檢視是否已經開啟了curl擴充套件

php魔術方法與魔術常量

類方法:

__construct();

說明:具有建構函式的類會在每次建立新物件時先呼叫此方法,適合在使用物件之前做一些初始化工作。如果子類中定義了建構函式則不會隱式呼叫其父類的建構函式。要執行父類的建構函式,需要在子類的建構函式中呼叫 parent::__construct()。如果子類沒有定義建構函式則會如同一個普通的類方法一樣從父類繼承。

__destruct();

說明:解構函式會在到某個物件的所有引用都被刪除或者當物件被顯式銷燬時執行。

方法過載:

__call();

說明:在物件中呼叫一個不可訪問方法時,__call(); 方法會被呼叫。

__callStatic();

說明:用靜態方式中呼叫一個不可訪問方法時,__callStatic(); 方法會被呼叫。

屬性過載:(只對類中私有受保護的成員屬性有效)

__get();

說明:讀取不可訪問屬性的值時,__get() 會被呼叫。

__set();

說明:在給不可訪問屬性賦值時,__set() 會被呼叫。

__isset();

說明:當對不可訪問屬性呼叫 isset()empty() 時,__isset() 會被呼叫。

__unset();

說明:當對不可訪問屬性呼叫 unset() 時,__unset() 會被呼叫。

序列化相關:

__sleep();

說明:序列化時呼叫,serialize() 函式會檢查類中是否存在該魔術方法。如果存在,該方法會先被呼叫,然後才執行序列化操作。

__wakeup();

說明:unserialize() 會檢查是否存在一個 __wakeup() 方法。如果存在,則會先呼叫該方法,用在反序列化操作中,例如重新建立資料庫連線,或執行其它初始化操作

操作類和物件方法:

__toString();

說明:方法用於一個類被當成字串時呼叫,例如把一個類當做字串進行輸出

__invoke();

說明:當嘗試以呼叫函式的方式呼叫一個物件時,__invoke() 方法會被自動呼叫。

__set_state();

說明:當呼叫 var_export() 匯出類時,此靜態方法會被呼叫。 本方法的唯一引數是一個陣列

__clone();

說明:當複製完成時,如果定義了__clone()方法,則新建立的物件(複製生成的物件)中的__clone()方法會被呼叫,可用於修改屬性的值。

__autoload();

說明:該方法可以自動例項化需要的類。當程式要用一個類但沒有被例項化時,改方法在指定路徑下查詢和該類名稱相同的檔案。否則報錯。

__debugInfo();

說明:php5.6增加的特性,var_dump()一個類時觸發,返回一個包含物件屬性的陣列

PHP 將所有以 __(兩個下劃線)開頭的類方法保留為魔術方法。所以在定義類方法時,除了上述魔術方法,建議不要以 __ 為字首。在命名自己的類方法時不能使用這些方法名,除非是想使用其魔術功能。

常量:

__LINK__//檔案中的當前行號。
__FILE__//檔案的完整路徑和檔名。如果用在被包含檔案中,則返回被包含的檔名。
__DIR__ //檔案所在的目錄。如果用在被包括檔案中,則返回被包括的檔案所在的目錄,它等價於 dirname(__FILE__)。
 
__FUNCTION__//函式名稱。自 PHP 5 起本常量返回該函式被定義時的名字(區分大小寫)。在 PHP 4 中該值總是小寫字母的。
__CLASS__ //類的名稱。自 PHP 5 起本常量返回該類被定義時的名字(區分大小寫)。在 PHP 4 中該值總是小寫字母的。
__METHOD__//類的方法名(PHP 5.0.0 新加)。返回該方法被定義時的名字(區分大小寫)。
__NAMESPACE__//當前名稱空間的名稱(大小寫敏感)。這個常量是在編譯時定義的(PHP 5.3.0 新增)

php.inisafe mod關閉 影響哪些函式和引數,至少寫6個?

move_uploaded_file();
exec();
system();                              
passthru();
popen();
fopen();
mkdir();                              
rmdir();
rename();                            
unlink();
copy();                                 
chgrp();
chown();                              
chmod();
touch();                               
symlink();
link();                                   
parse_ini_file();
set_time_limit();                  
max_execution_time; 
mail();

isset()empty()is_null的區別

  • 當變數未定義時,is_null() 和“引數本身”是不允許作為引數判斷的,會報Notice警告錯誤;
  • empty , isset首先都會檢查變數是否存在,然後對變數值進行檢測。而is_null 和 “引數本身”只是直接檢查變數值,是否為null,因此如果變數未定義就會出現錯誤!
  • isset():僅當null和未定義,返回false
  • empty()""0"0"NULLFALSEarray(),未定義,均返回true
  • is_null():僅判斷是否為null,未定義報警告;
  • 變數本身作為引數,與empty()一致,但接受未定義變數時,報警告;

MVC的優缺點

MVC的優點

  • 可以為一個模型在執行時同時建立和使用多個檢視。變化-傳播機制可以確保所有相關的檢視及時得到模型資料變化,從而使所有關聯的檢視和控制器做到行為同步。
  • 檢視與控制器的可接插性,允許更換檢視和控制器物件,而且可以根據需求動態的開啟或關閉、甚至在執行期間進行物件替換。
  • 模型的可移植性。因為模型是獨立於檢視的,所以可以把一個模型獨立地移植到新的平臺工作。需要做的只是在新平臺上對檢視和控制器進行新的修改。
  • 潛在的框架結構。可以基於此模型建立應用程式框架,不僅僅是用在設計介面的設計中。

MVC的不足之處

  • 增加了系統結構和實現的複雜性。對於簡單的介面,嚴格遵循MVC,使模型、檢視與控制器分離,會增加結構的複雜性,並可能產生過多的更新操作,降低執行效率。
  • 檢視與控制器間的過於緊密的連線。檢視與控制器是相互分離,但確實聯絡緊密的部件,檢視沒有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。
  • 檢視對模型資料的低效率訪問。依據模型操作介面的不同,檢視可能需要多次呼叫才能獲得足夠的顯示資料。對未變化資料的不必要的頻繁訪問,也將損害操作效能。
  • 目前,一般高階的介面工具或構造器不支援MVC模式。改造這些工具以適應MVC需要和建立分離的部件的代價是很高的,從而造成使用MVC的困難。

sessioncookie的聯絡和區別(執行機制),session共享問題解決方案

區別與聯絡:

使用session_start()呼叫session,伺服器端在生成session檔案的同時生成session ID雜湊值和預設值為PHPSESSIDsession name,並向客戶端傳送變數為PHPSESSID(session name)(預設)值為一個128位的雜湊值。伺服器端將通過該cookie與客戶端進行互動,session變數的值經php內部系列化後儲存在伺服器機器上的文字檔案中,和客戶端的變數名預設情況下為PHPSESSIDcookie進行對應互動,即伺服器自動傳送了http 頭:header(‘Set-Cookie: session_name()=session_id(); path=/’);setcookie(session_name(),session_id());當從該頁跳轉到的新頁面並呼叫 session_start()後,PHP將檢查與給定ID相關聯的伺服器端存貯的session資料,如果沒找到則新建一個資料集。

共享方案:

  • 使用資料庫來儲存session,就算伺服器當機了也沒事,session照樣在。

問題:程式需要定製;每次請求都進行資料庫讀寫開銷不小,另外資料庫是一個單點,可以做資料庫的hash來解 決這個問題。

  • 使用memcache來儲存session, 這種方式跟資料庫類似,記憶體存取效能比資料庫好很多。

問題:程式需要定製,增加了工作量;存入memcached中的資料都需要序列化,效率較低,斷電或者重啟電腦容易丟失資料;

  • 通過加密的cookie,在A伺服器上登入,在使用者的瀏覽器上新增加密的cookie,當使用者訪問B伺服器時,檢查有無Session,如果沒有,就檢驗 Cookie是否有效,Cookie有效的話就在B伺服器上重建session。簡單,高效, 伺服器的壓力減小了,因為session資料不存在伺服器磁碟上。根本就不會出現session讀取不到的問題。

問題:網路請求佔用很多。每次請求時,客戶端都要通過cookie傳送session資料給伺服器,session中資料不能太多,瀏覽器對cookie的大小存在限制。不適合高訪問量的情況,因為高訪問量的情況下。

相關文章