PHPの話」カテゴリーアーカイブ

「気づけばプロ並みPHP」でPHPの勉強を再開

2020年5月17日

PHPで金沢の安い宿の一覧のプログラムを改良したのを機に、PHPの勉強を再開しました。
購入したのは、「気づけばプロ並みPHP 谷藤賢一」です。「気づけばプロ並みPHP 谷藤賢一」には改訂版も出版されていますが、内容はセキュリティの増強があるだけで、ほとんど同じ内容です。

「PHPの絵本」でPHPの基礎を勉強し、「公開API活用ガイド (I・O BOOKS)」で楽天トラベル空室検索APIを使っての安い宿一覧の表示に使い、「よくわかるPHPの教科書  たにぐち まこと」「Bootstrapファーストガイド」でネット掲示板を作り、残りのPHPの主な利用用途はお店のショッピングカートということになります。
それで、お店のショッピングカートを作るのに役立つ本を探して見つけたのが、「気づけばプロ並みPHP 谷藤賢一」です。

ちょっと読んでみましたが、とても分かりやすいです。

同じ著者の「いきなりはじめるPHP~ワクワク・ドキドキの入門教室~  谷藤賢一」も初心者用には良さそうなので購入しました。

1年のブランクでPHPの基礎も、すっかり忘れていたので、良い機会だと思います。

2020年5月19日

「いきなりはじめるPHP~ワクワク・ドキドキの入門教室~  谷藤賢一」を読んでみました。
2011年に書かれた本なので、WindowsXP、WindowsVista、Windows7などしかない時代なので、さすがに内容は古いです。それを考慮しても、参考になる良書だと思います。
PHPの本当に基本的な部分は詳細に説明されていませんが(そういうのは「PHPの絵本」がお奨め)PHPでMySQLやデータベースを使う際の基本的な部分が判りやすくピックアップされているので良いです。
サンプルソースが付いていると実際に動作するのか確認出来て良いのにと思います。

2020年5月20日

「いきなりはじめるPHP~ワクワク・ドキドキの入門教室~  谷藤賢一」を読んで、PHPで理解が浅い弱点が、判ってきました。

1.シングルクォーテーション「’」とダブルクォーテーション「”」の使い方の違い
2.<form> </form>から送られてきた配列変数(スクリプトのコード中どこからでも使用可)
$_POST[‘変数‘]
3.HTMLの入力・送信フォーム
<form method=”post” action=”submitボタンをクリックされた時の飛び先“>
<input type=”submit” value=”OK”>
</form>
4.<form> </form>内でフォームの送信時にユーザーが見たり変更したりすることができないデータの扱い
<input name=”入力欄の名前” type=”hidden” value=”渡したいデータ“>
渡したいデータが変数なら
<input name=”入力欄の名前” type=”hidden” value=”‘.変数.'”>
5.SQLの入力
INSERT INTO テーブル名 (フィールド名1フィールド名2フィールド名2) VALUES (“データ1“,”データ2“,”データ3“)
6.データベース接続
「いきなりはじめるPHP~ワクワク・ドキドキの入門教室~  谷藤賢一」では
$dsn=’mysql:host=ホストのアドレス;dbname=データベース名‘;
$user = ‘ユーザー名‘;
$password =’パスワード‘;
$dbh = new PDO($dsn,$user,$password);
$dbh ->query(‘SET NAMES utf8’);
になっていますが、
$dsn=’mysql:host=ホストのアドレス;dbname=データベース名‘;
$db = new PDO($dsn, ‘ユーザー名‘, ‘パスワード‘);
を使っています。
7.データベースエンジンにSQL文で指令を出す
「いきなりはじめるPHP~ワクワク・ドキドキの入門教室~  谷藤賢一」では
$sql=’SQL文‘;
$stmt =$db->prepare($sql);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC); //$stmtから1つずつデータを取りだす
になっていますが、
$stmt =$db->query(“SQL文“);
$result = $stmt->fetch(); //$stmtから1つずつデータを取りだす
を使っています。
.データベースの登録データを読み出す
SELECT * FROM テーブル名 WHERE 条件
.データベースからデータを全部受け取る
$sql = ‘SELECT * FROM テーブル名 WHERE 1’;
$stmt = dbh->prepare($sql);
$stml->execute();
10.$stmtからデータを順番に1つずつ取り出す
$rec = $stmt->fetch(PDO::FETCH_ASSOC);
それを表示するのは
print $rec[‘フィールド名’];
すべてのページを処理するには
while(1)
{
$rec = $stmt->fetch(PDO::FETCH_ASSOC);
if($rec==false)
{
break;
}
print $rec[‘フィールド名’];
}
$dbh = null;

「気づけばプロ並みPHP改訂版 谷藤賢一」も購入しました。
「気づけばプロ並みPHP 谷藤賢一」と比較して、「気づけばプロ並みPHP 谷藤賢一」旧版のほうが必要なければ、メルカリで売ろうと思います。安く買ったので、ほとんど持ち出しなしで売れると思います。

楽天トラベル空室検索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/
で条件を設定した場合の、出力例を見る事が出来ます。
上記サイトで、+カスタムパラメーターをクリックして条件設定を行います。
地域をsmallClassCodeで指定する場合は、largeClassCode、middleClassCod、smallClassCodeのすべてを指定しないとエラーになります。
日付指定して、金沢で、1人、2000円以上(バースデー限定などの特殊条件での特別料金を外すために極端な安値は除外)、最安値を1ページ・1データで価格のみ表示という条件設定だと下記のようになります。

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

出力例では、きちんと条件に合った宿のデータが表示されていますが、実際にブラウザを立ち上げて、アドレス欄にそのまま入力するとエラー表示されます。
ブラウザ上で表示するには、どのデータを表示させるか(elements=)指定しないといけないようです

その他のパラメーターは
https://webservice.rakuten.co.jp/api/vacanthotelsearch/
で調べることができます。

部屋はシングルの場合はf_rm_bed=singleを加えます。部屋がツインの場合はf_rm_bed=twin、部屋に拘らない場合はf_rm_bed=*です。
表示をホテル名にする場合はelements=hotelName
ホテル名と料金の総額を表示する場合はelements=hotelName,total

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

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

{“hotels”:[{“hotel”:[{“hotelBasicInfo”:{“hotelName”:”ゲストハウス 和んで”}}]}]}

と表示されます。

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,total&applicationId=1089363386770913344

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

{“hotels”:[{“hotel”:[{“hotelBasicInfo”:{“hotelName”:”ゲストハウス 和んで”}},{“roomInfo”:[{“dailyCharge”:{“total”:2000}}]},{“roomInfo”:[{“dailyCharge”:{“total”:2000}}]},{“roomInfo”:[{“dailyCharge”:{“total”:3500}}]}]}]}

と出力されます。料金も表示すると、すべての該当するプラン全部の料金が出力されます。

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

公開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 = ‘**************’;

//affiliateIdを設定する
$affiliateId = ‘*************’;

//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 = ‘***************’;

//affiliateIdを設定する
$affiliateId = ‘****************’;

//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 = ‘***********’;

//affiliateIdを設定する
$affiliateId = ‘**************’;

//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”

うまく動作しました。

2019年6月5日

急にデータの取得が途中で止まるようになりました。
set_time_limit(120);
usleep(100000);
と2箇所の数値を変更して対処しました。

2019年6月30日

