12

Kohana/CodeIgniter では、次の形式の URL を使用できます。

http://www.name.tld/controller_name/method_name/parameter_1/parameter_2/parameter_3 ...

次に、コントローラーのパラメーターを次のように読み取ります。

class MyController 
{
    public function method_name($param_A, $param_B, $param_C ...)
    {
        // ... code
    }
}

Zend フレームワークでこれをどのように達成しますか?

4

5 に答える 5

11

Zend_Controller_Router クラスを見てみましょう。

http://framework.zend.com/manual/en/zend.controller.router.html

これらにより、必要な方法で URL にマップする Zend_Controller_Router_Route を定義できます。

Index コントローラーの Index アクションに 4 つの静的パラメーターを使用する例を次に示します。

$router = new Zend_Controller_Router_Rewrite();

$router->addRoute(
    'index',
    new Zend_Controller_Router_Route('index/index/:param1/:param2/:param3/:param4', array('controller' => 'index', 'action' => 'index'))
);

$frontController->setRouter($router);

これは、フロント コントローラーを定義した後にブートストラップに追加されます。

アクションに入ったら、次を使用できます。

$this->_request->getParam('param1');

値にアクセスするためのアクション メソッド内。

アンドリュー

于 2008-10-02T10:13:47.303 に答える
6

更新 (2016 年 4 月 13 日): 以下の回答のリンクが移動し、修正されました。しかし、万が一それが再び消えてしまった場合に備えて、この手法に関する詳細な情報を提供し、元の記事を参考資料として使用するいくつかの代替手段を以下に示します。


@ Andrew Taylorの応答は、URL パラメータを処理する適切な Zend Framework の方法です。ただし、コントローラーのアクションに URL パラメーターを含める場合 (例のように) - Zend DevZone のこのチュートリアルを確認してください。

于 2008-10-08T20:54:59.383 に答える
4

コントローラー クラスを拡張Zend_Controller_Actionし、次の変更を加えました。

メソッドでdispatch($action)置換

$this->$action();

call_user_func_array(array($this,$action), $this->getUrlParametersByPosition());

そして、次のメソッドを追加しました

/**
 * Returns array of url parts after controller and action
 */
protected function getUrlParametersByPosition()
{
    $request = $this->getRequest();
    $path = $request->getPathInfo();
    $path = explode('/', trim($path, '/'));
    if(@$path[0]== $request->getControllerName())
    {
        unset($path[0]);
    }
    if(@$path[1] == $request->getActionName())
    {
        unset($path[1]);
    }
    return $path;
}

今のようなURLのために/mycontroller/myaction/123/321

私のアクションでは、コントローラーとアクションに続くすべてのパラメーターを取得します

public function editAction($param1 = null, $param2 = null)
{
    // $param1 = 123
    // $param2 = 321
}

URL に追加のパラメーターを指定してもエラーは発生しません。これは、定義したメソッドに追加のパラメーターを送信できるためです。それらはすべて取得でき、通常の方法でfunc_get_args() 使用することもできます。getParam()URL には、デフォルトのものを使用するアクション名が含まれていない可能性があります。

実際、私の URL にはパラメーター名が含まれていません。それらの値のみ。(問題のとおりです)そして、フレームワークの概念に従い、Zendメソッドを使用してURLを構築できるようにするには、ルートを定義してURLのパラメーター位置を指定する必要があります。しかし、URL 内のパラメーターの位置を常に知っている場合は、このように簡単に取得できます。

これは、リフレクション メソッドを使用するほど洗練されていませんが、オーバーヘッドが少ないと思います。

Dispatch メソッドは次のようになります。

/**
 * Dispatch the requested action
 *
 * @param string $action Method name of action
 * @return void
 */
public function dispatch($action)
{
    // Notify helpers of action preDispatch state
    $this->_helper->notifyPreDispatch();

    $this->preDispatch();
    if ($this->getRequest()->isDispatched()) {
        if (null === $this->_classMethods) {
            $this->_classMethods = get_class_methods($this);
        }

        // preDispatch() didn't change the action, so we can continue
        if ($this->getInvokeArg('useCaseSensitiveActions') || in_array($action, $this->_classMethods)) {
            if ($this->getInvokeArg('useCaseSensitiveActions')) {
                trigger_error('Using case sensitive actions without word separators is deprecated; please do not rely on this "feature"');
            }
            //$this->$action();
            call_user_func_array(array($this,$action), $this->getUrlParametersByPosition()); 
        } else {
            $this->__call($action, array());
        }
        $this->postDispatch();
    }

    // whats actually important here is that this action controller is
    // shutting down, regardless of dispatching; notify the helpers of this
    // state
    $this->_helper->notifyPostDispatch();
}    
于 2011-07-21T13:13:32.053 に答える
3

より複雑な構成を可能にする簡単な方法については、この投稿を試してください。要約すれば:

作成application/configs/routes.ini

routes.popular.route = popular/:type/:page/:sortOrder
routes.popular.defaults.controller = popular
routes.popular.defaults.action = index
routes.popular.defaults.type = images
routes.popular.defaults.sortOrder = alltime
routes.popular.defaults.page = 1
routes.popular.reqs.type = \w+
routes.popular.reqs.page = \d+
routes.popular.reqs.sortOrder = \w+

追加bootstrap.php

// create $frontController if not already initialised
$frontController = Zend_Controller_Front::getInstance(); 

$config = new Zend_Config_Ini(APPLICATION_PATH . ‘/config/routes.ini’);
$router = $frontController->getRouter();
$router->addConfig($config,‘routes’);
于 2009-12-30T18:04:49.940 に答える
1

もともとここに投稿されたhttp://cslai.coolsilon.com/2009/03/28/extending-zend-framework/

私の現在の解決策は次のとおりです。

abstract class Coolsilon_Controller_Base 
    extends Zend_Controller_Action { 

    public function dispatch($actionName) { 
        $parameters = array(); 

        foreach($this->_parametersMeta($actionName) as $paramMeta) { 
            $parameters = array_merge( 
                $parameters, 
                $this->_parameter($paramMeta, $this->_getAllParams()) 
            ); 
        } 

        call_user_func_array(array(&$this, $actionName), $parameters); 
    } 

    private function _actionReference($className, $actionName) { 
        return new ReflectionMethod( 
            $className, $actionName 
        ); 
    } 

    private function _classReference() { 
        return new ReflectionObject($this); 
    } 

    private function _constructParameter($paramMeta, $parameters) { 
        return array_key_exists($paramMeta->getName(), $parameters) ? 
            array($paramMeta->getName() => $parameters[$paramMeta->getName()]) : 
            array($paramMeta->getName() => $paramMeta->getDefaultValue()); 
    } 

    private function _parameter($paramMeta, $parameters) { 
        return $this->_parameterIsValid($paramMeta, $parameters) ? 
            $this->_constructParameter($paramMeta, $parameters) : 
            $this->_throwParameterNotFoundException($paramMeta, $parameters); 
    } 

    private function _parameterIsValid($paramMeta, $parameters) { 
        return $paramMeta->isOptional() === FALSE 
            && empty($parameters[$paramMeta->getName()]) === FALSE; 
    } 

    private function _parametersMeta($actionName) { 
        return $this->_actionReference( 
                $this->_classReference()->getName(), 
                $actionName 
            ) 
            ->getParameters(); 
    } 

    private function _throwParameterNotFoundException($paramMeta, $parameters) { 
        throw new Exception(”Parameter: {$paramMeta->getName()} Cannot be empty”); 
    } 
} 
于 2009-06-25T02:17:25.823 に答える