騰訊面試題

PHP開發工程師筆試試卷

姓名:天才
一、PHP開發部分
1.合併兩個數組有幾種方式,試比較它們的異同

答:1、array_merge()
2、’+’
3、array_merge_recursive

array_merge 簡單的合併數組
array_merge_recursive 合併兩個數組,如果數組中有完全一樣的數據,將它們遞歸合併
array_combine 和 ‘+’ :合併兩個數組,前者的值作爲新數組的鍵
2.請寫一個函數來檢查用戶提交的數據是否爲整數(不區分數據類型,可以爲二進制、八進制、十進制、十六進制數字)

答:其實主要還是is_int和 floor 這個方法

if(!is_numeric($jp_total)||strpos($jp_total,".")!==false){  
    echo "不是整數";  
}else{  
    echo "是整數";  
}  

    1
    2
    3
    4
    5

3.PHP的strtolower()和strtoupper()函數在安裝非中文系統的服務器下可能會導致將漢字轉換爲亂碼,請寫兩個替代的函數實現兼容Unicode文字的字符串大小寫轉換

答:原因是:中文是由多字節組成的,而只有英文系統的單個英文字符只有一個字節,所以該系統把中文的每一個字節都做了strtolower()處理,改變後的中文字節拼接在一起就成了亂碼(新生成的編碼映射對應的字符可能就不是中文了)

手動解決:用str_split(string string,int

split_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);  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

4.PHP的is_writeable()函數存在Bug,無法準確判斷一個目錄/文件是否可寫,請寫一個函數來判斷目錄/文件是否絕對可寫

答:其中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;
    }
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43

5.PHP的chmod()函數存在Bug,無法保證設置成功,請寫一個函數在指定路徑下創建一個目錄/文件並確保可以正確設置權限掩碼

答:我也找不到答案
6.PHP處理上傳文件信息數組中的文件類型$_FILES[‘type’]由客戶端瀏覽器提供,有可能是黑客僞造的信息,請寫一個函數來確保用戶上傳的圖像文件類型真實可靠

答:用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
    2
    3
    4
    5
    6
    7
    8
    9

如果通過getimagesize()函數返回的是這樣的一個數組 說明上傳的是頭像文件。其中索引爲2的表示類型
1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte
order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 =
JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM,
你可以通過這個再去限制上傳的頭像類型

<?php
    $file=$_FILES['file'];
    if(!empty($file))
    {
        var_dump($file);
        var_dump(getimagesize($file["tmp_name"]));
    }   
?>

    1
    2
    3
    4
    5
    6
    7
    8

7.PHP通過對數據的URL編碼來實現與Javascript的數據交互,但是對於部分特殊字符的編解碼與Javascript的規則不盡相同,請具體說明這種差異,並針對UTF-8字符集的數據,寫出PHP的編解碼函數和Javascript的編解碼函數,確保PHP編碼數據可以被Javascript正確解碼 、Javascript編碼的數據可以被PHP正確解碼

答:

<?php
 $str = '思源博客siyuantlw/tlw/sy/俺只是一個打醬油的';
 $str = iconv("GB2312",'UTF-8',$str);
 $str = urlencode($str);
?>

    1
    2
    3
    4
    5

//js  decodeURIComponent   貌似對GB2312編碼的格式不識別,必須轉爲utf-8纔可以,然後,如果字符串中有空格的  就轉爲 +  號了
<html>
 <script>
  var ds = '<?php echo $str;?>';
  var dddd= decodeURIComponent (ds);
  alert(dddd);
 </script>
</html>

    1
    2
    3
    4
    5
    6
    7
    8

8.試闡述Memcache的key多節點分佈的算法?當任一節點出現故障時PHP的Memcache客戶端將如何處置?如何確保Memcache數據讀寫操作的原子性?

答:原理:一致性hash

原子性
原子性會導致的問題:簡單的說就是A,B都想操作key1,然後都在key1上增加自己的信息,就會有問題
memcached是原子的嗎?宏觀
所有的被髮送到memcached的單個命令是完全原子的。如果您針對同一份數據同時發送了一個set命令和一個get命令,它們不會影響對方。它們將被串行化、先後執行。即使在多線程模式,所有的命令都是原子的;命令序列不是原子的。如果您通過get命令獲取了一個item,修改了它,然後想把它set回memcached,我們不保證這個item沒有被其他進程(process,未必是操作系統中的進程)操作過。在併發的情況下,您也可能覆寫了一個被其他進程set的item。
memcached 1.2.5以及更高版本,提供了gets和cas命令,它們可以解決上面的問題。如果您使用gets命令查詢某個key的item,memcached會 給您返回該item當前值的唯一標識。如果您覆寫了這個item並想把它寫回到memcached中,您可以通過cas命令把那個唯一標識一起發送給 memcached。如果該item存放在memcached中的唯一標識與您提供的一致,您的寫操作將會成功。如果另一個進程在這期間也修改了這個 item,那麼該item存放在memcached中的唯一標識將會改變,您的寫操作就會失敗。
9.如何實現PHP的安全最大化?怎樣避免SQL注入漏洞和XSS跨站腳本攻擊漏洞?

