0

Imagine I have a URL that loads a controller if the name matches (Ignoring any security issues with this at the moment hehe)

    public function Load( $controller, $action = "Index" )
    {                                             
        require_once( "Controllers/" . $controller . "Controller.php" );
        $controllerName = $controller . "Controller";  
        $loadedController = new $controllerName();
        $actionName = "ActionResult_" . $action;
        $loadedController->$actionName();
    }

Now imagine I want a log in form to send its $_POST details as parameters of the receiving controller launched above:

<?php
    class ExcelUploadController extends Controller
    {
        public function ActionResult_Login( $username = NULL, $password = NULL )
        {
            // The parameters need to be mapped to the $_POST parameters names probably from the Load method somewhere and pumped in to the $loadedController->$actionName();
            $post_username = $username;
            $post_password = $password;
            $this->ReturnView( "ExcelUpload/Index" );   
        }
    }
?>

But also so that it does not matter what order the parameters are declared, it matches the parameter in the function based on the $_POST key.

How might I go about doing this, any ideas?

So to clarify if this doesn't make sense.. the method might look something like this:

    public function Load( $controller, $action = "Index" )
    {                                             
        require_once( "Controllers/" . $controller . "Controller.php" );
        $controllerName = $controller . "Controller";  
        $loadedController = new $controllerName();

        $actionName = "ActionResult_" . $action;

        $checkIfPostData = $_POST;
        if( isset( $checkIfPostData ) )
        {
            // Do some funky wang to map the following $loadedController->$actionName();
            // with the username and password or any other $_POST keys so that in the calling method, I can grab hold of the $_POST values

        }

        $loadedController->$actionName();
    }
tereško
  • 58,060
  • 25
  • 98
  • 150
Jimmyt1988
  • 20,466
  • 41
  • 133
  • 233
  • A method I use is to pass an associative array as a single argument and add safeguard conditions to match keys. – Ian Brindley Oct 21 '13 at 15:41
  • Within the receiving method you mean? Any examples dude? – Jimmyt1988 Oct 21 '13 at 15:44
  • 1
    @JamesT you should abstract the user input as some type of `Request` class instance, which then you pass as a single parameter to the method: `public function postLogin(Request $request){ ..` You might find [this](http://stackoverflow.com/a/13396866/727208) post *[shameless self-promotion]* somewhat useful. – tereško Oct 22 '13 at 12:24
  • Thanks for that, it looks good and i'll read about it when I get back home! – Jimmyt1988 Oct 22 '13 at 12:32

2 Answers2

1

What your are looking for is call_user_func_array()

EDIT, to reply to comment : You have two options: rewrite all your function so that they accept only one array() as argument and you parse that array for values. A bit fastidious but it can be useful in some cases. Or you can request for the required argument of a function:

// This will create an object that is the definition of your object
$f = new ReflectionMethod($instance_of_object, $method_name);
$args = array();
// Loop trough params
foreach ($f->getParameters() as $param) {
    // Check if parameters is sent through POST and if it is optional or not
    if (!isset($_POST[$param->name]) && !$param->isOptional()) {
        throw new Exception("You did not provide a value for all parameters");
    }
    if (isset($_POST[$param->name])) {
        $args[] = $_POST[$param->name];
    }
    if ($param->name == 'args') {
        $args[] = $_POST;
    }
}
$result = call_user_func_array(array($instance_of_object, $method_name), $args);

That way your array will be properly constructed. You can also add some specific treatment whether a parameter is optional or not (I guess you can understand how to do it from the code I gave you ;)

Community
  • 1
  • 1
Bibear
  • 69
  • 9
  • Do you happen to know how to map the keys coming through so that regardless of which order the keys are passed, in the receiving function the variable name will suffice in matching the key to the callback function? – Jimmyt1988 Oct 21 '13 at 16:26
  • Note that instead of `$_POST` you can use `$_REQUEST` to get the contents of `$_GET` and `$_COOKIE` as well. You probably want to take into account parameters from GET requests too. – Fred Oct 23 '14 at 17:17
0

Since the data is being sent through POST you don't need to pass any parameters to your method:

class ExcelUploadController extends Controller {

    private $userName;
    private $login;

    public function ActionResult_Login() {
        $this->userName = $_POST['username'];
        $this->login = $_POST['login'];
    }
}

Don't forget to sanitize and validate the user input!

Neil Girardi
  • 4,533
  • 1
  • 28
  • 45
  • Thing is, I want them to be passed through as parameters my dear friend. This is to be a sexy little MVC framework and I want to do behind the scenes validation etc. You know how symfony and code ignite does it. Thanks though! much obliged – Jimmyt1988 Oct 21 '13 at 15:50
  • In MVC parameters are passed to action methods by parsing the URL from the $_GET superglobal array. However, this is not a $_GET request, this is a $_POST request. – Neil Girardi Oct 21 '13 at 15:58
  • call_user_func_array() seems to work a treat! with post data.. so now I have to map them too :D – Jimmyt1988 Oct 21 '13 at 16:26