AOA150の不具合を修正するためにBIOSをアップデートしたら、firefoxの起動時にXAMPPがまだ起動していない事によるアクセス先につながらないというトラブルが発生し、遅延起動バッチファイルを修正し、起動後150秒後にfirefoxが起動するように変更しました。

@echo off
:遅延起動バッチファイル
:10秒待つ
timeout 10
start “” “C:\xampp\xampp-control.exe”
echo 遅延起動を開始します2。
:150秒待つ
timeout 150
:プログラム実行(カレントディレクトリ指定なし)
start “” “C:\Program Files\Mozilla Firefox\firefox.exe”

最初の10秒待ちは、バッチを中止したい場合に手動で中止できるようにするためです。
ソフトの起動に時間がかかるのは、ウィルス対策ソフトAvast Free Antivirusの影響かもしれません。

2019年7月15日

ウィルス対策ソフトAvast Free Antivirusをアンインストールしたら、ソフトの立ち上がりも速くなったし動作も安定しました。

バッチファイルも

@echo off
:遅延起動バッチファイル
:10秒待つ
timeout 10
start “” “C:\xampp\xampp-control.exe”
echo 遅延起動を開始します2。
:20秒待つ
timeout 20
:プログラム実行(カレントディレクトリ指定なし)
start “” “C:\Program Files\Mozilla Firefox\firefox.exe”

に変更しました。

2019年11月20日

最近、金沢の宿泊料金の値崩れが起きているようなので、1人1泊の最低料金を1500円に変更しました。
また、ゆにろーず金沢TS店(136975)、HOTEL花IchiRinKANAZAWA(160759)はバースデー限定などの特殊条件での特別料金の設定は無くなったようなので、除外施設から外しました。

2019年11月29日

最近、1人1泊の最低料金の宿一覧でK’s House Kanazawaが異常に多いので、調べてみました。
K’s House Kanazawaが2000円で、もっと安い宿が存在するので不思議だと思い、設定の条件を変えてみたりしたのですが、プログラムは正常に動作しているようでした。
よく調べると、K’s House Kanazawaは楽天ポイント10%というプランがあったので、実質1800円で登録されているのでした。
まあ、原因がはっきりしたのでホッとしました。

2019年12月24日

PHPで宿泊情報を表示したページをPHPファイルでアップロードしていたのですが、アフィリエイトの収益が極端に落ちてしまいました。PHPファイルだとGoogleでの検索順位が極めて不利なようです。
対策として、ファイルをhtmlに戻して、PHPでの処理結果はiframeを利用してフレーム内に表示することにしました。

<iframe src=”https://kimassi.net/yadoitirandy.php” style=”width:100%; height:600;” frameborder=0 ></iframe>

2020年4月17日

なんとか料金も表示できるように頑張ってみることにしました。
でも半年たっているので、使い方を全く忘れています。

https://webservice.rakuten.co.jp/api/vacanthotelsearch/ を見ると
予約候補内最安値はlowestChargeになっていて、データの位置は
hotels->hotel->hotelReserveInfo->lowestCharge

になっています

とりあえず、2020年5月6日チェックインで金沢でシングルベット、2000円以上で1人で宿泊した場合の最低料金は下記で出るようです。

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

表示は

{“hotels”:[{“hotel”:[{“hotelBasicInfo”:{“hotelName”:”ゲストハウス 和んで”}},{“hotelReserveInfo”:{“lowestCharge”:2000}}]}]}

になりました。該当する条件の全てのプランの料金が表示されます。この結果から「ゲストハウス 和んで」と「2000」を取り出すことが必要です。

2020年4月20日

PHPを動作させる方法すら忘れているので、さあ大変です。

自分のパソコン内でPHPを動作させるためにXAMPPをインストールすることから始めないといけないのですが、幸い、前回インストール済なので、そのまま利用する事ができます。

c:/xampp/htdocs/ に動作するPHPファイル(例えば test.php)を設置してあれば
XAMPPを起動して、 Control PanelでApacheとMySQLをStartさせて
http://localhost/test.php
でtest.phpを動作させることができます。

PHPのファイルを作る際には、UTF-8で入力することが必要であることに注意して、さあスタートです。

<?php

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

//affiliateIdを設定する
$affiliateId = ‘************’;

//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’.
‘&elements=hotelName’.
‘&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 = “2020-05-05”;
$checkoutDate = “2020-05-06”;
$minCharge = “2000”;
$adultNum = “1”;
$f_rm_bed = “single”;

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

?>

を動作したら
金沢家
と表示されます。

$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;

$Items = $xml->hotels->hotel->hotelReserveInfo->lowestCharge;
に変更して
‘&elements=hotelName’.

‘&elements=lowestCharge’.
に変更すると

Notice: Trying to get property ‘hotelReserveInfo’ of non-object in C:\xampp\htdocs\rakuten\rakutenyado.php on line 35

Notice: Trying to get property ‘lowestCharge’ of non-object in C:\xampp\htdocs\rakuten\rakutenyado.php on line 35

と表示されます。

$Items = $xml->hotels->hotel;

に変更して次の行に

echo var_dump($Items);

を追加すると、

object(SimpleXMLElement)#4 (1) { [“hotelBasicInfo”]=> object(SimpleXMLElement)#3 (1) { [“hotelName”]=> string(9) “金沢家” } }

の表示になります。

‘&elements=lowestCharge’.

を削除すると

