2013-11-01 59 views
0

我想使用SEF URL來確定用戶在哪個頁面上。它的工作方式如下:如何編寫不失敗的連接,如果沒有找到?

public function getIdsByPath(array $path, $langId) { 
    $select = 'SELECT '; 
    $from = ' FROM pages t0 '; 
    $where = 'WHERE '; 

    for($i = 0; $i < count($path); $i++) { 
     $ii = $i - 1; 
     if($i > 0) { 
      $select .= ', '; 
      $from .= "LEFT JOIN pages t$i ON (t$i.pid = t$ii.id) "; 
      $where .= ' AND '; 
     } 
     $select .= "t$i.id"; 
     $where .= "t$i.alias = ?"; 
    } 
    $where .= " AND t0.pid = ?"; 
    $q = $this->db->prepare($select.$from.$where); 

    for($i = 0; $i < count($path); $i++) { 
     $q->bindValue($i + 1, $path[$i]); 
    } 
    $q->bindValue($i + 1, $langId); 
    $q->execute(); 
    return $q->fetch(PDO::FETCH_NUM); 
} 

此方法的目的是檢查頁面層次結構並驗證它是否正確。然而,問題在於,因爲層次結構是以SEF URL的形式呈現的,所以path/to/page/module/action/123在某些時候explode('/')上述字符串中的項目不再代表頁面,而是代表其他變量。

如果我將此整個字符串path/to/page/module/action/item/123提供給該方法,由於JOIN語句,查詢將找不到任何內容。我嘗試了其他所有JOIN我也能想到。他們都確定,因爲沒有找到所有的東西,所以沒有找到時期。

這整個的做法很好地工作,如果首先從關鍵字將URL檢測到的其他變量,但結果是更冗長的網址,這是我不想要的。 path/to/page/some-module/edit/123將更改爲path/to/page/module/some-module/action/edit/item/123。不太好。

有沒有辦法來JOIN的東西,這樣的MySQL之類的加入所能做和忽略其他人呢?我沒有說明「我要告訴你,如果這個頁面層次結構是有效的」,我描述的這個方法應該陳述「我要告訴你什麼時候該頁面層次結構是有效的。」

任何幫助表示讚賞。

回答

2

問題是,儘管您使用的是LEFT JOIN,但由於您正在爲WHERE子句中的每個表指定一個值,因此您正在強制每個表都有一條記錄,該記錄呈現的結果將與內部聯接。

因此,改變

$where .= "t$i.alias = ?"; 

$where .= "(t$i.alias = ? OR t$i.id IS NULL)"; 

,讓您充分利用LEFT JOIN的和「跳過」不匹配表,同時仍返回結果是什麼被發現。

你的SELECT將回該id S代表發現這些網頁,然後空的不對應到一個頁面的剩餘價值。

相關問題