## 一、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數組函數常見的那些?
1、數組遍歷函數
~~~
list(); //不是真正的函數,而是PHP的語言結構,用于給一組變量賦值,僅能用于索引數組
each(); //返回數組當前元素的鍵值對,并將指針移動到下一個元素位置
while(); //可配合list或each使用:while(list($key, $value) = each($arr)){each $key, $value; }
~~~
2、數組內部指針控制
~~~
current(); //讀取指針位置的內容
key(); //讀取當前指針指向內容的索引值
next(); //將數組中的內部指針指向下一單元
prev(); //將數組內部指針倒回一位
end(); //將數組內部指針指向最后一個元素
reset(); //將目前指針指向第一個索引位置
~~~
3、數組鍵值操作函數
~~~
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); // 刪除數組中重復的值
~~~
4、數組回調函數
~~~
array_filter(); //使用回調函數過濾數組中的元素,如果回調返回true則當前的元素被包含到返回數組中
array_walk(); //回調函數處理數組,自定義函數要有兩個參數,本函數第三個參數可以作為回調第三個參數返回
array_map(); //可以處理多個數組,每個數組的長度應該相同,傳入數組的個數和回調函數參數個數應該一致
~~~
5、數組的分段和填充
~~~
array_slice($arr, 0, 3); //將數組中的一段取出,此函數忽略鍵名(數組的分段)
array_splice($arr, 0, 3,array("black","maroon")); //將數組中的一段取出,返回的序列從原數組中刪除
array_chunk($arr, 3, TRUE); //將一個數組分割成多個,TRUE為保留原數組的鍵名(分割多個數組)
~~~
6、數組與棧,列隊
~~~
array_push($arr, "apple", "pear"); //將一個或多個元素壓入數組棧的末尾(入棧),返回入棧元素的個數
array_pop($arr); // 將數組棧的最后一個元素彈出(出棧)
array_shift($arr); //數組中第一個元素移出并返回(長度減1,其他元素向前移動一位,數字鍵名改為從零計數,文字鍵名不變)
array_unshift($arr,"a",array(1,2)); //在數組的開頭插入一個或多個元素
~~~
7、數組的排序
~~~
sort($arr); //由小到大,忽略鍵名
rsort($arr); //由大到小,忽略鍵名
asort($arr); //由小到大,保留鍵名
arsort($arr); //由大到小,保留鍵名
ksort($arr); //按照鍵名正序排序
krsort($arr); //按照鍵名逆序排序
~~~
8、數組的計算
~~~
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); //返回交集結果數組,鍵名也做比較
~~~
9、其他的數組函數
~~~
array_unique($arr); //移除數組中重復的值,新的數組中會保留原始的鍵名
shuffle($arr); // 將數組的順序打亂
~~~
## 三、PHP中幾個輸出函數echo,print(),print_r(),sprintf(),var_dump()的區別??
* echo:是語句不是函數,沒有返回值,可輸出多個變量值,不需要圓括號。不能輸出數組和對象,只能打印簡單類型(如int,string)。
* print:是語句不是函數,有返回值 1 ,只能輸出一個變量,不需要圓括號。不能輸出數組和對象,只能打印簡單類型(如int,string)。
* print_r:是函數,可以打印復合類型,例如:stirng、int、float、array、object等,輸出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結束標記結束,結束標記必須頂頭寫,不能有縮進和空格,且在結束標記末尾要有分號。開始標記和開始標記相同,比如常用大寫的EOT、EOD、EOF來表示,也可以使用其他標記,只要保證開始標記和結束標記不在正文中出現就行。
* 位于開始標記和結束標記之間的變量可以被正常解析,但是函數則不可以。在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;
}
~~~
## 五、禁掉cookie的session使用方案,設置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語言家族的習慣(包括C、C++、C#、Java、JavaScript、Perl、 Python等)。這些特性使JSON成為理想的數據交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成(網絡傳輸速率)。
* "名稱/值"對的集合 不同語言中,它被理解為對象(object),記錄(record),結構(struct),字典(dictionary),哈希表(hash table),鍵列表(keyed list)等
* 值的有序列表 多數語言中被理解為數組(array)
## 七、php獲取文件內容的方法,對應的函數
* file_get_contents得到文件的內容(可以以get和post的方式獲取),整個文件讀入一個字符串中
* 用fopen打開url, 以get方式獲取內容(借助fgets()函數)
* 用fsockopen函數打開url(可以以get和post的方式獲取),以get方式獲取完整的數據,包括header和body
* 使用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.ini 中safe 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"、NULL、FALSE、array(),未定義,均返回true;
* is_null():僅判斷是否為null,未定義報警告;
* 變量本身作為參數,與empty()一致,但接受未定義變量時,報警告;
## 十一、MVC的優缺點
優點
* 可以為一個模型在運行時同時建立和使用多個視圖。變化-傳播機制可以確保所有相關的視圖及時得到模型數據變化,從而使所有關聯的視圖和控制器做到行為同步。
* 視圖與控制器的可接插性,允許更換視圖和控制器對象,而且可以根據需求動態的打開或關閉、甚至在運行期間進行對象替換。
* 模型的可移植性。因為模型是獨立于視圖的,所以可以把一個模型獨立地移植到新的平臺工作。需要做的只是在新平臺上對視圖和控制器進行新的修改。
* 潛在的框架結構。可以基于此模型建立應用程序框架,不僅僅是用在設計界面的設計中。
缺點
* 增加了系統結構和實現的復雜性。對于簡單的界面,嚴格遵循MVC,使模型、視圖與控制器分離,會增加結構的復雜性,并可能產生過多的更新操作,降低運行效率。
* 視圖與控制器間的過于緊密的連接。視圖與控制器是相互分離,但確實聯系緊密的部件,視圖沒有控制器的存在,其應用是很有限的,反之亦然,這樣就妨礙了他們的獨立重用。
* 視圖對模型數據的低效率訪問。依據模型操作接口的不同,視圖可能需要多次調用才能獲得足夠的顯示數據。對未變化數據的不必要的頻繁訪問,也將損害操作性能。
* 目前,一般高級的界面工具或構造器不支持MVC模式。改造這些工具以適應MVC需要和建立分離的部件的代價是很高的,從而造成使用MVC的困難。
## 十二、session與cookie的聯系和區別(運行機制),session共享問題解決方?案
區別與聯系:
使用`session_start()`調用session,服務器端在生成session文件的同時生成session ID哈希值和默認值為PHPSESSID的session name,并向客戶端發送變量為PHPSESSID(session name)(默認)值為一個128位的哈希值。服務器端將通過該cookie與客戶端進行交互,session變量的值經php內部系列化后保存在服務器機器上的文本文件中,和客戶端的變量名默認情況下為PHPSESSID的cookie進行對應交互,即服務器自動發送了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的大小存在限制。不適合高訪問量的情況,因為高訪問量的情況下。
參考鏈接:https://segmentfault.com/a/1190000013782036?utm_source=index-hottest