本篇文章給大家帶來了關於的相關知識,其中主要介紹了PHP面試題,總結了三十九個常見的面試題,php面試題的題型很多,但是都離不開PHP面試題基礎常見的,希望對大家有幫助。
推薦學習:《》
這個問題的核心是域名解析和伺服器(nginx)解析這兩部分,基本上這兩部分詳細闡述就可以了。
步驟一、解析URL
瀏覽器會解析當前的URL資料,判斷此URL是否為合法的連結。如果是合法連結則正常的向下一步驟前進。如果不是合法的連結,則會執行搜尋功能,例如執行百度、360、Google搜尋等。
步驟二、解析域名
伺服器是以ip的形式存在的。而域名需要解析到ip上,解析IP會有三個小的步驟:
1)、從瀏覽器自身的快取中解析此域名資料
2)、從本地電腦的HOST檔案中解析域名
3)、通過DNS伺服器解析域名
步驟三、拿資訊
這個步驟我們拿到了URL的資訊,主要是IP和埠資訊。
步驟四、封包並進行三次握手
瀏覽器將請求資訊進行打包,通過TCP的三次握手將資料傳遞至伺服器。
步驟五、伺服器解析、處理、返回資料
伺服器通過種種層級、方式拿到傳遞的資料,對資料進行分析、處理,最後返回響應類MIME型別資料。正常狀態碼為200,非正常的錯誤碼有404、500、501等等
步驟六、瀏覽器獲得、渲染、展現資料
瀏覽器從伺服器拿到資料、通過載入資源、渲染頁面等操作,將頁面展現給使用者。
1)、http無狀態協定,不能區分使用者是否是從同一個網站上來的,同一個使用者請求不同的頁面不能看做是同一個使用者。
2)、SESSION儲存在伺服器端,COOKIE儲存在使用者端。Session比較安全,cookie用某些手段可以修改,不安全。Session依賴於cookie進行傳遞。
禁用cookie後,session不能正常使用。Session的缺點:儲存在伺服器端,每次讀取都從伺服器進行讀取,對伺服器有資源消耗。Session儲存在伺服器端的檔案或資料庫中,預設儲存在檔案中,檔案路徑由php組態檔的session.save_path指定。Session檔案是公有的。
一二三四五原則: 一. 訊息系列 二 成功系列 三. 重定向系列 四. 請求錯誤系列 五. 伺服器端錯誤系列
302:臨時轉移成功,請求的內容已轉移到新位置 403:禁止存取 500:伺服器內部錯誤 401代表未授權。
Tar.gz:
打包: tar czf file.tar.gz file.txt
解壓: tar xzf file.tar.gz
Bz2:
打包: bzip2 [-k] 檔案
解壓: bunzip2 [-k] 檔案
Gzip(只對檔案,不保留原檔案)
打包: gzip file1.txt
解壓: gunzip file1.txt.gz
Zip: -r 對目錄
打包: zip file1.zip file1.txt
解壓: unzip file1.zip
Int 整數 char 定長字元 Varchar 變長字元 Datetime 日期時間型 Text 文字型 Varchar 與char的區別 char是固定長度的字元型別,分配多少空間,就佔用多長空間。 Varchar是可變長度的字元型別,內容有多大就佔用多大的空間,能有效節省空間。 由於varchar型別是可變的,所以在資料長度改變的時,伺服器要進行額外的操作,所以效率比char型別低。
MyISAM型別不支援事務,表鎖,易產生碎片,要經常優化,讀寫速度較快,而InnoDB型別支援事務,行鎖,有崩潰恢復能力。讀寫速度比MyISAM慢。
建立索引:alert table tablename add index (`欄位名`)
理解:session_start()開啟時,生成一個常數 SID,當COOKIE開啟時,這個常數為空,當COOKIE關閉時,這個常數中儲存了PHPSESSID的值。通過在URL後加一個SID引數來傳遞SESSIONID的值,從而使使用者端頁面可以使用SESSION裡面的值。 當用戶端開啟COOKIE和伺服器端開啟SESSION時。 瀏覽器第一次請求,伺服器會向瀏覽器端傳送一個COOKIE裡面儲存SESSIONID. 當瀏覽器第二次請求時,會把已存在
Isset判斷變數是否存在,可以傳入多個變數,若其中一個變數不存在則返回假,empty判斷變數是否為空為假,只可傳一個變數,如果為空為假則返回真。
答:主要有兩種方式:
1) 快照持久化
在redis組態檔中已經自動開啟了,
格式是:save N M
表示在N秒之內,redis至少發生M次修改則redis抓快照到磁碟。
當然我們也可以手動執行save或者bgsave(非同步)命令來做快照
2)append only file AOF持久化
總共有三種模式,如
appendfsync everysec預設的是每秒強制寫入磁碟一次
appendfsync always 每次執行寫操作的時候就強制寫入磁碟
appendfsync no 完全取決於os,效能最好但是持久化沒法保證
其中第三種模式最好。redis預設的也是採取第三種模式。
答:常用的主要分為兩種,一種是innodb,一種是myisam,兩者的主要區別是
1)myisam不支援事務處理,而innoDB支援事務處理
2)myisam 不支援外來鍵,innoDB支援外來鍵
3)myisam支援全文檢索,而innoDB在MySQL5.6版本之後才支援全文檢索
4)資料的儲存形式不一樣,mysiam表存放在三個檔案:結構、索引、資料,innoDB儲存把結構儲存為一個檔案,索引和資料儲存為一個檔案
5)myisam在查詢和增加資料效能更優於innoDB,innoDB在批次刪除方面效能較高。
6)myisam支援表鎖,而innoDB支援行鎖
答:SQL隱碼攻擊指的是使用者或者駭客通過構建特殊的輸入作為引數傳入我們的Web應用程式端,而這些輸入大都是SQL語法裡的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程式設計師沒有細緻地過濾使用者輸入的資料,致使非法資料侵入系統而造成的。因此我們在做開發過程中一定要預防sql注入,主要從兩方面著手:
1)預留位置的方式,就是對sql語句進行預處理,然後執行sql語句
2)通過addslashes或者mysql_real_escape_string這兩個函數對使用者輸入的值進行跳脫處理,把一些特殊的字元跳脫掉。
答:用過,PDO類中,有個prepare方法可以實現預處理,PDOStament類中 的excute方法可以執行預處理,預處理的引數分為兩種,一種是:字串預留位置,另一種是?預留位置,:字串預留位置在執行預處理傳遞引數時傳入的是關聯陣列,而?預留位置傳遞的是索引陣列。兩者不能混合使用,但一般推薦使用:字串預留位置。
答:一般成熟的開源框架中都考慮到了資料安全這方面的東西,但有時候我們可能會使用一些原生的SQL語句時,我們就需要考慮自己對sql語句進行預處理。當然有時候框架中的過濾方法我們不希望採用,比如使用文字編輯器時,我們可以使用自己的過濾方式。
答:mysql優化主要從以下幾個方面來實現:
1)設計角度:儲存引擎的選擇,欄位型別選擇,正規化
2)功能角度:可以利用mysql自身的特性,如索引,查詢快取,碎片整理,分割區、分表等
3)sql語句的優化方面:儘量簡化查詢語句,能查詢欄位少就儘量少查詢欄位,優化分頁語句、分組語句等。
4)部署大負載架構體系:資料庫伺服器單獨出來,負載大時可以採用主從複製,讀寫分離機制進行設計
5)從硬體上升級資料庫伺服器。
按值傳遞:函數範圍內對值的任何改變在函數外部都會被忽略
按參照傳遞:函數範圍內對值的任何改變在函數外部也能反映出這些修改
優缺點:按值傳遞時,php必須複製值。特別是對於大型的字串和物件來說,這將會是一個代價很大的操作。按參照傳遞則不需要複製值,對於效能提高很有好處。
設定 PHP 的報錯級別並返回當前級別。
原理:快速排序使用分治策略來把待排序資料序列分為兩個子序列,具體步驟為:
(1)從數列中挑出一個元素,稱該元素為「基準」。
(2)掃描一遍數列,將所有比「基準」小的元素排在基準前面,所有比「基準」大的元素排在基準後面。
(3)通過遞迴,將各子序列劃分為更小的序列,直到把小於基準值元素的子數列和大於基準值元素的子數列排序。
//快速排序(陣列排序) function QuickSort($arr){ $num = count($arr); $l=$r=0; for($i=1;$i<$num;$i++){ if($arr[$i] < $arr[0]){ $left[] = $arr[$i]; $l++; }else{ $right[] = $arr[$i]; $r++; } } if($l > 1){ $left = QuickSort($left); } $new_arr = $left; $new_arr[] = $arr[0]; if($r > 1){ $right = QuickSort($right); } for($i=0;$i<$r;$i++){ $new_arr[] = $right[$i]; } return $new_arr; }
//二分查詢(陣列裡查詢某個元素) function bin_sch($array, $low, $high, $k){ if ($low <= $high){ $mid = intval(($low+$high)/2); if ($array[$mid] == $k){ return $mid; }elseif ($k < $array[$mid]){ return bin_sch($array, $low, $mid-1, $k); }else{ return bin_sch($array, $mid+1, $high, $k); } } return -1; } //順序查詢(陣列裡查詢某個元素) function seq_sch($array, $n, $k){ $array[$n] = $k; for($i=0; $i<$n; $i++){ if($array[$i]==$k){ break; } } if ($i<$n){ return $i; }else{ return -1; } }
//二維陣列排序, $arr是資料,$keys是排序的健值,$order是排序規則,1是升序,0是降序 function array_sort($arr, $keys, $order=0) { if (!is_array($arr)) { return false; } $keysvalue = array(); foreach($arr as $key => $val) { $keysvalue[$key] = $val[$keys]; } if($order == 0){ asort($keysvalue); }else { arsort($keysvalue); } reset($keysvalue); foreach($keysvalue as $key => $vals) { $keysort[$key] = $key; } $new_array = array(); foreach($keysort as $key => $val) { $new_array[$key] = $arr[$val]; } return $new_array; }
class regx { public static function check($str) { if(preg_match("/^([1-9,])+$/",$str)) { return true; } return false; } } $str="12345,6"; if(regx::check($str)) { echo "suc"; } else { echo "fail"; }
class Db { private static $instance; public $handle; Private function __construct($host,$username,$password,$dbname) { $this->handle=NULL; $this->getcon($host,$username,$password,$dbname); } public static function getBb() { self::$instance=new Db(); return self::$instance; } private function getcon($host,$username,$password,$dbname) { if($this->handle!=NULL){ return true; } $this->handle=mysqli_connect($host,$username,$password,$dbname); } }
A) SQLite Database
B) MySQL Database
C) Shared Memory
D) File System
E) Session Server
答:原因是:中文是由多位元組組成的,而只有英文系統的單個英文字元只有一個位元組,所以該系統把中文的每一個位元組都做了strtolower()處理,改變後的中文位元組拼接在一起就成了亂碼(新生成的編碼對映對應的字元可能就不是中文了)
手動解決:用str_split(string string,intstring,intsplit_length = 1)按每個位元組切割,像中文能切割成三個位元組。對識別到的位元組若是英文字母則進行轉換。
<?php function mystrtoupper($a){ $b = str_split($a, 1); $r = ''; foreach($b as $v){ $v = ord($v); if($v >= 97 && $v<= 122){ $v -= 32; } $r .= chr($v); } return $r; } $a = 'a中你繼續F@#$%^&*(BMDJFDoalsdkfjasl'; echo 'origin string:'.$a."\n"; echo 'result string:'; $r = mystrtoupper($a); var_dump($r);
答:其中bug存在兩個方面,
1)在windowns中,當檔案只有唯讀屬性時,is_writeable()函數才返回false,當返回true時,該檔案不一定是可寫的。
如果是目錄,在目錄中新建檔案並通過開啟檔案來判斷;
如果是檔案,可以通過開啟檔案(fopen),來測試檔案是否可寫。
2)在Unix中,當php組態檔中開啟safe_mode時(safe_mode=on),is_writeable()同樣不可用。
讀取組態檔是否safe_mode是否開啟。
/** * Tests for file writability * * is_writable() returns TRUE on Windows servers when you really can't write to * the file, based on the read-only attribute. is_writable() is also unreliable * on Unix servers if safe_mode is on. * * @access private * @return void */ if ( ! function_exists('is_really_writable')) { function is_really_writable($file) { // If we're on a Unix server with safe_mode off we call is_writable if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE) { return is_writable($file); } // For windows servers and safe_mode "on" installations we'll actually // write a file then read it. Bah... if (is_dir($file)) { $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100)); if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE) { return FALSE; } fclose($fp); @chmod($file, DIR_WRITE_MODE); @unlink($file); return TRUE; } elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE) { return FALSE; } fclose($fp); return TRUE; } }
答:用getimagesize來判斷上傳圖片的型別比$_FILES函數的type更可靠
同一個檔案,使用不同的瀏覽器php返回的type型別是不一樣的,由瀏覽器提供type型別的話,
就有可能被駭客利用向伺服器提交一個偽裝撐圖片字尾的可執行檔案。
可以通過getimagesize()函數來判斷上傳的檔案型別,如果是頭像檔案 會返回這樣的一個陣列
Array ( [0] => 331 [1] => 234 [2] => 3 [3] => width="331" height="234" [bits] => 8 [mime] => image/png );
答:基本原則:不對外界展示伺服器或程式設計細節(遮蔽錯誤),不相信任何使用者提交的資料(過濾使用者提交)
1)遮蔽錯誤,將display_errors 設定為off
2)過濾使用者提交引數,這裡需要注意的是不能僅僅通過瀏覽器端的驗證,還需要經過伺服器端的過濾
這裡是需要注意最多的地方,因為所有使用者提交的資料入口都在這裡,這是過濾資料的第一步。 1 考慮是否過濾select,insert,update,delete,drop,create等直接運算元據的命令語句 2 使用addslashes 將所有特殊字元過濾 3 開啟magic_quotes_gpc,開啟該引數數後自動將sql語句轉換,將 ' 轉換成 \'
3)可以考慮設定統一入口,只允許使用者通過指定的入口存取,不能存取未經許可的檔案等內容
4)可以考慮對安全性要求高的檔案進行來源驗證,比如要想執行b.php必須先執行a.php,可以在b.php中判斷來自a.php的referer,避免使用者直接執行b.php
答:由於 –enable-cli 和 –enable-cgi 同時預設有效,因此,不必再設定行中加上 –enable-cli 來使得 CLI 在 make install 過程中被拷貝到 {PREFIX}/bin/php
php -f 「index.php」 php -r 「print_r(get_defined_constants());」
說明:
1)如果,你熟悉PHP原始碼,那麼請從原始碼入手,回答些問題,會獲得額外加分
2)如果,你不熟悉PHP原始碼,那麼盡你所能,多寫點東西,包括利用自己的程式設計直覺得到的資訊,都可以。
3)對,則有分,錯誤不扣,不寫無分。
答:PHP可以自動進行記憶體管理,清除不再需要的物件。PHP使用了參照計數(referencecounting)這種單純的垃圾回收(garbagecollection)機制。每個物件都內含一個參照計數器,每個reference連線到物件,計數器加1。當reference離開生存空間或被設為NULL,計數器減1。當某個物件的參照計數器為零時,PHP知道你將不再需要使用這個物件,釋放其所佔的記憶體空間。
1. get是從伺服器上獲取資料,post是向伺服器傳送資料。 2. get是把引數資料佇列加到提交表單的ACTION屬性所指的URL中,值和表單內各個欄位一一對應,在URL中可以看到。post是通過HTTP post機制,將表單內各個欄位與其內容放置在HTML HEADER內一起傳送到ACTION屬性所指的URL地址。使用者看不到這個過程。 3. get傳送的資料量較小,不能大於2KB。post傳送的資料量較大,一般被預設為不受限制。 4. get安全性非常低,post安全性較高。但是執行效率卻比Post方法好。
一:在php.ini中設定session.gc_maxlifetime = 1440 //預設時間 二:程式碼實現 $ lifeTime = 24 * 3600; //儲存一天 session_set_cookie_params($ lifeTime); 在session_start();
他問的是已經支付成功後,但是回撥失敗了。
自己可以建立定時任務在每天的凌晨執行,去微信那邊對賬,然後更新資料庫訂單狀態。
來自PHP技術交流群 群友分享
看看你的服務的存取紀錄檔,在防火牆中加過濾,或者在web伺服器中加過濾吧。方法有以下幾種。
是消耗伺服器資源為主還是純流量攻擊?消耗資源的可以通過設定防火牆過濾規則防禦中小規模的攻擊。如果是純流量攻擊,考慮你用的是linode真心無解。即便你封了IP封了埠也沒用,人家不管你接不接受他的請求,他都會塞滿你的頻寬。linode必然認為你是被流量攻擊或者消耗過多資源然後給你掛起。
Groupadd mysql 新增一個使用者組mysql Useradd -g mysql mysql 新增一個mysql使用者指定分組為mysql Cd /lamp/mysql 進入mysql目錄 ./configure –prefix=/usr/local/mysql/ –with-extra-charsets=all Make Make all
優化程式,優化資料庫,如果程式和資料庫已經最佳化,使用以下解決方法:
1)索引的目的是什麼?
2) 索引對資料庫系統的負面影響是什麼?
負面影響:建立索引和維護索引需要耗費時間,這個時間隨著資料量的增加而增加;索引需要佔用物理空間,不光是表需要佔用資料空間,每個索引也需要佔用物理空間;當對錶進行增、刪、改的時候索引也要動態維護,這樣就降低了資料的維護速度。
3) 為資料表建立索引的原則有哪些?
4) 什麼情況下不宜建立索引?
單引號不能解釋變數,而雙引號可以解釋變數。
單引號不能跳脫字元,在雙引號中可以跳脫字元。
方法一: <?php class Dtime{ function get_days($date1, $date2){ $time1 = strtotime($date1); $time2 = strtotime($date2); return ($time2-$time1)/86400; } } $Dtime = new Dtime; echo $Dtime->get_days(’2021-2-5′, ’2021-3-6′); ?> 方法二: <?php $temp = explode(‘-’, ’2021-2-5′); $time1 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]); $temp = explode(‘-’, ’2021-3-6′); $time2 = mktime(0, 0, 0, $temp[1], $temp[2], $temp[0]); echo ($time2-$time1)/86400; 方法三:echo abs(strtotime(「2021-2-5″)-strtotime(「2021-3-1″))/60/60/24 計算時間差
<?php function BubbleSort(&$arr){ $cnt=count($arr); $flag=1; for($i=0;$i<$cnt;$i++){ if($flag==0){ return; } $flag=0; for($j=0;$j<$cnt-$i-1;$j++){ if($arr[$j]>$arr[$j+1]){ $tmp=$arr[$j]; $arr[$j]=$arr[$j+1]; $arr[$j+1]=$tmp; $flag=1; } } } } $test=array(1,3,6,8,2,7); BubbleSort($test); var_dump($test);
推薦學習:《》
以上就是歸納整理39道PHP面試題(總結分享)的詳細內容,更多請關注TW511.COM其它相關文章!