4

私はCakePHP 2.4を使用しています

/sent?note=123&test=abc などの URL があります。

note残りの URL を返しながら、パラメーターを削除したいと考えています。すなわち

/sent?test=abc

クエリ パラメータに対してのみ機能するコードがあります。コードを次のように改善する方法を知りたいです。

  1. 名前付きパラメーター
  2. 渡されたパラメーター
  3. ハッシュタグ

例えば

/sent/name1:value1?note=123&test=abc#top

これは私がこれまでに書いたコードです。https://github.com/simkimsia/UtilityComponents/blob/master/Controller/Component/RequestExtrasHandlerComponent.php#L79

更新パート III:

より一般的な答えが何を意味するかを示すために、さらに例を挙げて説明しましょう。

より一般的な回答は、URL パターンに関する予備知識がないことを前提としています。

このURLが与えられたと仮定します

/sent/name1:value1?note=123&test=abc

クエリパラメータだけを取り除いてnote元に戻したい

/sent/name1:value1?test=abc

より一般的な解決策は、この URL を返すために機能するはずです。

もう一つの例。今回は、名前付きパラメーターを削除します。

このURLが再び与えられたと仮定します

/sent/name1:value1?note=123&test=abc

私は取り除き、name1元に戻したい:

/sent?note=123&test=abc

繰り返しますが、より一般的なソリューションでもこれを達成できるはずです。

更新パート II:

より一般的な答えを探しています。Web アプリは、URL が送信済みと呼ばれることを認識していないと仮定します。また、クエリ パラメータに単語 note または test が含まれているかどうかもわかりません。上記を達成するにはどうすればよいですか?

どのアクションにも同じコードを使用できるようにしたい。そうすれば、簡単に再利用できるようにコンポーネントにパッケージ化できます。

更新パート I:

ハッシュタグが PHP に渡されないことを理解しています。だから無視してください。

ハッシュタグから値を取得する方法の手がかり:

4

3 に答える 3

1

次のルートを作成したとします。

Router::connect('/projects/:id/quotations/:quotation_id/*', 
    array(
        'controller' => 'quotations', 
        'action' => 'get_all_by_project', "[method]" => "GET"),
    array(
        'pass' => array('id', 'quotation_id'),
        'id' => '[0-9]+',
        'quotation_id' => '[0-9]+'
    ),
    array(
        'named' => array(
            'name1',
            'name2',
            'name3'
        )
    )
);

このルートでは:

  • 渡されたパラメーターは必須パラメーターidとなりquotation_id、1 番目と 2 番目に渡されたパラメーターの順序に従います。
  • 名前付きパラメーターは、オプションのパラメーターname1name2、および になりname3ます。
  • もちろん、クエリ パラメータもオプションであり、URL に実際に含まれているものによって異なります。
  • 名前付きパラメーターが通過できるように、最後にアスタリスクが必要です

次のきれいな URL と同じアクションの醜い URL を想定してみましょう。

/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (pretty)

/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?note=abc&test=123 (ugly)

答えの最初の部分:クエリ パラメータnote を削除するシナリオだけを考えてみましょう。

戻るべきだ

/projects/1/quotations/23/name2:value2/name3:value3/name1:value1?test=123 (pretty)

/quotations/get_all_by_project/1/23/name2:value2/name3:value3/name1:value1?test=123 (ugly)

次のComponentメソッドが機能します。醜いURLときれいなURLの両方でテストしました。

public function removeQueryParameters($parameters, $here = '') {
    if (empty($here)) {
        $here       = $this->controller->request->here;
    }
    $query          = $this->controller->request->query;
    $validQueryParameters   = array();

    foreach($query as $param=>$value) {
        if (!in_array($param, $parameters)) {
            $validQueryParameters[$param] = $value;
        }
    }

    $queryString = $this->_reconstructQueryString($validQueryParameters);

    return $here . $queryString;
}

protected function _reconstructQueryString($queryParameters = array()) {
    $queryString = '';
    foreach($queryParameters as $param => $value) {
        $queryString .= $param . '=' . $value . '&';
    }

    if (strlen($queryString) > 0) {
        $queryString = substr($queryString, 0, strlen($queryString) - 1);
        $queryString = '?' . $queryString;
    }
    return $queryString;
}

これは、Component メソッドを呼び出す方法です。

$newUrl = $this->RequestExtrasHandler->removeQueryParameters(array('note'));

RequestExtrasHandler上記のメソッドを持つ、私が書いたコンポーネントの名前です。

答えの 2 番目の部分:名前付きパラメーターname2 を削除するシナリオのみを考えてみましょう。

戻るべきだ

/projects/1/quotations/23/name3:value3/name1:value1?test=123 (pretty)

/quotations/get_all_by_project/1/23/name3:value3/name1:value1?test=123 (ugly)

次のComponentメソッドが機能します。醜いURLときれいなURLの両方でテストしました。

public function removeNamedParameters($parameters, $here = '') {
    if (empty($here)) {
        $here   = $this->controller->request->here;
    }
    $query      = $this->controller->request->query;
    $named      = $this->controller->request->params['named'];

    $newHere    = $here;
    foreach($named as $param=>$value) {
        if (in_array($param, $parameters)) {
            $namedString = $param . ':' . $value;
            $newHere = str_replace($namedString, "", $newHere);
        }
    }

    $queryString = $this->_reconstructQueryString($query);

    return $newHere . $queryString;
}

これは、Component メソッドを呼び出す方法です。

$newUrl = $this->RequestExtrasHandler->removeNamedParameters(array('name2'));

RequestExtrasHandler上記のメソッドを持つ、私が書いたコンポーネントの名前です。

回答の 3 番目の部分: 渡されたパラメーターが必須であることに気付いた後、渡されたパラメーターを削除する必要があったとしても、実際にはビジネス上必要ないことがわかりました。

もう 1 つの問題は、名前付きパラメーターやクエリ パラメーターとは異なり、渡されたパラメーターにキーが存在しない傾向があることです。$this->controller->request->params['pass']

$this->controller->request->params['pass']通常、数値インデックス付き配列の形式です。

したがって、渡された正しいパラメーターを取り出すことは非常に困難です。

そのため、渡されたパラメーターを削除するメソッドは作成しません。

詳細については、こちらのコードをご覧ください。

https://github.com/simkimsia/UtilityComponents/blob/d044da690c7b83c72a50ab97bfa1843c14355507/Controller/Component/RequestExtrasHandlerComponent.php#L89

于 2013-09-06T17:09:17.410 に答える
0

おそらく単純なphp関数であなたが望むことができるでしょう

$url =  '/sent?note=123&test=abc'; //for example
$unwanted_string = substr($url, 0,strrpos($url,'&') + 1);
$unwanted_string = str_replace('/sent?', '', $unwanted_string);
$url = str_replace($unwanted_string, '', $url);
于 2013-08-29T10:27:03.273 に答える