问题
I want to collect the unique amount of visitors on my website and store them in a database. Even when someone without an account accesses the website the visitor count goes up. How can I accomplish this?
I know I have to fetch the users IP address or something along those lines but I don't know how to fetch the IP address of a user without an account when the page loads
Currently I have this DB table
Visitors
- ip
- date_visited
Route
Route::get('/', function () {
$ip = Request::ip();
return view('welcome', compact('ip'));
});
回答1:
Try to use Request::ip()
to get the ip;
$ip = Request::ip();
For Laravel 5.4 +:
$ip = $request->ip();
// or
$ip = request()->ip();
And I think you can use middleware and redis to calculate this count, this will reduce the db's pressure.
回答2:
One good solution in this case is to create an middleware
that tracks all your users. We can put any kind of business logic in the middleware
.
<?php
namespace App\Http\Middleware;
use Closure;
class TrackUser
{
public function handle($request, Closure $next)
{
/* You can store your user data with model, db or whatever...
Here I use a repository that contains all my model queries. */
$repository = resolve('App\Repositories\TrackUserRepository');
$repository->addUser([
'ip' => request()->ip(),
'date' => now(),
]);
return $next($request);
}
}
Then add the middleware
to App\Kernel.php
:
- Add it to
$middleware
if you want it to be an global middleware that runs on every request. - Add it to
$middlewareGroups
if you want it to only run on everyweb
-route. - Add it to
$routeMiddleware
if you want to specify inroutes/web.php
when the middleware should apply.
You should also consider moving any logic in the middleware
inside a "try
catch
"-statement, it minimized the risk that your user gets halted by any errors caused be the "tracking"-code.
try {
$repository = resolve('App\Repositories\TrackUserRepository');
$repository->addUser([
'ip' => request()->ip(),
'date' => now(),
]);
} catch (\Exception $e) {
// Do nothing or maybe log error
}
return $next($request);
回答3:
It's better to use combination of user_agent
and ip
to have more accurate results, many user may have the same IP but usually have different user agents:
request()->userAgent();
request()->ip();
Alternatively if you're using web
middleware (not api
), Laravel starts a session for each client. You can change your session driver and use database
instead of default file
.
This way Laravel will store a record for each client on sessions
table containing all info you need and even more:
Schema::create('sessions', function ($table) {
$table->string('id')->unique();
$table->unsignedInteger('user_id')->nullable();
$table->string('ip_address', 45)->nullable();
$table->text('user_agent')->nullable();
$table->text('payload');
$table->integer('last_activity');
});
As you can see, there is ip_address
, user_agent
and last_activity
. The user_id
will be null
for guest users and has value for authenticated users.
See Laravel docs to config your session driver to use database
.
回答4:
As @tsaiKoga mentioned how you will get ip address.
create a new table for for ip address and their visits timestamp .
check IF IP does not exists OR time()-saved_timestamp > 60*60*24
(for 1 day) ,edit the IP's timestamp to time() (means now) and increase your view one else do nothing!
Moreover, You can get IP by $_SERVER['REMOTE_ADDR']
More ways for getting IP is mentioned here. https://stackoverflow.com/a/54325153/2667307
Reviewed the comment which returns 127.0.0.1
Please try:-
request()->server('SERVER_ADDR');
OR you may use
$_SERVER['SERVER_ADDR'];
OR
$_SERVER['REMOTE_ADDR']
来源:https://stackoverflow.com/questions/59896017/laravel-get-website-unique-visitor-count