Ré,
J'ai la requête suivante:
$property =
Property::select(
DB::raw("title, lat, lng, (
3959 * acos(
cos( radians(:lat) ) *
cos( radians( lat ) ) *
cos( radians( lng ) - radians(:lng) ) +
sin( radians(:lat) ) *
sin( radians( lat ) )
)
) AS distance", ["lat" => $lat, "lng" => $lng, "lat" => $lat])
)
->having("distance", "<", $radius)
->orderBy("distance")
->take(20)
->get();
Cela ne fonctionne pas: Invalid parameter number: mixed named and positional parameters
.
Est-ce que quelqu'un connaît une astuce ou une solution de contournement (je peux évidemment écrire la requête complète mais préfère utiliser le générateur couramment).
OK, après quelques expériences, voici la solution que je propose:
$property =
Property::select(
DB::raw("title, lat, lng, (
3959 * acos(
cos( radians( ? ) ) *
cos( radians( lat ) ) *
cos( radians( lng ) - radians(?) ) +
sin( radians( ? ) ) *
sin( radians( lat ) )
)
) AS distance")
)
->having("distance", "<", "?")
->orderBy("distance")
->take(20)
->setBindings([$lat, $lng, $lat, $radius])
->get();
setBindings
doit être appelé sur la requête. Je souhaite que cela a été documenté!
Ancienne question, mais si nous devons répéter une variable, nous devons modifier sa valeur de clé dans le tableau de liaisons.
$property = Property::select(
DB::raw("title, lat, lng, ( 3959 * acos( cos( radians(:lat) ) *
cos( radians( lat ) ) * cos( radians( lng ) - radians(:lng) ) +
sin(radians(:lat_i) ) * sin( radians( lat ) ) ) ) AS distance"),
["lat" => $lat, "lng" => $lng, "lat_i" => $lat]);
C'est assez.
pourquoi pas?
$latitude = $request->input('latitude', '44.4562319000');
$longitude = $request->input('longitude', '26.1003480000');
$radius = 1000000;
$locations = Locations::selectRaw("id, name, address, latitude, longitude, image_path, rating, city_id, created_at, active,
( 6371 * acos( cos( radians(?) ) *
cos( radians( latitude ) )
* cos( radians( longitude ) - radians(?)
) + sin( radians(?) ) *
sin( radians( latitude ) ) )
) AS distance", [$latitude, $longitude, $latitude])
->where('active', '1')
->having("distance", "<", $radius)
->orderBy("distance")
->get();
J'ai rencontré le même problème tout récemment et la réponse se trouve dans le message d'erreur mixed named and positional parameters
. Dans votre cas, le :lat
et le :lng
sont des paramètres nommés alors que vous avez $radius
comme positionnel. Donc, une solution possible à votre problème consiste à utiliser havingRaw()
et à appliquer les paramètres nommés.
--havingRaw('distance < :radius', ['radius' => $radius])
J'ai porté la recherche à proximité de Doctrine v1 à Laravel, jetez-y un œil ici.
Ajoutez simplement le trait Geographical
au modèle pour pouvoir ensuite:
$model->newDistanceQuery($request->query('lat'), $request->query('lon'))->orderBy('miles', 'asc')->get();
Cela fonctionne en utilisant selectRaw avec des liaisons comme ceci:
$sql = "((ACOS(SIN(? * PI() / 180) * SIN(" . $latName . " * PI() / 180) + COS(? * PI() / 180) * COS(" . $latName . " * PI() / 180) * COS((? - " . $lonName . ") * PI() / 180)) * 180 / PI()) * 60 * ?) as " . $unit;
if($kilometers){
$query->selectRaw($sql, [$lat, $lat, $lon, 1.1515 * 1.609344]);
}
else{
// miles
$query->selectRaw($sql, [$lat, $lat, $lon, 1.1515]);
}
$select = <<<SQL
title,
lat,
lng,
(3959*acos(cos(radians( ? ))*cos(radians(lat))*cos(radians(lng)-radians( ? ))+sin(radians( ? ))*sin(radians(lat)))) AS distance
SQL;
$property = Property::selectRaw($select, [$lat, $lng, $lat])
->having('distance', '<', $radius)
->orderBy('distance')
->take(20)->get();