EXPLAINの解説が丁寧です。
公開って程でもないけど!!ハードルを下げてからいきます。
なぜモジュールがあるrubyでないのか、面倒だったからです・・・。
lib/blink1.php
<?php class blink1 { public function __construct() { // $this->blink1Tool('-m 0 --off'); } protected function blink1Tool($arg) { $last_line = system('blink1-tool ' . $arg, $retval); echo $last_line; return $retval; } protected function rgb($r, $g, $b, $ms = 500) { $this->blink1Tool("-m {$ms} --rgb {$r},{$g},{$b}"); } protected function turnOnOne($r1, $g1, $b1, $r2, $g2, $b2, $ms = 500) { $this->blink1Tool("-l 1 -m {$ms} --rgb {$r1},{$g1},{$b1} && blink1-tool -l 2 -m {$ms} --rgb {$r2},{$g2},{$b2}"); } private function repeatFlashes($r, $g, $b, $repeat) { for($i = 0; $i < $repeat; $i++) { $this->rgb($r, $g, $b); usleep(500000); $this->rgb(0, 0, 0); usleep(500000); } } public function red($repeat = 3) { $this->repeatFlashes(255, 0, 0, $repeat); } public function green($repeat = 3) { $this->repeatFlashes(0, 255, 0, $repeat); } public function blue($repeat = 3) { $this->repeatFlashes(0, 0, 255, $repeat); } public function white($repeat = 3) { $this->repeatFlashes(255, 255, 255, $repeat); } public function yellow($repeat = 3) { $this->repeatFlashes(255, 255, 0, $repeat); } public function purple($repeat = 3) { $this->repeatFlashes(255, 0, 255, $repeat); } public function policecar($repeat = 6) { for($i = 0; $i < $repeat * 2; $i++) { $this->turnOnOne( 255, 0, 0, 0, 0, 0, 300 ); usleep(300000); $this->turnOnOne( 0, 0, 0, 0, 0, 255, 300 ); usleep(300000); $this->rgb(0, 0, 0, 100); usleep(100000); } } public function fireengine($repeat = 6) { for($i = 0; $i < $repeat * 2; $i++) { $this->turnOnOne( 255, 0, 0, 0, 0, 0, 300 ); usleep(300000); $this->turnOnOne( 0, 0, 0, 255, 0, 0, 300 ); usleep(300000); $this->rgb(0, 0, 0, 100); usleep(100000); } } } |
Windows版ユーティリティの点灯パターンをちょっとだけ再現。
gmail.php
<?php require_once 'lib/blink1.php'; $gmail = new gmail(); $gmail->check(); class gmail { private $hostname; private $port; private $flags; private $username; private $password; public function setUp() { mb_language('ja'); mb_internal_encoding('UTF-8'); $this->hostname = 'imap.googlemail.com'; $this->port = '993'; $this->flags = '/novalidate-cert/imap/ssl'; $this->username = 'アカウント名'; $this->password = 'パスワード'; } public function check(){ $this->setUp(); $mbox = imap_open( '{' . $this->hostname . ':' . $this->port . $this->flags . '}INBOX', $this->username, $this->password ); $uids = imap_search($mbox, 'UNSEEN', SE_UID); imap_close($mbox); if($uids === false) return ; $unread = count($uids); $blink1 = new blink1(); if($unread >= 1 && $unread <= 3) { $blink1->blue(5); } else if($unread >= 4 && $unread <= 6) { $blink1->yellow(5); } else if($unread >= 7 && $unread <= 10) { $blink1->red(5); } else if($unread > 10) { $blink1->fireengine(); } } } |
単純に未読数をしきい値に光らせてます。
check.sh
#!/bin/bash cd /home/pi/notification /usr/bin/php gmail.php |
シェルスクリプトを作って、cronから呼びます。
*/15 8-23 * * * /home/pi/notification/check.sh |
夜中は光ってほしくないので8~23時の間、15分間隔でチェック。
開発者、永遠のテーマであるアーキテクチャ。
自身ではMVCがシンプルで拡張性も高く好きです。
先日開催された「PHPカンファレンス福岡2015」で発表されたスライドを引用させてもらいます。
CakePHPを土台に作る事が多い+改修などでも出会う機会が増えてきました。
割りと制約が多い方に部類されるCakePHPでも、それぞれ特徴が出たり、ありがちなControllerにビジネスロジックがごっそり入っているパターンだったり、Modelにビジネスロジックが入っていてもシステムが大きくなる程に、役割や責任の範囲が曖昧になり、巨大なModelの出来上がりとなるのは「開発あるある」ではないでしょうか。
スライドにあるような、レイヤーにサービス層を入れる事で、Facadeパターンを取り入れたような設計ができます。
ちなみにCakePHP2系でパッケージを追加するのは簡単です。
app/Config/bootstrap.php
App::build(array( 'Service' => array('%s' . 'Service' . DS) ), App::REGISTER); |
で追加して、下記のように呼び出せます。
app/Controller/HogeController.php
App::uses('FugaService', 'Service'); |
ControllerはHTTPリクエストの操作、Viewの呼び出し、Service実行のみを行う。
Serviceはリクエストの検証、ビジネスロジック。Model実行。
Modelはバリデーション、DB操作のみを行う。ORマッパ経由でもServiceレイヤーには書かない。
Viewはロジックを入れないでとか、データ加工ならHelperとかElementを上手く使って。
これだけでも後から見たり、人が増えたりしても仕様理解が早く済む。と思っています。
これからはCakePHP3が既にリリースされているので、新機能との合わせ技で試行錯誤してみたいですね。
PHP7のリリースも迫っていて、楽しみ半分、大変そうです。