amari3のはてなダイアリー このページをアンテナに追加 RSSフィード

2014-03-29

[]PHPマイクロフレームワークSlimを使ってTinyURLを作ってみた

Slim は RubySinatra の様なマイクロフレームワークで、PHP で簡単な Webアプリを書くにはちょうどいいと思う。今回はその Slim を使って、短縮 URL(bitly みたいなやつ)を作ってみた。なお、tokuhirom さんの Amon2 のサンプルからアイデアを拝借しています。

環境

Mac OS X 10.9.2

PHP 5.4.26

See also

Slim Framework v2

インストール

Slim のインストールは Composer で行う。Ruby の Bundler や Perl の Carton の様なライブラリ管理ツールである。

% cd /path/to/project
% curl -s https://getcomposer.org/installer | php

composer.json に以下を記述する。

{
    "require": {
        "slim/slim": "2.*"
    }
}

以下のコマンドでインストールする。vendor ディレクトリに slim が格納される。

% php composer.phar install

ディレクトリレイアウト

ベターなディレクトリレイアウトがあるかもしれないけど、手探り状態で作ったので、良いディレクトリレイアウトがあったら教えて下さい!

project/
    composer.json
    composer.lock
    composer.phar
    root/  # ドキュメントルート
        .htaccess  # PHP ビルトインサーバを使用したので今回は必要なし
        index.php
    tmpl/  # テンプレート
        index.php
        result.php
    vendor/
        slim/slim/   # Slimライブラリ
    sql/
        sqlite3.sql
    development.db

TinyURL を作る

まずは DB のテーブルを作成する。以下のスキーマを作成して、sql/sqlite3.sql で保存する。

sql/sqlite3.sql

create table tinyurl (
    key varchar(20) primary key,
    url text
);

以下のコマンドを実行して、DB のテーブルを作成する。

% sqlite3 development.db < sql/sqlite3.sql

これで DB の準備は完了。

今回はあくまで動くものを作ることが目的なので、エラーチェックやバリデーション等は甘いです。

root/index.php

<?php
require '../vendor/autoload.php';

$app = new \Slim\Slim(array(
    "debug" => true,
    "templates.path" => "../tmpl"
));
$db = new PDO('sqlite:../development.db');

// 引数で指定した長さのランダムな文字列を生成
function stringRandom($len = 5) {
    if (!is_numeric($len) || $len <= 0) {
        die("positive interger is required.");
    }

    $str = '';
    for ($i = 0; $i < $len; ) {
        $num = mt_rand(0x30, 0x7A);
        if ((0x30 <= $num && $num <= 0x39) || (0x41 <= $num && $num <= 0x5A) ||
(0x61 <= $num && $num <= 0x7A)) {
            $str .= chr($num);
            $i++;
        }
    }
    return $str;
}

$app->get('/', function () use ($app) {
    $app->render("index.php");
});

$app->post('/create/', function () use ($app, $db) {
    $req = $app->request();
    $url = $req->post("url");
    if (!$url) {
        $app->redirect('/');
        return;
    }

    // dup check
    $sth = $db->prepare('SELECT key FROM tinyurl WHERE url = ? LIMIT 1;');
    $sth->execute(array($url));
    $result = $sth->fetch(PDO::FETCH_ASSOC);
    $key = $result['key'];
    if (!$key) {
        // create new one
        $key = stringRandom(6);
        $sth = $db->prepare('INSERT INTO tinyurl (key, url) VALUES (?, ?);');
        $sth->execute(array($key, $url));
    }
    $app->render('result.php', array("tinyurl" => $req->getUrl() . '/g/' . $key));
});

$app->get('/g/:key', function ($key) use ($app, $db) {
    if (!$key) {
        $app->redirect('/');
        return;
    }

    $sth = $db->prepare('SELECT url FROM tinyurl WHERE key = ? LIMIT 1;');
    $sth->execute(array($key));
    $result = $sth->fetch(PDO::FETCH_ASSOC);
    $url = $result['url'];
    $app->redirect(($url) ? $url : '/');
});

$app->run();
?>

tmpl/index.php

<!DOCTYPE html>
<html>
  <head>
    <title>TinyURL</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h1>tinyurl</h1>
    <form action="/create/" method="POST">
      <input type="text" name="url" value="">
      <input type="submit" name="submit" value="tiny!">
    </form>
  </body>
