楽天トラベル空室検索APIを使ってPHPで宿泊情報の表示

2019年3月3日

楽天APIを利用して商品検索して表示するPHPプログラムが動作したので、アフィリエイトにも役立てようと、楽天APIを利用した宿泊情報の表示にトライすることにしました。

楽天APIの一覧で使いたいAPIを選んでおきます。使うのは楽天トラベル空室検索APIです。
https://webservice.rakuten.co.jp/document/
新規アプリ登録をして、楽天のデベロッパーIDとアフィリエイトIDを取得するのは同様です。
https://webservice.rakuten.co.jp/
忘れないようにメモしておいた方が良いです。

日付指定をして通常条件で最安値を表示するのが当座の目標です。
最近、最安値で検索した時に上位に表示されて目立つようにバースデーの客限定で特別価格を設定してたりするので本当に誰もが利用できる最安値を検索するのは難しいです。
最終的にはバースデープランを採用しているホテルは除外するようにしようと思います。

https://webservice.rakuten.co.jp/explorer/api/Travel/VacantHotelSearch/
で条件を設定した場合の、出力例を見る事が出来ます。

日付指定して、金沢で、1人、部屋はシングル、2000円以上(バースデー限定などの特殊条件での特別料金を外すために極端な安値は除外)、最安値を1ページ・1データで価格のみ表示という条件設定だと下記のようになります。

https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?format=jsor&checkinDate=2019-04-06&checkoutDate=2019-04-07&smallClassCode=kanazawa&adultNum=1&f_rm_bed=single&hits=1&page=1&sort=%2BroomCharge&largeClassCode=japan&middleClassCode=ishikawa&minCharge=2000&elements=hotelMinCharge&applicationId=1089363386770913344

部屋がツインの場合はf_rm_bed=twin、部屋に拘らない場合はf_rm_bed=*です。

そのままブラウザのアドレスに挿入すると

{"hotels":[{"hotel":[{"hotelBasicInfo":{"hotelMinCharge":1500}}]}]}

と表示されます。設定した最低価格2000円以上なのに1500円と表示されてしまいます。

最安値(elements=hotelMinCharge)は、その日の最安値ではなく、その宿泊施設が登録した最安値なので、あまり意味が無いようです。
天トラベルの空室検索APIでは、その宿泊施設での指定日・指定条件での最低料金というのはAPIのデータとして存在しないようです。
それで、最安値を出力するのではなく、宿泊施設名を出力するようにしました。

https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?format=jsor&checkinDate=2019-04-06&checkoutDate=2019-04-07&smallClassCode=kanazawa&adultNum=1&f_rm_bed=single&hits=1&page=1&sort=%2BroomCharge&largeClassCode=japan&middleClassCode=ishikawa&minCharge=2000&elements=hotelName&applicationId=1089363386770913344&datumType=1&responseType=large&searchPattern=0

ブラウザのアドレス欄に入力すると

{"hotels":[{"hotel":[{"hotelBasicInfo":{"hotelName":"SHAQ BIGHOUSE"}}]}]}

と出力されます。

とりあえず施設名だけを表示させないいけません。

公開API活用ガイド ZAPA著を参考に日付指定した時の最安値の宿泊施設名を表示するPHPプログラムを作ってみました。
https://www.pahoo.org/e-soul/webtech/php06/php06-45-01.shtm
も参考にしました。

チェックイン2019-04-05、チェックアウト2019-04-06、金沢で、部屋はシングル、1人、2000円以上(特殊条件での特別料金を外すために極端な安値は除外)、宿泊施設名を1ページ・1データで表示するプログラムを作ってみました。ファイル名はrakuten4.phpとしました。
SHAQ BIGHOUSE と宿泊施設名だけが表示されました。成功です。
後は、日付やその他の条件を変更して一覧を表示すれば目的を果たせます。

<?php

//楽天トラベルから宿を検索してHTMLタグを返す関数
function yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed){
//developerIdを設定する
$applicationId = ‘1089363386770913344’;

//affiliateIdを設定する
$affiliateId = ‘15040cf4.7d33bce5.15040cf5.078e12d9’;

//URLを生成する
$url = ‘https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?format=xml’.
‘&applicationId=’.$applicationId.
‘&largeClassCode=japan’.
‘&middleClassCode=ishikawa’.
‘&smallClassCode=kanazawa’.
‘&checkinDate=’.$checkinDate.
‘&checkoutDate=’.$checkoutDate.
‘&adultNum=’.$adultNum.
‘&minCharge=’.$minCharge.
‘&hits=1’.
‘&page=1’.
‘&sort=+roomCharge’.
‘&f_rm_bed=’.$f_rm_bed ;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);

//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);

//xpathによって、Item要素だけを取り出す
$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;