object(SimpleXMLElement)#4(2){[“hotelBasicInfo”] => object(SimpleXMLElement)#3(27){[“hotelNo”] => string(6) “172555” [“hotelName”] => string( 9) “金沢家” [“hotelInformationUrl”] => string(67) “https://img.travel.rakuten.co.jp/image/tr/api/re/pvonD/?f_no=172555” [“planListUrl “] => string(78)” https://img.travel.rakuten.co.jp/image/tr/api/re/vFumt/?f_no=172555&f_flg=PLAN “[” dpPlanListUrl “] => object(SimpleXMLElement )#7(0){} [“reviewUrl”] => string(73) “https://img.travel.rakuten.co.jp/image/tr/api/re/gJNfM/?f_hotel_no=172555” [ “hotelKanaName”] => string(15) “かなざわや” [“hotelSpecial”] => string(126) “敷地内の駐車場13台無料。1Fカプセルベッド14室、2F個室2部屋。夜景、景色が良い “[” hotelMinCharge “] => string(4)” 2100 “[” latitude “] => string(9 ) “131449.88” [“longitude”] => string(9) “491887.06” [“postalCode”] => string(8) “921-8154” [“address1”] => string(9) “石川県” [ “address2”] => string(22) “金沢市高尾南2-68” [“telephoneNo”] => string(12) “076-298-9000” [“faxNo”] => string(12) “076 -298-1221 “[” access “] => string(151)”金沢駅よりお車にて約25分/小松空港よりお車にて約40分バスご利用の方は高尾南1丁目でお降り下さい。 “[” parkingInformation “] => string(44)”有り13台無料予約無しOK “[” nearestStation “] => string(6)”金沢 “[” hotelImageUrl “] =>文字列(62)” https://img.travel.rakuten.co.jp/share/HOTEL/172555/172555.jpg “[” hotelThumbnailUrl “] =>文字列(51)” https://img.travel.rakuten.co.jp/HIMG/90/172555.jpg “[” roomImageUrl “] => string(67)” https://img.travel.rakuten.co.jp/share/ HOTEL / 172555 / 172555_kan1.jpg “[” roomThumbnailUrl “] =>文字列(57)” https://img.travel.rakuten.co.jp/HIMG/INTERIOR/172555.jpg “[” hotelMapImageUrl “] =>文字列(65) “https://img.travel.rakuten.co.jp/share/HOTEL/172555/172555map.gif” [“reviewCount”] => string(1) “5” [“reviewAverage”] =>文字列(3) “4.5” [“userReview”] =>object(SimpleXMLElement)#8(0){}} [“roomInfo”] => array(2){[0] => object(SimpleXMLElement)#5(2){[“roomBasicInfo”] => object(SimpleXMLElement) #8(12){[“roomClass”] => string(10) “kanazawa03” [“roomName”] => string(83) “新品カプセルベッド全室テレビ付き駐車場無料手ぶらOK” [“planId”] => string(7) “4414223” [“planName”] => string(134) “【2019年1月1日OPEN】☆新品カプセルベッド☆駐車場無料☆タオル・アメニティ等・ランドリー無料” [“pointRate “] => string(1)” 1 “[” withDinnerFlag “] => string(1)” 0 “[” dinnerSelectFlag “] => string(1)” 0 “[” withBreakfastFlag “] =>string(1) “0” [“breakfastSelectFlag”] => string(1) “0” [“payment”] => string(1) “1” [“reserveUrl”] => string(203) “https:/ /img.travel.rakuten.co.jp/image/tr/api/re/IdsCY/?f_no=172555&f_syu=kanazawa03&f_hi1=2020-05-05&f_hi2=2020-05-06&f_heya_su=1&f_otona_su=1&f_s1=0&f_s2=0&f_y1=0&f_y1=0 0&f_y3 = 0&f_y4 = 0&f_camp_id = 4414223 “[” salesformFlag “] => string(1)” 0 “} [” dailyCharge “] => object(SimpleXMLElement)#7(4){[” stayDate “] => string(10 ) “2020-05-05” [“rakutenCharge”] => string(4) “2550” [“total”] =>string(4) “2550” [“chargeFlag”] => string(1) “0”}} [1] => object(SimpleXMLElement)#6(2){[“roomBasicInfo”] => object(SimpleXMLElement)# 7(12){[“roomClass”] => string(10) “kanazawa01” [“roomName”] => string(68) “43型テレビ付き夜景と映画無料見放題201号室” [“planId”] = > string(7) “4416178” [“planName”] => string(132) “ゆったりとしたセミダブルベッド2台【Netflix映画無料見放題】☆駐車場無料☆手ぶらOK禁煙” [“pointRate”] => string(1) “1” [“withDinnerFlag”] => string(1) “0” [“dinnerSelectFlag”] => string(1) “0” [“withBreakfastFlag “] => string(1)” 0 “[” breakfastSelectFlag “] => string(1)” 0 “[” payment “] => string(1)” 1 “[” reserveUrl “] => string(203 ) “https://img.travel.rakuten.co.jp/image/tr/api/re/IdsCY/?f_no=172555&f_syu=kanazawa01&f_hi1=2020-05-05&f_hi2=2020-05-06&f_heya_su=1&f_otona_su=1&f_s1=0&f_s2 = 0&f_y1 = 0&f_y2 = 0&f_y3 = 0&f_y4 = 0&f_camp_id = 4416178 “[” salesformFlag “] => string(1)” 0 “} [” dailyCharge “] => object(SimpleXMLElement)#8(4){[” stayDate “] => string(10) “2020-05-05” [“rakutenCharge”] => string(4) “2900” [“合計 “] => string(4)” 2900 “[” chargeFlag “] => string(1)” 0 “}}}}

と表示されるので、ちゃんと料金もデータとして出力されている事になっています。

$Items = $xml->hotels->hotel->hotelBasicInfo;
echo var_dump($Items);

にすると、料金などの予約情報は表示されなくなります。

$Items = $xml->hotels->hotel->hotelReserveInfo;
echo var_dump($Items);

にすると、

オブジェクト(SimpleXMLElement)#3(0){}

になります。

$Items = $xml->hotels->hotel->dailyCharge;
echo var_dump($Items);

にしても、

オブジェクト(SimpleXMLElement)#3(0){}

になります。やっぱりデータが無いようです。

$Items = $xml->hotels->hotel;
‘&elements=rakutenCharge’.
echo var_dump($Items);

にしたら、

object(SimpleXMLElement)#4(1){[“roomInfo”] => array(2){[0] => object(SimpleXMLElement)#3(1){[“dailyCharge”] => object(SimpleXMLElement)#6 (1){[“rakutenCharge”] => string(4) “2550”}} [1] => object(SimpleXMLElement)#5(1){[“dailyCharge”] => object(SimpleXMLElement)#6(1 ){[“rakutenCharge”] => string(4) “2900”}}}}

になります。

echo var_dump($Items);

を削除したら何も表示しなくなります。そのまま

$Items = $xml->hotels->hotel;
‘&elements=’hotelName.

にしても何も表示されません。

$Items = $xml->hotels->hotel->hotelName;
‘&elements=’hotelName.

にしても何も表示されません。やっぱり

$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;
‘&elements=’hotelName.

のようにしっかりと指定しないとデータとして取得出来ないようです。
いろいろ試行錯誤して、

$Items = $xml->hotels->hotel->roomInfo->dailyCharge->rakutenCharge;
‘&elements=rakutenCharge’.

で料金を取り出せる事に気づきました。一挙に前進です。

<?php

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

//affiliateIdを設定する
$affiliateId = ‘***************’;

//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’.
‘&elements=hotelName’.
‘&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;
}

function yado_rakuten2($checkinDate,$checkoutDate,$adultNum,$minCharge,$f_rm_bed){
//developerIdを設定する
$applicationId = ‘**************’;

//affiliateIdを設定する
$affiliateId = ‘**************’;

//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’.
‘&elements=rakutenCharge’.
‘&f_rm_bed=’.$f_rm_bed ;

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

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

//xpathによって、Item要素だけを取り出す
$Items2 = $xml->hotels->hotel->roomInfo->dailyCharge->rakutenCharge;

return $Items2;
}
?>

<?php
$checkinDate = “2020-05-05”;
$checkoutDate = “2020-05-06”;
$minCharge = “2000”;
$adultNum = “1”;
$f_rm_bed = “single”;

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

で宿名と料金を出力できました。

金沢家2550

これを利用して、csvファイルを作成するPHPプログラムも無事動作しました。
後は、サーバーのデータベースのテーブルのカラムを変更して、作成したcsvファイルを送って、ページの表示部分を少し変更するだけです。
とは言え、データベースの操作方法も完全に忘れています(苦笑!)

http://kimassi.****.coreserver.jp/log/phpmyadmin/
にアクセスして
データーベース kimassi_yadoを作成

ユーザー名   kimassi_yadoでログイン
データーベース kimassi_yadoを選択して

テーブル    yasuiyado2 を作成
id  主  int(11)  AUTO_INCREMENT(AI)
no      int(11)
date   text    照合順位はutf8_unicode_ci
yadomei  text    照合順位はutf8_unicode_ci
ryoukin  int(11)

インデックス   PRIMARY  BTREE  ユニーク はい  カラム id  照合順序 A
ID      BTREE  ユニーク いいえ カラム id  照合順序 A

