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

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

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

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

PHP

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

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

Q&A

解決済

3回答

2368閲覧

PHPの接続先DBを変更したい

ysk1118

総合スコア22

MySQL

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

PHP

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

XAMPP

XAMPP(ザンプ)は、ウェブアプリケーションの実行に必要なフリーソフトウェアをパッケージングしたApacheディストリビューションです。 XAMPPひとつインストールするだけで、Apache、MySQL、PHP、Perlなどのソフトウェアと、 phpMyAdminなどの管理ツール、SQLiteなどのソフトウェアやライブラリモジュールなどを利用することが可能です。

0グッド

0クリップ

投稿2018/11/30 02:08

編集2018/12/05 01:30

前提・実現したいこと

XAMPP(Apache,PHP,MySql)をインストールしたPCが2台あります。(仮にサーバAとサーバBとします。)
サーバAでPHPの動作テストを行い、サーバBにコピーして本運用という運用を考えています。
ただし、DBはテスト環境(サーバA)でも本運用のDB(サーバB)を使用して動作テストを行いたいのですが、
この場合、下記のようなソースコードでは、$db['host']のIPアドレスにサーバBを指定すればよいと思いましたが、
実際にやってみるとデータベースエラーになってしまいます。
PDOによる接続先DBの指定=db['host']と考えていますが、これは間違った認識なのでしょうか?

なお、サーバAはXAMPPインストール先がC:\xampp、サーバBはD:\xamppとなっています。
これも原因の一つに考えられますか?

PHP

1<?php 2 //セッション開始 3 session_start([ 4 'cookie_lifetime' => 1800, 5 ]); 6 7 $db['host']="(本運用環境のIPアドレス)"; //接続先を本運用DBにする 8 $db['user']="tc_guest"; 9 $db['pass']="(パスワード)"; 10 $db['dbname']="(DB名)"; 11 12 //エラーメッセージ初期化 13 $err_msg=""; 14 15 //ログインボタンが押された場合 16 if(isset($_POST["login"])){ 17 // 1.ユーザIDの入力チェック 18 if(empty($_POST["userid"])) { //emptyは値が空の判定 19 $err_msg='ユーザIDが未入力です。'; 20 }else if(empty($_POST["password"])) { 21 $err_msg='パスワードが未入力です。'; 22 } 23 24 if(!empty($_POST["userid"]) && !empty($_POST["password"])) { 25 //入力されたユーザIDを格納 26 $userid=$_POST["userid"]; 27 28 // 2.ユーザIDとパスワードが入力されていたら認証する 29 $dsn = sprintf('mysql: host=%s; dbname=%s; charset=utf8',$db['host'],$db['dbname']); 30 31 // 3.エエラー処理 32 try { 33 $pdo=new PDO($dsn,$db['user'],$db['pass'],array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)); 34 …以下略 35       }catch (PDOException $e){ 36 $err_msg='データベースエラー:'; 37   echo $e->getMessage(); 38 }

発生している問題・エラーメッセージ

次のエラーメッセージが出ています。何故かここだけ文字化けしています。エラーコードから推測すると、おそらくNo such file or directoryだと思いますが…。

