Call POST Method from Another Controller in Laravel

Preamble

Sometimes when developing systems, I sometimes come across cases that require calling a post method from another function in Laravel. These functions may or may not be in the same controller / class. Previously when handling these cases, my handling was rudimentary and handling this case made my code very confusing and made it difficult for others to read the code if I didn’t really understand the purpose of the paragraph. my code. After a while of researching, I also found a better way to handle this case, so today I will introduce you how to handle it when you have to call a post method from another function in laravel. .

Problem

Suppose you have a very complex method that takes one input parameter Illuminate\Http\Request $request. This method will normally be called from a form or an AJAX function. So how can you call that method from another method - even in another class?

To make the problem easier to imagine, I will go into specific code. The following is a very complex method that we initialize, and suppose we don’t want to have to fix it at all.

The Very Complex Method

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class VeryComplexController extends Controller
{
    public function __contruct()
    {
        //do constructor stuff
    }

    public function veryComplexMethod(Request $request)
    {
        //wow there is some very complex stuff in here
    }
}

VeryComplexController.php

Meanwhile we have another method that we want to call here veryComplexMethod()

The Simple Method

<?php

namespace App\Http\Controllers;

class SimpleController extends Controller
{
    public function __construct()
    {
        //do constructor stuff...
    }

    public function simpleMethod()
    {
        //we want to call veryComplexMethod() from here... but how?
    }
}

SimpleController.php

Simple handling

This is the way I used to, that we created a “Calling” function, copy the entire process code veryComplexMethodto another function that we can call from the current function. In essence, you will create a function to retrieve data from the post request and then call another function - this function is actually where the processing is done - by passing parameters from Request to. So now when it veryComplexMethodis called, it will extract the data from the Request and pass it on veryComplexMethodProcessing- this is the actual processing function.

<?php

public function veryComplexMethod(Request $request)
{
    $data = $request->all();
    return $this->veryComplexMethodProcessing($data);
}

public function veryComplexMethodProcessing($data)
{
    //process data....
    return $answer;
}

SolutionController.php

Advantages:

  • Don’t Repeat Yourself: You are following the DRY principle, you don’t need to rewrite any code.

Defect:

  • Refactor: You have to fix something and change some functions for your code to work.
  • Inconsistencies: Not all of your methods need this, which means that eventually you will have some functions that use the calling function while some don’t.
  • In case you have consistency and all your post methods use the “calling” function, you will increase the number of functions you have to handle.

Better handling

To handle the above drawbacks, create a class that can make a request that can excute any method we want and then simply pass that Request as a parameter. In other words, we will try to imitate what a form or an AJAX will do.

For example, I will create a class PostCaller

<?php

namespace App\Http;

class PostCaller
{ 
    /**
     * $class is the class where the method you will be calling is located.
     */
    public $class;

    /**
     * $method is the name of the method you want to call that exists inside of $class.
     */
    public $method;

    /**
     * $requestClass is the type of Request. You can use custom requests 
     * and don't have to use Illuminate\Http\Request.
     */
    public $requestClass;

    /**
     * $data is the data you are passing into the method. It should be an array with indexes
     * and values. No CSRF token is required.
     */
    public $data;

    /**
     * $requestSending is the actual request object you will be sending. You will attach the data to this.
     */
    public $requestSending;

    public function __construct($class, $method, $requestClass, $data)
    {
        //assign parameter values to class object
        $this->class = $class;
        $this->method = $method;
        $this->requestClass = $requestClass;
        $this->data = $data;

        //instantiate the request object and replace the data.
        $this->requestSending = new $this->requestClass();
        $this->requestSending->replace($this->data);
    }

    /**
     * Execute the method and return the response.
     * @return mixed
     */
    public function call()
    {
        $response = app($this->class)->{$this->method}($this->requestClass::createFromBase($this->requestSending));

        return $response;
    }
}

PostCaller.php

In this class we will define some parameters and pass in constructand finally the callfunction to handle calling a function and receiving a response.

This solution solves a number of problems that were not resolved previously.

  • First, it becomes a generic call function that works with any method that accepts a Request as input - in any class.
  • Second, it actually sends one Requestas a parameter, which may or may not matter to the function you are calling.
  • Third, you don’t need to refactor the method you’re trying to call. In the previous way we had to convert the word processing part Requestto the “calling” function and then pass the data over.

Let’s explain a bit about the method callofPostcaller

app($this->class)

Here we are creating a Laravel service container instance and binding it to the class you are choosing. There are several advantages to using a service container this way:

  • You do not need to use keywords new
  • It returns an instance of the class that you can use in just one line of code
  • You do not need to import class namespace into the scope of PostCallerthe keyworduse

Add to that the other benefits of service containers .

{$this->method}()

Call a specific method inside the class that we passed in. Using the syntax {}, we can automatically call a method. So, if our class is TestingClass::classand method is runTest, this will correspond to app(TestingClass::class)->{'runTest'}().

$this->requestClass::createFromBase($this->requestSending)

We create an Illuminate request from the Symfony Instance. We can pass in requestClass- maybe one, Illuminate\Http\Requestbut it can also be a custom FormRequest

return $response

We can then return any response that method returns to us. You can then use this response to process the returned data.

Finally, how to use. This is an example of usagePossCaller

<?php

namespace App\Http\Controllers;

use App\Http\PostCaller;
use Illuminate\Http\Request;
use App\Http\Controllers\VeryComplexController;

class SimpleController extends Controller
{
    public function __construct()
    {
        //do constructor stuff...
    }

    public function simpleMethod()
    {
        //we decide we would like to call veryComplexMethod() from here using PostCaller
        $post = new PostCaller(
            VeryComplexController::class,
            'veryComplexMethod',
            Request::class,
            [
                'Field1' => 'something',
                'Field2' => 'something else',
            ]
        );
        $response = $post->call();
        //do something with the response.
    }
}

SimpleController.php

summary

The above is a way we can call a method to get parameters Requestfrom another method in Laravel. There may be many other ways to do this, the above is just one of the ways I learn. Hopefully this approach can help you a little on your way to becoming a programmer with your mind and reach.

#php #laravel

Call POST Method from Another Controller in Laravel
202.55 GEEK