return $Items;
}
?>
<?php
$checkinDate = “2019-04-05”;
$checkoutDate = “2019-04-06”;
$minCharge = “2000”;
$adultNum = “1”;
$f_rm_bed = “single”;

echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed);
?>

2019年3月4日

最安値の宿泊施設名を取り込むことができたのですが、30日分のデータを表示したいので、日付の設定と曜日入りの日付を表示できるようにする必要があります。

検索のための日付
<?php
$day = date(“Y-m-d”);
echo $day;
?>

表示のための曜日付の日付
<?php
$day = date(“Y-m-d”);
$w = date(“w”);
$week_name = array(“日”, “月”, “火”, “水”, “木”, “金”, “土”);
$day2= date(“Y-m-d”).'(‘.$week_name[$w].’)’;
echo $day2;
?>

1日後の日付
<?php
$day = date(“Y-m-d”,strtotime(‘+ 1 day’));
echo $day;
?>

後は変数を配列にしてデータベースSQLに保存すれば思っていたページができます。
当日のシングル1人・ツイン2人・すべての部屋を対象にした1人 での宿泊の最安の施設名
明日のシングル1人・ツイン2人・すべての部屋を対象にした1人 での宿泊の最安の宿泊名
明後日のシングル1人・ツイン2人・すべての部屋を対象にした1人 での宿泊の最安の宿泊名
3日後のシングル1人・ツイン2人・すべての部屋を対象にした1人 での宿泊の最安の宿泊名
29日後のシングル1人・ツイン2人・すべての部屋を対象にした1人 での宿泊の最安の宿泊名

2019年3月9日

すべての部屋を対象にした1人・シングルルーム1人・ツインルーム2人での宿泊予約の最安値の施設を表示するプログラムを作成しました。
高年齢の人を対象にした誕生日だけの限定激安を設定しているホテルリブマックス金沢医大前(153335)、ホテルリブマックス金沢駅前(165677)、ゆにろーず金沢TS店(136975)、ホテルトレンド金沢駅前(171908)、HOTEL花IchiRinKANAZAWA(160759)の宿泊施設IDは省くようにしました。
当日から30日間の
年月日(曜日) 最安値の宿泊施設名
を表示するプログラムです。

<?php

//楽天トラベルから宿を検索してHTMLタグを返す関数
function yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed){
//developerIdを設定する
$applicationId = ‘1089363386770913344’;

//affiliateIdを設定する
$affiliateId = ‘15040cf4.7d33bce5.15040cf5.078e12d9’;

//URLを生成する
$url = ‘https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?format=xml’.
‘&applicationId=’.$applicationId.
‘&largeClassCode=japan’.
‘&middleClassCode=ishikawa’.
‘&smallClassCode=kanazawa’.
‘&checkinDate=’.$checkinDate.
‘&checkoutDate=’.$checkoutDate.
‘&adultNum=’.$adultNum.
‘&minCharge=’.$minCharge.
‘&hits=1’.
‘&page=1’.
‘&sort=+roomCharge’.
‘&f_rm_bed=’.$f_rm_bed ;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);

//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);

//xpathによって、Item要素だけを取り出す
$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;
$hotelNo = $xml->hotels->hotel->hotelBasicInfo->hotelNo;
if ($hotelNo ==’153335′ or $hotelNo ==’136975′ or $hotelNo ==’171908′ or $hotelNo ==’160759′ or $hotelNo ==’171908′){$Items=”表示しない”;}
return $Items;
}
?>
<?php

echo ‘大人1人で宿泊’;print “<br>\n”;
for($n=0;$n<30;$n++)
{$n1=$n+1;
$n2=’+’.$n.’ day’;
$n3=’+’.$n1.’ day’;
$checkinDate = date(“Y-m-d”,strtotime(“$n2”));
$checkoutDate = date(“Y-m-d”,strtotime(“$n3”));
$minCharge = “1500”;
$adultNum = “1”;
$f_rm_bed = “*”;
$w=date(“w”,strtotime(“$n2”));
$week_name = array(“日”,”月”, “火”,”水”,”木”,”金”,”土”);
$day2=date(“Y-m-d”,strtotime(“$n2”)).'(‘.$week_name[$w].’)’;
echo $day2;
echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed);
print “<br>\n”;
}
?>
<?php
print “<br>\n”;
echo ‘大人1人でシングルルームでの宿泊’;print “<br>\n”;
for($n=0;$n<30;$n++)
{$n1=$n+1;
$n2=’+’.$n.’ day’;
$n3=’+’.$n1.’ day’;
$checkinDate = date(“Y-m-d”,strtotime(“$n2”));
$checkoutDate = date(“Y-m-d”,strtotime(“$n3”));
$minCharge = “2000”;
$adultNum = “1”;
$f_rm_bed = “single”;
$w=date(“w”,strtotime(“$n2”));
$week_name = array(“日”,”月”, “火”,”水”,”木”,”金”,”土”);
$day2=date(“Y-m-d”,strtotime(“$n2”)).'(‘.$week_name[$w].’)’;
echo $day2;
echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed);
print “<br>\n”;
}
?>
<?php
print “<br>\n”;
echo ‘大人2人でツインルームでの宿泊’;print “<br>\n”;
for($n=0;$n<30;$n++)
{$n1=$n+1;
$n2=’+’.$n.’ day’;
$n3=’+’.$n1.’ day’;
$checkinDate = date(“Y-m-d”,strtotime(“$n2”));
$checkoutDate = date(“Y-m-d”,strtotime(“$n3”));
$minCharge = “3000”;
$adultNum = “2”;
$f_rm_bed = “twin”;
$w=date(“w”,strtotime(“$n2”));
$week_name = array(“日”,”月”, “火”,”水”,”木”,”金”,”土”);
$day2=date(“Y-m-d”,strtotime(“$n2”)).'(‘.$week_name[$w].’)’;
echo $day2;
echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed);
print “<br>\n”;
}
?>

