1. 程式人生 > >PHP各種各樣的面試題目整理

PHP各種各樣的面試題目整理

伺服器方面 

1、nginx平滑重啟

    nginx 執行新的工作程序並從容關閉舊的工作程序,通知工作程序關閉監聽套接字,但是繼續為當前連線的客戶提供服務。所有的客戶端的服務完成後,舊的工作程序被 關閉。如果新的配置檔案應用失敗,nginx 將繼續使用舊的配置檔案進行工作。     說簡單點就是 nginx會繼續處理之前的請求,並且啟動一個新的程序來處理新的請求,舊的程序處理完成之後會被kill。

2、獲取檔案後10行。     tail -10 a.log

3、檢視佔用系統資源比較多的程序       top         ps:輸完top命令之後,按1可以看記憶體以及cpu使用情況

3、檢視關鍵字出現函式     grep -n ‘我是要查詢的關鍵字’ a.txt | cut  -d “:” - f1           統計檔案中關鍵字分別出現的哪一行:         grep -n "關鍵字"    “檔案路徑” | cut -d ":"  -f1 統計檔案中關鍵字出現的最後一行行號:         grep -n "關鍵字"    “檔案路徑” | tail -n 1 | cut -d ":"  -f1

4、在/root/目錄下搜尋帶有關鍵字“www”的檔案,在終端下執行命令: find /root/ –type f | xargs grep “www

5、統計檔案 行數  wc -l  a.txt 

    統計demo目錄下,js檔案數量:         find demo/ -name "*.js" |wc -l     統計demo目錄下所有js檔案程式碼行數:         find demo/ -name "*.js" |xargs cat|wc -l           wc -l `find ./ -name "*.js"`|tail -n1     統計demo目錄下所有js檔案程式碼行數,過濾了空行:         find /demo -name "*.js" |xargs cat|grep -v ^$|wc -l

6、實時監控一個檔案     tail -f a.log

7、nginx日誌中訪問最多的100個ip及訪問次數 nginx日誌中訪問最多的100個ip及訪問次數  awk '{print $1}' /opt/software/nginx/logs/access.log| sort | uniq -c | sort -n -k 1 -r | head -n 100

