Posted on

JQueryにてJSONをPHPに送り、さらにベーシック認証の指定のURLにPOSTしてJSON形式のデータを受け取る方法

長いタイトルになってしまいましたが、ようするにJSON形式なら受け渡しが楽になりますよということです。
まず、JQueryからPHPにJSON形式のデータを渡す方法(www/index.php)




    
    
    
    Ajax Sample


Ajax sample

JQueryからJSON形式のデータを受け取りPHPで連想配列にして他のURLにポストする方法(www/ajax_api.php)
ちなみに、ベーシック認証がない場合は、define(‘DEMO’, true);をdefine(‘DEMO’, false);へ

 "{$memberId}"
    );
    $data = http_build_query($data, "", "&");

    if (DEMO) {
        //header
        $header = array(
            'User-Agent: My User Agent 1.0',    //ユーザエージェントの指定
            'Authorization: Basic ' . base64_encode('account:password'),//ベーシック認証
            "Content-Type: application/x-www-form-urlencoded",
            "Content-Length: " . strlen($data)
        );
    } else {
        //header
        $header = array(
            "Content-Type: application/x-www-form-urlencoded",
            "Content-Length: " . strlen($data)
        );
    }

    $context = array(
        "http" => array(
            "method"  => "POST",
            "header"  => implode("\r\n", $header),
            "content" => $data
        )
    );
    $res = file_get_contents(SAMPLE_API, false, stream_context_create($context));
    return $res;
}
?>

POSTデータを頂き、情報(連想配列のID指定にしていますが、ご利用の際には、DBから取得する方法へもバージョンアップできます。)
を取得JSON形式の返信を頂く方法(wwwapi/index.php)

 array("id" => 10000,'name' => 'Name10000','tel' => "000100010001"),
	"9999" => array("id" => 9999,'name' => 'Name9999','tel' => "000900090009"),
	"9998" => array("id" => 9998,'name' => 'Name9998','tel' => "000900090008"),
	"9997" => array("id" => 9997,'name' => 'Name9997','tel' => "000900090007"),
	"9996" => array("id" => 9996,'name' => 'Name9996','tel' => "000900090006"),
	"9995" => array("id" => 9995,'name' => 'Name9995','tel' => "000900090005"),
	"9994" => array("id" => 9994,'name' => 'Name9994','tel' => "000900090004"),
	"9993" => array("id" => 9993,'name' => 'Name9993','tel' => "000900090003"),
	"9992" => array("id" => 9992,'name' => 'Name9992','tel' => "000900090002"),
	);

$memberId = $_POST['member_id'];

if(empty($memberArray[$memberId])) {
	echo json_encode(array());
}
echo json_encode($memberArray[$memberId]);
?>

※jquery-1.11.2.min.jsは、特にふれていませんが、実行するには必要になります、ご注意ください。

Posted on

本日は曇天なり

前回の僕のブログが(フランス革命歴)時報だったから、電話番号似ているつながりと言うわけでもないですが、今回は天気予報を取ってくるという話があったので、そのときにやったことをメモしておきます。

天気予報情報はここ。OpenWeatherMap.orgを使いました。
https://openweathermap.org/

いろいろ英語で書いてあって苦手な人は大変ですが、とりあえず必要なことは

  • Sign Upから登録
  • API keysから文字列を持ってくる

だいたいこんなところです。Subscribeは今のところ必要ない感じです。(月額ですし)

こちら側でやる必要があることはだいたい、

  • 持ってきた文字列を含むHTTPリクエストをURLに投げる
  • JSONを受け取る

あとはお好きなように使う、といったところです。

/**
* 定数、配列定義
*/

//アクセス用APIキー
define('API_KEY','/*ここに取得したAPIキー*/');
//アクセス用URL
define('API_URL','http://api.openweathermap.org/data/2.5/forecast?units=metric&id=1853908&APPID='.API_KEY);//大阪のcity idを使用

/* HTTPリクエストを投げる感じのクラスHttpRequestも用意しておく */

/*ここから取得*/
$http = new HttpRequest(API_URL,HttpRequest::REQ_HTTP_GET);
$code = $http->sendRequest();

if($code!=200){
    echo 'Error:データの取得に失敗した';
    exit;
}

$rawWeather=$http->getResponseBody();

ここで、$rawWeatherの中身はこんな感じ

