答え
'latitude' => ['required','numeric','regex:/^[-]?((([0-8]?[0-9])(\.[0-9]{6}))|90(\.0{6})?)$/'], // 緯度
'longitude' => ['required','numeric','regex:/^[-]?(((([1][0-7][0-9])|([0-9]?[0-9]))(\.[0-9]{6}))|180(\.0{6})?)$/'], // 経度
ヒット例
上記のバリデーションで、以下の文字列にヒットするはず
緯度 -89.999999 ~ 89.999999 または -90.000000 または 90.000000
経度 -179.999999 ~ 179.999999 または -180.000000 または 180.000000
geometry型ではなく、double precision型。うちではそういう方針だったので。
エラー例
次のような文字列を入力すると弾かれれば期待動作。
緯度 -99.999999, 90, 90.00, 90.000001, 89.999999999999
経度 -999.999999, 180, 180.00, 180.000001, 179.9999999999
ポイント
- バリデーションを配列にしていること
'latitude' => [], // ←これ。[]
これがないと、「preg_match(): No ending delimiter '/' found」みたいなエラーが出るはず。
型の作り方
なお、double precision型はマイグレーションファイルに次のように記述することで生成できる
$table->float('latitude')->nullable();
$table->float('longitude')->nullable();
今回、マップ機能を実装することになり、Google Map APIを使うことになったのでメモ。
追記:Viewで小数点以下を表示させる
上記のバリデーションにより、緯度経度の入力が可能にはなったが、
小数点以下が全て0の場合(90.000000)は0が省略されてしまう(90で表示される)。
その状態で何もせず登録しようとすれば、バリデーションに引っかかってしまうので、小数点以下6ケタも表示されるように修正する
Modelを修正
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Tests extends Model
{
public function getLatitudeAttribute($latitude)
{
return $this->attributes['latitude'] = sprintf('%s', number_format($latitude, 6));
}
public function getLongitudeAttribute($longitude)
{
return $this->attributes['longitude'] = sprintf('%s', number_format($longitude, 6));
}
}
関数名は必ず「get~~Attribute」にすること。
~~の部分は必ず大文字で始める。区切り文字も大文字にする。
「hoge_hoge」とかならgetHogeHogeAttribute($hoge)になる。
この小数点以下の表示はこのモデルを使用する全てのViewで表示されるようになる。