SQLSTATE[HY000] [2002] �Ώۂ̃R���s���[�^�[�ɂ���ċ��ۂ��ꂽ���߁A�ڑ��ł��܂���ł����B

ご指摘に沿い、apacheのエラーログを確認しました。エラーを発生させた日時に該当するエラーログを抽出しましたが、
直接エラーと関与するような記述は見受けられませんでした。

[Fri Nov 30 12:13:37.889772 2018] [ssl:warn] [pid 3408:tid 616] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name

[Fri Nov 30 12:13:38.046179 2018] [core:warn] [pid 3408:tid 616] AH00098: pid file D:/xampp/apache/logs/httpd.pid overwritten -- Unclean shutdown of previous Apache run?
[Fri Nov 30 12:13:38.249217 2018] [ssl:warn] [pid 3408:tid 616] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Nov 30 12:13:38.296097 2018] [mpm_winnt:notice] [pid 3408:tid 616] AH00455: Apache/2.4.25 (Win32) OpenSSL/1.0.2j PHP/7.1.6 configured -- resuming normal operations
[Fri Nov 30 12:13:38.296097 2018] [mpm_winnt:notice] [pid 3408:tid 616] AH00456: Apache Lounge VC14 Server built: Dec 17 2016 10:42:52
[Fri Nov 30 12:13:38.296097 2018] [core:notice] [pid 3408:tid 616] AH00094: Command line: 'd:\xampp\apache\bin\httpd.exe -d D:/xampp/apache'
[Fri Nov 30 12:13:38.296097 2018] [mpm_winnt:notice] [pid 3408:tid 616] AH00418: Parent: Created child process 4036
[Fri Nov 30 12:13:39.483729 2018] [ssl:warn] [pid 4036:tid 624] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Nov 30 12:13:39.749383 2018] [ssl:warn] [pid 4036:tid 624] AH01909: www.example.com:443:0 server certificate does NOT include an ID which matches the server name
[Fri Nov 30 12:13:39.796265 2018] [mpm_winnt:notice] [pid 4036:tid 624] AH00354: Child: Starting 150 worker threads.

試したこと

本環境のMySQLに対して、外部ホスト接続許可は行いました。具体的には、コマンドプロンプトで下記コマンドを実行し、
テスト環境サーバからmysqlコマンドでアクセスできることは確認済みです。

CMD

1grant all privileges on DB名.* to tc_guest@"テスト環境サーバのIP" identified by 'パスワード' with grant option;

追加情報

ふと、テスト環境であるサーバAのMySQLのサービスをスタートさせたところ、ソースの処理が正常に動作しました。
ただし、DBはサーバBではなくサーバAを見に行っているようです。ソースはユーザ認証の処理なのですが、
サーバAにしか存在していないユーザ情報でログインされましたし、その後表示されるデータもサーバAにしかないデータが
出力されています。ということは、ソースの先頭で指定したホストの指定は全く意味がないということなのでしょうか…?

追記

新たにテスト確認したソースを開示します。

php

1<?php 2 3$db['host']="172.20.0.34";//サーバBのIPアドレス 4$db['user']="tc_guest"; 5$db['pass']="パスワード"; 6$db['dbname']="DB名"; 7 8$dsn = sprintf('mysql: host=%s; dbname=%s; charset=utf8',$db['host'],$db['dbname']); 9 10// 3.エエラー処理 11try { 12 $pdo=new PDO($dsn,$db['user'],$db['pass'],array(PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION)); 13 14 $stmt=$pdo->prepare('select * from t_userdata'); 15 $stmt->execute(); 16 17 foreach($stmt as $row){ 18 echo $row["userid"] . " "; 19 } 20 21 22}catch(PDOExecption $e){ 23 echo $e->getMessage(); 24} 25 26?>

また、下記はサーバA,Bそれぞれのt_userdataテーブルの中身です。
イメージ説明
↑サーバA
イメージ説明
↑サーバB
次の条件で上記コードのphpファイルにアクセスした際の結果です。
条件1:サーバAのMysqlサービス開始 → 18895 5823 22192 15739 99999 22299 1
条件2:サーバAのMysqlサービス停止 → Fatal error: in C:\xampp\htdocs\dakoku\test.php on line 12
条件3:サーバAのMysqlサービス開始・サーバBのサービス停止 → 18895 5823 22192 15739 99999 22299 1
以上のことから、ソース上で指定したIPアドレスは意味を成していないように思われます。

追加情報2

別のphpファイルソースを編集していた際、誤ってパスワードの記載までを変えてしまったことに気付かず処理を行いました。
当然、エラーが出力されたのですが、このエラー内容の一部に

PDO->__construct('mysql:host=172....', 'tc_guest', 'test', Array)

とありました。
hostの指定がIPアドレスの第1オクテットしか表示されていないため、
もしやと思って、$db['host']への設定値をIPアドレスからホスト名に変更してみたところ、
無事DBの参照先を切り替えることに成功しました。
自己解決という形になってしまいましたが、ホスト名指定にIPアドレス指定がNGというのはどうも納得がいかないような…。

