0

I'm searching for the best supported/secure approach to capture visitors Ip address.

At the moment I'm able to save visitor Ip by the following approach

Route from which call is made.

Route::get('/','VisitorController@multidisplay');

In multidisplay function, I'm calling another controller to capture and store Visitor Ip like->

 public function multidisplay()
    {   
        //calling log visitor controller
        app()->call('App\Http\Controllers\LogVisitIpController@store');


        return view('welcome')
        ->with('sliderimg', Sliderimage::all())
        ->with('postimg', PostImage::orderBy('created_at', 'desc')->take(3)->get())
        ;

    }

and finally, the actual function to store visitor's Ip in LogVisitIpController

public function store(Request $request)
    {
        $bla=$this->getIp();
        $myvisitor = new LogVisitIp();
        $myvisitor->visitorIp=$bla;
        $myvisitor->save();
    }

Now i have two question.

  1. Is it ok to use a controller like that in another controller?

  2. Should I use another approach to capture visitor ip using one controller?

Note: VisitorController is used to save request from the visitors in DB and send mail, I can collect IP and pass it from the visitor's request but my aim is to capture Ip as soon as the visitor open my website or make a ping request.

Syed Aqeel
  • 19
  • 1
  • 4
  • Do you have any login system or its for anyone who will visit your website's particular module ? – Gopal Panadi Mar 29 '19 at 13:02
  • No, it's a one-page website. A visitor can only send a request as a guest. – Syed Aqeel Mar 29 '19 at 13:06
  • Then its fine. You can use any way for storing visitor's IP the way you want. You have used a pretty nice approach using calling model for a single project. – Gopal Panadi Mar 29 '19 at 13:11
  • It's a bad approach to call a function from one controller in any other controller according to https://stackoverflow.com/a/30365349 I'm calling contranLogVisitIpController@store inside VisitorController@multidisplay. I want to use an eloquent model as middle man b/w two controllers or any other better approach like php trait. – Syed Aqeel Mar 29 '19 at 13:16

2 Answers2

2

Even if your code works actually, i would not recommend using that technique. Here is what you should do.

Define a class that is used only to save the ips. you will move your code that really logs the ip here.

Class VisitIpLoggerService
{
    public function storeIp(Request $request)
    {
        $myvisitor = new LogVisitIp();
        $myvisitor->visitorIp=$request->ip();
        $myvisitor->save();
    }
}

Then you will inject that service into your controller's function and call the function like that. That way your code will be easier to maintain.

public function multidisplay(Request $request, VisitIpLoggerService $ipLogger)
{   
    //just call the service
    $ipLogger->storeIp($request);
elfif
  • 1,837
  • 17
  • 23
  • 3
    I would go even further and create a route middleware – namelivia Mar 29 '19 at 13:34
  • Agreed. But i wanted to keep it simple in a way – elfif Mar 29 '19 at 14:23
  • LogVisitIpController is only used to capture IP address, the only difference b/w your approach and my approach is the way function store/storeip called/accessed in VisitorController. However, your way of calling looks clean. Also if used Laravel's built-in method to capture IP address, how do I find out if its the real IP aka not a proxy. – Syed Aqeel Mar 29 '19 at 22:39
  • Just tested your approach. It doesn't worked out for me, it throws an exception " BadMethodCallException Call to undefined method App\LogVisitIp::store()" . – Syed Aqeel Mar 29 '19 at 22:54
  • @SyedAqeel i can't help with no code to inspect, post it somewhere and i would try to take a look... – elfif Apr 01 '19 at 13:15
0

add this in your controller...

'ip_address_variable' => \Request::ip();

For your case,

public function store(Request $request)
    {
        $bla=$this->getIp();
        $myvisitor = new LogVisitIp();
        $myvisitor->visitorIp=$request->ip();
        $myvisitor->save();
    }