2016-12-21 63 views
1

我目前正在爲我們的網站開發一個自定義URL路由腳本。我們希望將URL模式定義爲數組鍵,並檢查指定的URL是否與格式中的某個鍵匹配。檢查字符串是否匹配數組鍵格式

例如,我們有一個數組定義如下:

$rewrites = array(
    'item[0-9].html' => array('target' => 'http://example.com') 
); 

我們想取回陣列$rewrites['item[0-9].html']當URL是item1.html,一樣的東西:

function get_info($url) 
{ 
    // $url = 'item1.html'; 
    // return value for $rewrites['item[0-9].html'] 
} 

我們如何能檢查數組鍵是否存在,並通過將item1.html傳遞給函數來檢索它的值?我擔心循環遍歷整個數組(這將容納200個項目)並且執行一個preg_match()上的密鑰將會很慢。有沒有更好的方法來實現這一目標?

+1

有沒有辦法左右用於測試由一個與你的方法中,所有的表情之一。考慮將這個邏輯轉移到http服務器的級別,在那裏正則表達式引擎更高效。 – arkascha

+0

此外,當你的鑰匙變得複雜時,你將*遇到未來的問題。請檢查htaccess重定向:) – Martijn

+0

否則,請考慮將其分解爲多步驟方法:不要逐個應用每個完整模式,直到找到匹配(或不),請考慮使用「前綴模式」(「^ item」)這個例子,如果你有多個模式,例如以相同的前綴開始。只有在前綴匹配的情況下,才能繼續執行第二步,並進一步測試該前綴。根據模式集的結構,_might_ drastical會減少要測試的模式總數。 – arkascha

回答

0

恕我直言200請求沒有那麼多,特別是如果您使用PHP7.0〜,所以我建議使用preg_match_all,並使用命名模式,這將幫助您哪種模式已取得結果,但通過這種方法,您可能有一個網址與多個模式匹配。

<?php 
/** 
* @param string $url 
* @param array $rewrites 
* 
* @return array 
*/ 
function get_info(string $url, array $rewrites): array 
{ 
    $patterns = [ 
     'original' => [], 
     'named' => [], 
    ]; 
    foreach (array_keys($rewrites) as $key => $pattern) { 
     $index = "pattern_{$key}"; 
     $patterns ['original'][$index] = $pattern; 
     $patterns ['named'][$index] = "(?P<{$index}>{$pattern})"; 
    } 

    $patternsString = '#(' . implode('|', $patterns['named']) . ')#'; 

    $matches = []; 
    preg_match_all($patternsString, $url, $matches); 

    $matchedPatterns = []; 
    if (count($matches) > 0) { 
     foreach ($matches as $key => $match) { 
      if (key_exists($key, $patterns['named']) 
       && count($match) > 0 
       && !empty($match[0])) { 
       $matchedPatterns [] = $rewrites[$patterns['original'][$key]]; 
      } 
     } 
    } 

    return $matchedPatterns; 
} 

$rewrites = [ 
    'item[0-9].html' => ['target' => 'http://example.com'], 
    '-item.html' => ['target' => 'http://example1.com'], 
]; 

$testData = [ 
    'item1.html' => [['target' => 'http://example.com']], 
    '-item.html' => [['target' => 'http://example1.com']], 
]; 

foreach ($testData as $key => $datum) { 
    $output = get_info($key, $rewrites); 
    assert($datum == $output, sprintf("\"%s\" has wrong matches.", $key)); 
} 

可以測試here

0
foreach ($rewrites as $key => $row) { 
    preg_match_all('/item\d\.html/', $key, $matches); 

    if (isset($matches[0][0])) { 
     echo $matches[0][0]; 
    } 
} 

我希望這對你有所幫助。

相關問題