komagataのブログ

static変数ってunsetできないの?

komagata@dev:~/works/example/php$ cat static.php
#!/usr/bin/env php
<?php
for ($i = 0; $i < 10; $i++) {
    increment();
}

function increment()
{
    static $foo;
    $foo++;
    if ($foo === 5) unset($foo);
    echo "$foo\n";
}
?>
komagata@dev:~/works/example/php$ ./static.php
1
2
3
4

6
7
8
9
10

どうやら俺は仕組みが良く分かってないようです。

ハッカーと画家 コンピュータ時代の創造者たち

金が無いのでyoshukiさんに借りて読みました。

「使う言語で考えるようになるから上位の言語の良さは理解できない」みたいなところに納得。PHPで思考してるところに「クラスや関数が式になってる方が便利だよ」っていってもさっぱり良さがわからん。(つまりココの俺みたいな状態?)

blog.xole.net : Seasar Conference 2006 Autumn開催するよ!

我(らが?)Seasar.PHPももちろん出ます。 ref – Seasar Conference 2006 Autumn – Session

最近のSeasar.PHPの(Update)動向をジャンジャンお話します。ここまで便利に。ここまで使い易くなってますよ。S2PHP5

セッションの題名が「 明日から始めるSeasar.PHP」にしてあるのにもワケがあって、「今日から」じゃないというのがミソ。

明日からってどういうことなんだろ!聞きてぇ~!

PHP4でDB系のテストがやりたくてrake db:fixtures:load的にテーブル毎のファイルからDBへロード/ダンプするクラスを書いてみました。

<?php
require_once 'INILoader.php';
dump_ini('/path/to/fixtures', 'mysql://user:pass@localhost/dbname');
?>

(magpieみたいにグローバルにいい加減なファサード作っちゃうquick & dirtyさ加減)

こんな感じで書くと、

% cat fixtures/member.ini
[member1]
id = "1" 
design_id = "1" 
account = "komagata" 
password = "aaa" 
email = "komagata@p0t.jp" 
createdtime = "2006-08-12 15:36:51" 
[member2]
id = "2" 
design_id = "2" 
account = "tom" 
password = "iii" 
email = "tom@gmail.com" 
createdtime = "2006-08-12 11:36:51" 
[member3]
id = "3" 
design_id = "3" 
account = "bob" 
password = "uuu" 
email = "bob@gmail.com" 
createdtime = "2006-08-12 12:36:51"

こんな感じの中身を指定したディレクトリに“テーブル名.ini”で吐く。yamlだとまんま過ぎなので何故かiniです。

<?php
require_once 'INILoader.php';
load_ini('/path/to/fixtures', 'mysql://user:pass@localhost/dbname');
?>

こう書くと逆にiniファイルを読んでテーブルにロードする。

以下コード。(さっとパッケージ化できる人になりたい)

<?php
require_once 'DB.php';

class INILoader
{
    var $fixtures_dir;
    var $dsn;
    var $key_check;
    var $db;

    function INILoader($fixtures_dir, $dsn, $key_check = true)
    {
        $this->fixtures_dir = $fixtures_dir;
        $this->dsn = $dsn;
        $this->key_check = $key_check;
        $this->db =& DB::connect($dsn);
        $this->db->autoCommit(false);
        $this->db->setFetchMode(DB_FETCHMODE_ASSOC);
    }

    function load($name = null)
    {
        if (is_null($name)) {
            $this->db->query('BEGIN');
            $this->_truncate_all();
            $this->_load_all();
            $this->db->commit();
        } else {
            $this->db->query('BEGIN');
            $this->_truncate($name);
            $this->_load($name);
            $this->db->commit();
        }
    }

    function dump($name = null)
    {
        if (is_null($name)) {
            $this->_remove_all();
            $this->_dump_all();
        } else {
            $this->_remove($name);
            $this->_dump($name);
        }
    }

