foldrr's weblog

旧ブログ http://d.hatena.ne.jp/foldrr/

PHP で irb や IPython みたいなことがしたい

環境

問題

PHP で手軽にコードを実行できる環境が欲しい。

解決方法

下記のようなスクリプトを用意しておくと、コンソールから直接スクリプトを実行できる。
※手抜きなので if をブロック無しで書いたりするとエラーになっちゃいます。

<?php
$___EXIT_COMMANDS = array('bye', 'exit', 'q', 'quit', ':q');
$___PROMPT = '> ';
$___PROMPT_CONT = ': ';


while(1){
    // read
    echo ! $___continue ? $___PROMPT : $___PROMPT_CONT;
    $___line = rtrim(fgets(STDIN), PHP_EOL);
    if($___line == ""){
        return false;
    }
    
    if(in_array($___line, $___EXIT_COMMANDS)){
        exit();
    }
    
    $___code .= $___line . "\n";
    $___tokens = token_get_all("<?php " . $___code . " ?>");
    
    $___starts = 0;
    $___ends = 0;
    for($___i = 0, $___n = sizeof($___tokens); $___i < $___n; $___i++){
        if($___tokens[$___i] == "{") $___starts++;
        if($___tokens[$___i] == "}") $___ends++;
    }
    if($___starts < $___ends){
        echo "Brace Error\n";
        $___continue = false;
        $___code = "";
        continue;
    }
    if($___starts != $___ends){
        $___continue = true;
        continue;
    }
    
    $___starts = 0;
    $___ends = 0;
    for($___i = 0, $___n = sizeof($___tokens); $___i < $___n; $___i++){
        if($___tokens[$___i][0] == 370) $___starts++;
        if($___tokens[$___i][0] == 371) $___ends++;
    }
    if($___starts < $___ends){
        echo "HereDoc Error\n";
        $___continue = false;
        $___code = "";
        continue;
    }
    if($___starts != $___ends){
        $___continue = true;
        continue;
    }
    
    
    // eval
    if(substr($___code, mb_strlen($___code) - 1) != ';'){
        $___code .= ';';
    }
    
    ob_start();
    $___eval = eval($___code);
    $___output = ob_get_contents();
    ob_end_clean();
    $___continue = false;
    $___code = "";
    
    
    // print
    if($___output != ""){
        $___output .= PHP_EOL;
    }
    echo $___output . "\n";
}
?>