2019年3月10日

部屋の種類ごとにデータを表示して初めて気づいたのですが、部屋の種類の指定が効いていないようです。

$f_rm_bed = “twin”; が無効なようです。
$roomClass = “twin”; にしてもダメです。

気合を入れて調べたのですが楽天トラベル空室検索APIでは部屋の種類の指定ができないようです。中途半端だなあ・・・・

表示されたデータを配列に登録してみましたが、登録して次の配列に処理が進むと、前の配列のデータが消えます。何が悪いのかなあ?
最後のecho $data[30];は表示されるのにecho $data[29];はエラーになります。

<?php

//楽天トラベルから宿を検索してHTMLタグを返す関数
function yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge){
//developerIdを設定する
$applicationId = ‘1089363386770913344’;

//affiliateIdを設定する
$affiliateId = ‘15040cf4.7d33bce5.15040cf5.078e12d9’;

//URLを生成する
$url = ‘https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?format=xml’.
‘&applicationId=’.$applicationId.
‘&largeClassCode=japan’.
‘&middleClassCode=ishikawa’.
‘&smallClassCode=kanazawa’.
‘&checkinDate=’.$checkinDate.
‘&checkoutDate=’.$checkoutDate.
‘&adultNum=’.$adultNum.
‘&minCharge=’.$minCharge.
‘&hits=1’.
‘&page=1’.
‘&sort=+roomCharge’.”;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);

//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);

//xpathによって、Item要素だけを取り出す
$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;
$hotelNo = $xml->hotels->hotel->hotelBasicInfo->hotelNo;
if ($hotelNo ==’153335′ or $hotelNo ==’136975′ or $hotelNo ==’171908′ or $hotelNo ==’165677′ or $hotelNo ==’160759′){$Items=”表示しない”;}
return $Items;
}
?>
<?php
echo ‘大人1人での宿泊’;print “<br>\n”;
for($n=0;$n<30;$n++)
{$n1=$n+1;
$n2=’+’.$n.’ day’;
$n3=’+’.$n1.’ day’;
$checkinDate = date(“Y-m-d”,strtotime(“$n2”));
$checkoutDate = date(“Y-m-d”,strtotime(“$n3”));
$minCharge = “2000”;
$adultNum = “1”;
$w=date(“w”,strtotime(“$n2”));
$week_name = array(“日”,”月”, “火”,”水”,”木”,”金”,”土”);
$day2=date(“Y-m-d”,strtotime(“$n2”)).'(‘.$week_name[$w].’)’;
echo $day2;
echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge);
print “<br>\n”;
$yado=yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge);
$data = [$n =>$yado];
echo $data[$n];
print “<br>\n”;
}
?>
<?php
echo $data[29];
echo $data[30];
?>

配列はやめて、一気にデータベースに登録する事にしました。
テーブルのカラムはid、No、date、yadomeiにしました。
dateは、曜日付の年月日を文字列(例えば2019-03-10(日))として登録します。
データを取り出す時には処理をしないで済むという作戦です。
とりあえず30件分のデータを手動で入力しました。データーベース名はyasuiyadoにするつもりが間違えてysuiyadoになってしまいました。

2019年3月11日

データベースのデータを一挙に更新する事に成功しました。
残りはデータベースのデータを取り出して宿のページで表示するだけです。

<?php
try {
$db = new PDO(‘mysql:dbname=ysuiyado;host=127.0.0.1;charset=utf8’, ‘root’, ”);
} catch (PDOException $e) {
echo ‘DB接続エラー: ‘ . $e->getMessage();
}
?>

