Call Route Function with Parameters in another function

I am working on slim v4 application i have a one route with the function

example:

$group->get('/greeting', '\V1:greeting');
function greeting($request,$response,$args,$message){
    //execution code
}

i want to call this same function in another function with only one parameter

example

function hello($message){
   data= this->greeting($message);
   //execution code
}

when we call the greeting function this ways it throws a error as

"Call to a member function getBody()

because of less number of parameter on call , we cannot pass the request,response parameter while call,

so how we can call the route function within another function
can any one help me to solve this

if there is any more doubt in question feel free to ask

Is the greeting and hello function a ā€œnormalā€ function or a class method?

To handle shared logic, I would recommend implementing invokable classes (single action controller) in combination with service classes for the business logic.

For example:

$group->get('/greeting', \App\Action\ExampleGroup\GreetingAction::class);

The action class just needs to implement the

public function __invoke($request, $response, $args)

method and returns the new response object.

greeting and hello are normal function

instead of this can we pass the parameters as null for request and response when it is called from another function

pass arguments as null which are not required

function hello($message){
   data= this->greeting(null,null,$message);
   //execution code
}

when i tried with this it did not return any error
whether it is good way?

Generally, $this is used inside a class to access (non-static) members of the current object.
I would suggest to use classes (for everything) instead.

@odan How we can pass the $request and $response parameters as optional parameters in slim v4 is this possible in slim v4

This is possible, but quite complex to set up.

By default, Slim controllers have a strict signature: $request, $response, $args.
As far as I know, the php-di/slim-bridge provides such a feature you are looking for. But I had a lot of troubles to get it working (so I do not use it anymore).

You could also implement your own InvocationStrategyInterface class.
The new RequestResponseNamedArgs class is such an example. But it does only use named parameters (PHP 8) for the route arguments, so you may have to implement your own class to make everything dynamic.

In the long run, all this complexity is not needed. Better keep it simple and use the default signature.

1 Like

@odan Thanks for the info , when calling the route function inside another function it shows as expected more arguments error because we cannot pass $request $response params while calling inside another function is there any other way to resolve this

I would try to solve it on another layer. Either just redirect to the other URL or create a service layer to handle the shared business logic.

1 Like

@odan Thanks odan , having another doubt what is replacement of $request->getBody()
in slim v4 function without $request and $resposne parameters

Not sure what you mean. Please create a new question and add more details.

@odan in slim v2 we get the body using below query

$app = new \Slim\Slim();
$body = $app->request->getBody();

but in slim v4 function how we can get the body in non route function
in non route function the $request is return as undefined variable

  function xyz(param1 , param2,param3)
        {      
            $json_request = json_decode($request->getBody());
        }

Now, the Slim 4 Body Parsing Middleware does that for you.

You can read the parsed Json from the HTTP request body using the $request->getParsedBody() method.

$data = $request->getParsedBody();

Please check the documentation: Body Parsing Middleware - Slim Framework

1 Like

@odan i am working updating slim 2 to slim 4 i am getting Call to a member function get() on null error when i call this method $Redis = $request->container->get('Redis');
can you help with what will be replace of this in slim 4

For further assistance regarding the migration to Slim 4, I would appreciate if you would consult me.

@odan mostly updated all having only two doubts which was

  1. what will be replacement of $Redis = $request->container->get('Redis'); this container method in slim 4
  2. how we can resolve the class not found error in slim 4
    here i attached the compoer.json file code
{
    "name": "slim/framework-standard-edition",
    "description": "The \"Slim Standard Edition\" distribution",
    "autoload": {
        "psr-0": { "": "app/" },
    },
    "require": {
        "slim/slim": "4.*",
        "predis/predis": "1.0.3",
        "symfony/event-dispatcher" : "~2.7",
        "symfony/console": "v4.0.2",
        "slim/psr7": "1.5",
        "php-di/php-di": "6.3.0"
    },
    "require-dev": {
        "phpunit/phpunit": "4.*"
    }

}

can you help me with the answers for this

Generally I would try to avoid ā€œmagic stringsā€ for DI container definitions. Instead try to use FQCN instead, e.g. Predis\Client::class instead of just ā€˜Redisā€™.

Second thing is that the DI container helps you to use ā€œcompositionā€. So you do not need to use the DI $container object directly anymore (except within the DI container definition itself).

So the ā€œreplacementā€ would be to write a class constructor instead of using the DI container instance.
For example:

use Predis\Client;

final class Demo
{
    private Client $client;

    public function _construct(Client $client)
    {
        $this->client = $client;
    }

  // ...
}

Also check your composer.json ā€œautoloadā€ settings. Please note, as of 2014-10-21 the PSR-0 has been marked as deprecated. PSR-4 is now the recommended way to go.

This should then also solve the ā€œclass not found errorā€.

1 Like