8、在編譯完成的php,新增新的擴充套件 ----------------------------------------- 原始碼安裝     1、找到php的原始碼目錄     2、跳轉到EXT目錄下邊     3、執行phpize生成configure檔案     4、 ./configure --with-php-config=/usr/local/php/bin/php-config     5、編譯 make     6、編譯安裝 make install         7、修改php.ini extension=/usr/local/***.so     8、重啟php-fpm

YUM安裝:

    1、去PHP的官網下載原始碼 (htpp://pecl.php.net)     2、解壓檔案     3、執行phpize生成configure檔案     4、 ./configure --with-php-config=/usr/local/php/bin/php-config     5、編譯 make     6、編譯安裝 make install     7、修改php.ini extension=/usr/local/***.so     8、重啟php-fpm -----------------------------------------

php優化 nginx優化 mysql優化

php優化: 1、將類的方法定義為static。 2、儘量使用單引號。 3、修改php-fpm程序數。 4、修改單個指令碼最大可使用記憶體。 5、大的陣列使用完之後要及時釋放。 6、迴圈的時候,制定最大迴圈次數  7、不使用@遮蔽錯誤 8、儘量採用大量的 PHP 內建函式 9、使用require代替require_once

nginx優化: 1、修改nginx的子程序數。 [ 最多65535 ] 2、開啟靜態快取 3、修改主程序數。建議按照cpu 數目來指定,一般為它的倍數 (如,2個四核的cpu計為8) 4、開啟gzip輸出   [ 開啟gzip,ob函式就不能用了 ] 5、keepalive_timeout 設定連線超時時間

mysql優化: 1、避免子查詢 2、有順序的讀取 3、避免重複的讀寫 4、設定自增id 5、避免使用select *  6、合理設定欄位型別 7、讀寫分離 8、分割槽、分表 9、建立合適的索引 10、避免使用耗費資源的操作 null 11、不要使用rand() 12、儘量不要使用 or  查詢 13、查詢一條資料的時候加上LIMIT 1  14、開啟查詢快取 15、前期對資料進行合理的評估,進行分割槽、分表 16、避免使用 %字首的模糊查詢  17、避免使用mysql自帶函式 18、使用多從解決查詢慢的問題

秒殺如何實現?

我們做的秒殺併發量就是十幾萬、下邊的版本是十幾萬的:

1、專門對秒殺伺服器  [ps:量大的話這麼說,如果小的話就不用了 ] 2、生成靜態頁面。 [ ps:如果還很大的可以把這個檔案放在 cdn上 ] 3、倒計時以及庫存從服務端獲取 [ 一段時間內只獲取一次,倒計時結束之後會請求下服務端,是否已經開始 ] 4、把要秒殺的資料庫存放到redis中   [ key value ] stock=10 5、設定一個redis佇列   [ 使用list做佇列 ] lpop rpush 6、使用者在請求的時候,判斷使用者是否參與過秒殺,沒有參加過把使用者資料寫入佇列中,同時庫存減1 ,參加過就提示已經參加過      ps:這塊用到了redid的原子性操作、以及事務 multi 和 watch     redis樂觀鎖  cas  ====  就是設定之前判斷下這個值有沒有改變  7、庫存減0就不能進行秒殺 8、非同步指令碼處理佇列資料 [ crontab + php檔案 ]

如果你說是1-3萬的話,就不用單獨去租伺服器了

如果問到業務相關的問題的話,就隨機應變吧!!!!

比如說: 10 個使用者買了都不支付怎麼辦?     第一種說法 :          就說當時的產品需求是不支付也沒有問題,其它使用者也不可以買了,當時在做的和產品討論了,產品說正常的話使用者都會支付,因為比較便宜     第二種說法:         會開啟下一輪的秒殺。  比如說小米的  2小時之後還可以繼續買!!     第三站說法:         會。。。。

怎麼保證不超買 ?     減庫存的時候是原子性操作,使用cas樂觀鎖。測試的時候沒有出現過超買的情況      還有就是秒殺的時候就不用購物車了,點選的時候就排隊了

Q1:防刷是怎麼做的?一般搶購都有很大優惠。如果有人惡意刷,那正常的使用者就失去了購買的機會。比如,搶購的商品數為1000,有人惡意刷了900,那只有 100 被正常使用者搶到。 等惡意搶到的 900 經過後面的支付環節驗證後,可能已經過了搶購時間了。就算惡意搶到的 900 都支付成功,那對正常使用者也是不公平的。     在這個業務場景中,我們做的是商品展示、商品的購買權的發放,真正產生消費是在第三方。那麼,使用者刷的問題,需要我們和第三方支付頁面一起來控制。在使用者通過排 隊機制,獲得了購買名額後,跳轉去第三方時候,我們按照和第三方約定的加密方式傳遞加密資訊,第三方按照約定的解密方式解密成功後才允許使用者支付,加密解密的過程中可以 帶具有生命週期的內容。這樣,使用者在高頻請求支付頁面獲取商品時候,實際只有:1)加密對;2)第一次,才可能獲得。不過,第三方都是為了銷售出商品,所以這類合作的成功 機率不大。惡意刷,的確會在我們的業務層面展示商品沒量了。導致想買的使用者沒了機會,但可以保證第三方不受損。這種刷的情況,若想在我們業務層規避,我想這就是一個通用 的防SPAM的問題了。這塊自己真懂得不多。

Q2:要想準確的放刷,判斷的維度就多,邏輯就複雜;與之矛盾的,搶購要求的是響應迅速。     對的,搶購業務因為請求壓力大、熱門商品搶購併發高,切忌增加過多邏輯,切忌過多後端依賴,越簡單效果越好。我們在設計系統時候,很多事不是咱們一個系統能cover 的,多少需要一些前置模組、能力的構建ready後,我們的系統才能run的不錯。建議構建帳號體系、使用者消費記錄這兩部分。 Q3:對賬只是和第三方去對比商品的庫存量嗎,金額是否去對比? 對賬,其實是對比的消費資料。避免出現我們統計今日產生了X件商品共價值Y的消費,第三方給出的是消費了N件共M價值的消費。避免金額不一致,造成結算、分成等問題的出現。 我想你問題中的庫存量的diff問題,還得靠第三方定期的通過我們資料層的介面來update他們提供的商品。其實在我們的商品庫中,商品不一定只允許第三方提供,也可以允許第三 方通過介面減少商品嘛,比如和一個賣水果的第三方合作,第三方上週釋出說有100件,但這周線下熱銷,只剩20件了,我們也應該允許第三方來update到一個低值。但這樣,我們 的系統中就會複雜挺多。

Q4:防刷,避免第三方的推廣效果達不到問題。     對的,使用者ID維度、IP維度,都是有效辦法。看具體場景。有帳號體系的業務,用使用者ID維度效果最好,藉助儲存記錄下每個使用者的購買記錄,來控制就好。市面上的電商 網站,基本是搶購業務都需要登入,並且限制每件商品單人購買數量,其實就是通過儲存記錄使用者的消費,並且再次產生消費前查詢並增加程式碼邏輯來控制。

Q5:每次搶購活動的時候用一套新的驗證碼?     驗證碼這個東東,屬於圖靈測試嘛,只要測試方法好,並且儘可能保證每次產生的驗證資訊從未出現過且無規律,就是好的驗證碼啦。

比較好的秒殺系統架構: http://www.csdn.net/article/2014-11-07/2822545 http://www.kuqin.com/shuoit/20141203/343669.html

演算法題:

http://blog.csdn.net/frimish/article/details/48666485 

怎麼在海量資料中找出重複次數最多的一個

網站日誌中記錄了使用者的IP,找出訪問次數最多的IP

假設有1kw個身份證號,以及他們對應的資料。身份證號可能重複,要求找出出現次數最多的身份證號。   有一個1G大小的一個檔案,裡面每一行是一個詞,詞的大小不超過16位元組,記憶體限制大小是1M。返回頻數最高的100個詞。

有10個檔案,每個檔案1G,每個檔案的每一行存放的都是使用者的query,每個檔案的query都可能重複。要求你按照query的頻度排序。

常見的排序: http://www.php100.com/html/php/rumen/2013/1029/6333.html

氣泡排序:     原理:         把第一個數字和所有數字進行比較,然後遇到大的交換位置,這樣第一次就把最大的放在了最後邊,然後繼續在比較,第二次比較的時候最後一個數字就不 用比較了,因為已經確定它是最大的了,以此類推。

        1. 氣泡排序法   *     思路分析:法如其名,就是像冒泡一樣,每次從陣列當中 冒一個最大的數出來。   *     比如:2,4,1    // 第一次 冒出的泡是4   *                2,1,4   // 第二次 冒出的泡是 2   *                1,2,4   // 最後就變成這樣           時間複雜度:         氣泡排序是一種用時間換空間的排序方法,最壞情況是把順序的排列變成逆序,或者把逆序的數列變成順序。      $arr=array(1,43,54,62,21,66,32,78,36,76,39);   function getpao($arr) {     $len=count($arr);   //設定一個空陣列 用來接收冒出來的泡   //該層迴圈控制 需要冒泡的輪數   for($i=1;$i<$len;$i++)   { //該層迴圈用來控制每輪 冒出一個數 需要比較的次數     for($k=0;$k<$len-$i;$k++)     {        if($arr[$k]>$arr[$k+1])         {             $tmp=$arr[$k+1];             $arr[$k+1]=$arr[$k];             $arr[$k]=$tmp;         }     }   }   return $arr; }    

2、選擇排序: http://jingyan.baidu.com/article/f3ad7d0f07516d09c3345b19.html http://mmm2010.blog.163.com/blog/static/174230348201292273310140/

function select_sort($arr) { //實現思路 雙重迴圈完成,外層控制輪數,當前的最小值。內層 控制的比較次數     //$i 當前最小值的位置, 需要參與比較的元素     for($i=0, $len=count($arr); $i<$len-1; $i++) {         //先假設最小的值的位置         $p = $i;         //$j 當前都需要和哪些元素比較,$i 後邊的。         for($j=$i+1; $j<$len; $j++) {             //$arr[$p] 是 當前已知的最小值             if($arr[$p] > $arr[$j]) {      //比較,發現更小的,記錄下最小值的位置;並且在下次比較時,  // 應該採用已知的最小值進行比較。                 $p = $j;             }         }         //已經確定了當前的最小值的位置,儲存到$p中。  //如果發現 最小值的位置與當前假設的位置$i不同,則位置互換即可         if($p != $i) {             $tmp = $arr[$p];             $arr[$p] = $arr[$i];             $arr[$i] = $tmp;         }     }     //返回最終結果     return $arr; }

3.快速排序法  

function quick_sort($arr) {     //先判斷是否需要繼續進行     $length = count($arr);     if($length <= 1) {         return $arr;     }     //如果沒有返回,說明陣列內的元素個數 多餘1個,需要排序     //選擇一個標尺     //選擇第一個元素     $base_num = $arr[0];     //遍歷 除了標尺外的所有元素,按照大小關係放入兩個陣列內     //初始化兩個陣列     $left_array = array();//小於標尺的     $right_array = array();//大於標尺的     for($i=1; $i<$length; $i++) {         if($base_num > $arr[$i]) {             //放入左邊陣列             $left_array[] = $arr[$i];         } else {             //放入右邊             $right_array[] = $arr[$i];         }     }     //再分別對 左邊 和 右邊的陣列進行相同的排序處理方式     //遞迴呼叫這個函式,並記錄結果     $left_array = quick_sort($left_array);     $right_array = quick_sort($right_array);     //合併左邊 標尺 右邊     return array_merge($left_array, array($base_num), $right_array); }

4、插入排序法  http://blog.csdn.net/hijiankang/article/details/9207735

情景描述:   緊接氣泡排序,每次同學們都屢試不爽,但是學生越來越多了,老師發現每次排完隊,就耽擱了大半節課時了,說道:“咱不用冒泡了,有點OUT了,今天來插入排序”。 這時體育老師擔任起了數學老師的職責,又給同學們講了種排隊方式--插入排序。 1. 開始以第一位同學為基準,由第二個同學開始向前和第一位同學比較,個頭高了不動,低了換位 2. 第三個同學要先和自己前面的第二位同學比較,如果低了,和第二換位,然後再向前和第一比較,低了再換,否則阻斷,不再比較 3. 從前往後依次執行步驟2,依次出來一位同學,每次和自己前面的同學進行比較,找到一個合適位置插入,其餘學生後移 合適位置:前一位同學等於或低於自己身高,並且後一位同學高於自己身高   按照這個方式,同學們一個個依次找準位置,再也不用每次相鄰的都比較,而且找到位置後就不必再往前面比較了......

插入排序法思路:將要排序的元素插入到已經 假定排序號的陣列的指定位置。 function insert_sort($arr) {     //區分 哪部分是已經排序好的     //哪部分是沒有排序的     //找到其中一個需要排序的元素     //這個元素 就是從第二個元素開始,到最後一個元素都是這個需要排序的元素     //利用迴圈就可以標誌出來     //i迴圈控制 每次需要插入的元素,一旦需要插入的元素控制好了,     //間接已經將陣列分成了2部分,下標小於當前的(左邊的),是排序好的序列     for($i=1, $len=count($arr); $i<$len; $i++) {         //獲得當前需要比較的元素值。         $tmp = $arr[$i];         //內層迴圈控制 比較 並 插入         for($j=$i-1;$j>=0;$j--) {    //$arr[$i];//需要插入的元素; $arr[$j];//需要比較的元素             if($tmp < $arr[$j]) {                 //發現插入的元素要小,交換位置                 //將後邊的元素與前面的元素互換                 $arr[$j+1] = $arr[$j];                 //將前面的數設定為 當前需要交換的數                 $arr[$j] = $tmp;             } else {                 //如果碰到不需要移動的元素            //由於是已經排序好是陣列,則前面的就不需要再次比較了。                 break;             }         }     }     //將這個元素 插入到已經排序好的序列內。     //返回     return $arr; }

/**      * 插入排序,預設第一位已經排好序,從第二位開始依次向前比較,確定自己的位置後插入,即前一位小余或等於當前,且後一位大於當前。      * 插入後,自己新位置後面的元素依次向後移位, 完成一輪插入排序      * @param arr      * @return      */     public static int[] insertSort(int[] arr) {         int len = arr.length;         for (int i = 1; i < len; i++) {             if (arr[i - 1] > arr[i]) {                 int k = arr[i];                 int j = i;                 while (j > 0 && arr[j - 1] > k) {                     arr[j] = arr[j - 1];                     j--;                 }                 arr[j] = k;             }         }         return arr;     }

