| 1 | #!/usr/bin/php |
|---|
| 2 | <?php |
|---|
| 3 | /** |
|---|
| 4 | * @author jonathan gotti <jgotti at the-ring dot homelinux dot net> |
|---|
| 5 | * @licence LGPL |
|---|
| 6 | * @since 2006-04-24 |
|---|
| 7 | * @changelog - 2006-10-10 - rewrite for PHP5 |
|---|
| 8 | * - 2006-04-30 - add a saveonexit command line parameter |
|---|
| 9 | * - save history even on a CTRL+D |
|---|
| 10 | * - 2006-04-27 - add history file support |
|---|
| 11 | * - add an allerror option |
|---|
| 12 | */ |
|---|
| 13 | require dirname(__file__).'/class-console_app.php'; |
|---|
| 14 | |
|---|
| 15 | $app = new console_app(); |
|---|
| 16 | $app->define_arg('include','i',false,'include file(s) before starting','check_inc',';'); |
|---|
| 17 | $app->define_flag('noprompt','P',FALSE,'Set this if you don\'t want the "PHP>>" prompt to appear'); |
|---|
| 18 | $app->define_flag('allerror','A',false,'Set error reporting to E_ALL'); |
|---|
| 19 | $app->define_flag('saveonexit',array('s','S'),TRUE,'Propose to save the script on closing'); |
|---|
| 20 | $app->define_flag('historyfile',array('hist','H'),TRUE,'set this flag if you want to save history across session (will only work if you have readline extension installed)'); |
|---|
| 21 | |
|---|
| 22 | console_app::$lnOnRead = FALSE; |
|---|
| 23 | console_app::$captureEOT = FALSE; |
|---|
| 24 | $app->parse_args(); |
|---|
| 25 | |
|---|
| 26 | if($app->get_arg('allerror')) |
|---|
| 27 | error_reporting(E_ALL); |
|---|
| 28 | |
|---|
| 29 | $prompt = $app->get_arg('noprompt')?'':'PHP>>'; |
|---|
| 30 | |
|---|
| 31 | # enable completion |
|---|
| 32 | if(console_app::$useReadline){ |
|---|
| 33 | readline_completion_function('mycompletion'); |
|---|
| 34 | # manage history file |
|---|
| 35 | if($app->get_arg('historyfile')){ |
|---|
| 36 | $history_file = $_SERVER['HOME'].'/.PHPinteractive_history'; |
|---|
| 37 | # $history_file = '~/.PHPinteractive_history'; |
|---|
| 38 | if(is_file($history_file)) |
|---|
| 39 | readline_read_history($history_file); |
|---|
| 40 | } |
|---|
| 41 | if(! isset($_SERVER['HISTSIZE']) ) |
|---|
| 42 | $_SERVER['HISTSIZE'] = 1000; |
|---|
| 43 | } |
|---|
| 44 | $_script_ = ''; |
|---|
| 45 | |
|---|
| 46 | # make includes if needed |
|---|
| 47 | if(is_array($incs = $app->get_arg('include'))){ |
|---|
| 48 | foreach($incs as $inc){ |
|---|
| 49 | include($inc); |
|---|
| 50 | $_script_ .= "include('$inc');\n"; |
|---|
| 51 | } |
|---|
| 52 | } |
|---|
| 53 | |
|---|
| 54 | # do the job |
|---|
| 55 | while(true){ |
|---|
| 56 | $cmd = read_until(';'); |
|---|
| 57 | if( $cmd === FALSE){ |
|---|
| 58 | if(isset($history_file)) # dump history to file if needed |
|---|
| 59 | save_history($history_file); |
|---|
| 60 | break; |
|---|
| 61 | } |
|---|
| 62 | eval($cmd); |
|---|
| 63 | $_script_ .= $cmd; |
|---|
| 64 | } |
|---|
| 65 | |
|---|
| 66 | # propose to save the script to a file |
|---|
| 67 | if($app->get_arg('saveonexit') && $_script_ && console_app::msg_confirm('do you want to save this session as a php script')){ |
|---|
| 68 | $fileout = console_app::read("file to save the script\n"); |
|---|
| 69 | $savemode = 'w'; |
|---|
| 70 | if(is_file($fileout)){ |
|---|
| 71 | if(console_app::msg_confirm("$fileout already exists !\nDo you want to append the script to the end of the file? (no will overwrite)")) |
|---|
| 72 | $savemode = 'a'; |
|---|
| 73 | } |
|---|
| 74 | $f = fopen($fileout,$savemode); |
|---|
| 75 | fwrite($f,"<?php\n$_script_\n?>\n"); |
|---|
| 76 | fclose($f); |
|---|
| 77 | } |
|---|
| 78 | |
|---|
| 79 | function save_history($history_file){ |
|---|
| 80 | global $app; |
|---|
| 81 | # dump history to file if needed |
|---|
| 82 | if(! readline_write_history($history_file) ){ |
|---|
| 83 | console_app::msg_error("Can't write history file"); |
|---|
| 84 | } |
|---|
| 85 | # nettoyage de l'historique |
|---|
| 86 | $hist = readline_list_history(); |
|---|
| 87 | if( ($histsize = count($hist)) > $_SERVER['HISTSIZE'] ){ |
|---|
| 88 | $hist = array_slice($hist, $histsize - $_SERVER['HISTSIZE']); |
|---|
| 89 | if(! $fhist = fopen($history_file,'w') ){ |
|---|
| 90 | console_app::msg_error("Can't open history file"); |
|---|
| 91 | }else{ |
|---|
| 92 | fwrite($fhist,implode("\n",$hist)); |
|---|
| 93 | fclose($fhist); |
|---|
| 94 | } |
|---|
| 95 | } |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | function read_until($waitchar=';'){ |
|---|
| 99 | global $app,$prompt; |
|---|
| 100 | $buff='';$i=0; |
|---|
| 101 | while(true){ |
|---|
| 102 | $query = console_app::read($i++<1?$prompt:'',null,FALSE); |
|---|
| 103 | # on doit regarder si ce n'est pas le dbut d'un bloc de code |
|---|
| 104 | if( $query===FALSE ) |
|---|
| 105 | return FALSE; |
|---|
| 106 | if( $_nbac = substr_count($query,'{') ){ |
|---|
| 107 | if( substr_count($query,'}') != $_nbac) |
|---|
| 108 | $query .= read_until('}'); |
|---|
| 109 | } |
|---|
| 110 | if( substr(trim($query),-1)==$waitchar ) |
|---|
| 111 | break; |
|---|
| 112 | if($query == 'quit') |
|---|
| 113 | return FALSE; |
|---|
| 114 | $buff .= "$query\n"; |
|---|
| 115 | } |
|---|
| 116 | return $buff."$query\n"; |
|---|
| 117 | } |
|---|
| 118 | |
|---|
| 119 | function mycompletion(){ |
|---|
| 120 | $funcs = get_defined_functions(); |
|---|
| 121 | return array_merge( get_declared_classes(), |
|---|
| 122 | $funcs['internal'] , $funcs['user'], |
|---|
| 123 | array_keys($GLOBALS) |
|---|
| 124 | ); |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | #### ARGUMENT VALIDATION FUNCTIONS #### |
|---|
| 128 | function check_inc($inc){ |
|---|
| 129 | if( !( is_array($inc) && count($inc)) ) |
|---|
| 130 | return FALSE; |
|---|
| 131 | foreach($inc as $f){ |
|---|
| 132 | if(! is_file($f) ) |
|---|
| 133 | return FALSE; |
|---|
| 134 | } |
|---|
| 135 | return TRUE; |
|---|
| 136 | } |
|---|
| 137 | |
|---|
| 138 | ?> |
|---|