PHP5 で PEAR の内部で Non-Static method エラーが出る

PHP5 で set_error_handler() を利用していると、PEAR のライブラリの各所(PEAR::isError, DB::connect など)で E_STRICT(=2048) が発生します。
set_error_handler の呼び出しを次のように変更すると回避可能です。

変更前:
    set_error_handler(‘handler’);
変更後:
 define(‘PHP5’, version_compare( phpversion(), “5.0.0”, “>=” ));
 if(PHP5){
     $old_error_handler = set_error_handler(‘handler’, E_ALL);
 }else{
     $old_error_handler = set_error_handler(‘handler’);
 }

バージョンに応じて第二引数を与えているのがミソです。もちろん、PHP5だけに対応するのであれば、単純に既存のものに第二引数を与えればいいだけです。
 
PHP5 (5.0.5 で確認)では static メソッドの認識が微妙ですね。
 
参考:
– #1491(Make code work on both PHP4 and PHP5) (LiveSupport – Trac)

Smarty で JavaScript や CSS を使うと構文エラーになる対策

{literal} 〜 [/literal}

で挟むとその間にあるものは、Smarty の構文解析を行いません。
互換性を考えないのであれば公式マニュアルにあるように left_delimiter と right_delimiter を {, } から、<!–{, }–> に変更するというのもスマートです。ただしその場合、タグの属性の一部を変数にいれる使い方をすると、ソースはプレーンな HTML ではなくなりますが..。

<option value=1 {checked}>

 
参考:
Smarty の構文解析を回避する(Smarty 2.6.3 マニュアル)

[PHP] PHPスクリプトから include_path を追加する方法

PHPプログラムからrequire/includeの検索パス(include_path)を上書き、追加するには、set_include_path()を使います。

例えば、ディレクトリ “/path/to/include/” をrequireの検索対象に追加する場合は以下のようにします。

&lt;?php
set_include_path(get_include_path().PATH_SEPARATOR."/path/to/include/");

または ini_set()を使う方法もあります。

&lt;?php
ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . '/usr/lib/pear');

get_include_path() や ini_get(‘include_path’) は、今のinclude_path 設定を取得している関数呼び出しです。
set_include_path() や ini_set() は既存設定を(追記ではなく)上書きするため、追記にするために既存設定を取得して、新しい設定をつなげて足して、追加としています。

PATH_SEPARATOR はPHPの定義済の定数で、include_pathでパスを繋げるための文字が入ります。
(Windowsならセミコロン、Mac OSやLinuxならコロンが入ります)

table から div へ

  .tr{ clear:left; }
  .td{ float:left; }

と指定すれば、

 <div class=”tr”>
     <div class=”td”>foo</td>
     <div class=”td”>boo</td>
 </div>

のように簡易的に列揃えの疑似テーブル構造ができます(行揃えはなし)。
過渡期の置き換え作業の際はこのように td, tr クラスを作るのもいいかもしれません。
 
参考:
CSS による段組(マルチカラム)レイアウト講座
CSSリファレンス(実験室:P)
テーブルを使わずにCSSでいこう

CUI で CD-ROM 等をイジェクトする

eject というコマンドを使うと、CUI で CD を出し入れできます。
何が便利というわけではありませんが、次の用途にいいんじゃないでしょうか。
 
1. CD を用いるインストーラでユーザビリティ向上
2. ビープ音の代わりに、何かを通知するのに用いる。

sleep 180 && eject

3. リモートから実行して近くにいる人にいたずら
参考:
– Manpage of EJECT

Emacs 編集基本

– カーソル上の文字を削除する。

Ctrl + d
または
delete

 Backspace も使用可能です。このあたりは、説明の必要はないでしょう。
 
– カーソルから行末まで削除する。

Ctrl + k

 カーソルが行末にある時は改行を削除します。
 
– 複数行を削除する。

削除開始位置で
Ctrl + Space
として(マーク)、削除終了位置で
Ctrl + w

 
– コピー(キルリングに保存)する。

コピー開始位置で
Ctrl + Space
として(マーク)、コピー終了位置で
Alt + w

vi でいうところの y キーと同じようなものですね。
 
– 最後に削除(あるいはキルリングに保存)したものを張り付ける(ヤンクする)。

Ctrl + y

 Emacs では vi 同様、削除 = カット(切り取り)となっています。
 
– 矩形削除する。

Ctrl + Space
Ctrl + x r k

ここで削除したものはコピー状態にはなりません。
 
– アンドゥ

Ctrl + –
または
Ctrl
または
Ctrl + x u

Undo, Redo の切替えには

Ctrl + g

を使います。
 
参考:
With Emacs Next – 5.4 基本的な編集操作
Emacs tips

ARP Poisoning してみる

どういうものかはあえて触れず、dsniff 付属の arpspool を使う手順だけメモしておきます。
下手をすると、自分がいる LAN 全体の通信を止めてしまう危険もあるものです。

(Linux + apt)
# apt-get dsniff
(FreeBSD)
# portinstall -r security/dsniff

ソースからビルドする場合は公式サイトからダウンロードします。
 
OS や FW の設定で、パケットの転送を許可しておく必要があります。

[Linux]
# sysctl -w net.ipv4.ip_forward = 1

転送を完全に許可するようにした上で、次のコマンドを打てば完了です。

arpspool < ゲートウェイのIPアドレス>