{
     "cod":"200",
     "message":0.021,
     "cnt":39,
     "list":[
         {
             "dt":1491793200,
             "main":{
                 "temp":12.43,
                 "temp_min":8.35,
                 "temp_max":12.43,
                 "pressure":892.44,
                 "sea_level":1032.22,
                 "grnd_level":892.44,
                 "humidity":78,
                 "temp_kf":4.08
             },
             "weather":[{
                 "id":500,
                 "main":"Rain",
                 "description":"light rain",
                 "icon":"10d"
             }],
             "clouds":{"all":68},
             "wind":{"speed":1.06,"deg":217.002},
             "rain":{"3h":0.155},
             "snow":{},
             "sys":{"pod":"d"},
             "dt_txt":"2017-04-10 03:00:00"
          },
          { ...以下、3時間ごと5日分の予報... }
     ]
     "city":{
         "id":1853908,
         "name":"Osaka",
         "coord":{"lat":35.95,"lon":137.2667},
         "country":"JP"
     }
 }

天気の内容はlist[n].weather.mainに、気温や気圧はlist[n].mainに出ています。list[n].dt_txtは世界標準時なので、日本時間では4月10日正午の天気ってことになります。URLにunits=metricをつけることで、気温の単位は摂氏として送られてきます。リクエスト文字列をいじると華氏にもできたりするそうです。
月額のないAPIだと1分間に60回までしか呼べないとかあったりしますけど、とりあえず試す分には十分でしょう。天気予報が必要になったら、こういう方法に頼れる、と言う話でした。

Posted on

使いどころは知らない

フランス革命歴CCXXIV年フリミエール(3月)25日(五曜日)3時81分。
このブログを書き始めた日本標準時を(いくつかの前提をつけて)フランス革命歴に計算しなおしてみました。

ええ、今年9月に入社して3か月半、このブログのためにネタを探した結果がこのざまです。

そもそも、そんな計算をしようと考えたのはphpにjdtofrenchなる関数が存在しているのを知ったからです。
ユリウス積算日をフランス革命歴に変換するという関数で…

http://php.net/manual/ja/function.jdtofrench.php

フランス革命歴が実際に使用された、わずか14年足らずの間は
この関数でフランス革命歴に変換できるそうなのです。

世間には西暦だけじゃなくて、皇紀だったり、他の紀元年も存在すれば、
和暦でもあえて今年を昭和から数えて91年と言ってみたり、ときとして”あえて使われていない暦年で言及する”
なんていうネタがありますけれど、さすがにjdtofrenchではそのネタに使えない。
たった14年足らずしか使われていなかったから、関数もその範囲で計算を打ち切ってます。
(当然といえば当然)
だから、自分で現在時刻をフランス革命歴に換算するのを組んでみたというわけです。

フランス革命歴は…詳しいことはご自分で調べてください。とりあえず、要点は

  • 1792年9月22日(秋分)が紀元
  • 30日12か月+年末に追加日5~6日
  • 曜日は日付の下一桁(10日周期) 追加日は曜日無し
  • うるう年に明確なルールはなかった(年始を秋分に合わせようとしていたらしい)
  • 1日=10時間, 1時間=100分 1分=100秒

jdtofrenchが1806年以降に対応していないのは、フランス革命歴が実際に使われていた時期だけに対応するほか、
XX年以降のうるう年が決まっていないから、ということによるものだそうです。
なので、今回換算するにあたって、グレゴリオ暦の秋分を常に年始に合わせることにしました。
おおむね、グレゴリオ暦と同じ周期でうるう年が出る計算になります。

秋分の日の計算はこちらを使わせていただきました。
http://php.o0o0.jp/article/php-equinox_day

//グレゴリオ暦$year年秋分の日00:00:00のタイムスタンプ
function autumn_equinox($year){
    $aeqday = floor(23.2488 + 0.242194 * ($year - 1980)) - floor(($year - 1980)/4);
    $aeqdate=mktime(0,0,0,9,$aeqday,$year);
    return $aeqdate;
}
$nowdate=strtotime("today");
$nowdatetime=strtotime("now");
//現在日時から日付(00:00:00)を引いて今日の経過秒数を求める 【1】
$nowclock=$nowdatetime-$nowdate;

//グレゴリオ暦1970年秋分=革命歴CDXXIX年ヴェンデミエール1日
$year = date('Y',time());
$fy=$year-1970+179;
//今年の秋分
$aeqdate = autumn_equinox($year);

//秋分前なら前年、秋分以降なら今年の秋分の日が革命歴の年始
if($nowdate<$aeqdate){
	$fy--;
	$ffirst=autumn_equinox($year-1);
}else{
	$ffirst=$aeqdate;
}

//革命歴年始からの日数
$ftdays=($nowdate-$ffirst)/(60*60*24);

//革命歴は30日x12か月+うるう日5~6日、よって30で割れば解決
$fm=floor($ftdays/30)+1;
$fd=($ftdays%30)+1;
//曜日は10日周期
$dn=$fd%10;