二分查詢:

http://www.tuicool.com/articles/2MbAR3q http://blog.csdn.net/xzjxylophone/article/details/4714326 1,2,3,4,5,6,7 我現在要查詢7 我先取出中間數 4 判斷下是不是要找的數字,發現小了 就去右邊查詢 然後取出右邊的所有的數 取出她們幾個的中間數 6  發現還小了 繼續找右邊的陣列 找到7了 ok了!!!

最差的一種情況就是這個數字不存在 ====

 1 <?php  2     #二分查詢  3     function binarySearch(Array $arr, $target) {  4         $low = 0;  5         $high = count($arr) - 1;  6           7         while($low <= $high) {  8             $mid = floor(($low + $high) / 2);  9             #找到元素 10             if($arr[$mid] == $target) return $mid; 11             #中元素比目標大,查詢左部 12             if($arr[$mid] > $target) $high = $mid - 1; 13             #重元素比目標小,查詢右部 14             if($arr[$mid] < $target) $low = $mid + 1; 15         } 16          17         #查詢失敗 18         return false; 19     } 20      21     $arr = array(1, 3, 5, 7, 9, 11); 22     $inx = binarySearch($arr, 1); 23     var_dump($inx); 24 ?>

安全方面: xss :跨站指令碼攻擊 csrf :  跨站請求偽造 Ddos:用很多機器對網址進行請求,把伺服器某方面搞掛。 sql注入: 通過關鍵字或者非法字元的注入,實現一些對資料庫一些非正常的操作

        最簡單的demo :         在使用者登陸的時候,使用者名稱和密碼的判斷,密碼後加上 or 1=1

