PHP: Using explode() with seperator “\n”

Posted by – December 26, 2011

有個以 PHP 開發的案子在測試階段回報有 bug,雖然兇手不是我,但還是去了解一下。原來的程式是讓使用者輸入多個 Youtube 影片網址,然後由程式取出每一支影片的 uid,封裝成陣列後回傳。之後的程式會取出 uid,然後在網站上 show 出 Youtube 影片。不過當使用者輸出多支影片的網址後,只有最後一支影片會出現,前面的都錯誤了。

原程式是這樣寫的...

<?php
//使用者輸入的影片網址. http://後面空一格是避免Wordpress把影片顯示出來
$youtube = <<<EOF
http:// www.youtube.com/watch?v=SAIEamakLoY
http:// www.youtube.com/watch?v=MhVp9gcxLJY
http:// www.youtube.com/watch?v=OxzucwjFEEs
EOF;

function get_youtube_hash($youtube){
    $hash = array();
    $youtube = explode("\n", $youtube);

    foreach($youtube as $y){
        $youtube_qs = parse_url($y, PHP_URL_QUERY);
        $youtube_qv = explode('&', $youtube_qs);

        foreach($youtube_qv as $key => $value){
            list($k, $v) = explode('=', $value);
            if($k == 'v') $hash[] = $v;
        }
    }

    if(empty($youtube)) return FALSE;
    else return $hash;
}
echo "<pre>";
print_r( get_youtube_hash( $youtube ) );
echo "</pre>";
?>

result:
Array
(
    [0] => SAIEamakLoY_
    [1] => MhVp9gcxLJY_
    [2] => OxzucwjFEEs
)

從輸出的結果可以發現除了最後一筆資料,其他的結尾都多了一個底線 ( _ )。

不難猜到是第 11 行的問題。用 \n 當截斷字元,有可能會留下看不見的 \r 字元。下一步 parse_url 又將所有不合法字元替換成底線,後面就一路錯下來了。

解決方法有兩種,一是把第 11 行改為

$youtube = explode(PHP_EOL, $youtube); //PHP_EOL可以跨平台, Windows, Linux, MacOS

二是把第 14 行 parse_url 的內容改為

$youtube_qs = parse_url(trim($y), PHP_URL_QUERY);

如此一來就可以得到正確的影片 uid 陣列了。

References:

Leave a Reply

Your email address will not be published. Required fields are marked *