<?php

//楽天トラベルから宿を検索してHTMLタグを返す関数
function yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge){
//developerIdを設定する
$applicationId = ‘1089363386770913344’;

//affiliateIdを設定する
$affiliateId = ‘15040cf4.7d33bce5.15040cf5.078e12d9’;

//URLを生成する
$url = ‘https://app.rakuten.co.jp/services/api/Travel/VacantHotelSearch/20170426?format=xml’.
‘&applicationId=’.$applicationId.
‘&largeClassCode=japan’.
‘&middleClassCode=ishikawa’.
‘&smallClassCode=kanazawa’.
‘&checkinDate=’.$checkinDate.
‘&checkoutDate=’.$checkoutDate.
‘&adultNum=’.$adultNum.
‘&minCharge=’.$minCharge.
‘&hits=1’.
‘&page=1’.
‘&sort=+roomCharge’.”;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);

//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);

//xpathによって、Item要素だけを取り出す
$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;
$hotelNo = $xml->hotels->hotel->hotelBasicInfo->hotelNo;
if ($hotelNo ==’153335′ or $hotelNo ==’136975′ or $hotelNo ==’171908′ or $hotelNo ==’165677′ or $hotelNo ==’160759′){$Items=”表示しない”;}
return $Items;
}
?>
<?php
echo ‘大人1人での宿泊’;print “<br>\n”;
for($n=0;$n<30;$n++)
{$n1=$n+1;
$n2=’+’.$n.’ day’;
$n3=’+’.$n1.’ day’;
$checkinDate = date(“Y-m-d”,strtotime(“$n2”));
$checkoutDate = date(“Y-m-d”,strtotime(“$n3”));
$minCharge = “2000”;
$adultNum = “1”;
$w=date(“w”,strtotime(“$n2”));
$week_name = array(“日”,”月”, “火”,”水”,”木”,”金”,”土”);
$day2=date(“Y-m-d”,strtotime(“$n2”)).'(‘.$week_name[$w].’)’;
echo $day2;
echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge);
print “<br>\n”;
$yado=yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge);
$sql=’UPDATE yasuiyado SET yadomei=\”.$yado.’\’,date=\”.$day2.’\’ WHERE id=’.$n1;
$prepare = $db->prepare($sql);
$prepare->execute();
print “<br>\n”;
}
?>

2019年3月12日

今まで、参考書通りでMySQLを操作している時にはデータの変更が画面を見ながら編集できたのですが、自分でプログラム作ってデータを挿入すると、画面での編集が出来なくなっていました。編集ができないと言うより先に、編集、コピー、削除のボタン自体が表示されていませんでした。
これでは都合が悪いという事で調べたら、
Current selection does not contain a unique column. Grid edit, checkbox, Edit, Copy and Delete features are not available.
という表示が出ていました。
日本語に訳すと「現在の選択には一意の列は含まれていません。グリッド編集、チェックボックス、編集、コピー、削除機能は利用できません」ということのようです。
対処としては、「ユニークキーなどのユニークなカラムを作成しなさい」ということのようで、idのカラムを選択し、ユニークキーの設定(主の鍵をクリック)をしたら編集できるようになりました。

とりあえず、データベースからデータを取得して表示してみました。
phpファイルです。

<!DOCTYPE html>
<html lang=”ja”>
</head>
<meta charaset=”UTF-8″>
<title>データベースのデータを取得</title>
</head>
<body>
<div>

<?php
try {
$db = new PDO(‘mysql:dbname=ysuiyado;host=127.0.0.1;charset=utf8’, ‘root’, ”);
} catch (PDOException $e) {
echo ‘DB接続エラー: ‘ . $e->getMessage();
}
?>
<?php
$sql=’SELECT * FROM yasuiyado’;
$prepare = $db->prepare($sql);
$prepare->execute();
echo ‘<pre>’;
$result = $prepare->fetchAll(PDO::FETCH_ASSOC);
print_r($result);
echo ‘</pre>’;
?>
</div>
</body>
</html>

下記のように表示しました(2つのデータのみ掲載しています)。
これから、このデータを見栄えよく表示しなければいけません。