答:基本原則:不對外界展示服務器或程序設計細節(屏蔽錯誤),不相信任何用戶提交的數據(過濾用戶提交)
1、1 屏蔽錯誤,將display_errors 設置爲off
2、 過濾用戶提交參數,這裏需要注意的是不能僅僅通過瀏覽器端的驗證,還需要經過服務器端的過濾

  這裏是需要注意最多的地方,因爲所有用戶提交的數據入口都在這裏,這是過濾數據的第一步。
      1 考慮是否過濾select,insert,update,delete,drop,create等直接操作數據的命令語句
      2 使用addslashes 將所有特殊字符過濾
      3 打開magic_quotes_gpc,開啓該參數數後自動將sql語句轉換,將 ' 轉換成  \'

    1
    2
    3
    4

3、 可以考慮設置統一入口,只允許用戶通過指定的入口訪問,不能訪問未經許可的文件等內容
4、可以考慮對安全性要求高的文件進行來源驗證,比如要想執行b.php必須先執行a.php,可以在b.php中判斷來自a.php的referer,避免用戶直接執行b.php
10.請設計一個數據結構可以實現無限級子菜單的樹型菜單功能並提供菜單生成算法,用UML描述設計並寫出相關PHP代碼

答:還沒找到答案
二、系統相關部分
1.請簡述Linux、FreeBSD、Soalaris、Mac OS、Windows幾種系統下進程與線程的內核實現方式、管理機制的異同
2.請簡述Linux/BSD系統下進程間通訊的方式有哪些,並具體說明在PHP下如何實現

答:
管道(Pipe)及有名管道(namedpipe):管道可用於具有親緣關係進程間的通信,有名管道克服了管道沒有名字的限制,因此,除具有管道所具有的功能外,它還允許無親緣關係進程間的通信;
信號(Signal):信號是比較複雜的通信方式,用於通知接受進程有某種事件發生,除了用於進程間通信外,進程還可以發送信號給進程本身;linux除了支持Unix早期信號語義函數sigal外,還支持語義符合Posix.1標準的信號函數sigaction(實際上,該函數是基於BSD的,BSD爲了實現可靠信號機制,又能夠統一對外接口,用sigaction函數重新實現了signal函數);
報文(Message)隊列(消息隊列):消息隊列是消息的鏈接表,包括Posix消息隊列systemV消息隊列。有足夠權限的進程可以向隊列中添加消息,被賦予讀權限的進程則可以讀走隊列中的消息。消息隊列克服了信號承載信息量少,管道只能承載無格式字節流以及緩衝區大小受限等缺點。
共享內存:使得多個進程可以訪問同一塊內存空間,是最快的可用IPC形式。是針對其他通信機制運行效率較低而設計的。往往與其它通信機制,如信號量結合使用,來達到進程間的同步及互斥。
信號量(semaphore):主要作爲進程間以及同一進程不同線程之間的同步手段。
套接口(Socket):更爲一般的進程間通信機制,可用於不同機器之間的進程間通信。起初是由Unix系統的BSD分支開發出來的,但現在一般可以移植到其它類Unix系統上:Linux和SystemV的變種都支持套接字。
3.請簡述Linux/BSD系統下系統的消息/事件異步通知機制有幾種,並加以比較
4.簡單比較TCP/UDP協議的異同,對於PHP的Socket擴展與Stream擴展,試比較兩者基於TCP/UDP協議的SOCKET編程差異?
5.爲什麼會出現僵死進程(孤兒進程)?怎樣查看僵死進程?如何解決僵死進程問題?

答:殭屍進程:一個進程使用fork創建子進程,如果子進程退出,而父進程並沒有調用wait或waitpid獲取子進程的狀態信息,那麼子進程的進程描述符仍然保存在系統中。這種進程稱之爲僵死進程。
查看:使用ps aux
刪除:ps aux | grep -e ‘^[Zz]’ | awk ‘{print $2}’ | xargs kill -9
6.對於System-V消息隊列,如何解決系統本身對於消息隊列條數、總容量(字節數)的限制?如何設置消息的優先級別?請比較阻塞模式和非阻塞模式的異同,並說明如何避免非阻塞模式下的消息隊列堵塞?
7.請描述Apache 2.x版本的MPM(Multi-Processing Module)機制,並具體說明在不同的MPM機制下如何支持PHP?

