Skip to content

Instantly share code, notes, and snippets.

@magnetik
Created June 20, 2012 12:14
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save magnetik/2959619 to your computer and use it in GitHub Desktop.
Save magnetik/2959619 to your computer and use it in GitHub Desktop.
Php command line parser
function parseArguments()
{
array_shift($argv);
$out = array();
foreach($argv as $arg)
{
if(substr($arg, 0, 2) == '--')
{
$eqPos = strpos($arg, '=');
if($eqPos === false)
{
$key = substr($arg, 2);
$out[$key] = isset($out[$key]) ? $out[$key] : true;
}
else
{
$key = substr($arg, 2, $eqPos - 2);
$out[$key] = substr($arg, $eqPos + 1);
}
}
else if(substr($arg, 0, 1) == '-')
{
if(substr($arg, 2, 1) == '=')
{
$key = substr($arg, 1, 1);
$out[$key] = substr($arg, 3);
}
else
{
$chars = str_split(substr($arg, 1));
foreach($chars as $char)
{
$key = $char;
$out[$key] = isset($out[$key]) ? $out[$key] : true;
}
}
}
else
{
$out[] = $arg;
}
}
return $out;
}
@lordspace
Copy link

Hey, nice code.

I've modified it to accept e.g. --long-opt value

<?php

Class App_Sandbox_Env {
    /**
    * Parses command line arguments. For some weird reason getopts breaks sometimes.
    * The original code has been modified to work with long arguments.
    * App_Sandbox_Env::parseArguments();
    * 
    * @return array
     * 
    * @see http://stackoverflow.com/questions/6553239/is-there-a-complete-command-line-parser-for-php
    * @see https://gist.github.com/magnetik/2959619
    */
   public static function parseArguments( $my_arg = null ) {
       $cmd_args = array();
       $skip = array();

       global $argv;
       $new_argv = is_null( $my_arg ) ? $argv : $my_arg;

       if ( is_null( $my_arg ) ) {
          array_shift( $new_argv ); // skip arg 0 which is the filename
       }

       foreach ( $new_argv as $idx => $arg ) {
           if ( in_array( $idx, $skip ) ) {
               continue;
           }

           $arg = preg_replace( '#\s*\=\s*#si', '=', $arg );
           $arg = preg_replace( '#(--+[\w-]+)\s+[^=]#si', '${1}=', $arg );

           if (substr($arg, 0, 2) == '--') {
               $eqPos = strpos($arg, '=');

               if ($eqPos === false) {
                   $key = trim($arg, '- ');
                   $val = isset($cmd_args[$key]);

                   // We handle case: --user-id 123 -> this is a long option with a value passed.
                   // the actual value comes as the next element from the array.
                   // We check if the next element from the array is not an option.
                   if ( isset( $new_argv[ $idx + 1 ] ) && ! preg_match('#^-#si', $new_argv[ $idx + 1 ] ) ) {
                       $cmd_args[$key] = trim( $new_argv[ $idx + 1 ] );
                       $skip[] = $idx;
                       $skip[] = $idx + 1;
                       continue;
                   }

                   $cmd_args[$key] = $val;
               } else {
                   $key = substr($arg, 2, $eqPos - 2);
                   $cmd_args[$key] = substr($arg, $eqPos + 1);
               }
           } else if (substr($arg, 0, 1) == '-') {
               if (substr($arg, 2, 1) == '=') {
                   $key = substr($arg, 1, 1);
                   $cmd_args[$key] = substr($arg, 3);
               } else {
                   $chars = str_split(substr($arg, 1));

                   foreach ($chars as $char) {
                       $key = $char;
                       $cmd_args[$key] = isset($cmd_args[$key]) ? $cmd_args[$key] : true;
                   }
               }
           } else {
               $cmd_args[] = $arg;
           }
       }

       return $cmd_args;
   }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment