Skip to content

Instantly share code, notes, and snippets.

@coderofsalvation
Created August 7, 2012 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coderofsalvation/3283636 to your computer and use it in GitHub Desktop.
Save coderofsalvation/3283636 to your computer and use it in GitHub Desktop.
Skeleton PHP CLI-cmd (robust)
#!/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