0

顧客名を取得し、データベースを検索して顧客と一致するコントローラーとアクションがあります。ミドルネームを持っている顧客もいれば、持っていない顧客もいます。

これには次の2つのルートがあります。

        'full-name' => array(
            'type' => 'regex',
            'options' => array(
                'regex' => '/(?<title>Mr|Miss|Mrs|Ms)/(?<firstname>[a-zA-Z0-9_-]+)/(?<middlename>[a-zA-Z0-9_-]+)/(?<lastname>[a-zA-Z0-9_-]+)',
                'defaults' => array(
                    'controller' => 'Application\Controller\Customers',
                    'action'     => 'index',
                ),
                'spec'  => '/%firstname%/%middlename%/%lastname%'
            )
        ),
        'name' => array(
            'type' => 'regex',
            'options' => array(
                'regex' => '/(?<title>Mr|Miss|Mrs|Ms)(?<firstname>[a-zA-Z0-9_-]+)/(?<lastname>[a-zA-Z0-9_-]+)',
                'defaults' => array(
                        'controller' => 'Application\Controller\Customers',
                        'action'     => 'index',
                ),
                'spec'  => '/%firstname%/%lastname%'
            )
        ),

両方を1つの正規表現ルールに組み合わせる方法があるかどうか疑問に思いましたが、ミドルネームに有効なものは見つかりませんでした。私は次のようないくつかのことを試しました:

(?<middlename>[a-zA-Z0-9_-]?)
(?<middlename>[a-zA-Z0-9_-]+|^$)

しかし、ミドルネームなしで試してみると、一致するルートがないという苦情がありました。もちろん、動作するのでそのままにしておくこともできますが、両方のルートを1つにまとめることができればいいのですが。

誰かがこれを行う方法を知っていますか?

編集:私はもともと私が実際に必要とするものと比較してコードを少し単純化しましたが、これは正規表現のオプションの値についての私の質問に答えない解決策につながりました。セグメントルートを使用できない理由を反映するようにコードを変更しました。

参考までに、これは私の最初のコードでした。

        'full-name' => array(
            'type' => 'regex',
            'options' => array(
                'regex' => '/Customer/(?<firstname>[a-zA-Z0-9_-]+)/(?<middlename>[a-zA-Z0-9_-]+)/(?<lastname>[a-zA-Z0-9_-]+)',
                'defaults' => array(
                    'controller' => 'Application\Controller\Customers',
                    'action'     => 'index',
                ),
                'spec'  => '/%firstname%/%middlename%/%lastname%'
            )
        ),
        'name' => array(
            'type' => 'regex',
            'options' => array(
                'regex' => '/Customer/(?<firstname>[a-zA-Z0-9_-]+)/(?<lastname>[a-zA-Z0-9_-]+)',
                'defaults' => array(
                        'controller' => 'Application\Controller\Customers',
                        'action'     => 'index',
                ),
                'spec'  => '/%firstname%/%lastname%'
            )
        ),

ありがとう!

4

2 に答える 2

1

Regexルートクラスについてはあまり詳しくありません。Segment私はこれがルートでできることを知っています。

'name' => array(
    'type'    => 'Segment',
    'options' => array(
        'route'    => '/[:title[/]]:firstname[/:middlename]/:lastname',
        'constraints' => array(
            'title' => 'Mr|Miss|Mrs|Ms',
            'firstname' => '[a-zA-Z0-9_-]+',
            'middlename' => '[a-zA-Z0-9_-]+',
            'lastname' => '[a-zA-Z0-9_-]+',
        ),
        'defaults' => array(
            'controller' => 'Application\Controller\Customers',
            'action'     => 'index',
        ),
    ),
),

編集:コメントを反映するように回答を更新しました。

于 2013-02-06T23:21:47.340 に答える
0

一致したルートからパラメーターを取得するときに、コントローラーでこれを解決しようとすることができます。

'full-name' => array(
    'type' => 'regex',
    'options' => array(
        // look here how I changed the regex in a way that the last parameter is optional
        'regex' => '/Customer/(?<firstname>[a-zA-Z0-9_-]+)/(?<middlename>[a-zA-Z0-9_-]+)/*(?<lastname>[a-zA-Z0-9_-]*)',
        'defaults' => array(
            'controller' => 'Application\Controller\Customers',
            'action'     => 'index',
            'lastname'   => false, // add some default value to the optional parameter
        ),
        'spec'  => '/%firstname%/%middlename%/%lastname%'
    )
),

次に、コントローラーで...

public function userAction()
{
    $firstName = $this->params()->fromRoute('firstname');

    // if lastname === false, we have just two parameters (firstname/lastname)
    if ($this->params()->fromRoute('lastname') === false) {
        $lastName = $this->params()->fromRoute('middlename');
        $middleName = NULL;
    } else {
        // if not, we have the three parameters (firstname/middlename/lastname)
        $lastName = $this->params()->fromRoute('lastname');
        $middleName = $this->params()->fromRoute('middlename');
    }
}

コントローラアクションを記述する他の方法(実際には同じことです):

public function userAction()
{
    $firstName = $this->params()->fromRoute('firstname');

    $lastName = $this->params()->fromRoute('lastname') === false ?
        $this->params()->fromRoute('middlename') :
        $this->params()->fromRoute('lastname');

    $middleName = $this->params()->fromRoute('lastname') === false ?
        NULL : $this->params()->fromRoute('middlename');
}

このようにして、1つのルートのみを使用できます。私はそれをする別の方法をすることはできません!

于 2013-02-07T04:50:43.710 に答える