//1日=革命歴10時間=革命歴1000分=革命歴100000秒
//革命歴1秒=1/100000日=グレゴリオ暦0.864秒
//革命歴経過秒数を求める
$ftsecond=floor($nowclock/0.864);

//革命歴10000秒ごとに革命歴1時間【2】
$fhour=floor($ftsecond/10000);
//革命歴1時~10時になるように調整
if($fhour<1) $fhour=10;
//革命歴1時間未満の革命歴100秒ごとに革命歴1分
$fminute=floor(($ftsecond%10000)/100);
//革命歴1分未満の革命歴秒を求める
$fsecond=$ftsecond%100;

あとは$fyから$fsecondを適当に整形する感じです。

【1】において、strtotime(“now”)が現在時刻、strtotime(“today”)が今日の00:00:00を意味しているから、
単純に引いてその日の経過秒数を使えるようにするというひと手間が要りました。
フランス革命歴下では、1秒の長さすら変化するゆえの策でした。
タイムスタンプが累計秒数だからできる荒業、でしょうか。これで、
【2】の剰余演算は%演算子を使う方向に統一しました。(fmodで計算する方法もあった。どちらが良かったのだろう)

暦年換算は、1秒の長さすら変わる暦年でもなければこれほど大掛かりなものにはならないかとは思います。
逆に、これほど大掛かりなものをわざわざ作ってみたことで、タイムスタンプは結局”ただの秒数”だと
再発見できたわけですし…

現在時刻をフランス革命歴に変換できる、という奇特なネタを身に着けることができた、というわけです。

現在時刻、(フランス革命歴)4時23分!

Posted on

便利に使えるdate関数

「10日後の日付を求めたい」「来月の最後の日付を求めたい」「日付の曜日を求めたい」・・
PHPを実務で使い始めて1年の間、date関数に馴染んでなかった僕としては、こんなことですごく困ったものでした。
今日の日付の取得はさすがにわかったのですが、そこから10日後を求めようとすると、月によって次月になる日が変わる。結構書かないといけないな。。と思っていたら先輩から「date使ったら一発ですよ」と言われ、そんな簡単にできてしまうのか、、とびっくりしました。
今回はそんなときに使った便利なdate関数について、忘備録としてまとめておきたいと思います。

date('Y-m-d H:i:s') //現在時刻
date('Y-m-d', strtotime("tomorrow")) // 明日
date('Y-m-d', strtotime("+ 10 day")) // 10日後
date('Y-m-d', strtotime("+ 2 weeks")) // 2週間後
date('Y-m-d', strtotime("- 1 month")) // 一ヶ月前
date('Y-m-d', strtotime("first day of - 1 month")) // 先月の最初の日
date('Y-m-d', strtotime("last day of next month")) // 来月の最後の日
date('Y-m-d H:i:s', strtotime("yesterday 15:00:00")) //昨日の15時0分0秒
date("Y-m-d",strtotime("last Sunday")) // 一番最近の日曜日

ここで勉強になったことを2点書いておきます。
last day of の指定は非常に便利で、strtotime(“2013-08-31 +1 month”)だと、2013/10/01になってしまうが、strtotime( “last day of 2013-08 +1 month” )と書くと2013/09/30と次の月の最終日になるみたいです。

date('Y-m-d', strtotime("2013-08-31 +1 month")) // 結果⇒2013/10/01
date('Y-m-d', strtotime("last day of 2013-08 +1 month")) // 結果⇒2013/09/30

strtotimeに「tomorrow」をしてした場合は明日の0時0分0秒に、「+ 1 day」を指定した場合は、明日のちょうど24時間後の時間になるみたいです。strtotime(“tomorrow”)=strtotime(“+ 1 day”)ではないので注意とのことでした。

date('Y-m-d H:i:s', strtotime("tomorrow")) // 明日の0時0分0秒
date('Y-m-d H:i:s', strtotime("+ 1 day")) // 24時間後の日時

(参考) http://kihon-no-ki.com/php-use-date-and-strtotime

Posted on

カレンダーの表示サンプル

ページいっぱいにカレンダーを表示するサンプルを作成しました。
参考になればご活用ください。
わたしの環境では、bootstrap.cssや社内で整備したcssを使っているのですが、
本サンプルでは、それらcssをこのサンプル内に記述しているため、すこし長くなっていますがお許しください。
サンプルの内容
初回表示は、今日の日付を元に今月のカレンダーを表示します。前月、次月は背景をグレーに、今日は背景を黄色にしています。
年、月を選択して、確認を押下すると、その月のカレンダーを表示します。
表示している内容は、スケジュールの件数とスケジュール内容(これはサンプルなので、使用される場合は、ここに表示したい
内容を設定してください)になります。
下記サンプル「index.html」ソースです。

