Webエンジニア 新人日記

Webエンジニアになりました。元々はCOBOLやらBASICやらでプログラムしてました。C言語やVisualBasicは趣味でやっていましたが、久々に現場復帰ということです。資格はエンベデッドスペシャリスト、DBスペシャリスト、ネットワークスペシャリスト、セキュリティスペシャリスト、システムアーキテクト、プロジェクトマネージャ他を所有

【Web】XAMPP環境におけるオレオレ証明書のインストール(2017年1月版)

XAMPPでSSL通信を使う場合、php.iniの

extension=php_openssl.dll

を有効にすればエラーの警告が表示されなくなる。


ただし、ここで使用される証明書はSHA1を利用しているため、2017年1月以降では「保護されない通信」になってしまう。
そこで、証明書生成用のバッチファイルmakesert.batを修正して実行することでsha256に対応させた証明書を発行する。

bin\openssl req -new -out server.csr

行に-sha256オプションを付与するだけ。

bin\openssl req -new -out server.csr -sha256

ついでに、有効期間を伸ばしておこう。

bin\openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 365

bin\openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650

にする。

デフォルトのインストール設定ではC:\xampp\apache\conf\ssl.crtに生成されたcrtファイルをダブルクリックでインストールする。証明書ストアの選択では「証明書をすべて次のストアに配置する」→「参照」→「信頼されたルート機関」でインストール。

【Javascript】【jQuery】画像の遅延読み込み

画像を大量に読み込むような場合、読み込むまでに時間がかかる。
読み込むまでの間、なにも表示されないと「壊れたかな?」と思ってリロードされる場合がある。
そうなると逆に負荷がかかり、余計に表示されなくなってしまう。

そこで、画像を表示する直前まで画像の読み込みをしないようにしてサーバ負荷を軽減する。
と同時に、ローディング中表示をすることによって余計な操作をさせないようにする。


Lazy Loadの準備

jQueryのLazy Loadプラグインを使うことにする。
jQueryプラグインなので、jQueryの後に読み込む。
同一サーバとの同時コネクション数に制限があるため、
スクリプトCSSを外部から読み込む際は別サーバにした方がよい。
今回はGoogleのCDNを使う。

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="js/jquery.lazyload.min.js"></script>

imgタグの設定

従来はimgタグのsrc属性で読み込む画像を指定していたが、LazyLoadプラグインではdata-original属性で読み込む画像を指定する。
src属性には、読み込み終わるまでに表示する画像を指定。今回はロード中画面を指定する。

<img class="lazy" src="img/gif-load.gif" data-original="image/graph1.jpg">

プラグインの実行

読み込んだオブジェクトに対して遅延読み込みを実行させる。
オプションを指定できる。サンプルで指定したオプションは以下の通り。
effect・・・フェードイン
effectspeed・・・500ミリ秒
threshold・・・画像読み込みまでのピクセル

<script>
  $('.lazy').lazyload({
    effect: 'fadeIn',
    effectspeed: 500,
    threshold : 10,
  });
</script>

【RaspberryPi】ラズパイを使ったサイネージ広告

約5000円という値段でHDMI出力付きのLinuxを動かすことができるマシンであるRaspberryPi。
これを使って余ったHDMI入力付きのTVをサイネージ化する。TVの電源はRaspberryPi側で管理する。


電源ON

RaspberryPi側の電源は、デジタルプログラムタイマー等で管理する。
起動時に自動で起動する/etc/rc.local等で下記のスクリプトを起動する。
cec-client で、TV側の電源を操作できる。
動画再生にはomxplayerを利用する。
ループ再生したときにタイトル等を表示させないようにオプションを設定する。

#!/bin/sh
#起動時にhdmiで接続しているTVの電源を入れる
echo "on 0" | cec-client -s
sudo -u pi startx > /dev/null 2>&1 &
omxplayer --no-osd --loop /var/movies/slide.mp4

電源OFF

TV側の電源を落とし、shutdownさせる。
スクリプトの起動自体はcronで設定する。
再起動にそなえ、cronで設定した時刻+αの時刻に
電源をOFFにするようにする。

#!/bin/sh
#hdmiで接続されたTVの電源をOFFにする
echo 'standby 0' | cec-client -s 
sudo shutdown -h now

【GPS】WebアプリにおけるGPS情報の取得と現在地の地名を求める

GPS情報をブラウザで取得するには、GeolocationAPIを利用する。
Chromeでは、http通信では使用できなくなっているので注意が必要。

※サンプルでは、取得したGPS情報をAjaxを使ってDBに書き込むと同時に地点を求めている。