</html>

tmpl/result.php

<!DOCTYPE html>
<html>
  <head>
    <title>TinyURL</title>
    <meta charset="UTF-8">
  </head>
  <body>
    <h1>tinyurl</h1>
    <div><?php echo htmlspecialchars($tinyurl, ENT_QUOTES, "UTF-8"); ?></div>
    <a href="/">return to top</a>
  </body>
</html>

実際に作ってみた感想

小さな Webアプリを早く作るには非常に使いやすいと感じた。フルスクラッチで書くと煩雑になりがちな、ルーティングを気にしないでいいのが個人的には大きいかな。PHP で簡単な Webアプリを書く時にはぜひ使っていこうと思う。

2013-08-26

[] CentOS(6.4) に daemontools をインストールした

PSGI なアプリを運用するにあたり、落ちた時に自動起動して欲しいなと思うわけです。そこで daemontools を導入しようと考えている。runit や monit 等同様なツールもあるわけだけど、 ネットで調べる限りだと daemontools での運用実績はかなり多そうなので良さそうかと思ったのだ。

インストール手順

何はともあれインストールしないと始まらないし、さくっとインストールしてみる。

パッチを当てないとコンパイルに失敗するので、併せてダウンロードしておこう。

本体&パッチのダウンロード

% wget http://cr.yp.to/daemontools/daemontools-0.76.tar.gz
% tar xpvf daemontools-0.76.tar.gz
% cd admin/daemontools-0.76
% wget http://qmail.org/moni.csi.hu/pub/glibc-2.3.1/daemontools-0.76.errno.patch

パッチ適用&コンパイル

% patch -s -p1 <./daemontools-0.76.errno.patch
% ./package/compile

このままインストールすると /command にシンボリックリンクが張られて、そこからさらに /usr/local/bin にシンボリックが張られるのだが、気持ち悪いし直接 /usr/local/bin にインストールする。

svscanboot の設定に /command の記述があるので、/usr/local/bin に修正しておこう。他のファイルも同様に修正しておくとよい。

% cd command/
% sudo install -o root -g root -m 0755 -s envdir /usr/local/bin
% sudo install -o root -g root -m 0755 -s envuidgid /usr/local/bin
% sudo install -o root -g root -m 0755 -s fghack /usr/local/bin
% sudo install -o root -g root -m 0755 -s multilog /usr/local/bin
% sudo install -o root -g root -m 0755 -s pgrphack /usr/local/bin
% sudo install -o root -g root -m 0755 -s readproctitle /usr/local/bin
% sudo install -o root -g root -m 0755 -s setlock /usr/local/bin
% sudo install -o root -g root -m 0755 -s setuidgid /usr/local/bin
% sudo install -o root -g root -m 0755 -s softlimit /usr/local/bin
% sudo install -o root -g root -m 0755 -s supervise /usr/local/bin
% sudo install -o root -g root -m 0755 -s svc /usr/local/bin
% sudo install -o root -g root -m 0755 -s svok /usr/local/bin
% sudo install -o root -g root -m 0755 -s svscan /usr/local/bin
% sudo install -o root -g root -m 0755 -s svstat /usr/local/bin
% sudo install -o root -g root -m 0755 -s tai64n /usr/local/bin
% sudo install -o root -g root -m 0755 -s tai64nlocal /usr/local/bin
% sudo install -o root -g root -m 0755 svscanboot /usr/local/bin

/service ディレクトリを作成する。

% sudo ./package/run

Upstart の設定をする。

% sudo vim /etc/init/svscan.conf
start on runlevel [12345]
respawn
exec /usr/local/bin/svscanboot

起動する

% sudo initctl reload-configuration
% sudo initctl list
% sudo initctl start svscan

これで daemontools が使用できるようになった。

と、daemontools のインストールをしておいてなんだが、supervisor を使ってみたいと今思ってる。

2012-11-29

[]sudoedit を実行するための sudoers の設定方法

2年半前くらいに書いたブログ 一般ユーザ権限で root 所持のファイルを編集するときは sudoedit を使おう - amari3のはてなダイアリーid:tokuhirom さんからブコメが付いてた。

