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

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

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

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

Q&A

解決済

4回答

2342閲覧

【PHP】レンタルサーバーにファイルをあげると、ローカルと挙動が変化する問題。

退会済みユーザー

退会済みユーザー

総合スコア0

PHP

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

0グッド

0クリップ

投稿2017/06/28 16:15

編集2017/06/29 11:43

初めまして。

レンタルサーバーのロリポップにファイルをアップロードしたところ、ローカルとは異なる動きをしたため、その原因と対処法をお聞きしたく質問しました。

言語はPHPです。

PHP5.4、windows10です。

実行結果が異なっているので、その画像を用意しました。

ローカルでの実行結果(正しい結果)
イメージ説明

レンタルサーバでの実行結果
イメージ説明

PHPのソースです。

PHP

1<?php 2header('Content-Type: text/html; charset=UTF-8'); 3require_once 'lib/dump.php'; 4 5// 値の受け取り 6foreach ($_POST as $key => $value) { 7 if(!empty($value) && $key != 'mode'){ 8 $post[] = $value; 9 } 10 11 // 移動手段取得 12 if($key == 'mode'){ 13 $mode = $value; 14 } 15} 16 17/* リクエスト用の目的地準備 */ 18// $postの要素数を取得 19$index_sum = count($post); 20// 目的地連結用変数 21$destination = ''; 22 23// 目的地連結 24foreach ($post as $key => $value) { 25 // 配列の0番目は出発地なので除外 26 if($key != 0){ 27 // 目的地の追加 28 $destination .= $post[$key]; 29 // 最後の要素以外なら連結記号を追加 30 if($key+1 != $index_sum){ 31 $destination .= '|'; 32 } 33 } 34} 35 36// apiのリクエストURL 37$url = "https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$post[0].'|'.$destination."&destinations=".$destination."&mode='".$mode."'&language=ja&key=AIzaSyDkfDsdgdhfjgkhNl4wMj8rV3WTlg"; 38// jsonデータを文字列として読み込む 39$json = file_get_contents($url); 40// 文字化け対策 41$json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN'); 42// jsonデータを連想配列に変換 43$arr = json_decode($json,true); 44// vardump($arr); 45 46if ($arr === NULL) { 47 /* 値がない場合(失敗) */ 48 print '失敗'; 49}else{ 50 /* 値がある場合(成功) */ 51 52 // 最適ルート取得用配列 53 $result_route = array(); 54 // 時間比較箇所指定変数 55 $seach_point = 0; 56 // 既出箇所指定配列 57 $drop_point = array(); 58 // 既出箇所指定配列の要素数取得用 59 $drop_cnt = 0; 60 // 出発地+目的地分のループ 61 for($i=0; $i<$index_sum-1; $i++){ 62 // 最適ルートの取得 63 $result_route[$i] = best_route($arr,$seach_point,$drop_point,$drop_cnt); 64 // 探索用添え字取得 65 $seach_point = $result_route[$i][0]; 66 // 既出箇所添え字取得 67 $drop_point[] = $result_route[$i][0]-1; 68 // 既出箇所指定配列の要素数取得 69 $drop_cnt = count($drop_point); 70 } 71 72 // 表示用配列へ格納 73 foreach ($post as $key => $value) { 74 if($key != 0){ 75 // 目的地 76 $result_destination[] = $post[$result_route[$key-1][0]]; 77 // 移動時間 78 $result_time[] = $result_route[$key-1][2]; 79 } 80 } 81} 82 83/********** 84* 最適ルート構築メソッド 85* $arr : APIレスポンス 86* $row_i : 探索場所添え字 87* $drop_point : 探索対象外指定添え字入り配列 88* $drop_cnt : 探索対象外指定添え字数 89**********/ 90function best_route($arr,$row_i,$drop_point,$drop_cnt){ 91 // 単体策対象外の指定上限判定用カウンター兼添え字用変数 92 $drop_if_cnt = 0; 93 // 目的地までの各時間取得を取得 94 foreach ($arr['rows'][$row_i]['elements'] as $key => $value) { 95 if(!empty($drop_point)){ 96 // 添え字が要素数を超えない為の対策 97 if($drop_cnt > $drop_if_cnt){ 98 // 既に最適目的地とされた場所は排除する 99 if($drop_point[$drop_if_cnt] != $key){ 100 // 時間を分単位に変換し、数値だけにする 101 $duration[] = time_change($arr['rows'][$row_i]['elements'][$key]['duration']['text']); 102 // 添え字インクリメント 103 $drop_if_cnt++; 104 // 表示用に時間取得 105 $output_time[] = $arr['rows'][$row_i]['elements'][$key]['duration']['text']; 106 }else{ 107 // 添え字合わせに要素の追加 108 $duration[] = 999; 109 $output_time[] = null; 110 } 111 }else{ 112 // 比較対象がなくなれば無条件で取得 113 $duration[] = time_change($arr['rows'][$row_i]['elements'][$key]['duration']['text']); 114 // 表示用に時間取得 115 $output_time[] = $arr['rows'][$row_i]['elements'][$key]['duration']['text']; 116 } 117 }else{ 118 // 初回は無条件で取得 119 $duration[] = time_change($arr['rows'][$row_i]['elements'][$key]['duration']['text']); 120 // 表示用に時間取得 121 $output_time[] = $arr['rows'][$row_i]['elements'][$key]['duration']['text']; 122 } 123 } 124 // 数字的に昇順でソート 125 asort($duration,SORT_NUMERIC); 126 // vardump($duration); 127 128 $temp_first_p = array_keys($duration); 129 $first_p = array_shift($temp_first_p); 130 // 返却用配列に最適目的地添え字を格納 131 $return_arr[0] = $first_p + 1; 132 // 返却用配列に最適目的地までの時間を格納 133 $return_arr[1] = array_shift($duration); 134 // 返却用配列に表示用時刻を格納 135 $return_arr[2] = $output_time[$first_p]; 136 137 return $return_arr; 138} 139 140/********** 141* 文字列で取得された時間を数値に変換するメソッド 142* 分単位 143* 「m分」「H時間m分」 144**********/ 145function time_change($time_str){ 146 /* 「m分」 */ 147 if(mb_strlen($time_str) < 4){ 148 // 文字列を配列化 149 $arr1 = str_split($time_str); 150 $time = ''; 151 foreach ($arr1 as $key => $value) { 152 if(ctype_digit($value)){ 153 // 数値のみ配列に格納 154 $time .= $value; 155 } 156 } 157 }else{ 158 /* 「H時間m分」 */ 159 // 文字列を配列化 160 $arr = str_split($time_str); 161 $flg = 0; 162 $time = 0; 163 foreach ($arr as $key => $value) { 164 if(ctype_digit($value)){ 165 // 数値のみ配列に格納 166 $time += (int)$value; 167 }else if($flg == 0){ 168 // 時間に60を掛けて分単位に変換 169 $time_h = $time * 60; 170 $time = 0; 171 $flg = 1; 172 } 173 } 174 $time = $time_h + $time; 175 } 176 return $time; 177} 178?>

