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 から最初に検出された場合、このアプローチ全体はうまく機能しますが、その結果、URL がより冗長になり、これは望ましくありません。path/to/page/some-module/edit/123に変わりますpath/to/page/module/some-module/action/edit/item/123。よくない。

JOINMySQL が可能なものを結合し、残りを無視するように詰め込む方法はありますか? 「このページ階層が有効かどうかをお知らせします」と述べる代わりに、私が説明したこのメソッドは、「このページ階層が有効であるポイントをお知らせします」と述べるべきです。

どんな助けでも感謝します。

4

1 に答える 1

2

問題は、LEFT JOIN を使用しているにも関わらず、WHERE 句で各テーブルの値を指定しているため、各テーブルにレコードを強制することになり、結果が INNER JOIN と同じになることです。

したがって、変更

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

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

これにより、LEFT JOIN を利用して、一致しないテーブルを「スキップ」しながら、見つかったものの結果を返すことができます。

SELECT は、id見つかったページに対して s を返し、ページに対応しない残りの値に対して null を返します。

于 2013-11-01T07:44:54.877 に答える