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アプリを書く時にはぜひ使っていこうと思う。

2014-03-27

[]PHP Built-in server の使い方メモ

PHP 5.4 から Built-in server が追加されてて、手軽にWebアプリの動作確認が出来る事を今更知ったので、忘れないうちにメモしておく。

以下の様な感じで実行する。

% php -S localhost:8080 -c /path/to/php.ini -t /path/to/htdocs

これで、PHP における Webアプリの開発がものすごくやりやすくなった気がする。

2011-01-09

[][][]Perlのリハビリ開始

昨年、転職した会社の開発言語が、PHP と Perl だったのだが、なぜかやったこともない PHP の案件ばっかりやることになって、ここ最近はPHP の勉強を中心にやってた。

PHP に関しては、良い作法もまだよくわからないし、自分のスキルを生かすことなく悶々としてた。ただ、違う言語を習得することは技術の幅が広がるし、活躍の場も広がると思う。

しかしながら、自分が最も得意としている Perl で開発する方が、はまる事も少なくなるだろうし、開発工数も抑えることができると思う。

そんな経緯もあり、次の開発は Perl で書くことになるだろう。もちろん、既存の PHP で書かれたサービスのメンテのために、ゆるく勉強は続けるつもり。

前置きが長くなってしまったけど、Perl でプロダクトコードを書くにあたり、リハビリが必要かなと思い勉強を始めたのである。

Perl を勉強するにあたって、とりあえずこんなところを抑えようと思っている。

新たなフレームワークを習得

今回選択したのは、Mojolicious である。モジュールの依存がほとんどないのが魅力であると感じた。あと、Mojo 自体にも興味を持ったので。

まずは、運用ツールの開発ができるくらいまで勉強しようと思う。

O/Rマッパーを捨てる勇気

DBICCDBI を使ってきたけど、もう少し薄いラッパーの方が使いやすいなと考えるようになった。具体的には、SQL::Abstract の勉強をしようと思う。

GTKGUI プログラミング

完全興味本位である。以前少しやってたが、他の勉強を優先したので、残念ながら止まってる。がんばって再開したい。

少しずつですが、がんばって行きたいです。

2010-10-12

[]memory_limit 変更した

PHP は始めたばかりで詳しくはないのだが、php.ini の memory_limit が 256M になっていたんで、それはないだろうと思って 32M にしたというメモ。

Apache の MaxClients を 120 にしてたから、何かの拍子にメモリを食いつぶしたらスワップに落ちる設定になっていてあせった。

この辺の設定の作法とかよくわからないんで、失敗しながら覚えていくんだろうなぁ。

2008-02-13 phpはよく分からんです

[][]pukiwikiの復旧作業

会社で使ってるpukiwikiが、何も表示されなくなったとのことで、その復旧をしますた。

てか、pukiwikiが動いてるサーバは僕管理じゃないんやけど、「amari3君復旧しといて」とさらっとメールが送られてきた。仕方が無いので、Oracleセミナーが終わってから(本当はデブサミ2008に行きたかったんだけどなぁ)、自宅でがんばってみることに。

ちなみに環境はこんな感じ。適当ですが。

  • Debian GNU Linux 4.0 etch
  • php5
  • apache2.2(もちろんprefork)

まずは症状確認。確かに何も表示されない。他のphpファイルで試してみると、ソースが表示されてる。

PHPが認識してないのかと思って、server-infoを見ると、mod_php5は読み込まれてる。ますます謎。

そんなこんなでやってみたことは、

  1. 他のサーバに持っていって実行
  2. 拡張子php3とかphtmlで実行

1はもちろん実行できる。2も実行できてしまう。

で、最終的に疑ったのは、拡張子phpがtext/htmlとして認識されてんじゃね、と。

疑ってみたは良いが、直し方がまったくわかんないので(そんなわけでもないけど)、ググってみるが

AddType application/x-httpd-php .php .phtml .php3

の記述についてたっぷりヒットする。もちろん記述してる。

んで、手詰まり感が出てきたので、仕方なく以下を記述してみる。

AddHandler application/x-httpd-php .php

なんとかphpが実行されて、pukiwikiが復旧。

う〜ん、phpはよく分からんです。かなりモヤモヤ感があるので、調査しなおしだな。