
اللغات : Laravel
كيفية الحصول على موقع المستخدم من عنوان IP في Laravel
تعلم ثلاث طرق للحصول على مدينة، بلد، إحداثيات، والمنطقة الزمنية للزائر عبر عنوان الـ IP في Laravel:
- الطريقة الأولى باستخدام حزمة جاهزة
- الطريقة الثانية باستخدام استدعاء HTTP مباشر مع API
لماذا نحتاج إلى تحديد الموقع عبر IP؟
- تخصيص المحتوى والعملة حسب الدولة.
- التحليلات الجغرافية وتحديد القيود حسب الموقع.
- الامتثال (مثل إظهار إشعارات الخصوصية حسب المنطقة).
الطريقة 1: باستخدام الحزمة stevebauman/location
التثبيت
composer require stevebauman/location
php artisan vendor:publish --provider="Stevebauman\Location\LocationServiceProvider"
إنشاء Controller باسم LocationController
php artisan make:controller LocationController
الكود داخل الـ Controller
// app/Http/Controllers/LocationController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Stevebauman\Location\Facades\Location;
class LocationController extends Controller
{
public function approach1(Request $request){
$ip = $request->ip();
// أو
// $ip = $_SERVER['REMOTE_ADDR'];
// ملاحظة: Location::get($ip) يعمل على السيرفر وليس على localhost
$location = Location::get($ip);
return view('location', [
'geo' => $location ? [
'ip' => $ip,
'country' => $location->countryName,
'countryCode' => $location->countryCode,
'region' => $location->regionName,
'city' => $location->cityName,
'postal' => $location->postalCode,
'lat' => $location->latitude,
'lon' => $location->longitude,
'timezone' => $location->timezone,
] : null,
'error'=>$location? null : 'لم نتمكن من تحديد موقعك'
]);
}
}
ملف المسارات
// routes/web.php
use App\Http\Controllers\LocationController;
Route::get('/approach1', [LocationController::class, 'approach1'])->name('approach1');
كود الـ Blade
<div class="max-w-xl mx-auto mt-8 p-6 bg-white dark:bg-gray-800 shadow rounded-xl">
<h2 class="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4">
🌍 موقع IP
</h2>
{{-- قسم الخطأ --}}
@if($error)
<div class="p-3 mb-4 text-sm text-red-800 rounded bg-red-100 dark:bg-red-200 dark:text-red-900">
{{ $error }}
</div>
@endif
{{-- قسم البيانات --}}
@if($geo)
<ul class="space-y-2 text-gray-700 dark:text-gray-200">
<li><strong>IP:</strong> {{ $geo['ip'] }}</li>
<li><strong>الدولة:</strong> {{ $geo['country'] }} ({{ $geo['countryCode'] }})</li>
<li><strong>المنطقة:</strong> {{ $geo['region'] }}</li>
<li><strong>المدينة:</strong> {{ $geo['city'] }}</li>
<li><strong>الرمز البريدي:</strong> {{ $geo['postal'] }}</li>
<li><strong>المنطقة الزمنية:</strong> {{ $geo['timezone'] }}</li>
<li><strong>خط الطول/العرض:</strong> {{ $geo['lat'] }}, {{ $geo['lon'] }}</li>
</ul>
@endif
</div>
الطريقة 2: باستخدام استدعاء HTTP + API (مثل ipapi أو IPinfo أو ip-api)
إنشاء Controller
php artisan make:controller LocationController
الكود داخل الـ Controller
// app/Http/Controllers/LocationController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Facades\Http;
class LocationController extends Controller
{
public function approach2(Request $request){
$ip = $request->ip();
try {
$res = Http::get("http://ip-api.com/json/{$ip}");
if (!$res->ok() || $res->json('status') == 'fail') {
return view('location', [
'geo' => null,
'error' => 'لم نتمكن من تحديد موقعك',
]);
}
return view('location', [
'geo' => [
'ip' => $ip,
'country' => $res->json('country'),
'countryCode' => $res->json('countryCode'),
'region' => $res->json('region'),
'city' => $res->json('city'),
'postal' => $res->json('zip'),
'lat' => $res->json('lat'),
'lon' => $res->json('lon'),
'timezone' => $res->json('timezone'),
'org' => $res->json('org'),
],
'error'=>null
]);
} catch (ConnectionException $exception) {
return view('location', [
'geo' => null,
'error' => 'خطأ غير متوقع: ' . $exception->getMessage(),
]);
}
}
}
ملف المسارات
// routes/web.php
use App\Http\Controllers\LocationController;
Route::get('/approach2', [LocationController::class, 'approach2'])->name('approach2');
كود الـ Blade
<div class="max-w-xl mx-auto mt-8 p-6 bg-white dark:bg-gray-800 shadow rounded-xl">
<h2 class="text-xl font-bold text-gray-900 dark:text-gray-100 mb-4">
🌍 موقع IP
</h2>
{{-- قسم الخطأ --}}
@if($error)
<div class="p-3 mb-4 text-sm text-red-800 rounded bg-red-100 dark:bg-red-200 dark:text-red-900">
{{ $error }}
</div>
@endif
{{-- قسم البيانات --}}
@if($geo)
<ul class="space-y-2 text-gray-700 dark:text-gray-200">
<li><strong>IP:</strong> {{ $geo['ip'] }}</li>
<li><strong>الدولة:</strong> {{ $geo['country'] }} ({{ $geo['countryCode'] }})</li>
<li><strong>المنطقة:</strong> {{ $geo['region'] }}</li>
<li><strong>المدينة:</strong> {{ $geo['city'] }}</li>
<li><strong>الرمز البريدي:</strong> {{ $geo['postal'] }}</li>
<li><strong>المنطقة الزمنية:</strong> {{ $geo['timezone'] }}</li>
@if(isset($geo['org']))
<li><strong>المؤسسة:</strong> {{ $geo['org'] }}</li>
@endif
</ul>
@endif
</div>
جدول مقارنة
المعيار | الحزمة (stevebauman/location ) | استدعاء API يدوي |
---|---|---|
سرعة الإعداد | سريع جدًا | سريع |
الدقة | حسب المزود | عالية (الخطط المدفوعة) |
القيود | حسب المزود | حسب سياسة المزود |
الخصوصية | حسب المزود | حسب المزود |
التكلفة | مجاني (قد يتم احتساب من المزود) | مجاني → مدفوع |
الصيانة | منخفضة | متوسطة–منخفضة |
برمجة سعيدة 🚀