    function _load_all()
    {
        if (!$this->key_check and preg_match("/^mysql/", $this->dsn)) {
            $this->db->query('SET FOREIGN_KEY_CHECKS = 0');
        }

        foreach ($this->_get_ini_files() as $file) {
            list($name, $ext) = split("\.", $file);
            $this->_load($name);
        }

        if (!$this->key_check and preg_match("/^mysql/", $this->dsn)) {
            $this->db->query('SET FOREIGN_KEY_CHECKS = 1');
        }
    }

    function _truncate_all()
    {
        foreach ($this->_get_ini_files() as $file) {
            list($name, $ext) = split("\.", $file);
            $this->_truncate($name);
        }
    }

    function _load($name)
    {
        echo "Load table {$name}... ";
        $data = parse_ini_file("{$this->fixtures_dir}/{$name}.ini", true);
        foreach ($data as $fields) {
            if (DB::isError($res = $this->db->autoExecute($name, $fields))) {
                $this->db->rollback();
                echo "failed\n";
                trigger_error('INILoader::_load(): Failed to load. '
                .$res->toString(), E_USER_ERROR);
            }
        }
        echo "succeed\n";
    }

    function _truncate($name)
    {
        echo "Truncate table {$name}... ";
        $sql = "TRUNCATE $name";
        if (DB::isError($res = $this->db->query($sql))) {
            $this->db->rollback();
            echo "failed\n";
            trigger_error('INILoader::_truncate(): Failed to truncate. '
            .$res->toString(), E_USER_ERROR);
        }
        echo "succeed\n";
    }

    function _dump_all()
    {
        foreach ($this->db->getTables() as $table) {
            $this->_dump($table);
        }
    }

    function _remove_all()
    {
        foreach ($this->db->getTables() as $table) {
            $this->_remove($table);
        }
    }

    function _dump($name)
    {
        echo "Dump table {$name}... ";
        $file = "{$this->fixtures_dir}/{$name}.ini";
        $handle = fopen($file, 'a');
        $sql = "SELECT * FROM $name";
        foreach ($this->db->getAll($sql) as $index => $fields) {
            $line = "[{$name}".++$index."]\n";
            foreach ($fields as $key => $value) {
                $line .= "{$key} = \"{$value}\"\n";
            }

            if (!fwrite($handle, $line)) {
                trigger_error("INILoader::dump(): Failed to write $file",
                E_USER_ERROR);
            }
        }
        fclose($handle);
        echo "succeed\n";
    }

    function _remove($name)
    {
        echo "Remove file {$name}.ini ... ";
        unlink("{$this->fixtures_dir}/{$name}.ini");
        echo "succeed\n";
    }

    function _get_ini_files()
    {
        $files = array();
        $d = dir($this->fixtures_dir);
        while ($entry = $d->read()) {
            if (preg_match("/\.ini$/", $entry)) {
                $files[] = $entry;
            }
        }
        $d->close();
        return $files;
    }
}

function load_ini($fixtures_dir, $dsn, $key_check = false)
{
    $loader =& new INILoader($fixtures_dir, $dsn, $key_check);
    $loader->load();
}

function dump_ini($fixtures_dir, $dsn)
{
    $loader =& new INILoader($fixtures_dir, $dsn);
    $loader->dump();
}
?>
Flickr Services

Serialized PHP Response Format

PHP has a built-in serialized data structure format, using the serialize() and unserialize() functions.

To return an API response in PHP serialized format, send a parameter ””format”” in the request with a value of ””php_serial””.

来てる!来てる!

p0t: PHPRPC

このフォーマットを汎用データ形式として広めようって剛の者はいないかな?

coLinuxやっと設定できました。

謎(ではないんだろうけど)の“インターネットゲートウェイ”って奴は“ネットワーク接続”の“詳細設定” > “オプション ネットワーク コンポーネント”の“ネットワーク サービス”の中の“インターネット ゲートウェイ デバイス検出とクライアントの制御”って奴を外したら無くなってくれました。

network_component