答:常用的應該就只有3個:worker|prefork|perchild
prefork:在功能上就是使用Apache的運行方式,一個父進程,然後根據設置以及連接情況生成相應的子進程數。這種模式可靠性和健壯性都是最好的。但是在性能上,開銷過大。達不到我們這些“吸血鬼”的要求了^_^。如果連接數過多的話,會導致我們無法遠程登陸,一定要等到連接數下降後才能連接,這也是最讓我頭痛的事情。
worker:混合線程/進程的MPM。一個父進程,後面是帶有線程的子進程。每個子進程的線程數是固定且相同的。這是最“平庸”的一個模式,但也是使用人最多的一種模式。因爲它性能等各方面比較均衡。性能上要比prefork好一些,只是犧牲了一點點的健壯性和可靠性而已。一般推薦使用這個選項。
perchild:也是混合線程/進程的MPM。當啓動perchild MPM時,它會建立指定數量的子進程,且每個子進程都具有指定數量的線程,如負載增加了,那它不會建立新的進程(子進程是固定的),只是在子進程下建立新的線程。它還有一個特點就是可以爲每一個子進程配置不同的用戶和組。也可以爲每個虛擬主機指定一個子進程。這種模式性能是最佳的,但是可靠性和健壯性就相對是最差的。各取所需,我個人覺得這種模式也不錯,如果你不用第三方的模塊的話^_^。
8.請簡述PHP在Apache下的幾種運行方式並加以比較?如何讓PHP在Linux+Apache下以Fast CGI方式運行?

答:php在apache有3中運行方式:CGI模式、FastCGI模式、Apache 模塊DLL。
比較:
Cgi模式和模塊dll加載方式比較:
Cgi模式下,apache調用外部執行器php.exe執行php代碼,並將解釋後生成的html代碼和原html整合,再傳遞給apache服務器,其在執行時每次都需要重新解析php.ini、重新載入全部dll擴展並重初始化全部數據結構,運行速度非常慢,但因爲是外部加載執行器,php代碼執行出錯不會導致apache崩潰。

在模塊化(DLL)中,PHP是與Web服務器一起啓動並運行的。所以從某種角度上來說,以apache模塊方式安裝的 PHP4有着比CGI模式更好的安全性以及更好的執行效率和速度。

Cgi和fastcgi模式比較:
Fastcig是cgi的升級版,Cgi和fastcgi工作模式大抵相同,但fastcgi模式中fastcgi的進程管理器可用來管理cgi解釋器,該管理器在cgi解釋器完成請求後,會處於掛起狀態,用以等待接下來的請求,因爲向比較cgi每次都需要重新解析php.ini、重新載入全部dll擴展並重初始化全部數據結構,fastcig模式明顯要快很多。
9. 請寫出讓PHP能夠在命令行下以腳本方式執行時安裝PHP所必須指定的configure參數,並說明如何在命令行下運行PHP腳本(寫出兩種方式)同時向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
    2

10.請簡述PHP 5.2的內存池及其內存管理機制、垃圾回收機制

內存管理機制
試題二:
1、請列舉你能想到的UNIX信號,並說明信號用途。

答:
Unix信號量也可以在文件/usr/include/sys/signal.h中查看
SIGHUP 進程由於控制終端死去或者控制終端發出起命令
SIGINT 鍵盤中斷所產生的信號
SIGQUIT 鍵盤終止
2、請列舉、你能想到的所有的字符串查找算法,並加註釋簡單說明。

答:
1 順序查找
2 二分查找
3 分塊查找
4 哈希表查找
3、有一個IP地址(192.168.0.1),請寫出其32位無符號整數形式。

答:此題是將十進制轉換成二進制 採用取餘法即可很簡單 答案是:11000000.10101000.00000000.00000001 千萬不能只記答案哦
4、寫出、你能想到的所有HTTP返回狀態值,並說明用途(比如:返回404表示找不到頁面)