如何防止sql注入:     關鍵字的過濾     pdo預處理     php 配置檔案 php.ini 中的 magic_quotes_gpc選項沒有開啟,被置為 off     addslashes stripslashes     mysql_real_escape_string     對一些資料型別做強制的校驗      如何防止xss攻擊?     xss攻擊最簡單的方式就是通過位址列輸入<script></script>,最簡單的列子我們在php在使用一個get的a引數的時候,如何客戶端傳過來是<script>alert(1)</script>, 這樣的話就會在我們的瀏覽器彈出來1,如果是頁面的跳轉,或者是一些其它指令碼、病毒的話,可能對我們網站的安全造成很大的隱患。

最簡單的解決辦法     不要相信客戶端的任何輸入,在程式做嚴格的判斷以及處理     htmlspecialchars進行過濾

csrf :     這個我們在學curl的時候做的模擬登陸就是跨站請求偽造!!!!     最簡單的大白話就是:         a網站往b網站請求資料。     加個token防止下就行了,簡單,粗暴,有效

Dos和Ddos防止:     阿里雲 高防ip     idc機房      放棄一部分請求不處理。

正則方面的問題:

貪婪模式和非貪婪模式的區別:     貪婪模式匹配到內容之後會繼續向後匹配     非貪婪模式則不回繼續匹配