ともあれ、コメントをいただいた方々、お付き合いいただきありがとうございました。
一先ず本件については自己解決という形でクローズさせていただきますが、この件について知見をお持ちの方は引き続きご助言いただけると幸いです。

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/11/30 02:46 編集

文字化け、SJIS出力がUTF-8エンコーディングの中に出現しただけなんじゃないだろうか? XAMPPのapacheのerror_logに同様の内容で出力しているだろうからそっちから引用してほしい。
kunai

2018/11/30 03:14

BのMySQLのPortは3306ですか?「テスト環境から本番サーバに接続出来ることは確認済み」とありますが、その時のコマンドは提示いただけませんか。IPアドレスがプライベートアドレスであれば、開示してもらえると助かります。
ysk1118

2018/11/30 03:22

portは3306です。コマンドは「mysql -h 172.20.x.x(サーバBのIP) -u tc_guest -p」でパスワード入力により接続できました。
kunai

2018/11/30 03:26

プライベートIPアドレスでしたら隠さずそのまま書けませんか。それを知ったところで、外部からそのアドレスへは接続は出来ません。実際、今起こっている問題はBにつなごうとしているはずがAにつながっているので、そのへんのIPアドレスが正確であることが重要なので。
ysk1118

2018/11/30 04:13

失礼しました。サーバAは172.20.16.92、サーバBは172.20.0.34です。
kunai

2018/11/30 04:25

ありがとうございます。コード上で、そのIPアドレスを記載した状態で書いてみてもらえますか?ちゃんとソースコードからコピペする形で。
kunai

2018/11/30 05:39

アクセスしているのは間違いなくサーバAなのでしょうか。アクセスログ確認してみてもらえます?
ysk1118

2018/11/30 06:34 編集

サーバAのアクセスログに「172.20.16.85 - - [30/Nov/2018:15:14:04 +0900] "GET /dakoku/test.php HTTP/1.1" 200 47 "-" "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"」と出力されていましたので、サーバAへのアクセスで間違いないと思います。※16.85のIPはweb閲覧したクライアントPCです。
guest

回答3

0

PHP

1$dsn = sprintf('mysql: host=%s; dbname=%s; charset=utf8',$db['host'],$db['dbname']);

DSN の文字列を生成する際には、経験上むやみにスペースを入れない方が良いです。
上記の場合、自分の PHP 環境では、mysql: と host の間のスペースを解釈することによって? host 指定が無視されるように見えます。

投稿2018/12/04 08:45

ssasaki

総合スコア1167

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

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

ysk1118

2018/12/05 01:15

ご指摘ありがとうございました。スペースを取り除いてみましたが、状況変わらずでした。
ysk1118

2018/12/07 00:44

自己完結後ですが、ご指摘されたようにスペースがある状態ではhost指定が無視されていることが分かりました。 (host指定をリモートホスト名とし、スペースありで実行確認するとローカルDBデータ参照されたため) 今後は無用なスペースを入れないようにしたいと思います。貴重なご助言ありがとうございました。
guest

0

自己解決

自己解決してしまいました。

PHP

1 $db['host']="(本運用環境のIPアドレス)"; //接続先を本運用DBにする

この部分を

PHP

1 $db['host']="(本運用環境のDBサーバ名)"; //接続先を本運用DBにする

とすることで、解決いたしました。DBホストの指定にIPアドレスがNGとは正直考えにくいのですが、
一先ずはこれで解決としておきます。

投稿2018/12/05 01:33

ysk1118

総合スコア22

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

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

0

接続先DB側パソコンでファイアウォールがあるならポート開放が必要、
セキュリティーソフトが強すぎて接続元になるwebサーバーからそもそもつなぎにいけないこともあるので、
念のためwebサーバー側パソコンでもポート開放。

投稿2018/11/30 02:48

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ysk1118

2018/11/30 07:33

サーバA,B共に、Symantec Endpoint Protectionを使用していますが、ファイアウォール機能は除外して運用しています。接続元PCも同様です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問