その後はTAP + NATで問題無く設定完了。 100%ハマるであろう未来の自分の為にメモを残しとこう。

  • 無線LAN[DHCP]
  • TAP[192.168.1.1](デフォルトゲートウェイ、DNSは空)
  • メモ/coLinux用RootFSイメージをDebianのISOイメージから作成を実行。
  • ネットワーク接続で落ちた場合coLinuxを上書きでいいからもう一回入れないと駄目(理由は不明)
  • 上記ネットワーク設定だとDHCPでは駄目なので手動で設定する。
  • coLinux[192.168.1.40]、resolve.conf[192.168.0.1]

coLinux、何度も何度も入れてるハズなのに毎回何故かハマる。多分全然学習してない。

ブリッジとNATで(何故かは忘れたが)確かNATの方が都合が良かったハズと思って設定してみるがcoLinuxから外へ行けない。多分下記のどれかが関係していて、おれがそのどれもハッキリ理解してないからだと思う。

  • 有線LANと無線LANがある(有線LANのみの環境だとハマッた覚えがない)
  • Windows XPのネットワーク接続に現れる”“インターネット接続 (インターネットゲートウェイ)”の存在が良く分からない(消せない)
  • coLinuxがちょっと新しい(0.6.4)

ブリッジ接続なら行けるんだけど、今度は下記にある「素からのインストール」をやろうとすると、

8. ネットワークを設定する。

の所でcoLinuxが落ちる。

メモ/coLinux用RootFSイメージをDebianのISOイメージから作成 – SaikyoLine.jp

一晩ハマって心が折れたので寝て起きてから考えよ。

Development Environment Conference

Development Environment Conference、開発者の開発環境のカンファレンスを 2006年9月8日にデジタルハリウッド大学(秋葉原ダイビル)にて開催しました。

DECon行ってきました。 やっぱりためんなって楽しかった。

  • vim小技
  • svk
  • オートリロード

とかは、すぐにでもやらなきゃ!って思いました。(あとpgrep, pkill知らなかった…。生まれなきゃよかった。) それとしつこいですが、デプロイ管理、運用系のツールが気になる!yumリポジトリ作ったり監視IRCボットとか、Plaggerリリースツールとかおしゃれだなー!(そんなことはない)

6aでは自作みたいですが、Capistrano的なのはperl, PHPにあるのかな?Catalyst、Symphonyとかにはあるのかも。あったら試してみたい。

IBM 5 つの共通 PHP デザイン・パターン : Open source : dW – Japan

デザイン・パターンがソフトウェア・コミュニティーに発表されたのは、「ギャング・オブ・フォー」として知られる Erich Gamma、Richard Helm、Ralph Johnson、そして John Vlissides 共著の『Design Patterns』のなかです。

地球上の誰かがふと思った、 『Javaとの差分だけ書いてくれれば、どれだけの人の時間が無駄にならずにすむだろうか…』

寄生獣 (1)
  • 寄生獣 (1)
  • 講談社(1990-07)
  • 講談社
  • (著)岩明 均
  • 定価:¥ 509
  • 中古価格:¥ 0
  • ASIN:4063140261
ご利用中のデータベースサーバについて

平素より弊社サービスをご利用いただき誠にありがとうございます。 さくらインターネットのカスタマーセンターです。

データベースサーバ mysql21.db.sakura.ne.jp において、サーバへの過負荷が 顕著であることを確認しました。弊社にて原因を調査いたしましたところ、お客 様ご利用のPHPプログラム(/home/attach/www/glue/bin/crawl.php) がCRONで定期的に実行されていることに起因しているのを確認いたしました。こ のため、緊急的措置として、設定済みのCRONを解除させていただきましたのでご 連絡いたします。

ちょ…。

「このサーバ、クローラ動かすべからず。」

「月500円のサーバの限界に立ち向かい、そして敗れた男達がいた…」

「風の中のすばるー♪ 砂の中の銀河ー♪ (略

丁度、新しいサーバを提供してもらえることになったところ。危なかった…。