Array
(
[0] => Array
(
[id] => 1
[no] => 1
[date] => 2019-03-12(火)
[yadomei] => SHAQ BIGHOUSE
)

[1] => Array
(
[id] => 2
[no] => 2
[date] => 2019-03-13(水)
[yadomei] => THE SHARE HOTELS HATCHi 金沢
)

データベースのデータを表にして出力しました。これだけできれば後はなんとかなりそうです。

<!DOCTYPE html>
<html lang=”ja”>

<head>
<meta charaset=”UTF-8″>
<STYLE>
<!–
.gyou{
line-height: 18pt ; padding-left:10pt ; padding-right:10pt;
}
–>
</STYLE>
<title>データベースのデータを取得</title>
</head>
<body>
<div>

<?php
try {
$db = new PDO(‘mysql:dbname=ysuiyado;host=127.0.0.1;charset=utf8’, ‘root’, ”);
} catch (PDOException $e) {
echo ‘DB接続エラー: ‘ . $e->getMessage();
}
?>
<?php
$sql=’SELECT * FROM yasuiyado’;
$stmt = $db->query( $sql );

echo “<table bgcolor=\”#fbe48c\”>\n”;
while( $result = $stmt->fetch( PDO::FETCH_ASSOC ) ){
echo “\t<tr>\n”;
echo “\t\t<td bgcolor=\”#ffffff\” class=\”gyou\”>{$result[‘date’]}</td>\n”;
echo “\t\t<td bgcolor=\”#ffffff\” class=\”gyou\”>{$result[‘yadomei’]}</td>\n”;
echo “\t</tr>\n”;
}
echo “</table>\n”;

?>
</div>
</body>
</html>

2019年3月14日

大人1人で泊まった場合の最安値の宿泊施設と大人2人で泊まった場合の最安値の宿泊施設を別の表で出力するように変更しました。

<!DOCTYPE html>
<html lang=”ja”>
<head>
<meta charaset=”UTF-8″>
<STYLE>
<!–
.gyou{
line-height: 18pt ; padding-left:10pt ; padding-right:10pt;
}
–>
</STYLE>
<title>データベースのデータを取得</title>
</head>
<body>
<div>
<?php
try {
$db = new PDO(‘mysql:dbname=ysuiyado;host=127.0.0.1;charset=utf8’, ‘root’, ”);
} catch (PDOException $e) {
echo ‘DB接続エラー: ‘ . $e->getMessage();
}
?>
<?php
echo ‘大人1人での宿泊’;print “<br>\n”;
echo “<table bgcolor=\”#fbe48c\”>\n”;
for($n=1;$n<30;$n++){
$stmt =$db->query(“SELECT * FROM yasuiyado where id=$n”);
$result = $stmt->fetch();
echo “\t<tr>\n”;
echo “\t\t<td bgcolor=\”#ffffff\” class=\”gyou\”>{$result[‘date’]}</td>\n”; echo “\t\t<td bgcolor=\”#ffffff\” class=\”gyou\”>{$result[‘yadomei’]}</td>\n”;
echo “\t</tr>\n”;
}
echo “</table>\n”;
?>
<?php
echo ‘大人2人での宿泊’;print “<br>\n”;
echo “<table bgcolor=\”#fbe48c\”>\n”;
for($n=31;$n<60;$n++){
$stmt =$db->query(“SELECT * FROM yasuiyado where id=$n”);
$result = $stmt->fetch();
echo “\t<tr>\n”;
echo “\t\t<td bgcolor=\”#ffffff\” class=\”gyou\”>{$result[‘date’]}</td>\n”; echo “\t\t<td bgcolor=\”#ffffff\” class=\”gyou\”>{$result[‘yadomei’]}</td>\n”;
echo “\t</tr>\n”;
}
echo “</table>\n”;
?>
</div>
</body>
</html>

次に1人での宿泊について、全ての部屋の種類での最安値とシングルでの最安値の施設を検索するボタンと、2人での宿泊について、全ての部屋の種類とツインに限定しての最安値の施設を検索するボタンを設置します。
さすがに60日分の一覧は長すぎるので、デフォルトは1人での宿泊にして、ボタンで2人での宿泊に切り替えるようにします。
その次は最安値の宿泊施設のデータを更新してページをリロードするボタンも設置します。自分でも毎朝更新しますが、ページを見ている人もデータを更新できるようにすれば更新頻度も増すという作戦です。
あとはモバイル対応に整形して、データベースをサーバー上のMySQLに変更すれば完成です。

<?php
$rel = $_GET[‘reload’];
if ($rel == ‘true’) {
header(“Location: ” . $_SERVER[‘PHP_SELF’]);
}
?>

2019年3月16日

1人用の最安値施設一覧と2人用最安値施設一覧のページから更新ページに飛んだ時に、処理が終わったら元のページに戻る処理が必要です。
そのプログラムが下記になります。

<?php
header(‘HTTP/1.1 303 See Other’);
header(“location:”.$_SERVER[‘HTTP_REFERER’]);
exit();
?>

1人での宿泊について、全ての部屋の種類での最安値とシングルでの最安値の施設を検索するボタンと、2人での宿泊について、全ての部屋の種類とツインに限定しての最安値の施設を検索するボタンを設置しました。
60日分の一覧は長すぎるので、デフォルトは1人での宿泊にして、2人での宿泊に切り替える事ができるようにしました。
最安値の宿泊施設のデータを更新して処理後に元のページに戻るリンクを設置しました。

2019年3月17日

モバイル対応への整形がうまくいきました。
後は、サーバーのMySQLに接続してインターネット上に公開するだけです。

まずはXAMPPのphpMyAdminのデータをエクスポートしました。エクスポートのファイルはyasuiyado.sqlです。
yasuiyado.sqlをFTPでサーバーの_db_dumpフォルダ(public_htmlと同じ階層のフォルダ)にコピー。
CORESERVER.JPにログインしてデータベースをクリックして、新しいMySQLデータベースを追加しました。
データベース名はkimassi_yadoにしました。文字コードはUNICODEに選択しました。
新コントロールパネルの表示から、MySQL一覧で新しく作成したkimassi_yadoのアクションの項目からDBリストアのマークをクリック(不要な操作かも)して、kimassi_yadoのアクションの項目のphpMyAdminのマークをクリックしました。
phpMyAdminの画面に入れますので、インポートをクリックしてyasuiyado.sqlを選択し実行です。
データを確認しましたが、無事にデータベースの引越が完了していました。
データベース名はkimassi_yadoでテーブル名はyasuiyadoです。

phpプログラムのデータベースアドレス関連をCORESERVER.JP用に書き換えてファイルをアップロードすれば完成かな?

データベースにログインするphpプログラムは下記になります。

<?php
try {
$dsn=’mysql:host=localhost;dbname=kimassi_yado’;
$db = new PDO($dsn, ‘ユーザー名’, ’12桁のパスワードを入力’);
} catch (PDOException $e) {
echo ‘DB接続エラー: ‘ . $e->getMessage();
}
?>

ユーザー名はデータベース名と同じでkimassi_yadoになります。本来のユーザー名kimassiではデータベースkimassi_yadoにアクセスできません。
host=localhost;はhost=127.0.0.1; でも動作します。

ところが実際にはPHPのプログラムから、なかなかデータベースにアクセスできませんでした。
CORESERVER.JPに新たにデータベースをMySQLを追加した時に、PhpMyAdminにログインした時に新たなデータベースを反映させるには順序が大切なようです。
CORESERVER.JPに新たにデータベースをMySQLを追加した時に、PhpMyAdminのインストールをクリックしてリセットします。
次にPhpMyAdminをインストールに隣接するログインをクリックする。
そこでユーザー名とパスワードを求められます。
ここで、ユーザー名に新たにデータベース名(自分の場合はkimassi_yado)を入力して、パスワードにCORESERVER.JPの12桁のパスワードを入力します。
これでやっと新しいデータベース(自分の場合はkimassi_yado)にアクセスできまるようになりました。

CORESERVER.JP(バリューサーバー)では標準のPHPが「PHP5.6(モジュール版)」になっていてPHPが7.2だと動作に制限があるようです。
でもPHPが7.2でもMySQLにアクセスできました。

でも、なぜか更新ページで処理が途中で止まってしまうようです。エラーは出てないのですが、すんなりとはいきません。

2019年3月18日

更新ページで処理が途中で止まる理由を調べようとプログラムを単純化してみたのですが、MySQLには関係なく、CORESERVER.JP(バリューサーバー)では処理に時間がかかると負荷の大きさに関わりなく、動作をストップする仕様になっているようです。
やっぱり、XAMPP上で楽天関連の処理を済ませて、その後、オンライン上でデータベースの更新をするしかないようです。
現在は、CORESERVER.JP(バリューサーバー)上のデータベース名(自分の場合はkimassi_yado)を削除して、XAMPP上のデータベース(自分の場合はkimassi_yado)をsql形式でエクスポートして、CORESERVER.JP(バリューサーバー)上でsqlファイルをインポートすることによって、対応していますが、もっと簡単な方法が無いか調べてみようと思います。
念のために、Value-domainのユーザーフォーラム:CGI/PHP/DB関連で問い合わせしました。

2019年3月19日

どうしても判らなくて困った時の最後の頼みはYahoo!知恵袋です。
今回も素敵なアドバイスをいただきました。

なんでもcron 機能っていうのがあって、3件までは正常に動作するようなので、20回のに処理を分割して数分おきに実行するという方法があるようです。
でも、CORESERVER.JP(バリューサーバー)上の仕様で「cronジョブの最短間隔は1時間に1回まで」と掲載されていました。これでは使えません。
念のために、Value-domainのユーザーフォーラム:CGI/PHP/DB関連で問い合わせしました。

2019年3月21日

「ローカルのxampp側のphpスクリプトでデータを取り込む処理をした後に、そのphpスクリプトで必要なSQL文(truncate tabeleしてalter tableでauto_incrementのリセットもしくはdrop tableしてcreate tableとデータをinsertするSQL文)をダウンロードして、coreserver上のPHPファイルでcoreserver上のMySQLにおいてSQLファイルだけ実行する。」
というアイデアもアドバイスしていただけました。
でも、phpスクリプトで必要なSQL文をダウンロードするというのがうまくいかなくて、ダウンロードしたSQL文をcoreserver上のMySQLにおいて実行したら動作が長時間続いてデータは削除されてしまいました。

2019年3月22日

Value-domainのユーザーフォーラム:CGI/PHP/DB関連でもSTAFFからの返答がありました。
「処理時間が長いPHPプロセスが強制終了いたしますのは仕様でございます。API取得先の処理時間が長くなる場合は、運用が苦しいかと存じます。」という返答でした。

2019年3月23日

「作業用テーブルを使い、load data infile で取り込んで本番テーブルとidかnoでJOINしてupdateする」というアドバイスもいただいていました。
具体的には、xampp上のPHPファイルで処理をして、データはxampp上のMySQLに登録しなく別のファイル形式で保存して
coreserver上のPHPファイルで、データを作業用テーブルにload data infile で取り込んで、
update 本番テーブル join 作業用テーブル
on 本番テーブル.id = 作業用テーブル.id
set 本番テーブル.no = 作業用テーブル.no,
本番テーブル.`date` = 作業用テーブル.`date`
本番テーブル.yadomei = 作業用テーブル.yadomei
でcoreserver上のMySQLに登録という処理の流れのようです。

とりあえずは、xampp上のPHPファイルで処理をしてデータをcsvファイルとしてパソコンに出力する事から始めました。

下記のデータベースを開く命令を削除します。

<?php
try {
$db = new PDO(‘mysql:dbname=ysuiyado;host=127.0.0.1;charset=utf8’, ‘root’, ”);
} catch (PDOException $e) {
echo ‘DB接続エラー: ‘ . $e->getMessage();
}
?>

その位置を下記のcsvファイルを開く命令に入れ替えます

<?php
# 保存するファイル名を設定します。
$csvFile = ‘../../../data/output/csv-put.csv’;
if (! is_dir(dirname($csvFile))) {
die(‘保存するディレクトリが存在しません。’);
}

# ファイルを追記モードで開きます(ファイルが存在しない場合は新規作成)。
$fp = fopen($csvFile, ‘c+’);
if (! is_resource($fp)) {
die(‘ファイルを開けませんでした。’);
}

# ファイルをロックします(排他的ロック)。
flock($fp, LOCK_EX);

# ファイルの中身を空にします。
ftruncate($fp, 0); // 追記する場合はこの処理は不要
?>

下記のデータベースをアップデート箇所を削除して

$sql=’UPDATE yasuiyado SET yadomei=\”.$yado.’\’,date=\”.$day2.’\’ WHERE id=’.$n1;
$prepare = $db->prepare($sql);
$prepare->execute();

は下記のように配列にしてCSVファイルとして出力する命令に変更します。

$data=[];
$data[‘id’] =$n1;
$data[‘no’] =$n1;
$data[‘date’] =$day2;
$data[‘yadomei’] =$yado;
echo var_dump($data);
fputcsv($fp, $data);
}

最後にファイルを閉じます。

<?php
# ファイルのロックを解除します。
fflush($fp);
flock($fp, LOCK_UN);

# ファイルを閉じます。
fclose($fp);

# 保存したCSVファイルを読み込み、画面に表示します。
if (file_exists($csvFile)) {
echo ‘CSVファイルは保存されました。<br>’;
echo ‘以下は出力されたCSVファイル(’ . $csvFile . ‘)です。<br>’;
$csv = file_get_contents($csvFile);
} else {
echo ‘CSVファイルは保存されませんでした。’;
}

?>

後は、csvファイルのデータをホームページ上に反映すれば完成です。

でもパソコン上のcsvファイルのデータをPHPのプログラムでcoreserver上のMySQLに登録するのは難しいようです。
LOAD DATA local INFILEを使えばなんとかなると考えましたが、うまくいきません。

2019年3月24日

ここで、現在の処理を整理してみます。
1.ローカルのxampp上のMySQLをスタート(Apacheは自動的にスタートされる)
2.ローカルのxampp上で楽天APIのデータをxampp上のMySQLに登録
http://localhost/rakuten/rakutenyado15.php
3.ローカルのxampp上のMySQL上でデーターベースkimassi_yadoを選択しエクスポート(詳細-可能なオプションをすべて表示でDROP TABLEをコマンドを追加してからエクスポート)。sqlファイルがダウンロードフォルダに出来ている。
4.coreserver上のMySQLにアクセスし、データベースkimassi_yadoを選択し先ほどエクスポートしたsqlファイルをインポートする。