匹配中文字元的正則表示式: [\u4e00-\u9fa5]  評註:匹配中文還真是個頭疼的事,有了這個表示式就好辦了  匹配雙位元組字元(包括漢字在內):[^\x00-\xff]  評註:可以用來計算字串的長度(一個雙位元組字元長度計2,ASCII字元計1)  匹配空白行的正則表示式:\n\s*\r  評註:可以用來刪除空白行  匹配HTML標記的正則表示式:<(\S*?)[^>]*>.*?</\1>|<.*? />  評註:網上流傳的版本太糟糕,上面這個也僅僅能匹配部分,對於複雜的巢狀標記依舊無能為力  匹配首尾空白字元的正則表示式:^\s*|\s*$  評註:可以用來刪除行首行尾的空白字元(包括空格、製表符、換頁符等等),非常有用的表示式  匹配Email地址的正則表示式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*  評註:表單驗證時很實用  匹配網址URL的正則表示式:[a-zA-z]+://[^\s]*  評註:網上流傳的版本功能很有限,上面這個基本可以滿足需求  匹配帳號是否合法(字母開頭,允許5-16位元組,允許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$  評註:表單驗證時很實用  匹配國內電話號碼:\d{3}-\d{8}|\d{4}-\d{7}  評註:匹配形式如 0511-4405222 或 021-87888822  匹配騰訊QQ號:[1-9][0-9]{4,}  評註:騰訊QQ號從10000開始  匹配中國郵政編碼:[1-9]\d{5}(?!\d)  評註:中國郵政編碼為6位數字  匹配身份證:\d{15}|\d{18}  評註:中國的身份證為15位或18位  匹配ip地址:\d+\.\d+\.\d+\.\d+  評註:提取ip地址時有用  匹配特定數字:  ^[1-9]\d*$    //匹配正整數  ^-[1-9]\d*$   //匹配負整數  ^-?[1-9]\d*$   //匹配整數  ^[1-9]\d*|0$  //匹配非負整數(正整數 + 0)  ^-[1-9]\d*|0$   //匹配非正整數(負整數 + 0)  ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮點數  ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配負浮點數  ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮點數  ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非負浮點數(正浮點數 + 0)  ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮點數(負浮點數 + 0)  評註:處理大量資料時有用,具體應用時注意修正  匹配特定字串:  ^[A-Za-z]+$  //匹配由26個英文字母組成的字串  ^[A-Z]+$  //匹配由26個英文字母的大寫組成的字串  ^[a-z]+$  //匹配由26個英文字母的小寫組成的字串  ^[A-Za-z0-9]+$  //匹配由數字和26個英文字母組成的字串  ^\w+$  //匹配由數字、26個英文字母或者下劃線組成的字串 

下面是一些特殊字元:  正則表示式中的特殊字元: (學習參考書-<<精通正則表示式>>)  字元  意義:對於字元,通常表示按字面意義,指出接著的字元為特殊字元,不作解釋。  例如:/b/匹配字元'b',通過在b 前面加一個反斜槓,也就是/b/,則該字元變成特殊字元,表示  匹配一個單詞的分界線。  或者:  對於幾個字元,通常說明是特殊的,指出緊接著的字元不是特殊的,而應該按字面解釋。  例如:*是一個特殊字元,匹配任意個字元(包括0個字元);例如:/a*/意味匹配0個或多個a。  為了匹配字面上的*,在a前面加一個反斜槓;例如:/a*/匹配'a*'。 

字元^  意義:表示匹配的字元必須在最前邊。  例如:/^A/不匹配"an A,"中的'A',但匹配"An A."中最前面的'A'。 

字元$  意義:與^類似,匹配最末的字元。  例如:/t$/不匹配"eater"中的't',但匹配"eat"中的't'。 

字元*  意義:匹配*前面的字元0次或n次。  例如:/bo*/匹配"A ghost booooed"中的'boooo'或"A bird warbled"中的'b',但不匹配"A goat g  runted"中的任何字元。 

字元+  意義:匹配+號前面的字元1次或n次。等價於{1,}。  例如:/a+/匹配"candy"中的'a'和"caaaaaaandy."中的所有'a'。 

字元?  意義:匹配?前面的字元0次或1次。  例如:/e?le?/匹配"angel"中的'el'和"angle."中的'le'。 

字元.  意義:(小數點)匹配除換行符外的所有單個的字元。  例如:/.n/匹配"nay, an apple is on the tree"中的'an'和'on',但不匹配'nay'。 

字元(x)  意義:匹配'x'並記錄匹配的值。  例如:/(foo)/匹配和記錄"foo bar."中的'foo'。匹配子串能被結果陣列中的素[1], ..., [n] 返  回,或被RegExp物件的屬性$1, ..., $9返回。 

字元x|y  意義:匹配'x'或者'y'。  例如:/green|red/匹配"green apple"中的'green'和"red apple."中的'red'。 

