Domanda

While I have successfully set up an AjaxController for typical patterns containing $Action/$ID/$OtherID, I don't seem to know how to set up a pattern for $Action + more than two parameters.

I'm trying to handle simple "calculator" URLs as in: myajax/add/5/6/7

routes.yml

Director:
 rules:
   'myajax//$action/$a/$b/$c': 'AjaxPage_Controller'

AjaxPage.php

<?php
 class AjaxPage extends Page {
 }

 class AjaxPage_Controller extends Page_Controller {
     public static $url_handlers = array(
         'myajax/add/$a/$b/$c' => 'add',
     );
     private static $allowed_actions = array (
         'add',
     );

     public function add($request){
         $v1 = (int) $request->param('a');
         $v2 = (int) $request->param('b');
         $v3 = (int) $request->param('c');
         echo json_encode(array('result' => $v1 + $v2 + $v3));
         return;
     }

 }

Then, when I visit: myajax/add/5/6/7?debug_request=1 I see 404 Page not found with the following debug info:

Debug (line 250 of RequestHandler.php): Testing 'myajax/add/$a!/$b!/$c' with 'add/5/6/7' on AjaxPage_Controller
Debug (line 250 of RequestHandler.php): Testing '$Action//$ID/$OtherID' with 'add/5/6/7' on AjaxPage_Controller
Debug (line 258 of RequestHandler.php): Rule '$Action//$ID/$OtherID' matched to action 'handleAction' on AjaxPage_Controller. Latest request params: array ( 'Action' => 'add', 'ID' => '5', 'OtherID' => '6', )
{"result":18}
Debug (line 250 of RequestHandler.php): Testing '$Action//$ID/$OtherID' with '' on ErrorPage_Controller
Debug (line 258 of RequestHandler.php): Rule '$Action//$ID/$OtherID' matched to action 'handleAction' on ErrorPage_Controller. Latest request params: array ( 'Action' => NULL, 'ID' => NULL, 'OtherID' => NULL, )
Debug (line 184 of RequestHandler.php): Action not set; using default action method name 'index'

As you see - in the middle of the debug info there is a correct result being echoed, despite of which framework still seeks fallback and produces 404.

Does anyone know what is happening here (ie. what kind of a mistake I make here)? I think I have exploited all combinations of the shift point // in the patterns. Each attempt was followed by dev/build and flush

È stato utile?

Soluzione

The reason why it's falling back to a 404 page is because the $Action//$ID/$OtherID only matches the add/5/6, so the 7 still needs to be matched.

As for why your url_handler isn't being matched, that comes down to what the shift point does. I'm going to use your code to try to explain it for you. Basically, the left of the shift point gets consumed by the match and the right is available for the next controller to try using.

The URL myajax/add/5/6/7 first gets sent to the Director. Here it matches the myajax//$action/$a/$b/$c, with $action = "add", $a = "5", $b = "6" and $c = "7", with nothing left to be matched.

As the shift point is directly after myajax, when passing control off to the AjaxPage_Controller, only parts to the right of myajax are sent along for further matching. So AjaxPage_Controller gets given add/5/6/7 to match.

This doesn't match myajax/add/$a/$b/$c as it doesn't start with a literal myajax string, so the $Action//$ID/$OtherID handler on the RequestHandler class is tried. This matches and sets $Action = "add", $ID = "5" and $OtherID = "6", with the 7 left over.

The add action is then run (you can see {"result":18} in your debug output) and returns nothing. Since it returns nothing, there's nothing to try matching the 7 against, so a 404 is generated as the URL hasn't been entirely processed by the last controller.

As to how to fix your code, I would change the myajax/add/$a/$b/$c url handler to add//$a/$b/$c, as the myajax has already been consumed and it allows for $a, $b and $c to all be optional.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top