PHP面试整理
PHP
HTTP Keep-Alive的作用
作用
Keep-Alive:使客戶端到服務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對(duì)服務(wù)器的后繼請(qǐng)求時(shí),Keep-Alive功能避免了建立或者重新建立連接。Web服務(wù)器,基本上都支持HTTP Keep-Alive。
缺點(diǎn)
對(duì)于提供靜態(tài)內(nèi)容的網(wǎng)站來(lái)說(shuō),這個(gè)功能通常很有用。但是,對(duì)于負(fù)擔(dān)較重的網(wǎng)站來(lái)說(shuō),雖然為客戶保留打開(kāi)的連 接有一定的好處,但它同樣影響了性能,因?yàn)樵谔幚頃和F陂g,本來(lái)可以釋放的資源仍舊被占用。當(dāng)Web服務(wù)器和應(yīng)用服務(wù)器在同一臺(tái)機(jī)器上運(yùn)行時(shí),Keep-Alive功能對(duì)資源利用的影響尤其突出。
解決
Keep-Alive: timeout=5, max=100
- timeout:過(guò)期時(shí)間5秒(對(duì)應(yīng)httpd.conf里的參數(shù)是:KeepAliveTimeout),
- max:是最多一百次請(qǐng)求,強(qiáng)制斷掉連接。就是在timeout時(shí)間內(nèi)又有新的連接過(guò)來(lái),同時(shí)max會(huì)自動(dòng)減1,直到為0,強(qiáng)制斷掉。
php數(shù)組函數(shù)常見(jiàn)的那些?
數(shù)組遍歷函數(shù)
list(); //不是真正的函數(shù),而是PHP的語(yǔ)言結(jié)構(gòu),用于給一組變量賦值,僅能用于索引數(shù)組 each(); //返回?cái)?shù)組當(dāng)前元素的鍵值對(duì),并將指針移動(dòng)到下一個(gè)元素位置 while(); //可配合list或each使用:while(list($key, $value) = each($arr)){each $key, $value; }數(shù)組內(nèi)部指針控制
current(); //讀取指針位置的內(nèi)容 key(); //讀取當(dāng)前指針指向內(nèi)容的索引值 next(); //將數(shù)組中的內(nèi)部指針指向下一單元 prev(); //將數(shù)組內(nèi)部指針倒回一位 end(); //將數(shù)組內(nèi)部指針指向最后一個(gè)元素 reset(); //將目前指針指向第一個(gè)索引位置數(shù)組鍵值操作函數(shù)
array_values($arr); //獲得數(shù)組的值 array_keys($arr); //獲得數(shù)組的鍵名 array_flip($arr); //數(shù)組中的值與鍵名互換(如果有重復(fù)前面的會(huì)被后面的覆蓋) array_search('PHP',$arr); //檢索給定的值,加true則是嚴(yán)格類型檢查 array_reverse($arr); //將數(shù)組中的元素翻轉(zhuǎn)(前后順序) in_array("apple", $arr); //在數(shù)組中檢索apple array_key_exists("apple", $arr); // 檢索給定的鍵名是否存在數(shù)組中 array_count_values($arr); // 統(tǒng)計(jì)數(shù)組中所有值出現(xiàn)的次數(shù) array_unique($arr); // 刪除數(shù)組中重復(fù)的值數(shù)組回調(diào)函數(shù)
array_filter(); //使用回調(diào)函數(shù)過(guò)濾數(shù)組中的元素,如果回調(diào)返回true則當(dāng)前的元素被包含到返回?cái)?shù)組中 array_walk(); //回調(diào)函數(shù)處理數(shù)組,自定義函數(shù)要有兩個(gè)參數(shù),本函數(shù)第三個(gè)參數(shù)可以作為回調(diào)第三個(gè)參數(shù)返回 array_map(); //可以處理多個(gè)數(shù)組,每個(gè)數(shù)組的長(zhǎng)度應(yīng)該相同,傳入數(shù)組的個(gè)數(shù)和回調(diào)函數(shù)參數(shù)個(gè)數(shù)應(yīng)該一致數(shù)組的分段和填充
array_slice($arr, 0, 3); //將數(shù)組中的一段取出,此函數(shù)忽略鍵名(數(shù)組的分段) array_splice($arr, 0, 3,array("black","maroon")); //將數(shù)組中的一段取出,返回的序列從原數(shù)組中刪除 array_chunk($arr, 3, TRUE); //將一個(gè)數(shù)組分割成多個(gè),TRUE為保留原數(shù)組的鍵名(分割多個(gè)數(shù)組)數(shù)組與棧,列隊(duì)
array_push($arr, "apple", "pear"); //將一個(gè)或多個(gè)元素壓入數(shù)組棧的末尾(入棧),返回入棧元素的個(gè)數(shù) array_pop($arr); // 將數(shù)組棧的最后一個(gè)元素彈出(出棧) array_shift($arr); //數(shù)組中第一個(gè)元素移出并返回(長(zhǎng)度減1,其他元素向前移動(dòng)一位,數(shù)字鍵名改為從零計(jì)數(shù),文字鍵名不變) array_unshift($arr,"a",array(1,2)); //在數(shù)組的開(kāi)頭插入一個(gè)或多個(gè)元素數(shù)組的排序
sort($arr); //由小到大,忽略鍵名 rsort($arr); //由大到小,忽略鍵名 asort($arr); //由小到大,保留鍵名 arsort($arr); //由大到小,保留鍵名 ksort($arr); //按照鍵名正序排序 krsort($arr); //按照鍵名逆序排序數(shù)組的計(jì)算
array_sum($arr); //對(duì)數(shù)組內(nèi)部的所有元素做求和運(yùn)算(數(shù)組元素的求和) array_merge($arr1, $arr2); //合并兩個(gè)或多個(gè)(相同字符串鍵名,后面覆蓋前面,相同的數(shù)字鍵名,后面的附加到后面)array_diff($arr1, $arr2); //返回差集結(jié)果數(shù)組 array_diff_assoc($arr1, $arr2, $arr3); //返回差集結(jié)果數(shù)組,鍵名也做比較 array_intersect($arr1, $arr2); //返回交集結(jié)果數(shù)組 array_intersect_assoc($arr1, $arr2); //返回交集結(jié)果數(shù)組,鍵名也做比較其他的數(shù)組函數(shù)
array_unique($arr); //移除數(shù)組中重復(fù)的值,新的數(shù)組中會(huì)保留原始的鍵名 shuffle($arr); // 將數(shù)組的順序打亂PHP中幾個(gè)輸出函數(shù)echo,print(),print_r(),sprintf(),var_dump()的區(qū)別
- echo:是語(yǔ)句不是函數(shù),沒(méi)有返回值,可輸出多個(gè)變量值,不需要圓括號(hào)。不能輸出數(shù)組和對(duì)象,只能打印簡(jiǎn)單類型(如int,string)。
- print:是語(yǔ)句不是函數(shù),有返回值 1 ,只能輸出一個(gè)變量,不需要圓括號(hào)。不能輸出數(shù)組和對(duì)象,只能打印簡(jiǎn)單類型(如int,string)。
- print_r:是函數(shù),可以打印復(fù)合類型,例如:stirng、int、float、array、object等,輸出array時(shí)會(huì)用結(jié)構(gòu)表示,而且可以通過(guò)print_r($str,true)來(lái)使print_r不輸出而返回print_r處理后的值
- printf:是函數(shù),把文字格式化以后輸出(參看C語(yǔ)言)
- sprintf:是函數(shù),跟printf相似,但不打印,而是返回格式化后的文字(該函數(shù)把格式化的字符串寫(xiě)寫(xiě)入一個(gè)變量中,而不是輸出來(lái)),其他的與printf一樣。
可以通過(guò)function_exists('函數(shù)名稱')進(jìn)行測(cè)試
var_dump(function_exists('print')); //bool(false) var_dump(function_exists('echo')); //bool(false) var_dump(function_exists('print_r')); //bool(trueheredoc
Heredoc在正規(guī)的PHP文檔中和技術(shù)書(shū)籍中一般沒(méi)有詳細(xì)講述。他是一種Perl風(fēng)格的字符串輸出技術(shù)。使用heredoc技術(shù)可以實(shí)現(xiàn)界面與代碼的準(zhǔn)分離,比如phpwind模板。
heredoc的語(yǔ)法是用”<<<”加上自己定義成對(duì)的標(biāo)簽,在標(biāo)簽范圍內(nèi)的文字視為一個(gè)字符串
- 以<<<End開(kāi)始標(biāo)記開(kāi)始,以End結(jié)束標(biāo)記結(jié)束,結(jié)束標(biāo)記必須頂頭寫(xiě),不能有縮進(jìn)和空格,且在結(jié)束標(biāo)記末尾要有分號(hào)。開(kāi)始標(biāo)記和開(kāi)始標(biāo)記相同,比如常用大寫(xiě)的EOT、EOD、EOF來(lái)表示,也可以使用其他標(biāo)記,只要保證開(kāi)始標(biāo)記和結(jié)束標(biāo)記不在正文中出現(xiàn)就行。
- 位于開(kāi)始標(biāo)記和結(jié)束標(biāo)記之間的變量可以被正常解析,但是函數(shù)則不可以。在heredoc中,變量不需要用連接符 . 或 , 來(lái)拼接,比如:
heredoc常用在輸出包含大量HTML語(yǔ)法文檔的時(shí)候。他要比傳統(tǒng)的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; }禁掉cookie的session使用方案,設(shè)置session過(guò)期的方法,對(duì)應(yīng)函數(shù)
通過(guò)url傳值,把session id附加到url上(缺點(diǎn):整個(gè)站點(diǎn)中不能有純靜態(tài)頁(yè)面,因?yàn)榧冹o態(tài)頁(yè)面session id 將無(wú)法繼續(xù)傳到下一頁(yè)面)
通過(guò)隱藏表單,把session id放到表單的隱藏文本框中同表單一塊提交過(guò)去(缺點(diǎn):不適用<a>標(biāo)簽這種直接跳轉(zhuǎn)的非表單的情況)
直接配置php.ini文件,將php.ini文件里的session.use_trans_sid= 0設(shè)為1,(好像在win上不支持)
用文件、數(shù)據(jù)庫(kù)等形式保存Session ID,在跨頁(yè)過(guò)程中手動(dòng)調(diào)用
json格式數(shù)據(jù)有哪些特點(diǎn)
JSON一種輕量級(jí)的數(shù)據(jù)交換格式(JavaScript Object Notation, JS 對(duì)象標(biāo)記)。它基于ECMAScript的一個(gè)子集。 JSON采用完全獨(dú)立于語(yǔ)言的文本格式,但是也使用了類似于C語(yǔ)言家族的習(xí)慣(包括C、C++、C#、Java、JavaScript、Perl、 Python等)。這些特性使JSON成為理想的數(shù)據(jù)交換語(yǔ)言。 易于人閱讀和編寫(xiě),同時(shí)也易于機(jī)器解析和生成(網(wǎng)絡(luò)傳輸速率)。
- "名稱/值"對(duì)的集合 不同語(yǔ)言中,它被理解為對(duì)象(object),記錄(record),結(jié)構(gòu)(struct),字典(dictionary),哈希表(hash table),鍵列表(keyed list)等
- 值的有序列表 多數(shù)語(yǔ)言中被理解為數(shù)組(array)
php獲取文件內(nèi)容的方法,對(duì)應(yīng)的函數(shù)
- file_get_contents得到文件的內(nèi)容(可以以get和post的方式獲取),整個(gè)文件讀入一個(gè)字符串中
- 用fopen打開(kāi)url, 以get方式獲取內(nèi)容(借助fgets()函數(shù))
- 用fsockopen函數(shù)打開(kāi)url(可以以get和post的方式獲取),以get方式獲取完整的數(shù)據(jù),包括header和body
- 使用curl庫(kù)獲取內(nèi)容,使用curl庫(kù)之前,需要查看php.ini,查看是否已經(jīng)打開(kāi)了curl擴(kuò)展
php魔術(shù)方法與魔術(shù)常量
類方法:
__construct();
說(shuō)明:具有構(gòu)造函數(shù)的類會(huì)在每次創(chuàng)建新對(duì)象時(shí)先調(diào)用此方法,適合在使用對(duì)象之前做一些初始化工作。如果子類中定義了構(gòu)造函數(shù)則不會(huì)隱式調(diào)用其父類的構(gòu)造函數(shù)。要執(zhí)行父類的構(gòu)造函數(shù),需要在子類的構(gòu)造函數(shù)中調(diào)用 parent::__construct()。如果子類沒(méi)有定義構(gòu)造函數(shù)則會(huì)如同一個(gè)普通的類方法一樣從父類繼承。
__destruct();
說(shuō)明:析構(gòu)函數(shù)會(huì)在到某個(gè)對(duì)象的所有引用都被刪除或者當(dāng)對(duì)象被顯式銷(xiāo)毀時(shí)執(zhí)行。
方法重載:
__call();
說(shuō)明:在對(duì)象中調(diào)用一個(gè)不可訪問(wèn)方法時(shí),__call(); 方法會(huì)被調(diào)用。
__callStatic();
說(shuō)明:用靜態(tài)方式中調(diào)用一個(gè)不可訪問(wèn)方法時(shí),__callStatic(); 方法會(huì)被調(diào)用。
屬性重載:(只對(duì)類中私有受保護(hù)的成員屬性有效)
__get();
說(shuō)明:讀取不可訪問(wèn)屬性的值時(shí),__get() 會(huì)被調(diào)用。
__set();
說(shuō)明:在給不可訪問(wèn)屬性賦值時(shí),__set() 會(huì)被調(diào)用。
__isset();
說(shuō)明:當(dāng)對(duì)不可訪問(wèn)屬性調(diào)用 isset() 或 empty() 時(shí),__isset() 會(huì)被調(diào)用。
__unset();
說(shuō)明:當(dāng)對(duì)不可訪問(wèn)屬性調(diào)用 unset() 時(shí),__unset() 會(huì)被調(diào)用。
序列化相關(guān):
__sleep();
說(shuō)明:序列化時(shí)調(diào)用,serialize() 函數(shù)會(huì)檢查類中是否存在該魔術(shù)方法。如果存在,該方法會(huì)先被調(diào)用,然后才執(zhí)行序列化操作。
__wakeup();
說(shuō)明:unserialize() 會(huì)檢查是否存在一個(gè) __wakeup() 方法。如果存在,則會(huì)先調(diào)用該方法,用在反序列化操作中,例如重新建立數(shù)據(jù)庫(kù)連接,或執(zhí)行其它初始化操作
操作類和對(duì)象方法:
__toString();
說(shuō)明:方法用于一個(gè)類被當(dāng)成字符串時(shí)調(diào)用,例如把一個(gè)類當(dāng)做字符串進(jìn)行輸出
__invoke();
說(shuō)明:當(dāng)嘗試以調(diào)用函數(shù)的方式調(diào)用一個(gè)對(duì)象時(shí),__invoke() 方法會(huì)被自動(dòng)調(diào)用。
__set_state();
說(shuō)明:當(dāng)調(diào)用 var_export() 導(dǎo)出類時(shí),此靜態(tài)方法會(huì)被調(diào)用。 本方法的唯一參數(shù)是一個(gè)數(shù)組
__clone();
說(shuō)明:當(dāng)復(fù)制完成時(shí),如果定義了__clone()方法,則新創(chuàng)建的對(duì)象(復(fù)制生成的對(duì)象)中的__clone()方法會(huì)被調(diào)用,可用于修改屬性的值。
__autoload();
說(shuō)明:該方法可以自動(dòng)實(shí)例化需要的類。當(dāng)程序要用一個(gè)類但沒(méi)有被實(shí)例化時(shí),改方法在指定路徑下查找和該類名稱相同的文件。否則報(bào)錯(cuò)。
__debugInfo();
說(shuō)明:php5.6增加的特性,var_dump()一個(gè)類時(shí)觸發(fā),返回一個(gè)包含對(duì)象屬性的數(shù)組
PHP 將所有以 __(兩個(gè)下劃線)開(kāi)頭的類方法保留為魔術(shù)方法。所以在定義類方法時(shí),除了上述魔術(shù)方法,建議不要以 __ 為前綴。在命名自己的類方法時(shí)不能使用這些方法名,除非是想使用其魔術(shù)功能。常量:
__LINK__//文件中的當(dāng)前行號(hào)。 __FILE__//文件的完整路徑和文件名。如果用在被包含文件中,則返回被包含的文件名。 __DIR__ //文件所在的目錄。如果用在被包括文件中,則返回被包括的文件所在的目錄,它等價(jià)于 dirname(__FILE__)。__FUNCTION__//函數(shù)名稱。自 PHP 5 起本常量返回該函數(shù)被定義時(shí)的名字(區(qū)分大小寫(xiě))。在 PHP 4 中該值總是小寫(xiě)字母的。 __CLASS__ //類的名稱。自 PHP 5 起本常量返回該類被定義時(shí)的名字(區(qū)分大小寫(xiě))。在 PHP 4 中該值總是小寫(xiě)字母的。 __METHOD__//類的方法名(PHP 5.0.0 新加)。返回該方法被定義時(shí)的名字(區(qū)分大小寫(xiě))。 __NAMESPACE__//當(dāng)前命名空間的名稱(大小寫(xiě)敏感)。這個(gè)常量是在編譯時(shí)定義的(PHP 5.3.0 新增)php.ini 中safe mod關(guān)閉 影響哪些函數(shù)和參數(shù),至少寫(xiě)6個(gè)?
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的區(qū)別
- 當(dāng)變量未定義時(shí),is_null() 和“參數(shù)本身”是不允許作為參數(shù)判斷的,會(huì)報(bào)Notice警告錯(cuò)誤;
- empty , isset首先都會(huì)檢查變量是否存在,然后對(duì)變量值進(jìn)行檢測(cè)。而is_null 和 “參數(shù)本身”只是直接檢查變量值,是否為null,因此如果變量未定義就會(huì)出現(xiàn)錯(cuò)誤!
- isset():僅當(dāng)null和未定義,返回false;
- empty():""、0、"0"、NULL、FALSE、array(),未定義,均返回true;
- is_null():僅判斷是否為null,未定義報(bào)警告;
- 變量本身作為參數(shù),與empty()一致,但接受未定義變量時(shí),報(bào)警告;
MVC的優(yōu)缺點(diǎn)
MVC的優(yōu)點(diǎn)
- 可以為一個(gè)模型在運(yùn)行時(shí)同時(shí)建立和使用多個(gè)視圖。變化-傳播機(jī)制可以確保所有相關(guān)的視圖及時(shí)得到模型數(shù)據(jù)變化,從而使所有關(guān)聯(lián)的視圖和控制器做到行為同步。
- 視圖與控制器的可接插性,允許更換視圖和控制器對(duì)象,而且可以根據(jù)需求動(dòng)態(tài)的打開(kāi)或關(guān)閉、甚至在運(yùn)行期間進(jìn)行對(duì)象替換。
- 模型的可移植性。因?yàn)槟P褪仟?dú)立于視圖的,所以可以把一個(gè)模型獨(dú)立地移植到新的平臺(tái)工作。需要做的只是在新平臺(tái)上對(duì)視圖和控制器進(jìn)行新的修改。
- 潛在的框架結(jié)構(gòu)。可以基于此模型建立應(yīng)用程序框架,不僅僅是用在設(shè)計(jì)界面的設(shè)計(jì)中。
MVC的不足之處
- 增加了系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)的復(fù)雜性。對(duì)于簡(jiǎn)單的界面,嚴(yán)格遵循MVC,使模型、視圖與控制器分離,會(huì)增加結(jié)構(gòu)的復(fù)雜性,并可能產(chǎn)生過(guò)多的更新操作,降低運(yùn)行效率。
- 視圖與控制器間的過(guò)于緊密的連接。視圖與控制器是相互分離,但確實(shí)聯(lián)系緊密的部件,視圖沒(méi)有控制器的存在,其應(yīng)用是很有限的,反之亦然,這樣就妨礙了他們的獨(dú)立重用。
- 視圖對(duì)模型數(shù)據(jù)的低效率訪問(wèn)。依據(jù)模型操作接口的不同,視圖可能需要多次調(diào)用才能獲得足夠的顯示數(shù)據(jù)。對(duì)未變化數(shù)據(jù)的不必要的頻繁訪問(wèn),也將損害操作性能。
- 目前,一般高級(jí)的界面工具或構(gòu)造器不支持MVC模式。改造這些工具以適應(yīng)MVC需要和建立分離的部件的代價(jià)是很高的,從而造成使用MVC的困難。
session與cookie的聯(lián)系和區(qū)別(運(yùn)行機(jī)制),session共享問(wèn)題解決方案
區(qū)別與聯(lián)系:
使用session_start()調(diào)用session,服務(wù)器端在生成session文件的同時(shí)生成session ID哈希值和默認(rèn)值為PHPSESSID的session name,并向客戶端發(fā)送變量為PHPSESSID(session name)(默認(rèn))值為一個(gè)128位的哈希值。服務(wù)器端將通過(guò)該cookie與客戶端進(jìn)行交互,session變量的值經(jīng)php內(nèi)部系列化后保存在服務(wù)器機(jī)器上的文本文件中,和客戶端的變量名默認(rèn)情況下為PHPSESSID的cookie進(jìn)行對(duì)應(yīng)交互,即服務(wù)器自動(dòng)發(fā)送了http 頭:header(‘Set-Cookie: session_name()=session_id(); path=/’);即setcookie(session_name(),session_id());當(dāng)從該頁(yè)跳轉(zhuǎn)到的新頁(yè)面并調(diào)用 session_start()后,PHP將檢查與給定ID相關(guān)聯(lián)的服務(wù)器端存貯的session數(shù)據(jù),如果沒(méi)找到則新建一個(gè)數(shù)據(jù)集。
共享方案:
- 使用數(shù)據(jù)庫(kù)來(lái)保存session,就算服務(wù)器宕機(jī)了也沒(méi)事,session照樣在。
- 使用memcache來(lái)保存session, 這種方式跟數(shù)據(jù)庫(kù)類似,內(nèi)存存取性能比數(shù)據(jù)庫(kù)好很多。
- 通過(guò)加密的cookie,在A服務(wù)器上登錄,在用戶的瀏覽器上添加加密的cookie,當(dāng)用戶訪問(wèn)B服務(wù)器時(shí),檢查有無(wú)Session,如果沒(méi)有,就檢驗(yàn) Cookie是否有效,Cookie有效的話就在B服務(wù)器上重建session。簡(jiǎn)單,高效, 服務(wù)器的壓力減小了,因?yàn)閟ession數(shù)據(jù)不存在服務(wù)器磁盤(pán)上。根本就不會(huì)出現(xiàn)session讀取不到的問(wèn)題。
總結(jié)
- 上一篇: 想做大牛,Java开发的必备技术点你了解
- 下一篇: 在Workstation 14中导入vC