TRY AND ERROR

気になったこと、勉強したこと、その他雑記など色々メモしていきます。。Sometimes these posts will be written in English.,

mysqlでtinyintがbooleanになる件

mysqlでtinyint(1)を指定したカラムのデータをcakephp3のモジュールで取得した際に、booleanとして扱われて困った。。

mysqlのバージョンは5.6.27

cakeのバグか?とも思ったんですが、リファレンスを見てみるとちゃんと書いてあった!

・BOOL、BOOLEAN
These types are synonyms for TINYINT(1). A value of zero is considered false. Nonzero values are considered true:

MySQL :: MySQL 5.6 Reference Manual :: 11.1.1 Numeric Type Overview

mysqlではbooleanはtinyint(1)のシノニムであり、0はfalse、0以外はtrueとして評価するとのことなので、cakeはtinyint(1)の値をbooleanに変換して処理してしまうようです。
ただ、実際にtinyint(1)には-128~127の整数値を入れられるので、ハマってしまう人も多いのではないでしょうか。

PHP7三項式まわりが快適すぎる

PHP7の三項演算あたりを本格的に使ってみましたが、快適すぎてやばいです!

あるkeyが存在するかどうかわからない配列をマージするような場合、
いちいちisset()しなくてよくなった!!

array_merge(
    $a['key'] ?? [],
    $b['key'] ?? [],
    $c['key'] ?? [],
    $d['key'] ?? []
);


isset地獄にみなさん1度はハマったことがあると思いますが、
PHP7だとスッキリしますね。

【Ruby】ChatworkAPI for Ruby

前回、ChatworkAPIクラスのPHP版を公開しましたが、今回Ruby版も作りました。

class Chatwork

	# イニシャライズ
	# apiToken: 自身のAPIトークン
	def initialize(apiToken)
		tokenHeaderKey = "X-ChatWorkToken: "
		@apiToken = apiToken										# APIトークン
		@reqHeader = "X-ChatWorkToken: #{@apiToken}"				# リクエストヘッダ
		@room = getRooms();        									# ルームID
	end


	# ルーム一覧取得
	def getRooms()
		ret = {}
		uri = URI.parse("https://api.chatwork.com/v1/rooms");
		
		# httpクラス
		http = Net::HTTP.new(uri.host, uri.port)
		http.use_ssl = true
		http.verify_mode = OpenSSL::SSL::VERIFY_NONE
		
		# httpリクエスト情報オブジェクト
		request = Net::HTTP::Get.new(uri.request_uri)
		request.add_field("X-ChatWorkToken", @apiToken)
		
		# httpレスポンス
		response = http.request(request)

		# ルーム名:ルームIDのハッシュにする
		JSON.parse(response.body).each{|data|
			ret[data["name"]] = data["room_id"]
		}
		return ret

	end
	private:getRooms


	# ルーム名からルームIDを取得する
	# roomName: ルーム名
	def getRoomID(roomName)
		return @room[roomName]
	end


	# メッセージを送る
	# roomid: ルームID
	# msg: メッセージ
	def sendMessage(roomid, msg)
		uri = URI.parse("https://api.chatwork.com/v1/rooms/#{roomid}/messages");

		# httpクラス
		http = Net::HTTP.new(uri.host, uri.port)
		http.use_ssl = true
		http.verify_mode = OpenSSL::SSL::VERIFY_NONE

		# httpリクエスト情報オブジェクト
		request = Net::HTTP::Post.new(uri.request_uri)
		request.set_form_data({'body'=>msg})
		request.add_field("X-ChatWorkToken", @apiToken)
		
		# ChatworkAPIにpostする
		http.request(request)
	end

end


使い方も前回同様にAPIトークンを渡してnewし、getRoomIDにメッセージを送信したいルーム名を渡してルームIDを取得、
sendMessageでメッセージを送るといった流れです。

GitHubリポジトリこちら


最低限の機能しか実装してませんのでカスタマイズしてみてくださいm(_ _)m

【PHP】ChatworkのAPI使ってみた

チャットワーク(Chatwork)のAPIを使って指定ルームにメッセージを送る
PHPのクラスを作ってみました。

バッチ処理の結果をチャットワークで見たい、メールの設定がめんどくさい、
みたいなときに使えるかも。。


クラスファイル:Chatwork.php

<?php

class Chatwork {
	
	private $tokenHeaderKey = "X-ChatWorkToken: ";
	private $apiToken;		//APIトークン
	private $reqHeader;		//リクエストヘッダ
	private $room = [];		//ルームID

	/*
	 * コンストラクタ
	 * $apiToken: 自分のAPIトークン
	*/
	public function __construct($apiToken) {
		$this->apiToken = $apiToken;
		$this->reqHeader = ["{$this->tokenHeaderKey}{$this->apiToken}"];
		$this->getRooms();
	}
	
	/*
	 * ルーム一覧を取得
	 * $apiToken: 自分が所属する部屋の一覧を取得
	*/
	private function getRooms() {
		$uri = "https://api.chatwork.com/v1/rooms";
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $uri);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $this->reqHeader);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		$ret = json_decode(curl_exec($ch));
		curl_close($ch);

		foreach ($ret as $r) {
			$this->room[$r->name] = $r->room_id;
		}
	}
	
	/*
	 * ルームIDを取得
	 * $roomName: ルーム名
	 * return: ルームID、見つからない場合false
	*/
	public function getRoomID($roomName) {
		return isset($this->room[$roomName]) ? $this->room[$roomName] : false;
	}
	
	
	/*
	 * ルームIDを指定してメッセージを送る
	 * $roomid: ルームID
	 * $msg: 送信メッセージ(改行は\n)
	*/
	public function sendMessage($roomid, $msg) {
		// リクエストURI
		$uri = "https://api.chatwork.com/v1/rooms/{$roomid}/messages";

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $uri);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $this->reqHeader);
		curl_setopt($ch, CURLOPT_POST, true);
		curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['body' => $msg]));
		curl_exec($ch);
		curl_close($ch);
	}

}

Chatwork.phpをinclude。自分のAPIトークンをコンストラクタに渡してインスタンス化すればOK。

$cw = new Chatwork('[API token]');


メッセージを送りたい部屋のルームIDを指定してメッセージを送れます。

$cw->sendMessage("[roomID]", "[Message]");

部屋名からルームIDを取得することもできます。
(というかChatwork画面から各部屋のルームIDを知る方法がわからなかった。。)

$roomid = $cw->getRoomID('[Room name]');

ほんと最低限の実相しかしてないので、興味ある方は公式ドキュメントを
参考に実装してみてはいかがでしょうかd( ̄  ̄)


Git:
https://github.com/kentaro-a/use-chatwork-api

参考:チャットワークAPIドキュメント

【PHP】巨大ファイルを読み込むとき

PHPでサイズの大きいファイルを読み込む時のメモ。


外部ファイルを全部読み込めればOK、ただし読み込めなかった場合には
エラーを返すというロジックを組みたかった。


たとえば、外部サイトをスクレイピングする際に、
HTMLファイルサイズが一定サイズを超える場合は取得しないよー、みたいなことです。
(もちろん法的に問題ない範囲での話ですが。。。)


file_get_contentsではオプションで読み込むバイト数を指定することはできますが、
この場合途中までの不完全なファイルになってしまう。


なので、1KBずつ読んで指定サイズを超えるた場合にエラー、
最後まで読みきれた場合はそのコンテンツを返す関数をつくってみた。

function ex_file_get_contents($uri, $maxSize) {
    $data = '';
    $size = 0;
    $K = 1024; //バイト計算上の1KB(≒10^3)
    $fp = @fopen($uri, "r");
    if ($fp) {
        while (!feof($fp)) {
            if ($size > $maxSize) {
				// 最大サイズを超えた時点で処理終了
            	@fclose($fp);
            	return false;
         	}
         	$data .= @fread($fp, $K);
         	$size += $K;
        }
        @fclose($fp);
    } else {
        return false;
    }
    return $data;
}

AMP HTML触ってみた

AMPってなに?