答:
200 (成功) 服務器已成功處理了請求。 通常,這表示服務器提供了請求的網頁。
301 (永久移動) 請求的網頁已永久移動到新位置。 服務器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
302 (臨時移動) 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。
401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,服務器可能返回此響應。
403 (禁止) 服務器拒絕請求。
404 (未找到) 服務器找不到請求的網頁。
500 (服務器內部錯誤) 服務器遇到錯誤,無法完成請求。
501 (尚未實施) 服務器不具備完成請求的功能。 例如,服務器無法識別請求方法時可能會返回此代碼。
502 (錯誤網關) 服務器作爲網關或代理,從上游服務器收到無效響應。
503 (服務不可用) 服務器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。
504 (網關超時) 服務器作爲網關或代理,但是沒有及時從上游服務器收到請求。
505 (HTTP 版本不受支持) 服務器不支持請求中所用的 HTTP 協議版本。

基礎任務-選作(會得到額外分數):
1、畫幾個你最熟悉的SERVER端模型出來(格式不重要,儘量將圖畫清楚,說明思路即可)
進階任務:
1、PHP的垃圾收集機制是怎樣的?

說明:
1)如果,你熟悉PHP源碼,那麼請從源碼入手,回答些問題,會獲得額外加分
2)如果,你不熟悉PHP源碼,那麼盡你所能,多寫點東西,包括利用自己的編程直覺得到的信息,都可以。
3)對,則有分,錯誤不扣,不寫無分。

答:PHP可以自動進行內存管理,清除不再需要的對象。PHP使用了引用計數(referencecounting)這種單純的垃圾回收(garbagecollection)機制。每個對象都內含一個引用計數器,每個reference連接到對象,計數器加1。當reference離開生存空間或被設爲NULL,計數器減1。當某個對象的引用計數器爲零時,PHP知道你將不再需要使用這個對象,釋放其所佔的內存空間。
2、請寫出HTTP頭,並符合以下要求:

1)這是一個post請求
2)目標:http://www.example.com:8080/test
3)POST變量:
username: test
pwd: test2
intro: Hello world!
4)包含以下COOKIE信息:
cur_query: you&me
說明:

1)如果,你記不得某個HTTP協議中的指令字了,那麼,無奈這舉是用“漢字”代替。
2)如果,你能記住更多的HTTP協議指令字,那麼多寫幾句,總是沒壞處,對吧?
3)最關鍵的,只需要畫出正確的“輪廓”(還記得httpwatch等工具打印出來的頭部嗎?那就是“輪廓”的含義),也會有分數,但如果,連“輪廓”都寫錯了,那麼就很遺憾了。
答:

Accept: text/html 可以接受的數據類型
Accept-Encoding: gzip 接受的壓縮類型
Accept-Language: zh-CN 接受語言
Cache-Control: no-cache 是否有緩存
Connection : keep-alive 是否保持鏈接
Host:http://www.example.com:8080/test
Cookie:intro=Hello world!
Content-Disposition: form-data; username=”test”&pwd=”test2”&intro=”hello world!”
User-Agent: 瀏覽器信息
Referer: 前一個頁面地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

設計任務:
1、最近總有人騷擾我們的投票模塊,需要你來設計一個投票限制的東東

要求如下:
1)要求每個QQ號碼(假設此QQ號碼在UNIT32內可以表示)10分鐘這內只能投5票。
2)我們的用戶很踊躍,平均每天要有2000萬人左右通過此程序投票。
說明:
1)無需寫代碼,只需要圖跟文字即可。
2)對於關鍵邏輯,請用圖加代碼表示出來,這也是對你文字表達能力的一個考驗。
3)對你能想到的所有的邊界條件列出來,這是對你邏輯思維全面與敏捷性的考驗。
4)存儲部分,盡你所能吧。如果,你需要一個自己設計的存儲層,那麼把這個存儲層的實現,用文字+圖片方式描述清楚,要是設計合理,你會獲得華麗的獎分。
答:找了好久終於找到個大神的回答:打字太累了 就截圖了
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
這裏寫圖片描述
編程任務:
1、我們碰到了大麻煩,一個新來的傳教士惹惱了上帝,上帝很憤怒,要求我們把聖經(bbe.txt)背熟,直至他說哪個單詞,我們就要飛快的回答出這個單詞在第幾行第幾個單詞位置。聽說你是個優秀的程序員,那麼髟助我們完成這個不可能的任務吧。

要求如下:
1)/myworks/example/bbe.txt,98版本英文聖經一本
2)輸入部分要求如下:php ./example.php [單詞]
3)輸出部分如下:[單詞] 1,2 2,4 5,6 表示:此單詞在1行2列(第二個單詞),2行4列…
說明:

