PHPCommand v0.9 passons aux choses sérieuses !
Par Hugo Vacher | Catégories : Créations | Posté : 26-08-2009
EDIT: Comme vous l’aurez surement constaté, j’ai plus ou moins abandonné le développement de PHPc, mais je viens de découvrir php-shell qui après un rapide test semble très aboutis.
Voila, après avoir découvert php -a qui fait pratiquement la même chose que PHPCommand v0.1 (Merci @paraboul), je me suis dit que mon script n’aurait aucun intérêt si je ne l’améliorais pas.
Voici donc un liste des amélioration de la version 0.9:
- ATTENTION: ce script utilise des commandes Unix spécifique, il ne fonctionne donc plus windows.
- Fonctionne sous Max OS X, et sur la plupart des distributions linux (support des « VT220 terminal escape sequences » et des commandes stty et dd nécessaire).
- Support de l’historique, utilisez les touches haut et bas pour naviguer dans l’historique.
- Support de la navigation horizontale pour corriger/inserer des caracteres, support des touches Del et Ret arrière.
- Si votre script affiche un message ne se términant pas par « \n » celui-ci est ajouté automatiquement.
Todo list:
- Ajouter l’aide avec F1 et avec –help
- Naviguer avec la souris
- Coloration syntaxique (merci @un_geek) ?
- D’autres idées ?
Voila le nouveau code (beaucoup plus long, ici on gere tout à la main (position du curseur, gestion des touches etc…):
#! /usr/bin/php <?php /** * Class used to isolate functions and vars that needs to keep defined while * evaluating users code. */ class PHPc{ const PROMPT = 'php>'; const PSIZE = 5;//Prompt's size +1 public static $lines = array(); public static $code_to_eval; public static function readChar(){ $ret = exec('stty cbreak -echo;c=`dd bs=1 count=1 2>/dev/null`;stty -cbreak echo;echo "$c."'); if($ret=='.') return "\n"; return substr($ret, 0, 1); } public static function delChar(&$line, $pos){ $line = substr($line, 0, $pos).substr($line, $pos+1); } public static function setLine(&$from, $to){ $size = strlen($from); $goto = strlen($to)+self::PSIZE; echo "\033[".self::PSIZE."G\033[{$size}P{$to}\033[{$goto}G"; $from = $to; return $goto; } } echo <<<INTRO PHP Command 0.9 Created by Hugo Vacher (korri.fr) Code is interpreted when line end with ';' or '}' and that all '{' are closed. You are free to use, modify and redistribute this code, please leave me a comment if you do it. INTRO; while(true){ PHPc::$code_to_eval = ''; $continue = true; while($continue){ //Reset history index $index = 0; //Say that line isn't finished $ln = true; //Reset cursor pos $c = PHPc::PSIZE; $total = PHPc::PSIZE; $line = ''; echo PHPc::PROMPT; //Add empty line array_unshift(PHPc::$lines, ''); while($ln){ $char = PHPc::readChar(); $cod = ord($char); //Gonna parse each key if($cod == 10){//Enter echo "\033[".PHPc::PSIZE."G\n"; $ln = false; }else if($cod == 127){//Ret arriere if($c > PHPc::PSIZE){ PHPc::delChar($line, --$c-PHPc::PSIZE); --$total; echo "\033[D\033[1P"; } }else if($cod == 4){//Ctrl + D break 3;//We exit programm }else if($cod == 27){ $key = PHPc::readChar().PHPc::readChar(); switch($key){ case '[3'://Del PHPc::readChar(); if($c < $total){ PHPc::delChar($line, $c-PHPc::PSIZE); --$total; echo "\033[1P"; } break; case '[A'://up if(isset(PHPc::$lines[$index+1])){ if($index==0) PHPc::$lines[0] = $line; $to = PHPc::$lines[++$index]; $c = PHPc::setLine($line, $to); $total = $c; } break; case '[B'://down if($index > 0){ $to = PHPc::$lines[--$index]; $c = PHPc::setLine($line, $to); $total = $c; } break; case '[D'://left if($c > PHPc::PSIZE) echo "\033[".--$c.'G'; break; case '[C'://right if($c<$total) echo "\033[".++$c.'G'; break; default: //We don't do nothing, here we'll handle F1 key } }else{ echo "\033[4h$char\033[4l";//Echo char in insert mode //Get the 2 next chars (special keys are at least 3chars $line = substr($line, 0, $c - PHPc::PSIZE); $line .= $char.substr($line, $c - PHPc::PSIZE); ++$c; ++$total; } } PHPc::$lines[0] = $line; PHPc::$code_to_eval .= $line; if(substr($line,-1)==';' || substr($line,-1)=='}'){ $cnto = substr_count(PHPc::$code_to_eval, '{'); $cntc = substr_count(PHPc::$code_to_eval, '}'); if($cntc >= $cnto){ $continue = false; } } } //Clear local vars unset($c, $total, $line, $continue, $char, $cod, $cnto, $cntc, $to, $index); ob_start(); eval(PHPc::$code_to_eval); $txt = ob_get_contents(); ob_end_flush(); if($txt!='' && substr($txt, -1) != "\n") echo "\n"; } echo "\nExit\n"; ?>
Le code seul ici: phpc.php
PS: Je ferais une version plus propre et mieux documentée, quand je sortirais la 1.0, pour le moment ce code n’a qu’un but utilitaire et non un but d’apprentissage.



[...] EDIT: Retrouvez la nouvelle version ici : PHPCommand 0.9 [...]