かなり面倒くさいです。
処理の問題で、ローカルのxampp上で楽天APIのデータを得るのは動かせないけど、その他の処理で省力化を図るのが課題です。

それでローカルのxampp上のMySQLを使わない方法を考えました。

1.ローカルのxampp上で楽天APIのデータをcsvファイルとしてハードディスクに保存
http://localhost/rakuten/rakutencsv.php
2.coreserver上のMySQLにアクセスし、テーブルyasuiyadoを選択し先ほどエクスポートしたcsvファイルをインポートする。
(フォーマット特有のオプションUpdate data when duplicate keys found on import (add ON DUPLICATE KEY UPDATE)にチェックを入れてインポート)

試してみましたが、うまくいきました。
最後に宿の名前の長さの上限を設定して取得するようにプログラムを変更します。

$data[‘yadomei’] =$yado;

の部分を

$data[‘yadomei’] =mb_substr($yado,0,34);

に変更して完成です。

完成したページはこちらです

2019年3月26日

今日からPHPの宿泊情報の表示を始めたのですが、楽天トラベル空室検索APIのデータを受け取る際にエラーが頻発して、最後まで処理できませんでした。

Notice: Trying to get property ‘hotelBasicInfo’ of non-object in C:\xampp\htdocs\rakuten\rakutencsv.php on line 55