「Accelerated Mobile Pages」略してAMP。
モバイルサイトの UX 改善(ユーザー体験)を目的とした Google 主体のプロジェクトで、 画像やスマートアド等、ロードコストのかかるコンテンツを即座にロードすることにより、 UX を改善しようというのが主な目的。
AMP HTML というオープンフレームワークが発表されており、この仕様に沿ってモバイルサイトを作成すると高速で読み込まれるサイトが実現できるというもの。
Amp が用意した javascript(https://cdn.ampproject.org/v0.js)を読み込むことで、AMP仕様のHTMLタグ(AMP Components)が使用可になるので、これを使ってマークアップする形になります。


特徴

とりあえずファーストビューを表示する

AMP で作成したサイトでは、ファーストビューをできるだけ早く、かつ CPU 負荷の高く ないものという条件で プレレンダリングするようブラウザに伝えられるので、サイトを訪れた際のファーストビ ューがかなり早い。

キャッシュ

AMP の仕様で作成されたサイトは GoogleTwitter 側にキャッシュされ、 このキャッシュからコンテンツを返すことによって、高速表示を可能にしている。 (Google が提供する CDN 経由での配信可能)

Javascript

ロードを遅くする要因の一つとして javascript を挙げており、
AMP が用意している javaScript 以外の javaScript は”一切含めない”としている。 広告を表示したり解析したりする場合に javascript が使用されるが、
AMP ではこれらの javascript を許可せずに、今後の課題としている。
現状、iframe で広告を表示できる。

コンテンツサイズ

ブラウザは画像ファイル等を読み込む前にあらかじめ設定されたサイズを参照し、表示領域を確保することができる。
例えば、300×200 のバナーがあったとき、実際の画像サイズと同じ値を指定するとレンダリングが速くなる。
AMPでは、このようにサイズ指定を必須としている。


必須なこと

・ HTML5 を使用

・ html タグに以下の文字列を記載すること <html ⚡> または <html amp>
(イナズママーク?とかめんどくさw)

・ <head>と<body>を記載すること(まあこれは今まで通り。。)

・ <canonical>を記載すること
AMP で書いたページ(モバイルサイト)以外の通常ページがある場合はそこに、 なければ AMP ページ自身に標準化するように記載する

・ <meta charset="utf-8">を記載すること

・ <meta name="viewport" content="width=device-width,initial-scale=1,minimum- scale=1,maximum-scale=1,user-scalable=no,minimal-ui">を記載すること

・ <script async src="https://cdn.ampproject.org/v0.js"></script>を記載すること
ここに AMP のカスタムタグの定義等が書かれている模様。

・ <style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript> を記載すること

AMP Components

AMP が用意した HTML のカスタムタグのこと。
・画像を表示するAMP Component

<amp-img width=500 height=500 src="URL"></amp-img>
※サイズ指定は必須で、ないと表示されない。

これ以外にも多数の AMP Components が用意されている。

amp-audio
amp-anim
amp-ad
amp-pixel
amp-video
amp-carousel
amp-lightbox
amp-iframe
amp-instagram
amp-twitter
amp-youtube

今後の展望

現状 javascript 等に課題が残るものの、Google 主体ということから今後はモバイルサイト コーディングのデファクトスタンダードになっていくと思われる。ちなみに、WP の AMP プラグインも開発中とのこと。

最近話題の広告ブロックについて

面白い記事を見かけたので勝手に持論を展開!!
広告ブロッカーの検知と計測について - クックパッド開発者ブログ


WEB上のあらゆる所で目にする広告ですが、
これをブロックする機能を有したツールが出回っていますね。

WEB広告を生業とする企業にとって有害なものであることに
間違いありませんが、現在の日本の法律ではどうなるのか
気になって少し調べてみました。

広告ブロックは法的にまずい?

現在、日本には広告ブロックを直接的に禁止する法律はなさそうですね。
言うとすれば、著作権関連で同一性保持権(著作物の無断改変)があり、
これに該当するしないで争うことになるのではないかと勝手に想像。。

同一性保持権(どういつせいほじけん)は、著作者人格権の一種であり、著作物及びその題号につき著作者(著作権者ではないことに注意)の意に反して変更、切除その他の改変を禁止することができる権利のことをいう(日本の著作権法20条1項前段。以下、特に断らない限り、引用法令は日本のもの)。
同一性保持権 - Wikipedia

ただ、過去に判例がなさそうなのでなんとも言えませんが、
少なくとも刑事罰が課せられるということは考えにくいのでは??

民事責任を問われるか?

刑事罰の対象にならずとも、民事責任を問われるケースもありますね。
(犯罪じゃないけど違法です!的な...)
広告ビジネスを展開する企業にとって広告ブロックは死活問題と成り得るため、
サイトやサービスの利用規約に広告ブロックを禁止しているものも少なくありません。

また損害額を立証しやすいと思うので、
広告ブロックが使用されたことと売り上げ低下の因果関係が認められれば、
利用規約違反ということで民事上の損害賠償とかで刺されるケースも有り得るのではないでしょうか。


まあ何にせよコンテンツを見る見ないはユーザーの自由ですし、
フリーの動画やWEBサイトでは対価を支払っていないわけだから、「ウザイから広告をブロックします!」というのは倫理に反している気もしますね。。