1)此文本4MB之巨…
2)單詞的含義:由英文字母(大小寫),數字(0-9)組成的串
3)提供給你的機器OS爲ubuntu 9.10,內存只有1G,而且,很不幸的,其中700M用來做了別的
4)上機考試不允許上網,但我裝了man文檔以及讀取CHM以及PDF的閱讀器,在電腦的桌面的CHM文件夾中,有相應的PHP參考手冊
5)算法複雜度要求不能大於O(N^2)(就是N的平方)
6)什麼?PHP低效且用起來不順手,好的,你可以用別的語言來實現。但注意:提供給你的機器上只有python 2.4/perl 5.8/gcc[g++] 4.1

答:兩份答案感覺還可以
bbe.txt文件咱們沒有 想像成是 空格 隔開的算了

hello123 hello tim jason
woaini1 tianjianxiong333 hh aaa

/* 此文件用於根據bbe.txt文件對所有單詞創建索引,相當於一次預處理 */   
ini_set('display_errors','on');  
set_time_limit(0);  
$file = file($src); // 數組  
foreach($file as $i => &$ls){  
    $a = explode(" ",$ls);  
    $len = count($a);  
    if ($len > 0){  
        for($j=0;$i<$len;$j++){  
            $data = "此單詞".$a[$j]."在".($i+1)."行,".($j+1)."列";  
            $key = md5(trim(strtolower($a[$j])));  
            file_put_contents($key,$data);  
        }  
    }  
    //echo $i.". > ".$ls.'<br />';  
}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

example.php:

#!/usr/local/bin/php -q   
<?php  
set_time_limit(0);   
$getkey=empty($argv[1]) ? $_REQUEST['k'] : $argv[1];  
$arr = explode(",",$getkey);    
$len = count($arr);  
if($len > 0){  
    for($i=0;$i<$len;$i++){  
        echo getKey($arr[$i])."\n";  
    }  
}  
functuion getKey($key){  
    $str = "沒有找到此單詞[".$key."]";  
    if($key){  
        $fc = md5($key);  
        $str = file_get_contents($fc));  
    }  
    return $str;  
}  
?>  

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

別人的方法:
1、使用ascii碼,判斷字符所在範圍
2、只要掃描一遍字符即可,複雜度爲O(N)
3、利用了php string{$i} 的特性,取字符串內任一字符
4、todo:改爲fgetc版本,可以完全不需要使用以上php特性
5、字符串匹配算法:http://wendell07.blog.hexun.com/14112681_d.html,目前看來最快的方法:Sunday,由於本題是單詞匹配,問題更簡單,只要找到頭尾……

$word = $argv[1];  
$lines = 0;  

$handle = @fopen("bbe.txt", "r");  
if ($handle) {  
    while (!feof($handle)) {  
        $line = fgets($handle, 4096);  
        $local = local_word($line, $word);  
        $lines++;  
        if( !empty($local) ){  
            echo "$lines,".implode(' ',$local)."\n";  
        }  
    }  
    fclose($handle);  
}  

function local_word($line, $word){  
    $local = array();  
    $local_length = 1;  
    $word_length = strlen($word);  

    for($i = 0; ( $char = $line{$i} ) !== ''; $i++ ){  
        // 單詞最後一個字符必定不是符號,且必有一個符號結尾,此計爲一個新詞  
        if( !is_symbel( $line{ $i-1 } ) && is_symbel($char) ){  
            $local_length++;  
        }      

        if( $char === $word[0] && // 如果第一個字符相同  
            is_symbel( $line{ $i-1 } ) && // 且爲單詞開始  
            is_symbel( $line{ $i+$word_length }) // 單詞結尾應該爲符號  
        ){  
            // 進入驗證單詞模式,一個一個字符比對  
            for($j = 1; ($w_char = $word{$j}) !== ''; $j++ ){  
                // 遇到單詞字符不匹配  
                if( $w_char != $line{ $i+$j } ){  
                    $i += $j;  
                    break;  
                }  
                // 如果單詞比對完全正確  
                if( $j == ($word_length-1) ){  
                    //echo "$line_length, $word_length\n";  
                    $local[] = $local_length;  
                }  
            }  
        }  
    }  
    return $local;  
}  

function is_symbel($char){  
    $asc = ord($char);  
    return !( (48 <= $asc && $asc <= 57) ||  
              (65 <= $asc && $asc <= 90) ||  
              (97 <= $asc && $asc <= 122) );  
}  
---------------------
作者:Rodgexue
來源:CSDN
原文:https://blog.csdn.net/rodgexue/article/details/79521499
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

 

https://blog.csdn.net/u011330276/article/details/79597200

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章