Notice: Trying to get property ‘hotelName’ of non-object in C:\xampp\htdocs\rakuten\rakutencsv.php on line 55

朝は、楽天側の処理数が多くて、サーバーの処理能力が落ちているのかもしれません。
これでは使い物にならないので、途中で待ち時間を設けるか処理速度を遅くするかの対応が必要だと感じました

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);

の後に

usleep(500000);

を挿入しました。1つのデータ毎に0.5秒待つ命令です。
そしたら途中まで調子よく動作したのですが、

Fatal error: Maximum execution time of 30 seconds exceeded

のエラーが表示されました。
PHPは処理時間の制限が30秒になっているようで、30秒過ぎた時に出るエラーのようです。

set_time_limit(100);

をPHPの処理の先頭に挿入しました。100秒まで処理を続けるという命令です。

これでうまくいきました。後は、正常に動作する待機の最短時間を探せば完成かな?

1つのデータ毎に0.5秒待機だと時々失敗するようなので0.8秒にしました。

usleep(80000);

処理の制限時間は最終的に80秒にしました。

4台のパソコンにXAMPPとPHPの環境を整えたのですが、使わなく放置しておいたWindows7のAOA150(液晶サイズ:8.9インチ CPU:Atom N270/1.6GHz/1コア メモリ容量:1GB)を、この処理のメインに使おうと思います。
寝室で起きた時に操作しようと思います。

2019年3月27日

何故か朝早いと昨日からのデータを求めてしまいます。

<?php
for($n=0;$n<30;$n++)
{
$n2=’+’.$n.’ day’;
$checkinDate = date(“Y-m-d”,strtotime(“$n2”));
echo var_dump($checkinDate);

}
?>

で確認したら、昨日からの日付が表示されました。おかしいなあ。

原因はPHPの設定で、php.iniの2000行あたりで
[Date]
date.timezone=Europe/Berlin
になっているのを
[Date]
date.timezone= Asia/Tokyo
に変更すれば良いみたいです。9時間程度のずれがあったみたいです。

2019年3月30日

ブラウザのアドレスにphpの拡張子が表示されるのはいかがわしいので、phpの拡張子を消すことにしました。
.htaccessファイルに

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.php [NC,L]
</IfModule>

を追加して消せました。
拡張子なしのアドレス(https://kimassi.net/yadoitiran)でアクセスすると、ブラウザのバーでは拡張子なしのアドレス(https://kimassi.net/yadoitiran)で表示されるし、拡張子付のアドレス(https://kimassi.net/yadoitiran.php)でアクセスすると、ブラウザのバーでは拡張子付
のアドレス(https://kimassi.net/yadoitiran.php)で表示されます。

省力化のために、スタートアップにXAMPP ControlPanel(Apacheは自動起動に設定済)と通常使わないブラウザ(ホームページにlocalhost/rakuten/rakutencsv.php を設定済み)を登録しました。
でもブラウザはセキュリティソフトが立ち上がらないと起動できないので失敗しました。
batファイルのショートカットをステートアップに登録することでスタートアップで起動するプログラムの起動する時間を調整できる事がわかったので試してみることにしました。

@echo off
:遅延起動バッチファイル

echo 遅延起動を開始します。
:20秒待つ
timeout 20
:プログラム実行(カレントディレクトリ指定なし)
start “” “C:\Program Files\Mozilla Firefox\firefox.exe”

うまく動作しました。



コメントを残す

メールアドレスが公開されることはありません。