這篇文章為大家帶來了關於PHP的相關知識,其中主要介紹了PHP面試題,總結了三十九個常見的面試題,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:
.com: 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 (`欄位名稱`)
8. isset() 和empty( ) 區別
9.持久化redis有幾種方式?
答案:主要有兩種方式:1) 快照持久化在redis設定檔中已經自動開啟了,格式為:save N M表示在N秒之內,redis至少發生M次修改則redis抓快照到磁碟。 當然我們也可以手動執行save或bgsave(非同步)指令來做快照2)append only file AOF持久化 總共有三種模式,例如appendfsync everysec預設的是每秒強制寫入磁碟一次appendfsync always 每次執行寫入作業的時候就強制寫入磁碟appendfsync no 完全取決於os,效能最好但是持久化沒辦法保證10.mysql儲存引擎
答案:常用的主要分為兩種,一種是innodb,一種是myisam,兩者的主要差異是1)myisam不支援事務處理,而innoDB支援事務處理2)myisam 不支援外鍵,innoDB支援外鍵3)myisam支援全文檢索,而innoDB在MySQL5.6版本之後才支援全文檢索4)資料的儲存形式不一樣,mysiam表存放在三個文件:結構、索引、數據,innoDB儲存把結構儲存為一個文件,索引和資料儲存為一個檔案5)myisam在查詢和增加資料效能更優於innoDB,innoDB在批次刪除方面效能較高。#11.sql注入是什麼及如何預防sql注入?
答:SQL注入攻擊指的是使用者或駭客透過建構特殊的輸入作為參數傳入我們的Web應用程式端,而這些輸入大都是SQL語法裡的一些組合,透過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程式設計師沒有細緻地過濾使用者輸入的數據,致使非法資料侵入系統而造成的。因此我們在做開發過程中一定要預防sql注入,主要從兩方面著手:1)佔位符的方式,就是對sql語句進行預處理,然後執行sql語句12.有用過預處理麼?
13.用框架還用自己的處理嗎
#######答:一般成熟的開源框架中都考慮到了資料安全這方面的東西,但有時候我們可能會使用一些原生的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);
推荐学习:《PHP视频教程》
以上是歸納整理39道PHP面試題(總結分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!