Created
August 7, 2012 09:12
-
-
Save coderofsalvation/3283636 to your computer and use it in GitHub Desktop.
Skeleton PHP CLI-cmd (robust)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env php | |
<?php | |
/* | |
* cli skeleton - starting point for cli/web-command with interaction,options,manual,dependancies and colors | |
* (needs chmod 755 for cli) | |
* (ROBUST VERSION) | |
* | |
* cheers, Coder of Salvation 2012 (http://leon.vankammen.eu) | |
*/ | |
// BEGIN MANUAL //////////////////////////////////////////////////////////////////////////////////// | |
$MANUAL=' | |
<<=cut | |
=head1 NAME | |
foo - a great cmdline utility | |
=head1 SYNOPSIS | |
This utility demystifies the wonderfull world of ... | |
=head1 DESCRIPTION | |
It does x and y.. | |
=head1 SEE ALSO | |
L, L | |
=head1 LICENSE | |
BSD License (so everybody can enjoy it) | |
=head1 AUTHOR(S) | |
James Brown, Edgar Davids | |
=cut | |
'; | |
// ENDOF MANUAL //////////////////////////////////////////////////////////////////////////////////// | |
$args = array(); | |
$require = array('gd','simplexml'); | |
$maxtime = 0; // maximum executiontime set to unlimited | |
$maxmem = 24; // in MB, max memory needed for process, increase if necessary | |
$minmem = 10; // in MB, process should die if system has this minimum amount of memory left | |
$lastmemcheck = 0; | |
$colors = array( | |
'normal' => "\033[0m", | |
'bold' => "\033[1m", | |
'black' => "\033[0;30m", | |
'red' => "\033[0;31;31m", | |
'green' => "\033[0;32m", | |
'yellow' => "\033[0;33m", | |
'blue' => "\033[0;34m", | |
'magenta' => "\033[0;35m", | |
'cyan' => "\033[0;36m", | |
); | |
if ('cli' === php_sapi_name() && basename(__FILE__) === basename($argv[0])) { | |
main($argv); | |
_printf("%normal%"); | |
} | |
function main($argv) { | |
global $args,$require,$lastmemcheck; | |
checkReq($require); | |
if( count($argv) == 1 ) die(usage()); | |
$args = $argv; | |
init(); | |
print_r($args); | |
printf("[x] press CTRL-C to cancel\n"); | |
while( true ){ | |
usleep(100000); // no need to hog all CPU resources | |
if(time() - 600 > $lastmemcheck) { // spot problems | |
$lastmemcheck = time(); | |
doMemCheck(); | |
} | |
printf("working..\n"); | |
} | |
destroy(); | |
} | |
function signalHandler($signal) { | |
printf("Caught {$signal}, shutting down\n"); | |
destroy(); | |
exit(); | |
} | |
function init(){ | |
global $maxtime, $maxmem; | |
date_default_timezone_set( 'Europe/Amsterdam' ); // ensure proper time | |
set_time_limit( $maxtime ); | |
ini_set("memory_limit", $maxmem."M" ); | |
declare(ticks = 1); | |
error_reporting(E_ALL); | |
//Add signal handlers to shut down the bot correctly if its getting killed | |
pcntl_signal(SIGTERM,"signalHandler"); | |
pcntl_signal(SIGINT, "signalHandler"); | |
pcntl_signal(SIGUSR1,"signalHandler"); | |
initArgs(); | |
} | |
function destroy(){ | |
printf("calling destroy()\n"); | |
} | |
function initArgs(){ | |
global $args; | |
$str = false; | |
$opts = getopt(null, array('min:', 'max:','manual::')); | |
if( isset($opts['manual']) ) manual(); | |
foreach( $args as $arg ) $str = !strstr( $arg, '--' ) && !strstr( $arg, basename(__FILE__) ) ? $arg : $str; | |
$args['parsed'] = array(); | |
$args['parsed']['str'] = $str; | |
$args['parsed']['min'] = (int) isset($opts['min']) ? trim($opts['min']) : false; | |
$args['parsed']['max'] = (int) isset($opts['max']) ? trim($opts['max']) : 100; | |
// interactive if missing | |
if( !$args['parsed']['min'] ) $args['parsed']['min'] = askArg('min', 'int'); | |
} | |
function checkReq( $reqs ){ | |
$ok = true; | |
ob_start(); phpinfo(); $result = strtolower(ob_get_contents()); ob_get_clean(); | |
foreach( $reqs as $req ) $ok =& strstr( $result, $req ); | |
if(!$ok) die("Error: your phpversion is missing one of the following requirements: ".implode(", ", $reqs ) ); | |
} | |
function usage(){ | |
return "Usage: foo [--min=integer, --max=integer] <str>\n\nor run 'foo --manual' for help\n\n"; | |
} | |
function _printf( $msg ){ | |
global $colors; | |
foreach( $colors as $k => $v ) $msg = str_replace("%{$k}%", $colors[ $k ], $msg ); | |
fwrite( STDOUT, $msg ); | |
} | |
function gets() { | |
return fgets(STDIN); | |
} | |
function askArg( $argname, $type = 'string' ){ | |
switch( $argname ){ | |
default: _printf("%green%Enter '{$argname}'> %normal%" ); break; | |
} | |
switch( $type ){ | |
case 'string': return gets(); break; | |
case 'boolean': return gets() == "true" ? "true" : "false"; break; | |
case 'int': return (int)gets(); break; | |
case 'float': return floatval( gets() ); break; | |
} | |
return 'unknown type!'; | |
} | |
function manual(){ | |
global $MANUAL; | |
$tmpfile = "/tmp/foo.1"; | |
$ok; | |
system( 'which pod2man', &$ok ); | |
if( $ok == 1 ) die( "sure you are on unix/linux? If so: please install perl"); | |
system("pod2man `readlink -f ".__FILE__."` > '{$tmpfile}'"); | |
system("clear"); | |
system("man '{$tmpfile}'"); | |
system("rm '{$tmpfile}'"); | |
die(); | |
} | |
function doMemCheck() { | |
global $maxtime,$maxmem,$minmem; | |
gc_collect_cycles(); | |
$memFree = ((($maxmem*1024)*1024) - memory_get_usage()); | |
if($memFree < (($minmem*1024)*1024)) | |
die("out of memory..aborting to prevent machinefreeze (possible memory leak?)"); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment