TRY AND ERROR

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

WordPressのAMPプラグインで/ampが真っ白になった件

WordPressのAMPプラグインを入れると一発でAMP化できるらしい、
という噂を聞いて早速試す、、、無事撃沈。
若干ハマったのでメモします。

・使ったプラグイン
AMP — WordPress Plugins


こちらのブログを参考にしたのですが、自分の環境でうまくいきませんでした。
プラグイン公式サイトのFAQに同じ質問が挙がっていたものの、未解決でした。。
WordPressのプラグインでブログをAMP対応にしてみた | 海外SEO情報ブログ



あれこれ調べた結果、サーバにphp-xmlがインストールされていなかったため、
プラグインのモジュール内でDomDocumentクラスが使えずに落ちていたことが原因でした。

WordpressのconfigでdebugモードをONにしてエラーを出してみると、
DomDocumentクラスが使えないみたいなメッセージがしっかりと出てました。

php-xmlをインストールしてapache再起動で解決。

yum -y install php-xml
service httpd restart


ちなみに、AMPプラグインでは現状投稿ページしかAMP対応できないそうです。
AMPのバリデートエラーもブラウザの機能でチェックできるようです。
詳しくはこちらで紹介されています。
検証!AMPに沿ったマークアップとエラーチェックの方法をご紹介! | サクラサクLABO公式ブログ



ヤレヤレ。。

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 プラグインも開発中とのこと。