作成したcsvファイルをyasuiyado2 にインポートしてデータベースの更新は完了です。

2020年5月1日

選んだ条件によって再安値の宿名で、宿泊者の条件を限定した場合は宿名を「表示しない」と表示しているのですが、「表示しない」が大量に並ぶと見栄えが悪いので、2番目に安い宿名を表示するのに変更しようと試みているのですが、難しいです。条件式を使ってなんとか除外対象でない最安値の宿名を表示することができました。

<?php

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

//affiliateIdを設定する
$affiliateId = ‘*************’;

//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=5’.
‘&page=1’.
‘&sort=+roomCharge’.
‘&elements=hotelName,hotelNo’;

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

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

$Items = $xml->hotels->hotel->hotelBasicInfo->hotelName;
$hotelNo = $xml->hotels->hotel->hotelBasicInfo->hotelNo;
$Items2 = $xml->xpath(‘hotels/hotel/hotelBasicInfo/hotelName’);
$hotelNo2 = $xml->xpath(‘hotels/hotel/hotelBasicInfo/hotelNo’);
foreach($hotelNo2 as $hotelNo3){
if (($hotelNo3 <>’153335′) && ($hotelNo3 <>’171908′) && ($hotelNo3 <>’165677′) && ($hotelNo3 <>’177472′)){
$Items=$hotelNo3;break;}
else {}

}

return $Items;
}

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

//affiliateIdを設定する
$affiliateId = ‘***************’;

//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.
‘&hotelNo=’.$Items.
‘&hits=5’.
‘&page=1’.
‘&sort=+roomCharge’.
‘&elements=hotelName,hotelNo’;
//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);

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

$Items2 = $xml->hotels->hotel->hotelBasicInfo->hotelName;

return $Items2;

}

function yado_rakuten3($checkinDate,$checkoutDate,$adultNum,$minCharge,$Items){
//developerIdを設定する
$applicationId = ‘*****************’;

//affiliateIdを設定する
$affiliateId = ‘****************‘;

//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.
‘&hotelNo=’.$Items.
‘&hits=5’.
‘&page=1’.
‘&sort=+roomCharge’.”;
‘&elements=total’;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);
//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);
//xpathによって、Item要素だけを取り出す
$Items3 = $xml->hotels->hotel->roomInfo->dailyCharge->total;

return $Items3;
}

?>
<?php
$checkinDate = “2020-05-20”;
$checkoutDate = “2020-05-21”;
$minCharge = “2000”;
$adultNum = “2”;
$Items = yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge);

echo yado_rakuten($checkinDate,$checkoutDate,$adultNum,$minCharge);
echo yado_rakuten2($checkinDate,$checkoutDate,$adultNum,$minCharge,$Items);
echo yado_rakuten3($checkinDate,$checkoutDate,$adultNum,$minCharge,$Items);
?>

2020年5月13日

あまりにも金沢中心街から離れている宿を除外して、場外対象を増やしたら最安値5位までのすべての宿が場外対象になってデータを取れなくなったので、取得データを5軒から8軒に増やした。

‘&hits=8’.

現時点の該当日の安値一覧を表示ボタンを設置していたのですが、日付が変わってから、翌朝データを取得するまでの時間帯で1日のずれが生じることに気づいた。なんとかしないといけません。

2020年5月14日

テーブルの項目を1つ増やしてチェックイン日を登録して表示させるようにしました。

http://kimassi.****.coreserver.jp/log/phpmyadmin/
にアクセスして

データーベース kimassi_yadoを作成

ユーザー名   kimassi_yadoでログイン
データーベース kimassi_yadoを選択して

テーブル    yasuiyado3 を作成
id  主  int(11)  AUTO_INCREMENT(AI)
no      int(11)
date   text    照合順位はutf8_unicode_ci
check  DATE
yadomei  text    照合順位はutf8_unicode_ci
ryoukin  int(11)

インデックス   PRIMARY  BTREE  ユニーク はい  カラム id  照合順序 A
ID      BTREE  ユニーク いいえ カラム id  照合順序 A

チェックイン日と翌日の年、月、日を取得するのは下記でできました。
翌日のデータを取得するstrtotimeの関数の書式が、PHPを説明するサイトによってまちまちで統一されていなくて動作しなかったりします。書式が経年的に変化しているのかもしれません。

<?php
for($n=1;$n<30;$n++){
$stmt =$db->query(“SELECT * FROM yasuiyado2 where id=$n”);
$result = $stmt->fetch();
$n2 = $result[‘check’];
$y1 = date(“Y”,strtotime(“$n2”));
$m1 = date(“m”,strtotime(“$n2”));
$d1 = date(“d”,strtotime(“$n2”));
$y2 = date(“Y”,strtotime($n2.”+1 day”));
$m2 = date(“m”,strtotime($n2.”+1 day”));
$d2 = date(“d”,strtotime($n2.”+1 day”));
}
?>

2020年5月23日

最近、120秒以内に処理できない事が増えてきて、処理時間の短縮が必要になりました。
function 関数を使うのをやめました。
ついでにデータベースにhotelNoも登録するように変更しました。

<?php
set_time_limit(120);
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”;
$w=date(“w”,strtotime(“$n2”));
$week_name = array(“日”,”月”, “火”,”水”,”木”,”金”,”土”);
$day2=date(“m-d”,strtotime(“$n2″)).'(‘.$week_name[$w].’)’;

//developerIdを設定する
$applicationId = ‘****************’;

//affiliateIdを設定する
$affiliateId = ‘****************’;

//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=8’.
‘&page=1’.
‘&sort=+roomCharge’.
‘&elements=hotelNo’;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);
usleep(160000);
//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);

$hotelNo2 = $xml->xpath(‘hotels/hotel/hotelBasicInfo/hotelNo’);
foreach($hotelNo2 as $hotelNo3){
if (($hotelNo3 <>’153335′) && ($hotelNo3 <>’171908′) && ($hotelNo3 <>’165677′) && ($hotelNo3 <>’177472′) && ($hotelNo3 <>’160759′) && ($hotelNo3 <>’172555′) && ($hotelNo3 <>’151419′)&& ($hotelNo3 <>’147855′)){
$Items=$hotelNo3;break;}
else {}

}

//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.
‘&hotelNo=’.$Items.
‘&hits=1’.
‘&page=1’.
‘&sort=+roomCharge’.”;
‘&elements=hotelName,total’;

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);
//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);
//xpathによって、Item要素だけを取り出す
$yado2 = $xml->hotels->hotel->roomInfo->dailyCharge->total;

$yado = $xml->hotels->hotel->hotelBasicInfo->hotelName;

usleep(140000);
$data=[];
$data[‘id’] =$n1;
$data[‘no’] =$n1;
$data[‘date’] =$day2;
$data[‘check’] =$checkinDate;
$data[‘hotelNo’] =$Items;
$data[‘yadomei’] =mb_substr($yado,0,34);
$data[‘ryoukin’] =$yado2;
echo var_dump($data);
fputcsv($fp, $data);

}
?>

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

2020年11月1日

検索日に空き室が全くない場合に、データを取得できなくて処理がエラーになる事態に陥りました。
途中でエラーが出ると、データがアップロードされないので全く更新できなくなります。

$hotelNo2 = $xml->xpath(‘hotels/hotel/hotelBasicInfo/hotelNo’);

でデータを取得できなかったのが原因のようです。