字元{n}  意義:這裡的n是一個正整數。匹配前面的n個字元。  例如:/a{2}/不匹配"candy,"中的'a',但匹配"caandy," 中的所有'a'和"caaandy."中前面的兩個  'a'。 

字元{n,}  意義:這裡的n是一個正整數。匹配至少n個前面的字元。  例如:/a{2,}不匹配"candy"中的'a',但匹配"caandy"中的所有'a'和"caaaaaaandy."中的所有'a' 

字元{n,m}  意義:這裡的n和m都是正整數。匹配至少n個最多m個前面的字元。  例如:/a{1,3}/不匹配"cndy"中的任何字元,但匹配 "candy,"中的'a',"caandy," 中的前面兩個  'a'和"caaaaaaandy"中前面的三個'a',注意:即使"caaaaaaandy" 中有很多個'a',但只匹配前面的三  個'a'即"aaa"。 

字元[xyz]  意義:一字元列表,匹配列出中的任一字元。你可以通過連字元-指出一個字元範圍。  例如:[abcd]跟[a-c]一樣。它們匹配"brisket"中的'b'和"ache"中的'c'。 

字元[^xyz]  意義:一字元補集,也就是說,它匹配除了列出的字元外的所有東西。 你可以使用連字元-指出一  字元範圍。  例如:[^abc]和[^a-c]等價,它們最早匹配"brisket"中的'r'和"chop."中的'h'。 

字元  意義:匹配一個空格(不要與b混淆) 

字元b  意義:匹配一個單詞的分界線,比如一個空格(不要與混淆)  例如:/bnw/匹配"noonday"中的'no',/wyb/匹配"possibly yesterday."中的'ly'。 

字元B  意義:匹配一個單詞的非分界線  例如:/wBn/匹配"noonday"中的'on',/yBw/匹配"possibly yesterday."中的'ye'。 

字元cX  意義:這裡的X是一個控制字元。匹配一個字串的控制字元。  例如:/cM/匹配一個字串中的control-M。 

字元d  意義:匹配一個數字,等價於[0-9]。  例如:/d/或/[0-9]/匹配"B2 is the suite number."中的'2'。 

字元D  意義:匹配任何的非數字,等價於[^0-9]。  例如:/D/或/[^0-9]/匹配"B2 is the suite number."中的'B'。 

字元f  意義:匹配一個表單符 

字元n  意義:匹配一個換行符 

字元r  意義:匹配一個回車符 

字元s  意義:匹配一個單個white空格符,包括空格,tab,form feed,換行符,等價於[ fnrtv]。  例如:/sw*/匹配"foo bar."中的' bar'。 

字元S  意義:匹配除white空格符以外的一個單個的字元,等價於[^ fnrtv]。  例如:/S/w*匹配"foo bar."中的'foo'。 

字元t  意義:匹配一個製表符 

字元v  意義:匹配一個頂頭製表符 

字元w  意義:匹配所有的數字和字母以及下劃線,等價於[A-Za-z0-9_]。  例如:/w/匹配"apple,"中的'a',"$5.28,"中的'5'和"3D."中的'3'。 

字元W  意義:匹配除數字、字母外及下劃線外的其它字元,等價於[^A-Za-z0-9_]。  例如:/W/或者/[^$A-Za-z0-9_]/匹配"50%."中的'%'。 

字元n  意義:這裡的n是一個正整數。匹配一個正則表示式的最後一個子串的n的值(計數左圓括號)。 

php函式方面的問題:

1、陣列函式

 array_key_exists 判斷key是否存在  is_array 判斷是否是一個數組  in_array 判斷給定的值是否在資料出現  array_count_values 判斷值出現的次數  array_search 陣列查詢  array_merge 數組合並  array_map 對陣列每個元素使用使用者自定義的函式  array_change_case 改變陣列key的大小寫  sort陣列排序 array_push 在陣列尾部插入一個或者多個元素 array_pop  彈出陣列最後一個元素 array_unshift 陣列開頭插入多個元素 array_shift 彈出陣列第一個元素 implode 陣列轉字串 shuffle 打亂陣列的排序 array_rand 隨機從陣列去處多個單元 array_chunk 陣列分割位新的陣列 array_diff 差集 array_inestsert 交集 array_flip 交換鍵值 array_keys 返回陣列所有鍵 count 計算陣列長度