GPS情報取得部分
if (navigator.geolocation) {
    // 現在の位置情報取得を実施
    navigator.geolocation.getCurrentPosition(
	// 位置情報取得成功時
	function (pos) { 
//取得したGPS情報を画面に書き出す
		var location ="<li>"+"緯度:" + pos.coords.latitude + "</li>";
		location += "<li>"+"経度:" + pos.coords.longitude + "</li>";
		var nDate = new Date();
		location += "<li>"+"時刻:" + nDate.getHours() + ":" + nDate.getMinutes() + ":" + nDate.getSeconds() + "</li>";
//ajaxにて現在地をDBに書き込む
		var data = {
			lat : pos.coords.latitude,
			lng : pos.coords.longitude,
		};
//Ajax通信メソッド
//type : HTTP通信の種類(POSTとかGETとか)
//url  : リクエスト送信先のURL
//data : サーバに送信する値
		$.ajax({
			type: "POST",
			url: "../common/xxxx.php",
			data: data,
			dataType: "html",
		//Ajax通信が成功した場合に呼び出されるメソッド
			success: function(html){
				$('#location').html(location);
				$('#result').html(html);
			}
		});	
	},
	// 位置情報取得失敗時
	function (error) {
		var message = "";

		switch (error.code) {
		   // 位置情報取得できない場合
		   case error.POSITION_UNAVAILABLE:
		       message = "位置情報の取得ができませんでした。";
		       break;
		  // Geolocation使用許可されない場合
		  case error.PERMISSION_DENIED:
		      message = "位置情報取得の使用許可がされませんでした。";
		      break;
		  // タイムアウトした場合 
		  case error.PERMISSION_DENIED_TIMEOUT:
		      message = "位置情報取得中にタイムアウトしました。";
		      break;
		  default:
		      message = error.code;
		}
		window.alert(message);
	},{
		enableHighAccuracy: true
	}
	);
} else {
	window.alert("本ブラウザではGeolocationが使えません");
}
地名情報取得部

上記で取得した緯度経度から、Yahoo!リバースジオコーダAPI
developer.yahoo.co.jp
を利用して地名を求める。
Yahoo!リバースジオコーダAPIはクレジット表示などの規約があるので注意する。

下記サンプルPHPJSONで受取り、パースして変数$locationNameに取り出す。
※DB書込部、POSTデータのサニタイズ部等は省略

/Yahoo!リバースジオコーダAPIにて、緯度経度から町名を導く
$uri = "http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder"
    . "?lat=" . $lat . "&lon=" . $lon . "&appid=" . $appid . "&output=json";

$curl = curl_init($uri);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
$response = curl_exec($curl);
curl_close($curl);

$res = json_decode($response,true);

$locationName = $res[Feature][0][Property][Address];

print $locationName . "付近\n";

【mineo】SIMフリースマホへのmineoSIM(docomoプラン、データ専用)の設定

※Android6.0の場合

設定→「無線とネットワーク」→「もっと見る」→「モバイルネットワーク」→
「アクセスポイント名」

(1)上の方の(+)を押して追加モード
名前:自分が解る名前(mineo等)
APN:mineo-d.jp
ユーザー名:mineo@k-opti.com
パスワード:mineo
認証タイプ:CHAP

上記だけでOK

メニューから保存して、選択して再起動

ちなみにFOMAスマホでも上記で動作確認完了

【VPS】ConoHaを使ってみて

OCNとかでHP公開用にクソ高いレンタルサーバを借りていたけど、どうも高い上にできることが限られる。
専用サーバっぽいのになにもできない。consoleすらない。

そこで、自分で好きにカスタマイズするためにVPSを選択。初期費用が安いのもあった。
最初はさくらVPSを選んでたけど、色々とあってConoHaを選択した。そのメリットを書いてみる。

イメージ保存機能

技術さえあればVPSは安く使うこともできる。初期インストールにテンプレートが用意されているので、OSのインストールまではそれほど手間もかからない。
しかし、Linuxディストリビューション毎に違うし、もっと言えばバージョン毎にも違う。
試行錯誤しながらシステムを構築していくことになる。
ConoHaの良い点は、ディスク全体のフルバックアップ(スナップショット)を簡単に取ることができる点。
リストアも簡単にできる。いやまあ、さくらVPSでもできるだんろうけど。
幾つか世代も取ることができるうえに50GBまでは無料。

しかし、dfコマンドで確認した容量よりも大きいサイズでバックアップされるのはご愛嬌かな。

[root@host-xxx-xx-xxx-xx ~]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       47G  8.5G   36G  20% /
tmpfs                 499M     0  499M   0% /dev/shm
/dev/vda1             477M   94M  358M  21% /boot