$hotelNo2 = $xml->xpath(‘hotels/hotel/hotelBasicInfo/hotelNo’); の1つ前の
$xml = simplexml_load_string($str); のデータが無い場合に該当なしのデータを登録して書き込む命令を挿入しました。

if(empty($xml)){
$data=[];
$data[‘id’] =$n1;
$data[‘no’] =$n1;
$data[‘date’] =$day2;
$data[‘check’] =$day2;
$data[‘hotelNo’] =””;
$data[‘yadomei’] =”該当なし”;
$data[‘ryoukin’] =””;
echo $data[‘date’].’ ‘.$data[‘check’].’ ‘.$data[‘yadomei’].’ ‘.$data[‘ryoukin’].”<br />”;

fputcsv($fp, $data);
}
else
{
従来の処理内容
}

2020年11月15日

エラー表示が出て、宿の最安値を取得できない日がある現象が起きました。
その他の日のデータは表示されるので、それほど致命的な状況ではありません。
その日のデータを調べると、その日に泊まれる宿は1軒だけしかありませんでした。
その宿が、高齢の誕生日の人だけに対しての特別価格を設置しているので、該当データから外してある宿なのでした。
こういう例は、滅多にない事なので、そのままにしておきました。

2021年1月5日

最近、エラー表示が出ることが増えました。
パソコンの性能の問題もあるかなと思ったのですが、パソコンを入れ替えてみました。

XAMPP Version: 7.4.13をインストールしました。特殊な設定をしなくてもすんなりと使えました。
なぜか日付時間が8時間ほどずれていました。
php.ini の地域をAsia/Tokyoに設定しました。

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone =Asia/Tokyo

でも解決しなくて、PHPファイル(XAMPP上のプログラムファイル)の最初に

<?php
date_default_timezone_set(‘Asia/Tokyo’);
?>

を加えると解決しました。

パソコンの性能が上がると、楽天のサーバー上の処理を待ちきれなくエラーになるので、usleep();の値を上げて待ち時間を確保しないといけないようです。

//RESTで返されるXMLファイルを取得する
$str = @file_get_contents($url);
usleep(20000);
//XMLを解析してオブジェクトにセットする
$xml = simplexml_load_string($str);
usleep(20000);
//xpathによって、Item要素だけを取り出す
$yado2 = $xml->hotels->hotel->roomInfo->dailyCharge->total;
$yado = $xml->hotels->hotel->hotelBasicInfo->hotelName;
usleep(200000);

usleep(20000);
$hotelNo2 = $xml->xpath(‘hotels/hotel/hotelBasicInfo/hotelNo’);
usleep(20000);
foreach($hotelNo2 as $hotelNo3)

2021年1月13日

エラー表示が出たのにアップロードされる場合のデータを確認しました。
宿の登録番号までは取得できているのに、宿名と宿泊費のデータを取得できていませんでした。

2021年1月20日

usleepの時間を延長すると、エラーが全くでなくなりました。
パソコンのスペックが上がると、データ処理の時間が短くなるので、usleepの時間を長くしてもサーバーでのPHPの処理時間の制限内に収める事ができるので、より安定的した処理が可能のようです。

2022年9月7日

最近、firefoxの起動時にXAMPPがまだ起動していない事が原因でアクセス先につながらないというトラブルが発生するようになってきました。

久しぶりに、このプログラムを触ろうと思ったら、どこにプログラムのファイルがあるかも忘れていて、すごく苦労しました。

c:xampp/htdocs/   にありました。

スタートアップに登録されている遅延起動バッチファイルを修正し、xampp-controlの起動を20秒後に、その50秒後にfirefoxが起動するように変更しました。

@echo off
:遅延起動バッチファイル
:20秒待つ
timeout 20
start “” “C:\xampp\xampp-control.exe”
echo 遅延起動を開始します。
:50秒待つ
timeout 50
:プログラム実行(カレントディレクトリ指定なし)
start “” “C:\Program Files\Mozilla Firefox\firefox.exe”

 

WordPressでのテンプレートの不満をまとめて修正しました

2019年5月29日

WordPressのブログでsitemap-generator.php on line 45に関してWarning: Use of undefined constant ddsg_languageのエラーが出るようになりました。
ネットで検索したら、PHP7.2以降でエラー表示するようです。
https://www.seojuku.com/blog/sitemap-generator-php-warning.html#comment-2305
で解決法が掲載されていて無駄な時間を費やさなくて済みました。
ありがたい事です。

そこで気づいたことがありました。pluginsってPHPで出来ているんですよね。
じゃあ、pluginsとかWordpressとか自分で好きなように改造できるんじゃないかと

例えば、sitemapは、従来1ページに50記事しか表示されなく、全部で2000記事があり45ページもあるので全部見るのが大変なんです。
それでsitemapで最初にカテゴリ一覧が表示されて、カテゴリをクリックしたら、そのカテゴリに登録された記事を全部まとめて表示できるようにしたいです。

それと、カテゴリ別での表示の場合、カテゴリごとの最新ページ一覧を表示させたいです。

2019年5月30日

カテゴリ別での記事一覧表示は、WordPress Popular Posts と WPP Plus Widgetというpluginsで対応できることがわかりました。
https://gameusers.org/dev/blog/wpp-plus-widget-new/
を参考に、記事フォーマットを

<li>
<div class=”wpp-list-category-new-title”>{title}</div>
</li>

にしました。記事一覧が10個しか表示されないのは物足りないので、20個ぐらいになるよう改造することにしました。

pluginsの WPP Plus Widgetの中のwpp-plus-widget.phpというファイルの中の

<p><label for=”<?php echo $this->get_field_id( ‘num_posts’ ); ?>”>記事数:</label>
<select class=”widefat” id=”<?php echo $this->get_field_id( ‘num_posts’ ); ?>” name=”<?php echo $this->get_field_name( ‘num_posts’ ); ?>”>
<?php for( $i = 1; $i <= 10; $i++ ) { ?>
<option<?php if( $i == $num_posts ) {echo ‘ selected’;} ?>><?php echo $i; ?></option>
<?php } ?>
</select></p>

