July 29, 2014

AngularJSで一文字ずつフェードインして表示するディレクティブのメモ

以下がサンプルです。 ポイントは、一文字ずつバラしてspanタグで囲み、1spanタグずつdelay()させつつfadeIn()させる感じです。(あんまりAngularJS関係ない。。。)

先日作ったインスタグラムカルタで使っていて、テスト(spec)は https://github.com/mamor/igkaruta/blob/master/spec/directives/myFadeInCharsSpec.js みたいな感じで書きました。

Travis CIでPHPUnitを実行して、Coverallsでカバレッジを表示するメモ

メモです。

大雑把な手順は
1. Coveralls でアカウント作成と対象レポジトリの登録
2. satooshi/php-coveralls のインストール
3. .travis.yml を編集
4. .coveralls.yml を作成
になります。

1. Coveralls でアカウント作成と対象レポジトリの登録
https://coveralls.io/ から特に問題なく出来たので割愛します。

2. satooshi/php-coveralls のインストール
Travis CIとCoverallsの連携にしか必要ないので、composer.jsonには書かずに.travis.ymlでインストールするようにしました。"before_script" で "composer require satooshi/php-coveralls:0.* --dev" とかすればOKです。

3. .travis.yml を編集
"phpunit --coverage-clover build/logs/clover.xml" として、PHPUnit実行時にカバレッジファイルを出力するようにします。また "after_script" で "php vendor/bin/coveralls"として、Coverallsに通知します。

4 の.coveralls.ymlは
src_dir: .
coverage_clover: build/logs/clover.xml
json_path: build/logs/coveralls-upload.json
としました。

まとめると
https://github.com/mamor/igkaruta/commit/99c1492f9862000bd70e6a974c72ea209413f088
みたいな感じです。

後は、README.mdにバッジのURL(Coveralls側でわかります)を書けば https://github.com/mamor/igkaruta#karuta-for-instagram のように表示することが出来ました。

July 26, 2014

AngularJS と Laravel による Instagram の写真を使ったカルタを Heroku にデプロイしてみた

ふと、Instagramの写真でカルタできそうだなと思いついたので、作ってみました。

アプリケーションのURLは以下になります。
http://igkaruta.herokuapp.com/

ソースは以下で公開しています。
https://github.com/mamor/igkaruta


以下、遊び方。


1.
Login with Instagram > Play KARUTA と進みます。

2.
対象ユーザを選択して "GET PHOTOS" を押します。対象ユーザの写真有無チェックはまだしていないので、写真が取れなかったら別のユーザを選んで下さい。

3.
写真が表示されたら "START" を押します。カルタが始まります。


4.
"STOP" で一時停止、"START" で再開ができます。

5.
"GET PHOTOS" で、所謂ニューゲームになります。


以下、開発周り。


サーバサイドにはLaravelを使いました。が、InstagramのAPI(認証含む)の実行程度なので、大したことはしていません。尚、雛形には、ちまちまとオレオレ化させている https://github.com/mamor/laravel を使っています。

Herokuへのデプロイは
http://madroom-project.blogspot.jp/2014/07/herokuphppackagejsonnodejs.html
http://madroom-project.blogspot.jp/2014/07/herokuapplication-error.html
https://github.com/mamor/igkaruta/commit/462461e50c7a81dec00a2fddcf10f8760537491f
みたいな感じです。

クライアントサイドにはAngularJSを使いました。一番最初に勉強がてら作った TroubleClinic https://github.com/mamor/TroubleClinic の頃と比べて、少しはAngularJS力がついたかなぁと思います。ディレクトリ構成やソースの書き方は、Yeomanを参考にしています。

ちなみにYouFMもAngularJSで作っています。コイツもよろしくお願いしますw
https://chrome.google.com/webstore/detail/youfm/gbpebippikipomjijplmbepmginobjbj

テストはそれぞれ、PHPUnitとJasmine(+ gulp.js + Karma)で行っています。何かの参考になれば幸いです。


P.S.
アイデア等、PR歓迎です。誰か神経衰弱作って下さいw

Herokuで"Application Error"が出た

Herokuで以下のエラーが出ました。


公式ドキュメントの https://devcenter.heroku.com/articles/error-codes#h14-no-web-dynos-running を参考に
heroku ps:scale web=1
したら解決しました。

HerokuにPHPアプリをデプロイ時、package.jsonがあるとnode.jsアプリと認識されるっぽい

HerokuにPHPアプリをデプロイしようとしたら、node.jsアプリと認識されてしまいました。

composer.jsonもcomposer.lockもあるのですが、雑多なタスクをまとめるためにpackage.jsonもあったので、それが原因なんだと思います。

なので、BUILDPACK_URLを設定してみると、解決出来ました。
heroku config:set BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-php

July 20, 2014

Goutteでダウンロードしたファイルの内容を取得する

PHPのスクレイピングライブラリで有名なGoutte https://github.com/fabpot/Goutte で、ダウンロードしたファイルの内容を取得する手順メモです。

Goutteをインストールします。
$ composer require fabpot/goutte:2.*
以下、ファイルをダウンロードするサンプルです。
<?php

require_once './vendor/autoload.php';

// Goutte\Client のインスタンスを生成する
$client = new Goutte\Client;

// ダウンロードしたいファイルがあるURLにアクセスする
$client->request('GET', 'http://example.com/download.php');

// レスポンスのオブジェクトを取得する
/** @var Symfony\Component\BrowserKit\Response $response */
$response = $client->getResponse();

// コンテンツのオブジェクトを取得する
/** @var GuzzleHttp\Stream\Stream $content */
$content = $response->getContent();

// seek(0) して getContents() するとファイル内容を取得できる
$content->seek(0);
echo $content->getContents();
これで、ダウンロードしたファイルの内容を取得出来ました。ポイントは seek(0) です。これをしないと、どうにも取得できませんでした。

尚、ダウンロードさせる側に、以下のPHPファイルを置いて確認しました。
<?php

// download.txt は別途用意する
$file = 'download.txt';
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$file);
header('Content-Length: ' . filesize($file));
readfile($file);

July 17, 2014

Piwikのメンテナンスモードを切り替えるプラグインを作りました

2014-07-18 追記:
Packagistに登録したので、Composerで簡単にインストールできるようになりました。
https://packagist.org/packages/mamor/piwik-plugins-maintenance

--

前回 http://madroom-project.blogspot.jp/2014/07/piwik.html の続きです。

というわけで、出来ました。
https://github.com/mamor/piwik-plugins-maintenance

どうも Piwik Plugins Marketplace http://plugins.piwik.org/ に反映されないので、インストール方法と使い方をメモしておきます。

1.
上記のソース一式を /path/to/piwik/plugins/Maintenance として配置します。

2.
Maintenanceプラグインを有効にします。たぶん画面からできますが config/config.ini.php に以下を追記してもOKでした。
[Plugins]
Plugins[] = "Maintenance"

[PluginsInstalled]
PluginsInstalled[] = "Maintenance"
3.
有効になったか確認します。
$ ./path/to/piwik/console
maintenance
  maintenance:off                        Disable Maintenance Mode.
  maintenance:on                         Enable Maintenance Mode.
4.
実行してみます。
$ ./path/to/piwik/console maintenance:on
Now, Maintenance Mode is 1.

$ ./path/to/piwik/console maintenance:off
Now, Maintenance Mode is 0.
config/config.ini.phpを書き換えるので、書き込み権限には注意して下さい。

Piwikのプラグインを作るメモ

Piwikのメンテナンスモードをコマンドラインから切り替えたいのですが、標準では備わっていないようなので作ってみようと思います。

出来上がったらPiwik Plugins Marketplaceで公開する予定です。
http://plugins.piwik.org/
http://developer.piwik.org/guides/distributing-your-plugin

以下、必要なファイルを生成する手順のメモです。
# プラグインを作成します
$ ./console generate:plugin

# プラグインの名前を入力します
Enter a plugin name: maintenance

# プラグインの説明を入力します
Enter a plugin description: Allows you to manage maintenance mode by CLI.

# プラグインのバージョンを入力します
Enter a plugin version number (default to 0.1.0):

# 併せてAPIとControllerを作成するか入力します
Shall we also create an API and a Controller? (y/N)N

# コマンドを作成します
$ ./console generate:command

# 先ほど作成したプラグインを選択します
Enter the name of your plugin: Maintenance

# コマンド名を入力します
# この場合は "./path/to/piwik/console maintenance:on" になります
Enter the name of the command: on

プラグインを有効にした後 plugins/Maintenance/Commands/On.php を好きに編集します。

July 10, 2014

PHP5.5 で "continue 2" したらメモリ使用量が増えた

PHP5.5 で "continue 2" したらメモリ使用量が増えている気がしたので、簡単に検証してみました。

使ったソースは以下です。
<?php

/**
 * メモリ使用量をKB表記で返す
 *
 * @return string
 */
function peak_usage() {
    return (memory_get_peak_usage(true) / 1024).'KB'.PHP_EOL;
}

// 100要素数の配列を作る
// 各要素には ['a', 'b', 'c'] が入る
$array = [];
for($i = 0; $i < 100; $i++) {
    $array[] = ['a', 'b', 'c'];
}

// もう一つ適当に配列を作る
$array2 = ['x' => 'X', 'y' => 'Y'];

// $array * $array2 を反復を 100 回行う
// $array * $array2 の反復の中で即時 continue 2 する
for($i = 0; $i < 100; $i++) {
    if ($i % 10 === 0) {
        echo php_sapi_name() === 'cli' ? peak_usage() : nl2br(peak_usage());
    }

    foreach ($array as $key => $value) {
        foreach ($array2 as $key2 => $value2) {
            continue 2;
        }
    }
}
まずは、PHP 5.4 (OS X Mavericks) で確認してみます。
$ php -v
PHP 5.4.24 (cli) (built: Jan 19 2014 21:32:15)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
ブラウザからアクセス (ビルトインサーバーで実行)
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
コマンドラインから実行
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
結果に違いはありませんでした。

次に、PHP 5.5 (Vagrant x Ubuntu 13.10) で確認してみます。
$ php -v
PHP 5.5.12-2+deb.sury.org~saucy+1 (cli) (built: May 12 2014 13:45:47)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies
    with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies

$ apache2 -v
Server version: Apache/2.4.9 (Ubuntu)
Server built:   Apr  1 2014 08:58:43
ブラウザからアクセスした結果 (Apacheで実行)
512KB
768KB
1280KB
1536KB
2048KB
2304KB
2816KB
3072KB
3584KB
3840KB
コマンドラインから実行した結果
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
512KB
ブラウザからアクセスした時に、かなり増えました。ちなみに "continue 2" の箇所をコメントアウトすると、ブラウザからアクセスした時も、ずっと "512KB" のままになりました。

Stack Overflowに以下の投稿が見つかり、"Zend OPcache"に関することが書かれています。
http://stackoverflow.com/questions/23231675/php-5-5-memory-leak-when-using-continue-2-inside-two-foreach-loops

2014-07-11 追記: PHP本家にも報告されていました。
https://bugs.php.net/bug.php?id=67111

再現条件は良くわかりませんが、Zend OPcacheのバグっぽいですね。

尚、foreach()している箇所をwhile()に変えたら、増加は発生せず、ずっと"512KB"となりました。応急処置するなら、この方法ですかねぇ。
reset($array);
while (list($key, $value) = each($array)) {
    reset($array2);
    while (list($key2, $value2) = each($array2)) {
        continue 2;
    }
}

July 3, 2014

PHPで2箇所の緯度経度から距離を計測するメモ

メモです。

MySQLのgeometry型とかは使用せず、以下のライブラリを用いてPHPだけで、多摩センターと新宿の距離を測ってみます。
https://github.com/mjaschen/phpgeo
(README.mdに書いてある通りですが。。。)

答え合わせには、以下を使わせて頂きました。
http://www.kyori.jp/

ライブラリをインストールして、適当なPHPを書きます。
$ composer require mjaschen/phpgeo:0.*
<?php

require_once 'vendor/autoload.php';

use Location\Coordinate;
use Location\Distance\Vincenty;

// 多摩センター
$coordinate1 = new Coordinate(35.623891, 139.42287299999998);

// 新宿
$coordinate2 = new Coordinate(35.6938401, 139.70354940000004);

echo $coordinate1->getDistance($coordinate2, new Vincenty());
"26573.928" (メートル)が出力されました。問題無さそう。