実行結果に違いがある理由と対処法が知りたいです。
よろしくお願いいたします。

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

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

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

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

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

shi_ue

2017/06/29 04:13

google map の apiキーはダミーですよね?もし本物なら差し替えたほうがよろしいかと。
退会済みユーザー

退会済みユーザー

2017/06/29 11:44

指摘ありがとうございます。そのままでしたので差し替えました。
guest

回答4

0

どちらの結果が意図した結果なのでしょうか?
正しいものを基準に切り分けていく必要があります。

中身の確認はしていませんが、検索結果が変わっているということは、API へ投げる内容に問題があると思います。
エンコードの失敗や文字化け等で、パラメータが効いていないとかじゃないでしょうか。

投稿2017/06/28 16:29

編集2017/06/28 16:31
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2017/06/28 22:30

回答ありがとうございます。 ローカルでの実行結果が意図した動きです。 質問を編集しました。 APIへ投げる内容と返却された内容を確認しましたが、一致していました。
退会済みユーザー

退会済みユーザー

2017/06/29 03:07

file_get_contents だと、request と response の確認が結構大変な気がしますが、確認した内容は 「vardump($arr) が一致した」とかですかね? $arr が正しく、その表示結果が変わるのであれば、その加工途中で各変数に差異が出る箇所があるはずなので、それを切り分けてみるのが適切です。 あまり人のコードを読むのが得意ではないので、「どこが」までの特定は出来ませんが、何箇所かで途中経過を出力させれば、切り分けはできると思います。 ただ、普通に考えると、同じスクリプトを通して挙動が変わるのは珍しいので、どっかでエラーが出ていないですかね? 本番環境のエラー抑止を解除して、確認してみてはいかがでしょうか?
退会済みユーザー

退会済みユーザー

2017/06/29 12:36

回答ありがとうございます。 time_change関数がうまく機能しておらず、想定外の動きをしていました。
guest

0

直接的な回答になりませんが。

まずは。PHPのバージョンや、環境情報を確認されてはいかがでしょうか。

あとは、レンタルサーバなので、ログが確認できなければ画面に、途中結果を出力するようにして
どこで違いがでるかを確認すると解決の糸口が見えるのではないでしょうか。

$JSONが同じとこまでは確認されてるようなので、なんらかの関数(array_keysとか)は
順序が保障されていないとかで、意図しない動きになっているとか・・・(想像)

地味ですが、最終結果が違うなら、途中のどこかの想定外の動き探すしかないかと思います。

投稿2017/06/29 01:36

momon-ga

総合スコア4820

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

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

退会済みユーザー

退会済みユーザー

2017/06/29 12:36

回答ありがとうございます。 time_change関数がうまく機能しておらず、想定外の動きをしていました。
guest

0

ベストアンサー

みなさま回答ありがとうございます。

time_change関数がうまく機能しておらず、想定外の動きをしていました。

PHP

1if(mb_strlen($time_str) < 4)

この部分で、文字数でなくバイトで判定されていたために条件に合わなくなっていました。

投稿2017/06/29 12:39

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

目的地のURLパラメータの渡し方、受け取り方が悪い気がします、
$_POSTは.htaccessなりで値が追加されたり削除されたりソートされたりされ得ます
リクエストしたURLの通りの値が全くそのまま入ってくる保証がありません

順番を保持したいなら配列で値を渡す方が確実かと思います

HTML

1<input type="text" name="destination[0]"/> 2<input type="text" name="destination[1]"/> 3<input type="text" name="destination[2]"/> 4....

PHP

1$post=$_POST['destination'];//本番ではちゃんとサニタイズしてください

投稿2017/06/29 02:28

KazuhiroHatano

総合スコア7804

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

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

退会済みユーザー

退会済みユーザー

2017/06/29 12:36

回答ありがとうございます。 time_change関数がうまく機能しておらず、想定外の動きをしていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問