setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { // تجاهل الخطأ إذا كان قد تم تعيينه بالفعل } // 1. استقبال المدخلات باستخدام دالة filterRequest الخاصة بك $query = trim((string) filterRequest("query")); $latMin = filterRequest("lat_min"); $latMax = filterRequest("lat_max"); $lngMin = filterRequest("lng_min"); $lngMax = filterRequest("lng_max"); // 2. التحقق من المدخلات if ($query === "" || $latMin === null || $latMax === null || $lngMin === null || $lngMax === null) { jsonError("Missing required parameters: query, lat_min, lat_max, lng_min, lng_max"); exit; } // تحويل الإحداثيات إلى أرقام عشرية $latMin = (float) $latMin; $latMax = (float) $latMax; $lngMin = (float) $lngMin; $lngMax = (float) $lngMax; // 3. بناء الاستعلام الذكي (الجزء المحدّث) // تحضير كلمة البحث لوضعها في MATCH() AGAINST() // نضيف '*' لكل كلمة للبحث عن الكلمات التي تبدأ بهذا الجزء $search_terms = preg_split('/\s+/', $query, -1, PREG_SPLIT_NO_EMPTY); $search_boolean = ''; foreach ($search_terms as $term) { $search_boolean .= '+' . $term . '* '; // '+' تعني أن الكلمة يجب أن تكون موجودة } $search_boolean = trim($search_boolean); // بناء المضلع الجغرافي (Bounding Box Polygon) للفهرس المكاني $bbox_wkt = sprintf( 'POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))', $lngMin, $latMin, $lngMax, $latMin, $lngMax, $latMax, $lngMin, $latMax, $lngMin, $latMin ); // الاستعلام النهائي الذي يجمع بين البحث النصي والجغرافي $sql = " SELECT id, latitude, longitude, name, name_ar, name_en, address, category, created_at FROM `{$tableName}` WHERE -- الشرط الأول: البحث بالنص الكامل (سريع جداً) MATCH(name, name_ar, name_en, address, category) AGAINST(? IN BOOLEAN MODE) -- الشرط الثاني: البحث الجغرافي (سريع جداً) AND ST_CONTAINS(ST_GEOMFROMTEXT(?), location) LIMIT 50; -- حد أعلى للنتائج الأولية "; // 4. تنفيذ الاستعلام وإرجاع النتيجة try { $stmt = $con->prepare($sql); // ربط المتغيرات بالاستعلام بالترتيب $stmt->execute([$search_boolean, $bbox_wkt]); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); jsonSuccess($rows); } catch (PDOException $e) { // يمكنك استخدام هذا السطر أثناء التطوير لعرض الخطأ الفعلي // jsonError('DB Error: ' . $e->getMessage()); exit; // تسجيل الخطأ في سجلات الخادم للرجوع إليه لاحقاً error_log("search_places_optimized.php error: " . $e->getMessage()); jsonError("Database query error occurred"); } ?>