php - How to use same controller function in other controller in laravel?

I have and function like this, and I am using this through API and send request object.

public function test(Request $request){
   //code
}

now I want to use the same function in another function like this

public function test2(){
   $id = 2;
   $this->test($id);
}

but in above I need to pass an id.

but the first function expects an argument type of request instance. How can it be done? and I can't add second argument.

Answer

Solution:

You should export your code in another function and then use a Trait in each of your controller. Therefore you will have access to the same function in two different classes.

By doing this, you can give whatever argument you want, even set defaults one without calling the controller function itself.

The official doc about Trait

Answer

Solution:

If you are not allowed to edit the method code for some reason, you can do the following:

  • Create a new Request instance.
  • Add id property to it with the value.
  • Call your method.

The Illuminate\Http\Request class has a capture() method which is like below:

/**
 * Create a new Illuminate HTTP request from server variables.
 *
 * @return static
 */
public static function capture()
{
    static::enableHttpMethodParameterOverride();

    return static::createFromBase(SymfonyRequest::createFromGlobals());
}

In your code, you would do like below:

<?php

use Illuminate\Http\Request;

class xyz{

    public function test(Request $request){
       //code
    }

    public function test2(){
       $request = Request::capture();
       $request->initialize(['id' => 2]);
       $this->test($request);
    }
}

Answer

Solution:

The best practice would be to create a third private method in the controller (or in a separate class, as you prefer) that is called by both functions:

class TestController extends Controller {
  public function test(Request $request){
   $id = $request->get('id', 0); // Extract the id from the request
   
   $this->doStuffWithId($id);
  }

  public function test2(){
   $id = 2;
   
   $this->doStuffWithId($id);
  }

  private function doStuffWithId($id) {
    // code
  }
}

Answer

Solution:

You can and should organize your shared code across multiple controllers with services. Basically create class

<?php

namespace App\Services;

class TestService
{

    public function testFunction($id)
    {
        // add your logic hear
        return 'executed';
    }
}

and in your controller inject this service and call function testFunction() like this:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\TestService;

class TestController
{ 
    protected $testService;

    public function __construct(TestService $testService)
    {
        $this->testService = $testService;
    }
    
    public function test(Request $request){
        // handle validation, get id
        $this->testService->testFunction($id);
        // return response from controller (json, view)
    }

Source