sudoers をきちんと設定しないと意味がない予感(きちんと設定できるかは未確認)

確かに具体的な設定方法とか書いてないから、実際のところどないやねんってのは、書いた僕自身感じた。というわけで、sudoers の設定の一例を書くことにする。

sudoers の設定

一般ユーザ amari3z が root 権限で、MySQL の設定ファイル /etc/my.cnf をパスワードレスで編集・保存出来る様にする。というシナリオで設定することにする。

なお、説明を単純にするために、Alias 設定は使わないこととする。

% sudo visudo
amari3z ALL=(root)      NOPASSWD: sudoedit /etc/my.cnf

sudoedit を使ってみる

以下のコマンドを実行するだけ、難しいところはないと思う。

% sudoedit /etc/my.cnf

パスワードを聞かれることもなく、普通に編集・保存が出来る。

別の実行例として、/etc/bashrc を編集しようとしてみる。

% sudoedit /etc/bashrc
Sorry, user amari3z is not allowed to execute 'sudoedit /etc/bashrc' as root on ...

パスワードが聞かれる上にパスワードを入力しても、↑の様なメッセージが出て実行出来ない。

詳しくは、man sudoers を実行して確認すればいいと思う。Cmnd_Alias の Cmnd_List の記述方法に sudoedit のそれも載っている。

最近ブログをサボり気味だから、これを機にまた続けて行かないと。

2011-02-06

[][]Debian GNU/Linux 6.0 インスコした

待ちに待った、Debian Squeeze がついに正式リリースとなったので、早速インスコしてみた。使用した iso イメージは、http://www.debian.org/distrib/netinst の、小さな CD の powerpc。

Debian Etch を入れたままにしてあった mac mini(powerpc)に、CD からクリーンインストールした。特に詰まることも無かったんで、正直あんまり書くこともなかったりする。

パーティションとか

とりあえずディスク関連は以下の様に切ってみた。

  • パーティションは root パーティション only*1
  • swap はメモリの3倍となる1.5GB*2

とりあえず導入したパッケージ

  • ssh
  • sudo
  • resolvconf
  • zsh
  • screen

sudo設定

root で直接作業をしたくないので、sudo で作業が出来るように設定する。Debian Squeeze では、sudo グループがデフォルトで登録されている。

%sudo ALL=(ALL) ALL

ユーザを sudo グループに所属させることで、root 相当の作業が出来るようになる。

# gpasswd -a amari3 sudo

ちなみに最近知ったんですが、Lenny からは、apt-get と aptitude が混在しても大丈夫らしいです。とりあえず色々触ってみよう。

*1:homeくらいは分けてもいいかもしれない

*2:swapの切り方は色んな考え方があると思う

2011-01-07

[][]Debian GNU/Linux 5.0 に Firefox を入れた

自宅で使ってる Debian GNU/Linux 5.0(ちょっと古いね) の Iceweasel のバージョンが低いのに飽き飽きして、Firefox を入れたので、インストール手順を覚書としてメモしとく。

ソースコンパイルは必要なかった

実は恥ずかしながら、Linux 向けのバイナリが提供されていることを知らずに、ソースコンパイル面倒だなぁと思ってて、重い腰を上げてインスコしようと思ったら、実はバイナリがあってちょっぴり嬉しい気分になった。

インストール手順

Mozilla のダウンロードサイト A better, faster, private browser for today | Firefox から最新の Firefox のバイナリをダウンロードしてくる。

root 権限で tarball を解凍する。(/usr/local/firefox に入れる)*1

% sudo tar xpvf firefox-3.6.13.tar.bz2 -C /usr/local

ライブラリのパスを通す。 /etc/ld.so.conf.d 以下に firefox.conf を作成し以下の様に記述。

% sudo vim firefox.conf
/usr/local/firefox
% sudo /sbin/ldconfig

.zshenv や .bashrc で firefox へのパスを通す。

export PATH=/usr/local/firefox:$PATH

以上でインストールは完了。ソースコンパイルを覚悟していたので意外とあっさりできた。

起動方法は以下の様に非常に簡単です。

% firefox

今までバージョンが低くて、使いたいアドオンが使えなかったり、色々悶々していたけどこれですべて解決。快適にネットが出来るもんです。

*1rootで解凍する必要はないが、所有者rootが良いと判断したため