イントロダクション
現在、GoogleMapを使用したブラウザアプリの作成中です(2019-07-11)。
実装中につまづいたのでメモがてらに記載します。
<作成プログラム概要>
- JSでのGoogleMap表示
- PHPでの入力データをDBに登録
こんな感じです。
PDO to MySql
- 参考サイト: PHPマニュアル
確認するポイント
- phpinfo()でPDOの使用が可能か確認
そして確認ができたらMySQLでのPDOのインストール方法(使用可能か確かめる)とDPDO使用方法を参照して使い方を理解する。
<作成したコード>
// DBアクセス $dns = 'mysql:host=localhost;dbname=test_dbname'; $username = DB_USER; $password = DB_PASS; $driver_options = [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, ]; $insertQuery = "INSERT INTO AREA_INFO(AREA_ID, INFO_NAME, INFO_URL, INFO_IMAGE, INFO_LAT, INFO_LNG, OWNER_ID, UPDATE_DATE) VALUES(?, ?, ?, ?, ?, ?, ?, ?)"; try { $pdo = new PDO($dns, $username, $password, $driver_options); echo "tee"; $pdo->prepare($insertQuery); $pdo->bind(1, 1); $pdo->bind(2, $name); $pdo->bind(3, $url); $pdo->bind(4, $lat); $pdo->bind(5, $lng); $pdo->bind(6, $imgTmp, PDO::PARAM_LOB); $pdo->bind(7, 1); } catch(Exception $e) { print($e->getTraceAsString()); }
PreparedStatement
SQLを実行するときによく使うのがプリペアードステートメント(PreparedStatement)です。
早い話が、SQLの値部分(?)にパラメータを渡してやるものです。
Sample
- INSERT INTO A_TBL(COL_A, COL_B) VALUES(?, ?);
というSQLクエリを実行(execute)しようとしたときに下のようにコードを書きました。
$pdo->prepare($insertQuery); $pdo->bind(1, 1); $pdo->bind(2, $name); $pdo->bind(3, $url); $pdo->bind(4, $lat); $pdo->bind(5, $lng); $pdo->bind(6, $imgTmp, PDO::PARAM_LOB); $pdo->bind(7, 1);
エラリました。。。
マニュアルを見ると「bind」なんてメソッドはありませんでした。。。
なのでマニュアルに習い以下のように書き換えました。
try { $pdo = new PDO($dns, $username, $password, $driver_options); echo "tee"; $statement = $pdo->prepare($insertQuery); $statement->bindParam(":id", $id); $statement->bindParam(":name", $name); $statement->bindParam(":url", $url); $statement->bindParam(":img", $imgTmp, PDO::PARAM_LOB); $statement->bindParam(":lat", $lat); $statement->bindParam(":lng", $lng); $statement->bindParam(":owner", $ownerId); $statement->execute(); } catch(Exception $e) { print($e->getTraceAsString()); }
これでDBにデータの登録ができるようになりました。作成した画面はこちらです。
ちなみにSELECT文などは「query()」が使える。
try { $pdo = new PDO($dns, $username, $password, $driver_options); foreach ($pdo->query($selectQuery) as $row) { $tags = $tags . '' . 'img src="data:image/jpg;base64,' . $row['INFO_IMAGE'] . '" alt="写真"' . '/div'; } // コネクションの解放 $pdo = null; } catch(Exception $e) { print($e->getTraceAsString()); } // レスポンスに出力 print($tags);でわでわ。。。
PHP PDO 〜invalid data source name〜
invalid data source name
表題のエラーが出てすごく困っていました。
下のようにコードを作成し最後のnew PDOの部分でエラーになるので「おかしい!」と悩んでいました。
参考サイトPHPマニュアル$dns = 'mysql:host=localhost;dbname=testdb'; $username = 'user'; $password = 'pass'; $driver_options = [ PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => false, ]; $pdo = new PDO($dsn, $username, $password, $driver_options);解決
スペスミスでした(笑)
$dns = 'mysql:host=localhost;dbname=testdb'; $pdo = new PDO($dsn, $username, $password, $driver_options);わかりづらいのですが、「$dns」と「$dsn」で間違っていたのでコンストラクタにから文字が渡されていました。。。
解決方法
以下のようにtry〜catchでエラーとレースを出力しました。
} catch(Exception $e) { print($e->getTraceAsString()); }これでエラーの詳細が出力されるので一発で解決できました。
エラー出力、ハンドリングはちゃんとやりましょう(笑)
でわでわ。。。
PHP Ajax 〜リクエストが取得できない〜
AjaxとPHP
XMLHttpRequestでPHPにリクエストを飛ばしたときにはまりました。
JSONでリクエストを送信したもののPHPでファイルデータが取得できない。。。バイト文字を送信するのも一つですが…解決
参考サイト
取得するのにFile形式で取得するようだった。。。。$post_body = file_get_contents('php://input');ここにたどり着くのに結構かかってしまいました。。。
みなさんお気をつけて。。。取得はできたけど、データの操作が出来ず…
結局はフォームデータにファイルをセットして送信しました。
注意としては、XmlHttpRquestのヘッダーに何も設定しない状態でリクエストを飛ばす事、これを見つけるのに苦労しました(笑)
次は、PHPで、入力データ(文字列とファイル)をMySqlに登録しようと思います。
既に、試したのですがPDOが使えないサーバがあるので、php Infoで確認した方が安全です。
でわでわ。。。
Ajax PHP 〜Ajax通信エラー No ‘Access-Control-Allow-Origin’ 〜
No 'Access-Control-Allow-Origin'
こんなエラーが出ました。JavaScriptで以下のようなコードを実行したときです。
xhr = new XMLHttpRequest(); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.onreadystatechange = recieveResponse xhr.open('GET', 'https://zenryokuservice.com/tools/maps/InsertMapInfo.php?param=test', true); xhr.send();
SampleMap.html:1 Access to XMLHttpRequest at 'https://zenryokuservice.com/tools/maps/InsertMapInfo.php?param=test' from origin 'null' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
答え
異なるドメインから呼び出すと、このようになるようです。
セキュリティの問題なようです。まぁ確かによろしくはないですね。。。参考サイトより対応
実はこのコードは自分のPCから直接実行しました。運用するときは自分のレンタルサーバー上にJSを配置するのでこの問題は起きません。。。
なのでサーバーにアップして再度実行します。
こんな感じでAjax通信のテストを完了できました。
作成したものはここにあります。
https://zenryokuservice.com/sample/js/SampleMap.html
次は
作成したフォームを送信します。
関連ページ
PHP 暗号化 〜openssl_encryptを使う〜
イントロダクション
前回、レンタルサーバー上でJavaを起動しようとして、結局は起動できませんでした。。。
結局は、PHPで暗号化することにしました。そして、サンプルがあったのでそれを失敬して、作成しました。
/** 暗号化メソッド */ function encrypt($post_str, $passphrase, $iv) { //暗号化用のメソッドを指定 $method = 'AES-256-CBC'; //利用可能な暗号メソッドの一覧を取得するには openssl_get_cipher_methods() を使用; /* $ciphers = openssl_get_cipher_methods(); var_dump($ciphers); */ //暗号化を実施 $options = OPENSSL_RAW_DATA; return openssl_encrypt($post_str, $method, $passphrase, $options, $iv); } /** 復号メソッド */ function decrypt($post_str, $passphrase, $mst_iv) { //暗号化用のメソッドを指定 $method = 'AES-256-CBC'; $iv = getIv($method); //復元を実施 $options = OPENSSL_RAW_DATA; $res = openssl_decrypt($post_str, $method, $passphrase, $options, $mst_iv); vreturn $res; } /** ivを取得する */ function getIv($method) { //暗号初期化ベクトル (iv) の長さを取得 $iv_size = openssl_cipher_iv_length($method); //暗号モードに対するIVの長さに合わせたキーを生成します return openssl_random_pseudo_bytes($iv_size); }上記のコードは暗号化と復号化の処理(メソッド)です。これを使用して実際に暗号と復号を行います。サンプルとしてブラウザで入力できるものを作りました。
良かったら見てやってください。こんな感じで、暗号化する文言を入力した後に「暗号化出力」以下の部分に結果が出力されます。「復号化処理」の結果も同じ場所に出力されます。
インターネットに繋がるのが「普通」の時代なので「セキュリティ」がとても重要な時代ですね。会社間で使用するデータなどは暗号化が必須になりますので、今後IT業界で何かやろうとしている人は知っておくと便利なのではないでしょうか?
でわでわ。。。
関連ページ
- PHP TwitterAPI ツイートを取得
- [TwitterAPI 〜PHPコードでツイートする手順〜](TwitterAPI 〜PHPコードでツイートする手順〜)
- WebページにTwitterボタンを追加する方法
- Twitter APIを使うために〜Twitterへのデベロッパ登録〜
- Git Webhook 〜リクエストの中身一覧〜
- Git 使い方 〜TwitterAPIと連携するには?〜
JS Google Maps API 〜オリジナル・データマップを作ろう〜
Google Maps APIを使う
Google Maps API(javascript版)を使用して便利な地図アプリを作成します。そのためにGoogleのAPIを使用するための手続きをやります。
参考サイトはこちらです。手順1
とりあえずはこちらのサイトを開きます。
そして、下のようなアイコンがあるのでそれをクリックします。
見つからない場合は下のように
をクリックして
GoogleMapを選択します。そして詳細をクリック
認証情報を作成
APIキーを選択
こんな感じでできました。
以下のような形で一定量は無料で使えます。詳細はGoogleに聞いてみるしかなさそうです。。。(Google Japanあたり?)
実装
HTMLで表示するので、JavaScriptでの実装を行います。
そしてこちらがJSのドキュメントです。JavaとかそこらへんのAPIも揃えているようなので、目移りしてしまいますね(笑)そして英語のなので当然! Google翻訳でドキュメントを読みます。
嬉しいことに
上記のドキュメントサイトにサンプルコードがありました。
このコピーしたコードの32行目に以下のようなコードがあります。<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY" callback=initMap'' async defer></script>ここの「YOUR_API_KEY」を上記で作成(取得)したキーを貼ります。その実行結果がこちらです。シドニーが表示されています。オーストラリア。。。いいですね。ジンギスカンですか。。。
とりあえずは初期表示ハローGoogle Mapと言うことで。。。
しかしエラーが
画面を表示して一瞬は正常に表示されたけどAPIキーの設定がまだだったのでエラー。。。
APIキーの設定をする
デフォルトの状態ではAPIの制限などが入っていないので問題ないのですが、自分は以前使用したものがありウェブサイトの指定を行なっていました。
なので今回使用するURLを追加しました。
最後に「*」アスタリスクをつけないとサブディレクトリが対象に含まれません。。。アカウントを有効化
この作業を行わないとAPIキーが有効になりません。ちょっとためらうのが「支払い設定」でした。
しかし、入力するページには下のような文言があり、無料での使用は可能だと言うことがわかります。「有料アカウントに手動でアップグレードしない限りは・・・」と言う記載があります。
そんなわけで、入力を続けていくと下のような画面が出てきます。これで設定完了!
そして、URLの制限などがないことを確認します。
そして表示!まだエラーが。。。
画面の表示はできるけど、シドニー(オーストラリア)は表示できるけど、日本は表示できない事件がありました。
原因は{lat: 141.33432, lng: 141.434334}のように北緯の値が90度以上になっていて表示できなかったというわけでした。
正しくは{lat: 43.064157, lng: 141.353364};でした。
追伸
Google Mapの座標を取得するページでの経度と緯度の値部分の順番がそのままではないので注意です。
lat: 経度 lng: 緯度でわでわ。。。
関連ページ
- Github page 〜Github pageでリポジトリの情報を公開しよう〜
- 夢を形にする① 目標ブレーク〜じゃんけんゲームの場合〜
- プログラム 習得 順序1 概要
- Github page 〜Github pageでリポジトリの情報を公開しよう〜
- Github 使い方〜リポジトリにライセンスを設定する〜
- Github 使い方〜Issueでやることを整理〜
PHP TwitterAPI ツイートを取得
ツイートを取得する時のめもです
できたもの
https://zenryokuservice.com/mokuhyoAP.php
ツイート表示のためのテンプレートHTML
ツイート取得時のJSONの中身
ツイートの取得時に「json_decode()」を使用します。というか使用していました。それはここからTwitterAPIのPHPラッパークラスにあるコードを使わせてもらったからです。
そして、案の定手こずりました。以下は取得したJSONのプロパティ一覧です。["truncated"]=> bool(false) ["entities"]=> object(stdClass)#5722 (4) { ["hashtags"]=> array(0) { } ["symbols"]=> array(0) { } ["user_mentions"]=> array(0) { } ["urls"]=> array(1) { [0]=> object(stdClass)#5723 (4) { ["url"]=> string(23) "https://t.co/ucfr5Mp3pk" ["expanded_url"]=> string(37) "https://zenryokuservice.com/mokuhyoAP" ["display_url"]=> string(29) "zenryokuservice.com/mokuhyoAP" ["indices"]=> array(2) { [0]=> int(75) [1]=> int(98) } } } } ["metadata"]=> object(stdClass)#5724 (2) { ["iso_language_code"]=> string(2) "ja" ["result_type"]=> string(6) "recent" } ["source"]=> string(82) "Twitter for iPhone" ["in_reply_to_status_id"]=> NULL ["in_reply_to_status_id_str"]=> NULL ["in_reply_to_user_id"]=> NULL ["in_reply_to_user_id_str"]=> NULL ["in_reply_to_screen_name"]=> NULL ["user"]=> object(stdClass)#5725 (41) { ["id"]=> int(2378007752) ["id_str"]=> string(10) "2378007752" ["name"]=> string(12) "たくのじ" ["screen_name"]=> string(13) "java_takunoji" ["location"]=> string(0) "" ["description"]=> string(288) "JavaでRPIなどの上で動くゲームを仕様から作成中。 好きな言葉は「ロッケンロールは1日にして成らず」#PGボックス #Java #opencv Create a game based java on RPi etc ... My favorite word is “ロッケンロールは1日にして成らず” thanks!" ["url"]=> string(23) "https://t.co/tYxRX8YCof" ["entities"]=> object(stdClass)#5726 (2) { ["url"]=> object(stdClass)#5727 (1) { ["urls"]=> array(1) { [0]=> object(stdClass)#5728 (4) { ["url"]=> string(23) "https://t.co/tYxRX8YCof" ["expanded_url"]=> string(39) "https://zenryokuservice.com/roadMap.php" ["display_url"]=> string(31) "zenryokuservice.com/roadMap.php" ["indices"]=> array(2) { [0]=> int(0) [1]=> int(23) } } } } ["description"]=> object(stdClass)#5729 (1) { ["urls"]=> array(0) { } } } ["protected"]=> bool(false) ["followers_count"]=> int(1756) ["friends_count"]=> int(3297) ["listed_count"]=> int(1) ["created_at"]=> string(30) "Sat Mar 08 02:49:23 +0000 2014" ["favourites_count"]=> int(5035) ["utc_offset"]=> NULL ["time_zone"]=> NULL ["geo_enabled"]=> bool(true) "verified"]=> bool(false) ["statuses_count"]=> int(957) ["lang"]=> string(2) "ja" ["contributors_enabled"]=> bool(false) ["is_translator"]=> bool(false) ["is_translation_enabled"]=> bool(false) ["profile_background_color"]=> string(6) "C0DEED" ["profile_background_image_url"]=> string(48) "http://abs.twimg.com/images/themes/theme1/bg.png" ["profile_background_image_url_https"]=> string(49) "https://abs.twimg.com/images/themes/theme1/bg.png" ["profile_background_tile"]=> bool(false) ["profile_image_url"]=> string(74) "http://pbs.twimg.com/profile_images/976105570573762560/jqMlT-a__normal.jpg" ["profile_image_url_https"]=> string(75) "https://pbs.twimg.com/profile_images/976105570573762560/jqMlT-a__normal.jpg" ["profile_link_color"]=> string(6) "1DA1F2" ["profile_sidebar_border_color"]=> string(6) "C0DEED" ["profile_sidebar_fill_color"]=> string(6) "DDEEF6" ["profile_text_color"]=> string(6) "333333" ["profile_use_background_image"]=> bool(true) ["has_extended_profile"]=> bool(false) ["default_profile"]=> bool(true) ["default_profile_image"]=> bool(false) ["following"]=> bool(false) "follow_request_sent"]=> bool(false) ["notifications"]=> bool(false) ["translator_type"]=> string(4) "none" } ["geo"]=> NULL ["coordinates"]=> NULL ["place"]=> NULL ["contributors"]=> NULL ["is_quote_status"]=> bool(false) ["retweet_count"]=> int(0) ["favorite_count"]=> int(2) ["favorited"]=> bool(false) ["retweeted"]=> bool(false) ["possibly_sensitive"]=> bool(false) ["lang"]=> string(2) "ja" }まぁ全部使わないのでここら辺にしておきます。
でわでわ。。。
PHP WordPress〜テンプレート関数をWP外部から使う〜
ファイヤーアルパカ 〜切り取った画像をファイル出力する〜
PHP 楽天API WordPress〜楽天プラグインを使う〜
イントロダクション
楽天APIを使用して商品検索を行うことはできる様になりました。
次は商品を紹介するためのページを作成します。そして最後にプラグインのしよう結果を記載します。
少しずつ確実に。。。
人間誰しも、いっぺんになんでもできません。なので1つずつ確実にやっていこうと思います。
とはいえ「確実」と言っても「確実に表示する」という意味でやって行きます。
前回はただ単に表示しただけなので、今回は少し色気をつけてみました。
取得したデータをテーブルタグを使用して揃えたものをループしただけです。デザインは苦手なのでこんなくらいがいっぱいいっぱいです。
それでも、まぁ形にはなったかな?と思います。ついでなのでデータを再検索する様に処理を追加しました。
function researchRctn() { var param = document.getElementById('category').value; console.log(param); location.href = "http://zenryokuservice.com/project/rakuten/php/rakutenCatalog.php?category=" + param; }
上のコードを追加してボタンのクリックで起動する様にしました。
< input id="category" type="text" /><button>商品をリロード</button>ついでに楽天プラグインを使って見る
「R」ボタンを押下して表示した文字は「rakuten ids=XXX」の様な文字が下に表示されただけですが、これはちゃんと投稿後にイメージなどが表示されるのでしょうか?