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

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

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

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

Q&A

解決済

2回答

7260閲覧

PHP PDOを利用してmysqlからselectする際に、たまに結果がfalseになる(エラー : Incorrect parameter count in the call to native..

ShujiYamagami

総合スコア7

MySQL

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

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

PHP

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

0グッド

0クリップ

投稿2018/03/16 01:54

編集2018/03/16 02:42

いつも拝見させていただいてます。
今回ちょっと分からない問題にあたってしまい、質問させていただきます。

物件情報に対して、検索した住所の緯度経度から半径◯km以内にある情報の検索のため、プログラムを書いています。

php5.6
mysql5x

php

1 $lat_long = get_gps_from_address($conditions['search-text']); 2 $lat = $lat_long['lat']; 3 $long = $lat_long['lng']; 4 5 # 半径値設定 6 $radius_val = 10; 7 8 # treatment id設定 9 $treatment_id = $conditions['treatment_id']; 10 11 12$select_sql = 'select cate01.parent_category_ids as cate1, cate02.parent_category_ids as cate2, t_salon.salon_cate02, t_salon.id, t_salon.salon_name, t_salon.salon_address, t_salon.salon_tel, t_salon.salon_latitude, t_salon.salon_longitude, 13(6371 * ACOS( 14 COS(RADIANS('.$lat.')) 15 * COS(RADIANS(salon_latitude)) 16 * COS(RADIANS(`salon_longitude`) - RADIANS('.$long.')) 17 + SIN(RADIANS('.$lat.')) 18 * SIN(RADIANS(salon_latitude)) 19)) AS distance 20from t_salon 21left join t_parent_category as cate01 on t_salon.salon_cate01 = cate01.id 22left join t_parent_category as cate02 on t_salon.salon_cate02 = cate02.id 23where cate01.parent_category_face = '.$store_id.' 24having 25 distance <= '.$radius_val.' 26order by 27 distance'; 28

このような感じでsqlを作り、変数に入力された値を元に検索をかけているのですが、
たまにエラーが発生する、という状態になっています。

try, catchでも取得できなかったため、

php

1 try { 2 $data = $pdo->query($select_sql); 3 if(!$data) { 4 echo "\nPDO::errorInfo():\n"; 5 print_r($pdo->errorInfo()); 6 exit; 7 return false; 8 } 9 $array = array(); 10 while($row = $data -> fetch(PDO::FETCH_ASSOC)) { 11 $tmp = array(); 12 foreach ($row as $key => $value) { 13 $tmp[$key] = $value; 14 } 15 array_push($array, $tmp); 16 } 17 return $array; 18 } catch (PDOException $e) { 19 exit('データベースエラー : '.$e->getMessage()); 20 }

という形にしているのですが、そこで表示されたエラーが

php

1PDO::errorInfo(): Array ( [0] => 42000 [1] => 1582 [2] => Incorrect parameter count in the call to native function 'RADIANS' )

でした。

たまに発生する + 受け渡している値も正常なため、何が原因か分からなくなっている状態です。

お手数をおかけいたしますが、
ご教示お願いできますでしょうか。
よろしくお願い致します。

【追記】
変更後コード

php

1$select_sql = 'select cate01.parent_category_ids as cate1, cate02.parent_category_ids as cate2, t_salon.salon_cate02, t_salon.id, t_salon.salon_name, t_salon.salon_address, t_salon.salon_tel, t_salon.salon_latitude, t_salon.salon_longitude, 2(6371 * ACOS( 3 COS(RADIANS(:lat)) 4 * COS(RADIANS(salon_latitude)) 5 * COS(RADIANS(`salon_longitude`) - RADIANS(:lng)) 6 + SIN(RADIANS(:lat)) 7 * SIN(RADIANS(salon_latitude)) 8)) AS distance 9from t_salon 10left join t_parent_category as cate01 on t_salon.salon_cate01 = cate01.id 11left join t_parent_category as cate02 on t_salon.salon_cate02 = cate02.id 12where cate01.parent_category_face = :treatment_id 13having 14 distance <= :radius_val 15order by 16 distance'; 17 18 19 20 try { 21 $data = $pdo->prepare($select_sql); 22 # bind処理 23 $data->bindParam(':lat', $lat, PDO::PARAM_DECIMAL); 24 $data->bindParam(':lng', $long, PDO::PARAM_DECIMAL); 25 $data->bindParam(':treatment_id', $treatment_id, PDO::PARAM_STR); 26 $data->bindParam(':radius_val', $radius_val, PDO::PARAM_STR); 27 28 $data->execute(); 29 if(!$data) { 30 echo "\nPDO::errorInfo():\n"; 31 print_r($pdo->errorInfo()); 32 exit; 33 return false; 34 } 35 $array = []; 36 while($row = $data -> fetch(PDO::FETCH_ASSOC)) { 37 $array[] = $row; 38 } 39 return $array; 40 } catch (PDOException $e) { 41 exit('データベースエラー : '.$e->getMessage()); 42 }

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

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

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

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

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

guest

回答2

0

SQL文で座標計算はしないといけないのでしょうか?
PHPで計算してSQLに投げたほうが切り分けがしやすいような気がします
またpdoを利用する限りユーザーから渡されるデータは信用してはいけません
queryではなくprepareで処理して下さい

ちなみに細かい話ですが

while($row = $data -> fetch(PDO::FETCH_ASSOC)) {

FETCH_ASSOCで得た$rowは普通に連想配列ですから
$tmpに読み替えて$arrayにpushする意味はないのでは?

PHP

1$rows=[]; 2while($row = $data -> fetch(PDO::FETCH_ASSOC)) { 3 $rows[]=$row; 4} 5return $rows;

で、いけそうな気がします

投稿2018/03/16 02:06

yambejp

総合スコア114581

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

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

ShujiYamagami

2018/03/16 02:44

ありがとうございます! どちらにしようか迷ったのですが、勉強がてらsqlを選択してしまいました‥ query→prepareに変更しました、ただ変数の受け渡しが上手くいかないのか、取得ができなくなってしまいました…
guest

0

ベストアンサー

RADIANS()に与えている引数が足りないと言っているので、
$lat$longが空になっていることがないか点検してください。
「受け渡している値も正常」じゃないから発生するので、
レアケースをしっかり追いかけられるよう、
デバッグ出力など強化してみてはいかがでしょうか。

なお、GETやPOSTでパラメータを受け取るのだと察しますが、
SQL文にGETやPOSTで受けたままの変数を文字列連結するのは控えて、
SQLインジェクション対策としてバインドの仕組みを使ってください。

投稿2018/03/16 02:02

編集2018/03/16 02:32
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ShujiYamagami

2018/03/16 02:42

早速のご回答をありがとうございます! 確認し、geocodeの経度緯度取得の箇所がコケていることがわかりました、ありがとうございます。 bindに関して仕組みを変えてみたのですが、検索に引っかからなくなってしまった状態です。 もしよろしければ、質問に追記しますので、一度見ていただけますでしょうか…?
退会済みユーザー

退会済みユーザー

2018/03/16 02:48

PDO::PARAM_DECIMAL という定数はおそらく存在しません。 http://php.net/manual/ja/pdo.constants.php 数字として扱えるのであれば、PDO::PARAM_INT で試してはいかがでしょうか。しっくりこないようであれば、もとの文字列連結に戻しつつも、$latや$longに不正なデータが入ってこないよう対策を盛り込んでください。
ShujiYamagami

2018/03/16 04:01

ありがとうございました! 基本数値として扱う方向で進めました。 また、検索に引っかからない箇所に関して、prepareの箇所の:latを2つ使っていたのですが、重複すると正しく動かないようで、:lat, ;lat2と分けて同一の数値をセットしたら動きました。 ご丁寧な解説をありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問