2、字串函式 addcslashes — 為字串裡面的部分字元新增反斜線轉義字元 addslashes — 用指定的方式對字串裡面的字元進行轉義 bin2hex — 將二進位制資料轉換成十六進位制表示 chop — rtrim() 的別名函式 chr — 返回一個字元的ASCII碼 chunk_split — 按一定的字元長度將字串分割成小塊 convert_cyr_string — 將斯拉夫語字元轉換為別的字元 convert_uudecode — 解密一個字串 convert_uuencode — 加密一個字串 count_chars — 返回一個字串裡面的字元使用資訊 crc32 — 計算一個字串的crc32多項式 crypt — 單向雜湊加密函式 echo — 用以顯示一些內容 explode — 將一個字串用分割符轉變為一陣列形式 fprintf — 按照要求對資料進行返回,並直接寫入文件流 get_html_translation_table — 返回可以轉換的HTML實體 hebrev — 將Hebrew編碼的字串轉換為可視的文字 hebrevc — 將Hebrew編碼的字串轉換為可視的文字 html_entity_decode — htmlentities ()函式的反函式,將HTML實體轉換為字元 htmlentities — 將字串中一些字元轉換為HTML實體 htmlspecialchars_decode —htmlspecialchars()函式的反函式,將HTML實體轉換為字元 htmlspecialchars — 將字串中一些字元轉換為HTML實體 implode — 將陣列用特定的分割符轉變為字串 join — 將陣列轉變為字串,implode()函式的別名 levenshtein — 計算兩個詞的差別大小 localeconv — 獲取數字相關的格式定義 ltrim — 去除字串左側的空白或者指定的字元 md5_file — 將一個檔案進行MD5演算法加密 md5 — 將一個字串進行MD5演算法加密 metaphone — 判斷一個字串的發音規則 money_format — 按照引數對數字進行格式化的輸出 nl_langinfo — 查詢語言和本地資訊 nl2br — 將字串中的換行符“\n”替換成“<br/>” number_format — 按照引數對數字進行格式化的輸出 ord — 將一個ASCII碼轉換為一個字元 parse_str — 把一定格式的字串轉變為變數和值 print — 用以輸出一個單獨的值 printf — 按照要求對資料進行顯示 quoted_printable_decode — 將一個字串加密為一個8位的二進位制字串 quotemeta — 對若干個特定字元進行轉義 rtrim — 去除字串右側的空白或者指定的字元 setlocale — 設定關於數字,日期等等的本地格式 sha1_file — 將一個檔案進行SHA1演算法加密 sha1 — 將一個字串進行SHA1演算法加密 similar_text — 比較兩個字串,返回系統認為的相似字元個數 soundex — 判斷一個字串的發音規則 sprintf — 按照要求對資料進行返回,但是不輸出 sscanf — 可以對字串進行格式化 str_ireplace — 像str_replace()函式一樣匹配和替換字串,但是不區分大小寫 str_pad — 對字串進行兩側的補白 str_repeat — 對字串進行重複組合 str_replace — 匹配和替換字串 str_rot13 — 將字串進行ROT13加密處理 str_shuffle — 對一個字串裡面的字元進行隨機排序 str_split — 將一個字串按照字元間距分割為一個數組 str_word_count — 獲取字串裡面的英文單詞資訊 strcasecmp — 對字串進行大小比較,不區分大小寫 strchr — 通過比較返回一個字串的部分strstr()函式的別名 strcmp — 對字串進行大小比較 strcoll – 根據本地設定對字串進行大小比較 strcspn — 返回字元連續非匹配長度的值 strip_tags — 去除一個字串裡面的HTML和PHP程式碼 stripcslashes — 反轉義addcslashes()函式轉義處理過的字串 stripos — 查詢並返回首個匹配項的位置,匹配不區分大小寫 stripslashes — 反轉義addslashes()函式轉義處理過的字串 stristr — 通過比較返回一個字串的部分,比較時不區分大小寫 strlen — 獲取一個字串的編碼長度 strnatcasecmp — 使用自然排序法對字串進行大小比較,不區分大小寫 strnatcmp — 使用自然排序法對字串進行大小比較 strncasecmp — 對字串的前N個字元進行大小比較,不區分大小寫 strncmp — 對字串的前N個字元進行大小比較 strpbrk — 通過比較返回一個字串的部分 strpos — 查詢並返回首個匹配項的位置 strrchr — 通過從後往前比較返回一個字串的部分 strrev — 將字串裡面的所有字母反向排列 strripos — 從後往前查詢並返回首個匹配項的位置,匹配不區分大小寫 strrpos – 從後往前查詢並返回首個匹配項的位置 strspn — 匹配並返回字元連續出現長度的值 strstr — 通過比較返回一個字串的部分 strtok — 用指定的若干個字元來分割字串 strtolower — 將字串轉變為小寫 strtoupper –將字串轉變為大寫 strtr — 對字串比較替換 substr_compare — 對字串進行擷取後的比較 substr_count — 計算字串中某字元段的出現次數 substr_replace — 對字串中的部分字元進行替換 substr — 對字串進行擷取 trim — 去除字串兩邊的空白或者指定的字元 ucfirst — 將所給字串的第一個字母轉換為大寫 ucwords — 將所給字串的每一個英文單詞的第一個字母變成大寫 vfprintf — 按照要求對資料進行返回,並直接寫入文件流 vprintf — 按照要求對資料進行顯示 vsprintf — 按照要求對資料進行返回,但是不輸出 wordwrap — 按照一定的字元長度分割字串

關於程式碼規範如何說?

我們在寫介面的時候寫了一個統一的驗證和返回