の部分の
<?php for( $i = 1; $i <= 10; $i++ ) { ?>

<?php for( $i = 1; $i <= 20; $i++ ) { ?>
に変更すると希望通りになりました。

後で気づいたのですが、個別の記事を単独で表示した場合も、関連のカテゴリの最新記事一覧が表示されるようになりました。便利です。

sitemapのほうもHierarchical HTML Sitemapというpluginsを使用すれば、希望通りに出来る事に気づきました。
さっそく導入しました。
最初にカテゴリ一覧が表示され、その下に記事一覧が延々と表示されます。
カテギリ一覧のカテゴリを表示すると、そのカテゴリ一覧の部分にジャンプします。
これは良いです。

ついでにカテゴリの表示順もMy Category Orderを使って修正しておきました。なんか元々pluginsにインストールしてあり有効化までしてあったのですが、外観—ウィジェットでMy Category Orderを登録してなかったので動作していなかったのです。

ずっと前から不満に思っていた事が、あっという間に解決しました。
もっと早く着手すれば良かった。

PHPのホームページの中に掲示板も設置してみました

2019年4月13日

Swiperを設置したホームページが完成したので、PHPのホームページの中に掲示板も設置してみようかなと思います。
PHPって、本当に面白いです。

2019年4月20日

最初にMySQLのデータベースのテーブルを設定しました。
kimassi_userデータベースで、user_id ,user_name ,user_nickname ,user_email ,user_password ,user_juusyo
kimassi_toukouデータベースで、toukou_id ,toukou_comment ,toukou_date ,toukou_bukken ,toukou_user_id
です。

2019年4月28日

大苦戦しています。
ネットでPHPの掲示板の検索をしてますがPHP7対応の物がほとんどなく、そのままちょっとした改造で使えるものは見つかりません。
その中でも、https://manablog.org/php7-review-bulletin-board/ のサイトが最も求めるものに近いかなと思い、それを基本にして掲示板を作る事にしました。
ただ、この掲示板のプログラムはデータベースの接続方法が最新のPDOを採用してないので、苦戦は覚悟していました。
最初は、データベースの構造も自分向けに改造し、しかも一挙にPDO対応で作ろうと思ったのですが、どうもうまく動作しなく、とりあえずはデータベースの構造だけ変更して、データベースMySQLへの接続方式は、$mysqliでMySQLに接続する仕様のままで動作確認をして、それからPDO対応に改造する方針に切り替えました。
なんで、これだけ苦戦しているのかというと、PHPファイルが単独で動作していないので、複数のファイルが完璧になって初めて正常に動作するのです。しかもデータベースを使うので、共通の仕様にする必要のある部分もあって、ファイルを1つ1つ仕上げていくという訳にはいかないのです。

2019年4月29日

なんとか、すべての機能を動作させることに成功しました。
かなり手を加えました。
これからPDO仕様に改造します。

2019年5月2日

$mysqliでMySQLに接続するプログラムをPDOでMySQLに接続する仕様に作り変えるのはかなり大変です。
今まで気づいたことをなんでもメモしておきます。

function login_user($user_email,$user_name,$user_nickname,$user_tel,$user_juusyo,$user_password,$pdo)
では使用するすべてのカラムの変数と、 $stmt = $pdo->prepare($sql); の変数$pdoを必ず記載する必要があります。

$stmt = $pdo->prepare( について、変数名$stmt、変数名$pdoは関係するプログラムすべてで統一する必要があります。自分で使う変数を統一しておく癖をつけておいたほうが良いようです。

if文で条件が同値の場合は == 条件が2つの分岐は elseif

他のページでも変数の値を受け取れる$_SESSION変数を使う場合は、$_SESSION変数が登録されていない場合の処置(if文)も必要。$_SESSION[‘log’]の場合は
if (!isset($_SESSION[‘log’]))

$_SESSION変数を使う場合は、session_start();が必要で、同じページ内で重複して使うとエラーになるので、functionのページには挿入しないほうが良い。
functionのページには2つの内容のfunctionは入れないほうが良い。

http://localhost/hudousan/public/detail.php?no=1 の1を取得して他のページでも使う場合は

$_SESSION[‘id’]= $_GET[‘no’];

2019年5月5日

なかなか正常に動作しなくて、悩み続けていたのですが、結局、MYSQLの設定が変わっていて、AUTO_INCREMENTが正常に動作していなかったのが主な原因でした。

$sqlの登録

$stmt = $pdo->prepare($sql);
$stmt->execute();

は正常に行われていたのですが、それを実行

$stmt->execute();

しても動作しなかったのです。
$sqlの内容を、直接 MySQLのSQLで直接記入し(copy&pasteできないので)実行させたのですが、何の反応もなく動作しませんでした。
それでプログラムの不備でなくてMYSQLの構造に不備がある事が判明しました。
テーブルtoukou にはtoukou_id というカラムがあるのですが、AUTO_INCREMENTが、うまく動作していなかったようです。

それにいたるまで、Yhooの知恵袋でも、いろいろ教わったし、勉強にもなりました。

次は、投稿内容を運営者と出品者にMAILを送るようにする事です。

【PHPでメール送信】XAMPPのローカル環境上でPHPを使って自分のgmailからメールを送信する


を参考に

XAMPP環境でメールを送る場合はSMTPの設定をC:\xampp\php\php.ini([mail function]のところの変更)、C:\xampp\sendmail/sendmail.ini のSMTPの設定を書き換えました。
Apacheの再起動をしてから設定が有効になりました。
無事、正常に動作しました。

次に、ユーザー登録で、住所と電話番号は任意にしました。
入力があれば、入力を登録し、入力が無ければnullを登録します。
住所と電話番号のカラムはnullでも対応できるようにMySQLを設定しておきます。

if(isset($_POST[‘user_tel’])){$user_tel = $_POST[‘user_tel’];}
else{$user_tel =null;}
if(isset($_POST[‘user_juusyo’])){$user_juusyo = $_POST[‘user_juusyo’];} else{$user_juusyo = null;}

掲示板単独では動作するようになったので、ページの内部に掲示版を挿入しようと思います。

2019年5月6日

XAMPP上ですが、ページの内部に掲示版を挿入することに成功しました。

やったね!!

よく見ると、スタイルシートが外部のサイトと接続して参照されているので、そのサイトが閉鎖されたり移転されると正常に表示されなくなる心配があるので、変更が必要だと気づきました。

2019年5月7日

XAMPP上ですが、ページの内部に掲示版を挿入することに成功しました。

http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js

リンク先のスタイルシートは自分のサイトにインストールすることも可能なようです。BootstrapからDownload Bootstrapをクリックしてダウンロードして、解凍したファイルについて

Bootstrapの公式サイトからダウンロードしたCSSファイル「bootstrap.css他」をCSSフォルダ(元々CSSフォルダに入っている)に入れる。
Bootstrapの公式サイトからダウンロードしたJavascriptファイル「bootstrap.js他」をJSフォルダ(元々JSフォルダに入っている)に入れる。
jQueryの公式サイトからダウンロードしたjavascriptファイル「jquery.min.js」をJSフォルダに入れる。

無事、動作しました。

2019年5月9日

いろいろと試行錯誤して、PDO::FETCH_ASSOC や #result =$stml_>fetch(); などFETCH関数は意味も分からずむやみに使わない方が良いようです。

MySQLからデータを取り込む場合は

$sql=”SELECT user_id,user_email,user_name,user_nickname,user_tel,user_juusyo,user_password
FROM user WHERE user_email = ‘$user_email'”;

$stml = $pdo->prepare($sql);
$stml->execute();

foreach($stml as $result){
$db_hashed_pwd = $result[‘user_password’];
$user_id = $result[‘user_id’];
}

みたいな感じで取得すれば良いようです。

最近、苦労してるのは、他のページやページをリダイヤルする
header(“location: ページURL”);
ですが、かなり制約があって難しいのです。
XAMPP上では正常に動作するのにインターネット上だと動作しない事もあったりします。
header()の前に文字を表示したりするとダメみたいなのですが、実際にどういう場合にはダメなのか、よくわかりません。
それとセッション変数を使っている場合に、途中で登録したデータが消えるという事です。
この2つが解決すると、PHPのプログラムでの不具合が随分減ると思います。

2019年5月10日

セッション変数に登録したデータが消える件は、解決法が見つかりました。
サーバーにあるphp.ini の編集をします。

xrea(coreserver)サーバのトップページからログインします。
php設定から自分のサイトで使っているのPHPバージョンを調べます。自分はphp7.2でした。
FTPでサーバにつなぎpublic_html配下の.fast-cgi-binフォルダ配下のphp53.ini,php54.ini,php55.ini,php56.ini,php70.ini の当該バージョンのphpXX.iniを編集します。
自分の場合はphp7.2.iniです。

session.auto_start = 0 なっているのを session.auto_start = 1 に変更してアップロードします。
これで一挙に解決しました。
ファイル上で、session_start(); が有効に動作しない場合もあるようで、session.auto_start = 1 にすると、常にセッション変数が有効になるようです。

2019年5月11日

セッション変数が記憶されない件と、メールが送れない件と同時に試行錯誤したので、何が原因でメールを送れないのかはっきりしないのですが、無事送れるようになりました。
メールは運営者である自分と、その物の売主に送るように設定しています
下記をCOPY&PASTEすると”や ‘が全角になるので注意して使ってください。
最初のプログラムでは
$to = “kimassi@spacelan.ne.jp,$adress”;
$title = ‘金沢近郊の激安の中古の戸建て物件’.$no;
$content = $add_toukou;
$from = ‘From: kimassi@spacelan.ne.jp’ . “\r\n”;
$result = mb_send_mail($to, $title, $content,$from);
if($result){
echo “メールを送信しました”;
} else {
echo “メールの送信に失敗しました”;
}

 

で、念のためSMTPでも送れるようなプログラムも作ってみました。
PHPMailerを使います。

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require ‘../src/Exception.php’;//ディレクトリを確認し修正が必要
require ‘../src/PHPMailer.php’;//ディレクトリを確認し修正が必要
require ‘../src/SMTP.php’;//ディレクトリを確認し修正が必要
/* オブジェクト生成 */
$mail = new PHPMailer(true);
try {
/* サーバー設定 */
$mail->isSMTP();
$mail->SMTPAuth = true;
$mail->Host = “mail.spacelan.ne.jp”;
$mail->Username = “メールサーバーのIDを記入”;
$mail->Password = “メールサーバーのパスワードを記入”;

$mail->Port = “587”;
/* 送受信者設定 */
$mail->setFrom(“kimassi@spacelan.ne.jp”, “激安戸建て”);
$mail->addAddress(“kimassi@spacelan.ne.jp,$adress”);
$mail->addReplyTo(“kimassi@spacelan.ne.jp”, “激安戸建て”);
/* コンテンツ設定 */
$mail->CharSet = “UTF-8”;
$mail->Encoding = “base64”;
$mail->Subject = “‘金沢近郊の激安の中古の戸建て物件’.$no”;
$mail->isHTML(【HTMLメール:`true`or`flase`】);
$mail->Body = “h($add_toukou)”;
/* メール送信試行 */
$mail->send();
} catch (Exception $e) {
/* 例外処理 */
die(“Message could not be sent. Mailer Error: “.$mail->ErrorInfo);
}

SMTPでも送れるようにするには、
Exception.php 、PHPMailer.php 、SMTP.php
をアップロードしておかなければいけません。
https://github.com/PHPMailer/PHPMailer/
でダウンロードできます(srcfフォルダ内にあります)。

「C:\xampp\php\php.ini」を編集して「include_path」の項目でinclude_path=”.;C:\xampp\php\PEAR” をinclude_path=“.;C:\xampp\php\PEAR;C:\xampp\php\PHPMailer”  に変更が必要です。

extension=php_openssl.dll の部分を行頭にセミコロンがあれば削除して有効化します。

これでSMTPでメールを送れるようになるはずです。

参考にしていた掲示板のサンプルプログラムでcssの制御にBootstrapが使われていたので、そのまま使っていたのですが、修正もしたいし、便利そうなのでBootstrapの勉強もしようと思います。
Bootstrapは、最も有名なWEBフレームワークだそうです。WEBページでよく使われるフォーム、ボタン、メニューなどの部品がテンプレートとして用意されていてモバイル対応にも優れているそうです。BootstrapではSwiperを使わなくても画像の入れ替えもできるようです。

2019年5月12日

Bootstrapの使い方を知らないままに、参考にしたサイトのままで使っていたのですが、選択画面の位置関係がどうしても気に入らなくて、いろいろ調べてみましたが、なかなか解決しなく苦戦していました。
結局、下記の方法で、希望の幅で表示する事が可能になりました。
(当然<head>より下で</head>より上の方に挿入します)

<STYLE>
<!–
@media (min-width: 800px) {
.container {
max-width: 800px;
}
}
–>
</STYLE>

あと、選択画面のメニューが狭い画面(スマートフォンなど)だと横線3本の表示になりますが、それをクリックしてもメニューが表示されません。ハンバーガーメニューというものらしいです。
XAMPP上では正常に動作しています。
これも解決しければいけません。

header(“location: ページURL”); が動作しない件は、他の件について試行錯誤していたら、知らない間に動作するようになりました。
プログラム上のトラブルでは無かったのかもいれません。
他のプログラムの変更以外は設定など変更したところは無いので不思議です。

ハンバーガーメニューの件も動作するようになりました。
</body> のすぐ後に
<script src=”https://kimassi.net/hudousan/js/jquery-3.4.1.min.js”></script>
<script src=”https://kimassi.net/hudousan/js/bootstrap.min.js”></script>
を入れる事と、jquery-3.4.1.min.jsをダウンロードしてアップロードすることが重要です。
それと、
https://kimassi.net/hudousan/css/bootstrap.min.css
https://kimassi.ne/hudousan/css/bootstrap-theme.min.css
については参考にしたプログラムとバージョンを合わせる事が必要ですし、念のため、ダウンロードしたBootstrapのファイルは全てアップロードしておいたほうが無難です。

Webデザインの知識がなくてもOK!Bootstrapの使い方【入門者向け】


http://proengineer.internous.co.jp/content/columnfeature/12468

が参考になりました。

一応、すべて完成しました。1ヶ月もかかりましたがPHPの勉強になりました。

https://kimassi.net/hudousan/hudousan.php

2019年5月19日

投稿があった時に、運営者と出品者にメールを送るようにしてあるのですが、Gmailのアドレスへ送るとメールが届かないようです。
自動送信メールはSMTP経由で送るようにした方が無難なようです。

SMTPで送るプログラム(PHPMailer使用)も作ってあったのですが、再び使うとインターネット上でもXAMPP上でも動作しなくなっていました。
おかしいなあ、以前は動作していたんだけど・・・・・・

ちなみに、spacelan ,gmail,yahoo,coreserverのいずれのサーバーで設定しても、SMTPホストへの接続ができません。
PHPMailerのバージョンとプログラムの書式の相性の問題かもしれません。
PHPMailerの使い方を説明したサイト自体が少なく、バージョンなど環境が一致しないので、なかなか自分の環境に合うものが見つからないのです。
古いバージョンのPHPMailerを使ったほうが良いようです。

2019年5月20日

PHPMailerのバージョンを6.0.7から5.2.27に入れ替えたら、gmailやcoreserverからは送れました。でもspacelanからは送れません。

それと、header(“location: ページURL”); が動作しなくなりました。メールを送る処理に時間がかかるせいかもしれません。
usleep(2000000); を入れて動作を一時停止をしても状況は変わりません。

2019年5月21日

PHPMailer使用してSMTPでメールを送ってもGmailでは受け取りを拒否するようです。
coreserverやspacelanやyahooメールでは受けとれます。

coreserverのSMTPから送る設定にしていましたが、XAMPP環境ではメールを送れていましたが、インターネット環境からはメールを送れません。
問題山積です。

spacelanからメールを送れない件はプロバイダ(金沢ケーブルテレビ)に問い合わせしておきました。

2019年5月23日

インターネット上でのPHPMailerの不具合とheader(‘Location:の不具合に苦戦しているのですが、それで、問題点を整理してみました。基本はXAMPPの環境で下記のPHPプログラムで動作確認しました。

<?php

mb_language(“japanese”);
mb_internal_encoding(“UTF-8”);

//ソースを全部読み込ませる
//パスは自分がPHPMailerをインストールした場所で

require dirname(__FILE__).’./../../php/phpmailer/PHPMailerAutoload.php’;

require dirname(__FILE__).’./../../php/phpmailer/language/phpmailer.lang-ja.php’;

//autoloderはcomposerでのインストールじゃないとないので
//あえて記述しません。

//SMTPの設定
$mail = new PHPMailer;//インスタンス生成

$mail->IsSMTP();//SMTPを作成
$mail->Host = ‘s197.coreserver.jp’;//メールの環境に合わせて
$mail->SMTPAuth = true ; // SMTP認証を有効に
$mail->CharSet = ‘utf-8’;//文字セットこれでOK

$mail->Username = ‘mail@kimassi.net’; // ユーザー名
$mail->Password = ‘***********’; // パスワードを記入
$mail ->SMTPSecure = ‘STARTTLS’ ; // TLS暗号化を有効に
$mail->Port = 587;//tlsは587でOK

$mail->SMTPDebug = 2;//2は詳細デバッグ1は簡易デバッグ本番はコメントアウトして
$mail->isHTML(true); // HTML形式のメールに設定
//メール本体

$mail->setFrom(‘mail@kimassi.net’,’激安戸建て’); //差出人の設定

$mail->Subject = ‘金沢近郊の激安の中古の戸建て物件’;//件名の設定
$mail->Body = ‘メッセージ本体coreserver’; //メッセージ本体
$mail->AddAddress(‘kanadylan@gmail.com’); // To宛先
$mail->addReplyTo(‘kimassi@spacelan.ne.jp’); //返却アドレス
$mail->addCC(‘syun@kimassi.net’); // Ccアドレス
$mail->isHTML(true);
if(!$mail->send()){
echo ‘Message could not be sent. Mailer Error: ‘, $mail->ErrorInfo;
} else {
echo ‘Message has been sent’;
}

?>
<?php
header(‘Location:https://www.yahoo.co.jp/’);
?>

XAMPP環境では上記のプログラムではSpacelanからはメールを送れませんが、gmailとcoreserverからはメールを送れました。
header(‘Location:https://www.yahoo.co.jp/’); はこれだけの内容だと機能しています。

インターネット上では
require dirname(__FILE__).’./../../php/phpmailer/PHPMailerAutoload.php’;require dirname(__FILE__).’./../../php/phpmailer/language/phpmailer.lang-ja.php’;
の部分を
require_once ‘https://kimassi.net/hudousan/phpmailer/PHPMailerAutoload.php’;
require_once ‘https://kimassi.net/hudousan/phpmailer/language/phpmailer.lang-ja.php’;
に変更しましたが動作しませんでした。
require_once ‘https://kimassi.net/hudousan/phpmailer/PHPMailerAutoload.php’;
require_once ‘https://kimassi.net/hudousan/phpmailer/language/phpmailer.lang-ja.php’;
でも動作しませんでした。

require dirname(__FILE__).’/phpmailer/PHPMailerAutoload.php’;
require dirname(__FILE__).’/phpmailer/language/phpmailer.lang-ja.php’;
にすると動作するようになりました。
絶対パスってhttps://から入れれば良いという事では無いようです。

ちなみに、階層を登ってパスする場合は
require dirname(__FILE__).’/../phpmailer/PHPMailerAutoload.php’;
require dirname(__FILE__).’/../phpmailer/language/phpmailer.lang-ja.php’;
のようにします。
もしrequireが書かれたファイルが元のPHPプログラムではなく、FUNCTIONのPHPプログラムであれば、dirname(__FILE__)はFUNCTIONのPHPプログラムの位置になります。

但し、coreserverからはメールを送れましたが、gmailからは重大なセキュリティ通知が届きました。gmailも身に覚えがあると通知したら、メールを送れるようになりました。

また、いつの間にかgmailでもPHPMailer使用してのSMTPからのメールを受け取れるようになりました。

インターネット上でのPHPMailerの不具合の原因は、絶対パスの記述方法の間違いでした。
こういうのは、ちゃんとエラー表示する設定にしておけば、すぐにわかる事なのかもしれません。
XAMPP上ではエラー表示するけど、ネット上ではエラー表示しないので、ネット上のphp.iniを触ったのだと思います。
とりあえず、プログラム製作中は、プログラム中に
ini_set( ‘display_errors’, 1 );
を入れることにしました。

メールの問題が解決したら、header(‘Location:も解決しました。
header(‘Location: は他に不具合があると正常に動作しないようです。

やっと全てが問題なく動作するようになりました。

2019年5月28日

Spacelanからのメールは、
$mail ->SMTPSecure = false;  を削除して
$mail->SMTPAutoTLS = false;  にすると動作しました。

同時に送ったメールの内、1つはウィルスメール扱いにされました。coreserver.jpからの転送メールです。

2020年6月13日

公開の掲示板の他に、非公開の交渉ができる交渉の部屋も設置しようかと思います。ユーザー登録した人のマイページのデータベースで、交渉内容のデータを管理します。その部屋に入るには、出品者の許可があった場合だけ可能で、その部屋入室があったことを他の人にもわかるようにしようと思います。

XREAやCORESERVERAの制限について

PHPやMySQLを使うようになって、現在使っているサーバーCORESERVERについて、仕様による制限によって不便に感じることが多くなって、いろいろ問い合わせをしてみました。

PHPのプログラムについては、不可の大小に関われず、処理時間が長い場合は強制終了されるようです。
実際には待っているという処理でも、時間が長いと強制終了されるそうです。
なお、その時間は、サーバーの負荷状況によりまして、強制終了となる継続時間に差があるそうです。

毎日、この時間にPHPのプログラムを実行したいという場合にcronという機能が、XREAやCORESERVERAにもあるのですが、1時間に1つしか使えないそうです。つまり1つのPHPのプログラムをcron設定すると、次にcronで動作するPHPのプログラムは1時間以上間隔をあけないとダメということです。

質問の回答に「PHP同時起動数の超過等により、サーバー自体の制限としてプロセスが強制終了となる可能性がある」との事だったのですが、具体的な目安を問い合わせしました。
「サイト設定」<「アクセス統計」で1,000pt前後が限界という事でした。
調べてみたら、該当のページにはいろいろな情報が掲載されていました。
2日間の情報しか掲載されていませんでしたが、使っているサーバーのパソコンにおいて、アカウントの負荷率は1日100pt以下で、そのパソコンでは50番目程度でした。たいした負荷はかけていないようです。
ただ、ドメイン毎の転送量は1日に800~900Mバイトで5番目、ドメイン毎のリクエスト数は1日で60000回程度で3番目、ドメイン毎のユニークホスト数は1日で3000件以上あってトップでした。
ユニークホスト数(アクセスカウンター)はweb上でも検出していますが、1日1500程度の検出なので、半分程度でしか検出できていないようです。
同時にアクセスがあった場合は1個分しか検出できていないのだと思います。