なのに、バックアップしたら30GBになった件。
直前のバックアップは使用量相当だったのにね。

10/3追記

ConoHaに上記の件を問い合わせた所、マッハで返事が帰ってきた。
ある程度、テンプレ質問なのかも。
大きいデータを書き込んでいた場合、そうなることがあるとのこと。ダミーデータを作成してから削除すれば良いとのことで、

# dd if=/dev/zero of=/tmp/zero.tmp bs=1M count=35240
# rm /tmp/zero.tmp

で様子を見ることに。


スケーラビリティ

メモリ、SSDも簡単に追加できる。
これこそがVPSのメリットだと思うんだけど、他社ではできるところがそんなに無いみたい。

【PHP】GDを使って画像に文字を埋め込む

グラフィックライブラリGDを使って、テンプレート画像に文字を埋め込むことを考えてみる。

GDを使ってPHPで文字を書き込む場合、呼び出し元は画像ファイルを表示するのと同じ要領で
imgタグを使って表示する。

<img src="image.php">

実際に表示する側。例えば、バナーに日程を埋め込んでいたものを自動で変更するような場合。
呼び出し元で動的に変更する場合もあるけど、たくさんあると非常に面倒で手間暇もかかる。

全体構造から

//日程の配列
//次回の日程を検索するため
$nitteiarray=array(
'2016-09-01',
'2016-10-02',
'2016-11-03',
'2016-12-04',
'2017-01-05',
'2017-02-06'
);
$week = array('日', '月', '火', '水', '木', '金', '土');


//画像に埋め込む日付を設定
$target_day = "";
$today = date("Y-m-d");
foreach($nitteiarray as $nittei){
	if(strtotime($today) <= strtotime($nittei)){
		$target_day = $nittei;
		break;
	}
}

//埋め込む文字の設定
//第n回 n月d日(曜日)
if($target_day != ""){
	$dispday = '第' . (array_search($target_day, $nitteiarray) + 1) . '回  ';
	$dispday .= date('n月j日', strtotime($target_day));
	$dispday .= '(' . $week[date('w', strtotime($target_day))] . ')';
} else {
	$dispday = (date("Y", strtotime($nitteiarray[0])) + 1) . '年度の日程は未定です';
}

//フォントファイル(環境により読み取るディレクトリが変わる)
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
	$font = '/usr/home/xxxxx/fonts/ipag.ttf';
} else {
	
	$font = "c:\\windows\\fonts\\ipag.ttf";
}

//OSにより、文字のエンコードを変更する
$dispday = con($dispday);

$image = imagecreatefromjpeg('./images/template.jpg');
$blue = imagecolorallocate($image, 0,0,255);
$result = imagettftext($image, 20, 0, 20, 85, $blue, $font, $dispday);

header("Content-type: image/jpeg");
imagejpeg($image, NULL, 80);
imagedestroy($image);

いくつか、ピンポイントで説明。

//フォントファイル(環境により読み取るディレクトリが変わる)
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
	$font = '/usr/home/xxxxx/fonts/ipag.ttf';
} else {
	
	$font = "c:\\windows\\fonts\\ipag.ttf";
}

Windows環境とLinux環境ではフォントの置き場所が変わる。ローカルでテストしてからLinuxでテストする時にフォントディレクトリを変更するのが面倒なので。

//OSにより、文字のエンコードを変更する
$dispday = con($dispday);

自前関数を使っている。
Linuxの場合、全角文字はUTF-8以外でないと文字化けするみたい。
逆にWindowsUTF-8でないと文字化けらしい。
ソースファイルをUTF-8にする手もあるらしいけど、それもアホらしい。
その中身は

function con($arg1){
	if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
		return(mb_convert_encoding($arg1, 'SJIS'));
	} else {
		return($arg1);
	}
}	
$image = imagecreatefromjpeg('./images/template.jpg');

テンプレートファイルを読み込む。

$blue = imagecolorallocate($image, 0,0,255);
$result = imagettftext($image, 20, 0, 20, 85, $blue, $font, $dispday);

イメージに、実際に文字を書き込む所。
imagettftextの引数は
第1・・・imagecreatefromjpegで読み込んだテンプレートファイル
第2・・・フォントサイズ
第3・・・角度
第4・・・位置(X座標)
第5・・・位置(Y座標)
第6・・・imagecolorallocateで指定した色
第7・・・フォントへのパス
詳しくは
PHP: imagettftext - Manual

header("Content-type: image/jpeg");
imagejpeg($image, NULL, 80);
imagedestroy($image);

header指定をjpegにして、イメージの中身を実際に出力して戻す所。