donglankui1263 2014-07-10 08:57
浏览 48
已采纳

使用AJAX操作编辑Symfony行为

Assuming I have an application using a lot of AJAX requests.

Is there a way to edit Symfony behavior and autommatically call indexAjaxAction instead of indexAction when my request is AJAX made ?

I already know that I can test if a request is Ajax with the Request::isXmlHttpRequest() method but I want it to be autommatic (i.e without testing in each controllerAction).

Does a service/bundle already makes it ?

Example :

<?php 

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FooController extends Controller
{
    public function indexAction($vars)
    {
        $request = $this->getRequest();         
        if($request->isXmlHttpRequest()) {
            return $this->indexAjaxAction($vars);
        }
        // Do Stuff
    }

    public function indexAjaxAction($vars){ /* Do AJAX stuff */ }
}

becomes

<?php 

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FooController extends Controller
{
    public function indexAction($vars) { }
    public function indexAjaxAction($vars) { }

    // Other functions
}
  • 写回答

2条回答 默认 最新

  • doujiaochan7317 2014-07-10 10:00
    关注

    One way would be to use a slightly modified controller resolver that would be used instead of the current controller resolver in the regular KttpKernel::handleRaw process.

    Please note that I may be wrong in my thinking here and it is untested.

    The controller resolver class has the id controller_resolver.class which you could overwrite with your custom one in your config using

    In your app/config/config.yml...

    .. config stuff ..
    
    parameters:
        controller_resolver.class: Acme\SomeBundle\Controller\ControllerResolver
    

    And then in your new ControllerResolver...

    namespace Acme\SomeBundle\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver
                        as BaseControllerResolver;
    
    class ControllerResolver extends BaseControllerResolver
    {
        /**
         * {@inheritdoc
         */
        public function getArguments(Request $request, $controller)
        {
            if (is_array($controller) && $request->isXmlHttpRequest()) {
                $action = preg_replace(
                    '/^(.*?)Action$/', 
                    '$1AjaxAction', 
                    $controller[1]
                );
    
                try {
                    $r = new \ReflectionMethod($controller[0], $action);
    
                    return $this->doGetArguments(
                        $request, 
                        $controller, 
                        $r->getParameters()
                    );
                } catch( \Exception $e) {
                    // Do nothing
                }
            }
    
            return parent::getArguments($request, $controller);
        }
    }
    

    This class just extends the current controller resolver and will attempt to use the youractionAjaxAction if it exists in the controller and then falls back to the regular resolver if it gets an error (method not found);

    Alternatively you could just use...

    if (is_array($controller) && $request->isXmlHttpRequest()) {
        $controller[1] = preg_replace(
            '/^(?P<action>.*?)Action$/', 
            '$1AjaxAction', 
            $controller[1]
        );
    }
    
    return parent::getArguments($request, $controller);
    

    .. which would just update the called action and then send it through to the regular resolver with no fall back, meaning that every action that could be called using an XmlHttpRequest would require a corresponding AjaxAction.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?