質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1293閲覧

Google mapで取得した位置データをmysqlのgeometryフィールドに挿入できない

hiro-chan

総合スコア18

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2020/01/28 06:48

編集2020/01/28 06:59

phpファイルにajaxを記述して、取得したユーザ名と現在位置をset_latlng_test.phpに送り、そのユーザの位置情報を格納したmysqlにupdateする実装をしております。

漠然とですが、updateが実施されなく困っております。
何かヒントがございましたらご教示いただけると幸いです。

database.php

php

1<?php 2 3/** 4 * database_test.php 5 * @since 2018/09/18 6 */ 7function h($string) 8{ 9 return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); 10} 11 12function connect() 13{ 14 $dsn = 'mysql:host=localhost;dbname=test_login;charset=utf8mb4;'; 15 $username = 'root'; 16 $password = ''; 17 $options = [ 18 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 19 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC 20 ]; 21 $pdo = new PDO($dsn, $username, $password, $options); 22 return $pdo; 23}

main_test.php

php

1<?php 2/** 3 * main_test.php 4 * 5 * @since 2018/09/18 6 */ 7session_start(); 8 9require 'database_test.php'; 10$login_user = $_SESSION['login_user']; 11?> 12131415 <script> 16 17 $(function() { 18 $('#btn1').click(function(){ 19 var form = document.forms.myform; 20 navigator.geolocation.getCurrentPosition(initMap, error);//成功と失敗を判断 21 var hoge = `<?php echo h($login_user[user_name]); ?>`; 22 23 //緯度経度をDBに格納 24 function initMap(position) { 25 var latitude = position.coords.latitude;//緯度 26 var longitude = position.coords.longitude;//経度 27 var latlng = new google.maps.LatLng( latitude, longitude ); 28 var map = new google.maps.Map(document.getElementById('map'), { 29 zoom: 14, 30 center: latlng 31 }); 32 //マーカーの設定 33           var marker = new google.maps.Marker({ 34 position: latlng, 35 map: map, 36 icon: { 37 //url: sailboat_image, 38 scaledSize: new google.maps.Size(60, 60) 39 } 40 }); 41 function insert_latlng(){ 42 $.ajax({ 43 url: "set_latlng_test.php", 44 type: "POST", 45 datatype: "text", 46 data: { 47 "login_user" : hoge, 48 "latitude" : latitude, 49 "longitude" : longitude 50 }, 51 }).done(function(data){ 52 console.log(data); 53 console.log(hoge); 54 console.log("DB通信完了"); 55 }).fail(function(data){ 56 console.log("DB通信失敗"); 57 console.log(data); 58 }); 59 }; 60 insert_latlng(); 61 }; 62 function error() { 63 console.log("map表示でエラー発生") 64 }; 65 }); 66 }); 67 </script> 6869

set_latlng_test.php

php

1<?php 2/** 3 * main_test.php 4 * 5 * @since 2018/09/18 6 */ 7 8//print_r($_POST['ary']); 9 10 11ini_set('display_errors',1); //これ重要 12 13session_start(); 14 15require 'database_test.php'; 16//$login_user = $_SESSION['login_user']; 17$login_user = $_POST['login_user']; 18$latitude = $_POST['latitude']; 19$longitude = $_POST['longitude']; 20 21$geometry = "ST_GeomFromText('POINT(" + (string)$longitude + " " + (string)$latitude + ")')"; 22 23$pdo = connect(); 24$stmt2 = $pdo->prepare("UPDATE User3 SET latlng = ? WHERE user_name = ?"); 25$params_add_latlng = []; 26$params_add_latlng[] = $geometry; 27$params_add_latlng[] = $login_user; 28// SQL実行 29$stmt2->execute($params_add_latlng); 30 31?>

mysqlのデータベース test_login
尚、latlngフィールドはユーザでログインした際に、適当な位置情報を格納しております。

mysql

1mysql> select * from User3; 2+----+------------+--------------------------------------------------------------+---------------------------+ 3| id | user_name | password | latlng | 4+----+------------+--------------------------------------------------------------+---------------------------+ 5| 1 | ashial.Ltd | pass | `? fxa@伀{摶攸@ | 6| 2 | minase | $2y$10$Yui/2sBgOTAKO9O3Qr/n2e2U69z9mopEu73iNAx0RYSuolEPIp9Om | `? fxa@伀{摶攸@ | 7| 3 | uchida | $2y$10$.lb2b7InyUYQ2yzfCr1AD.8aKb9y5rN2dRQQFb2jEEjSiXC4vhL8y | `? fxa@伀{摶攸@ | 8| 4 | yamada | $2y$10$easFTwRXddoVepx4ojct8u.7Fdzljv47XfDBWXZAFA1Mj1/VUvbVq | `? fxa@伀{摶攸@ | 9+----+------------+--------------------------------------------------------------+---------------------------+ 104 rows in set (0.00 sec)

mysql

1mysql> SELECT id, user_name, ST_X(latlng) as lng, ST_Y(latlng) as lat, ST_AsText(latlng) as geomtext FROM User3; 2+----+------------+------------+-----------+-----------------------------+ 3| id | user_name | lng | lat | geomtext | 4+----+------------+------------+-----------+-----------------------------+ 5| 1 | ashial.Ltd | 139.762522 | 35.706752 | POINT(139.762522 35.706752) | 6| 2 | minase | 139.762522 | 35.706752 | POINT(139.762522 35.706752) | 7| 3 | uchida | 139.762522 | 35.706752 | POINT(139.762522 35.706752) | 8| 4 | yamada | 139.762522 | 35.706752 | POINT(139.762522 35.706752) | 9+----+------------+------------+-----------+-----------------------------+ 104 rows in set (0.01 sec)

イメージ説明
おそらく以下の箇所が怪しそうです。

php

1$geometry = "ST_GeomFromText('POINT(" + (string)$longitude + " " + (string)$latitude + ")')"; 2$stmt2 = $pdo->prepare("UPDATE User3 SET latlng = ? WHERE user_name = ?");

■仕様説明
main_test.phpの
$login_user = $_SESSION['login_user'];
から、ログインユーザ名を取得し、
var hoge = <?php echo h($login_user[user_name]); ?>;
でhogeに格納しております。
ボタン「btn1」をクリックすると、latitudeとlongitudeが取得され、hogeと共に
insert_latlng()でset_latlng_test.phpへPOSTされます。
set_latlng_test.phpで受け取ったhogeのユーザ名のレコードの位置情報をupdateするようにしています。
chromeのデバッグツールで、POSTによりset_latlng_test.phpへhoge、latitude、longitudeが
送信されたことは確認済です。

尚、tableはこのように作りました。

CREATE TABLE User3 (
id INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'AI',
user_name VARCHAR(64) NOT NULL DEFAULT '' COMMENT '氏名',
password VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'パスワード',
latlng geometry NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY user_name (user_name),
SPATIAL KEY spot_latlng_index (latlng)
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

長文で読みづらいかと思いますが、何卒ご協力くださいますようよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

php

1$geometry = "ST_GeomFromText('POINT(" . (string)$longitude . " " . (string)$latitude . ")')";

って話だったりしない?


もしかすると

php

1$pdo = connect(); 2$stmt2 = $pdo->prepare("UPDATE User3 SET latlng = ST_GeomFromText('POINT(:lng :lan)') WHERE user_name = :user"); 3$stmt2->bindValue(':lng', $longitude, PDO::PARAM_INT); 4$stmt2->bindValue(':lan', $latitude, PDO::PARAM_INT); 5$stmt2->bindValue(':user', $login_user, PDO::PARAM_STR); 6// SQL実行 7$stmt2->execute();

こうなんじゃないかなぁ。
(名前付きプレースホルダーに改めてみました。)

SQL文に直接POSTやGET由来の変数を展開してしまうと、
SQLインジェクション攻撃の標的になりかねないため、
上記のようなプレースホルダーを駆使した書き方を身に着けたいものです。

投稿2020/01/28 08:33

編集2020/01/29 01:38
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiro-chan

2020/01/28 08:42

ご回答ありがとうございます。 エラー内容が減り、以下のものだけになりました。 <br /> <b>Fatal error</b>: Uncaught PDOException: SQLSTATE[22003]: Numeric value out of range: 1416 Cannot get geometry object from data you send to the GEOMETRY field in /var/www/html/.vscode/DB_write_test/set_latlng_test.php:27 Stack trace: #0 /var/www/html/.vscode/DB_write_test/set_latlng_test.php(27): PDOStatement-&gt;execute(Array) #1 {main} thrown in <b>/var/www/html/.vscode/DB_write_test/set_latlng_test.php</b> on line <b>27</b><br /> 27行目は $stmt2->execute($params_add_latlng); の箇所です。
hiro-chan

2020/01/29 00:45 編集

ありがとうございます。以下のエラーに変わりました。 Uncaught PDOException: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /var/www/html/.vscode/DB_write_test/set_latlng_test.php:33 このエラーで片っ端から探してみます 33行目は $stmt2->execute(); です。 尚、バージョンは以下となります。 PHP 7.2.11 mysqld Ver 8.0.17 for Linux on x86_64 となります
退会済みユーザー

退会済みユーザー

2020/01/28 09:33

execute()で乱暴にプレースホルダー用のデータを与えずに、 bindValue()で一つ一つ丁寧に与える書き方をしているため、 execute()の引数は不要になっています。
hiro-chan

2020/01/29 01:10

ご回答ありがとうございます。 $stmt2 = $pdo->prepare("UPDATE User3 SET latlng = ST_GeomFromText('POINT($longitude $latitude)') WHERE user_name = '$login_user'"); $stmt2->execute(); にすると無事にDBのupdateができました
退会済みユーザー

退会済みユーザー

2020/01/29 01:34

prepare()で与えるSQL文で、変数を直接置くのは本末転倒です。 bindValue()でプレースホルダーを駆使しないと、POST受信したデータに意図的なものが仕込まれたら太刀打ちできません。SQLインジェクションっていうんですけどね。 セキュリティ対策の意識がお有りであれば、もうちょっと踏ん張って、プレースホルダーを駆使した方法での実現ができるようになることを望みます。
guest

0

set_latlng_test.phpを以下のように変更するとDBのupdateができました。

php

1$stmt2 = $pdo->prepare("UPDATE User3 SET latlng = ST_GeomFromText('POINT($longitude $latitude)') WHERE user_name = '$login_user'"); 2$stmt2->execute();

投稿2020/01/29 01:01

hiro-chan

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問