Richard
Richard

Reputation: 1590

PHP call_user_func alternative

I am looking for a pretty equivalent in PHP to its function call_user_func. The problem I am encountering with this function is that it does not go into an "object mode". By this, I mean I cannot use $this and other stuff in the class, so pretty much in two words: not oop.

I need this basically as I am dealing with the requested url, parsing it, and seeing if everything is ok and so on, and then doing the following lines:

call_user_func(array(ucfirst( $controller . "Controller" ),  '_initAction'), $param);       
call_user_func(array(ucfirst( $controller . "Controller" ), $action . 'Action'), $param);

as I want to dynamically call the "Controller" and its actions. But I cannot use $this in the $action methods as it is not OOP.

Here the message I get:

Fatal error: Using $this when not in object context in E:\htdocs\wit\application\controller\InformationController.php on line 6

So I hope that somebody could help me.

Could you also tell me if I am approaching this problem in a wrong way?

PS: Please don't recommend me any MVC frameworks that take care of this stuff. I like Zend, but sometimes, its just too heavy :(( I need a lightweight setup for this.

Upvotes: 4

Views: 4970

Answers (5)

Dmitry Leiko
Dmitry Leiko

Reputation: 4412

Also you can try this way:

$controller = new $class();

$method = $action . 'Action';

[$controller, $method]()

Upvotes: 0

Richard
Richard

Reputation: 1590

$view       =   View::getInstance( $config['view'] );
$err        =   new ErrorController(array(), $view);

//load the class and its method
//pass the params to it 
$class      =   ucfirst( $controller . "Controller" );
if ( class_exists($class) )
{
    $con    =   new $class($param, $view);  
    $act    =   $action . 'Action';
    if ( method_exists($con, $act)  )
    {
        $con->$act();

    }
    else
    {
        $view->setController("error");
        $view->setAction('index');
        $err->indexAction();
    }
}
else
{
    $view->setController("error");
    $view->setAction('index');
    $err->indexAction();
}

So this is my solution how i solved my problem. it is based on @AlexAtNet solution and parts of glue that was recommend to me by @Sean

Upvotes: 0

Dominic Barnes
Dominic Barnes

Reputation: 28439

If I completely miss the point of your question, I'm sorry. It sounds to me like you're trying to call an object method using call_user_func. You can do that, you just pass an array with the object as the first index, and the string name of the method as the second index.

For example, say you have your controller "IndexController" with "index" as your action/method.

class IndexController {
    public function index() {
        // $this available here
    }
}

$controller = new IndexController();

// if you know your parameters all ahead of time
call_user_func(array($controller, 'index'), $param1, $param2);

// if you want to pass an unknown number of params
call_user_func_array(array($controller, 'index'), $params);

Upvotes: 0

Alex Netkachov
Alex Netkachov

Reputation: 13562

You can call the object method by passing object in first element of the callback:

$class = ucfirst($controller . "Controller");
$controller = new $class();
call_user_func(array($controller,  $action . 'Action'), $param);

Actually, you can even use

$controller = new $class();
$controller->{$action . 'Action'}();

Upvotes: 11

Sean
Sean

Reputation: 681

Take a look at how Glue calls user defined functions. It may point you in the right direction, since users define classes to handle routes.

<?php
require_once('glue.php');
$urls = array(
    '/' => 'index'
);
class index {
    function GET() {
        echo "Hello, World!";
    }
}
glue::stick($urls);
?>

Upvotes: 0

Related Questions