要求每個檔案必須有自己的註釋、每個類都有自己的註釋、每個方法都必須有註釋 、對於不確定的需求或者後期可能遇到的問題  必須加上  todo

關鍵邏輯必須寫上註釋

在呼叫外部介面不能在程式寫死,必須單獨自己建議一個配置檔案,方便後期修改

資料庫操作必須寫在model裡邊,不允許在C層寫資料庫操作。

變數名必須能報清楚的表達自己的意思。

寫介面之前必須搞定介面文件。

私有的方法必須加上 _  [ 重要 ,顯得自己也是老司機]

類檔案都是以.class.php為字尾(這裡是指的ThinkPHP內部使用的類庫檔案,不代表外部載入的類庫檔案),使用駝峰法命名,並且首字母大寫,例如 DbMysql.class.php;

類的名稱空間地址和所在的路徑地址一致,例如 Home\Controller\UserController類所在的路徑應該是 Application/Home/Controller/UserController.class.php; 確保檔案的命名和呼叫大小寫一致,是由於在類Unix系統上面,對大小寫是敏感的(而ThinkPHP在除錯模式下面,即使在Windows平臺也會嚴格檢查大小寫); 類名和檔名一致(包括上面說的大小寫一致),例如 UserController類的檔案命名是UserController.class.php, InfoModel類的檔名是InfoModel.class.php,  並且不同的類庫的類命名有一定的規範;

函式、配置檔案等其他類庫檔案之外的一般是以.php為字尾(第三方引入的不做要求);

函式的命名使用小寫字母和下劃線的方式,例如 get_client_ip;

方法的命名使用駝峰法,並且首字母小寫或者使用下劃線“_”,例如 getUserName,_parseType,通常下劃線開頭的方法屬於私有方法; 屬性的命名使用駝峰法,並且首字母小寫或者使用下劃線“_”,例如 tableName、_instance,通常下劃線開頭的屬性屬於私有屬性; 以雙下劃線“__”打頭的函式或方法作為魔法方法,例如 __call 和 __autoload;

常量以大寫字母和下劃線命名,例如 HAS_ONE和 MANY_TO_MANY;

配置引數以大寫字母和下劃線命名,例如HTML_CACHE_ON;

語言變數以大寫字母和下劃線命名,例如MY_LANG,以下劃線打頭的語言變數 通常用於系統語言變數,例如 _CLASS_NOT_EXIST_;

對變數的命名沒有強制的規範,可以根據團隊規範來進行;

ThinkPHP的模板檔案預設是以.html 為字尾(可以通過配置修改);

資料表和欄位採用小寫加下劃線方式命名,並注意欄位名不要以下劃線開頭,例 如 think_user 表和 user_name欄位是正確寫法,類似 _username 這樣的資料表字段可能會被過濾。

tp底層看過沒有?

1、看過框架的底層沒有?      看過tp的資料庫驅動相關。 關於配置資料庫方面的,在配置檔案配置就直接可以使用各種資料庫型別,自己簡單看了下,主要就是通過一個driver(驅動類)來判斷當前連線類 型,然後呼叫對於的資料庫操作類。      ps:如果是要我們自己實現的話,可以藉助介面,每個資料庫的操作類都需要整合一個介面,然後根據具體的配置去呼叫每個操作類。 就算後期我修改了資料庫的型別,也不 會導致程式需要改動。

2、看過tp的cache類,和資料庫類似,修改過redis的cache類,因為tp的redis操作類不支援認證。    主要就是在redis操作類添加了個認證     $this->handler  = new \Redis;         $options['timeout'] === false ?             $this->handler->$func($options['host'], $options['port']) :             $this->handler->$func($options['host'], $options['port'], $options['timeout']);             $this -> handler->auth( C(‘REDIS_AUTH_KEY’) );

3、看過tp的處理異常類 路徑  ThinkPHP/library/Think/Think.class.php

主要使用的是php自帶的錯誤處理相關函式

register_shutdown_function 定義PHP程式執行完成後執行的函式 set_error_handler    設定使用者自定義的錯誤處理程式 set_exception_handler 設定自己的異常處理機制

藉助 get_last_error獲取最後一次報錯的資訊 根據報錯級別可以自定義寫日誌 這個地方我們在做介面的時候紀錄了一些錯誤日誌,幫助我們排查一些問題。 如果要看檔案載入以及呼叫關係可以藉助 print_debug_backtrace獲取檔案載入的順序

     // 註冊AUTOLOAD方法       spl_autoload_register('Think\Think::autoload');             // 設定錯誤和異常處理       register_shutdown_function('Think\Think::fatalError');       set_error_handler('Think\Think::appError');       set_exception_handler('Think\Think::appException');

4、簡單看了下tp的名稱空間自動記載     框架下的核心類都包含進來了,其他的事藉助 spl_register_autoload實現 ---------------------  作者:luyaran  來源:CSDN  原文:https://blog.csdn.net/luyaran/article/details/54097000?utm_source=copy  版權宣告:本文為博主原創文章,轉載請附上博文連結!