2015,2016=>2016,2017=>2017);
$monthArr = array(1=>1,2=>2,3=>3,4=>4,5=>5,6=>6,7=>7,8=>8,9=>9,10=>10,11=>11,12=>12);
?>

  
    
    calender
    
  
  

カレンダー表示画面 

$val) { if ($key == 0) { echo ''; } if ($key != 0 && ($key % 7) == 0) { echo ''; } $classTd = ''; if ($val['gray']) { $classTd = 'class="bg-gray"'; } if ($val['today']) { $classTd = 'class="today"'; } ?> ' ?>
>
' . h("件数:{$cnt}") . ''; } ?>
$cadataVal) { echo '
' . h($cadataVal['schedule']) . '
'; $i++; // 4件まで if ($i >= 4) { break; } } ?>
データがありません。'; } ?>
Posted on

EC-CUBEでカートに商品を入れすぎるとエラー発生

EC-CUBE2.13(たぶん2系全て?)で商品を100個とか沢山カートに入れるとなぜかエラーが出てしまいます。

MySQLで、dtb_session.sess_dataにカートの内容を保持しており、このフィールドはTEXT型になっているんですが、調べてみるとどうもこのTEXT型ではサイズ(容量)が足りないようです。

結局、TEXT型を使ってたのをMEDIUMTEXT型に変更したらいけたのですが、まあ、通常のBtoC取引では100種類の商品も買うこと想定してなかったんでしょうね。

今回調べたTEXT型について以下にまとめます。
TEXT型には4つのタイプTINYTEXT、TEXT、MEDIUMTEXT、LONGTEXTがあります。

・TINYTEXT 最長255 バイト
・TEXT 最長65,535 バイト(64KB)
・MEDIUMTEXT 最長16,777,215 バイト(約1.6MB)
・LONGTEXT 最長4,294,967,295 バイト(約4.3GB)

カートのセッション情報を保存する、といった最長サイズで引っかかりそうなフィールドは、MEDIUMTEXTにしておいた方がよさそうですね。

(参考)http://webrescue.net/archives/4030

Posted on

PHPのfloor関数で痛い目に合う

PHPのfloor関数で痛い目に合ったのでメモしておきます。

お客さんから連絡がありシステムででの計算の結果がおかしいとのことで調べるとfloor関数を使った後に結果がずれてきていました。
何でやと調べると意外と有名な話だった・・・
浮動小数点の精度が微妙と本家で警告が出ている。http://php.net/manual/ja/language.types.float.php

echo floor((0.1+0.7)*10);を実行すると8になってほしいのに7になってしまうというお話。
一番簡単な対策としてecho floor((string)(0.1+0.7)*10);として回避しておきました。

Posted on

DBで使うビューについて

最近仕事で、データベース上にビューを作る機会が何度か出てきました。最初は使い方も使う意味もわからなかったのですが、何度か教えてもらっているうちに、すごく便利なものだということがわかってきました。そのビューの使い方等、この機会に復習がてら自分なりにまとめておきたいと思います。

実際に表示したい項目がDBテーブルに存在しない場合は、新たに項目を設けてビューを作っておくと実際にDBテーブル上の項目と同じように使えるので、その値を表示させたり、あるいはその項目でソートさせたりすることもできるので非常に便利です。また、リアルタイムでビューが更新されるので、誕生日から現在の年齢を求めるときなど動的な値を算出するときにも便利です。
続きを読む DBで使うビューについて

Posted on

phpexcel斜め罫線を引く方法

phpexcelで斜め罫線を引く方法がわからず、
延べ2日間くらい探してなかったので、
右端の四角罫線に対して、画像で斜め線をつけていたのですが、
印刷でどうしても1ページに収まらないため、再度探しました。
すると、斜め罫線を引く方法の英語サイトで見つけました。
私がすこし変更したものですが、情報として提供したいと思います。

// 斜め罫線
$styleArray = array(
    'borders' => array(
        'diagonal' => array(
            'style' => PHPExcel_Style_Border::BORDER_THIN,
            'color' => array('argb' => 'FF000000'),
        ),
        'diagonaldirection' => PHPExcel_Style_Borders::DIAGONAL_DOWN,
    ),
);
$sheet->getStyle("N16")->applyFromArray($styleArray);
Posted on

PHPで統計処理を行うには

ビッグデータの活用がすっかり定着してきた昨今、どうデータを分析するかがとても大事になってきました。
PHPはWEBアプリケーション用言語ですので従来はデータ分析と言っても単にカテゴライズや平均を求める程度で需要は満たせましたが、今後は統計的な手法を用いてさらに突っ込んだ解析を行う場面も出てくるかと思います。
そんな時に使えるライブラリを紹介します。

そのライブラリとは、ズバリ、

続きを読む PHPで統計処理を行うには