もし転送が禁止になっている状態でこれを実行すると、当然ですが指定のゲートウェイを通る新規の通信が全てつながらなくなります。
 
なお、何か通信に問題が発生した時に気づいてプログラムを停止しても, ゲートウェイの ARP テーブルが更新されるまでの数秒はつながらないままになります。
参考:
dsniffFAQ
– Dumnetと遊ぼう
– eringe – Statically Compiled ARP Poisoning Tool

PHP で MVC モデリングの Hello world

近年は MVC というと PHP の Mojavi とか Java の Struts 等の MVC フレームワークが取りざたされます。しかし MVC フレームワークと聞くと何か難しい、MVC も概念は分かるけど使うのは難しい、という人もいるんじゃないでしょうか。
 
というわけで、フレームワークを一切使わず、MVC モデルの Hello, world 的スクリプトを PHP で書いてみました。
 
名前を入力してその人に挨拶する、次のようなコードがあります。これを MVC の構造に変えてみましょう。

nameform.php:
<html>
<head><title>名前入力</title></head>
<body>
   <form action=”” method=”POST”>
       名前:<input type=”text” name=”name”><br>
       <input type=”submit” value=”挨拶”><br>
   </form>
   <?php
      if(!empty($_POST[‘name’])){
          $name = htmlspecialchars($_POST[‘name’]);
          echo “こんにちは、$name!!”;
      }
   ?>
</body>
</html>

これに簡単な MVC モデルを適用すると、次のようになります。

nameform.php:
<?php
    // 挨拶プログラム(Controller)
    
    // 機能部分を読み込み
    require_once ‘include/greeting.inc’;
    // 挨拶を実行し、出力用に特殊文字をエスケープする。
    $result = htmlspecialchars( greet() );
    // 結果を表示。
    require_once ‘template/nameform.html’; // View を呼び出し。
?>

include/greeting.inc:
<?php
  //
  // 挨拶プログラムの Model (ドメイン固有)
  //
  
  require_once dirname(__file__).’/request.inc’; // パラメータ取得用
  /**
   * 名前を取得し、挨拶する。
   * @return string 挨拶の言葉。処理できなかった場合空文字
   * @access public
   */
  function greet(){
      $name = get_parameter(‘name’);
      if($name){
          return greet_to($name);
      } else {
          return;
      }
  }
  
  /**
   * 指定した相手に挨拶する。
   * @param string $name 相手
   * @param string 挨拶の言葉
   * @access private
   */
  function greet_to($name){
      echo “こんにちは、$name!!”;
  }
?>

include/request.inc
<?php
//
// パラメータ操作用ユーティリティファイル (非ドメイン固有 Model)
//
/**
 * 指定した名前を持つリクエストパラメータを取得する。
 * 存在しない場合は空文字を返す。
 * @access public
 * @param string $key 取得したいパラメータの識別名
 * @return string パラメータの中身。存在しない場合空文字
 */
function get_parameter($key){
    return empty($_POST[$key])? : $_POST[‘key’];
}
?>

template/nameform.html:
<!– 名前入力フォーム(view) –>
<html>
<head><title>名前入力</title></head>
<body>
    <form action=”” method=”post”>
        名前:<input type=”text” name=”name”><br>
        <input type=”submit” value=”挨拶”><br>
    </form>
    <!– 処理結果 –>
    $result
    ?>
</body>
</html>

どうでしょう?
PHP のコード(モデル、コントローラ)と HTML デザイン(ビュー)がしっかり分離できているのが確認できると思います。また、メインルーチン(コントローラ)と関数(モデル)が別ファイルに分けられていて、関数はさらに汎用的なもの(共通モデル)と挨拶プログラム固有と思われるもの(ドメイン固有モデル)とに分けています。
 
この程度であればメリットは感じず、ただ書く量が増えるだけに感じると思いますが、これが数百行を超えると大きく変わってきます。
 
– ビューとコントローラを分けることでデザイナとプログラマの作業分担をしやすくなる。
– コントローラとモデルを分けることで同じ処理を行う時にコピーペーストを行う必要がなくなる。
– さらにモデルをドメイン固有モデルと共通モデルとに分ける事で、他のシステムで使い回しても影響がない部品(=共通モデル)が明確になり、再利用性が高まる。
 
感覚が掴めそうな方は、サンプルに挙げた挨拶プログラムを基本として、次のように改善していってみましょう。
 
– ビューに PHP コードでなく Smarty を使うようにする。その場合、htmlspecialchars はやめ、代わりに Smarty の ${result|escape} など escape 修飾子を利用するといいでしょう。
– モデルを関数ではなくクラスにする。
– コントローラに処理を書いていく時は、処理を関数として抽出できないか目を光らせておきましょう。抽出できそうな時はドメイン固有モデルとして抽出、移動しましょう。
– ドメイン固有モデルが増えてきた時は、汎用的な共通モデルにできないか考えましょう。つまり、モデルのコードを一切変更することなく、他のシステムで利用可能かどうか考えましょう。他のシステムでも有用な機能があるのに、他のシステムで使うには変更の必要がありそうなときは、変更せずに済む方法を実装し、共通モデルにすることも検討してみましょう。(内部パラメータの setter を用意する、設定ファイルを読み込めるようにするなど)
 
なお、PHP での MVC モデリングについては Zend コーディング指針の MVC の項も参考になります。
 
参考:
Smarty(日本語マニュアル)