PHP has own interpreter, HTTP server!

jjohn on 2002-10-09T15:37:35

Perky PHP is branching out into Real Programming with its standalone interpreter. The guys must think this is the bees' knees because one of them has written an HTTP server in PHP! Surely we'll be seeing more standalone PHP programs in the future. *wink*


splutter

gnat on 2002-10-09T15:53:20

My favourite part of that web site is because it's running inside a VM, it's quite secure. Uh huh.

--Nat

Getopt in PHP

petdance on 2002-10-09T21:53:04

PHP has had standalone interpreter for a while. We've written command-line utilities that have to use PHP because of existing libraries.

PHP doesn't (yet) have argument processing, so I whipped up this little subset of Getopt::Long. It uses a warn() function that I leave to the reader as an exercise to implement. Please forgive the hosed indents. If you want a clean copy, email me.

<?php

/*

GetOptions() takes an array of field specifications that describe what
command line options are valid, and how they should look.  The options
are pulled from the global $argv array.  After each options is
processed, it's deleted from $argv[].  This leaves only filenames in
the $argv[].

Each key in the key-value pairs passed in is an option name.  Each value
is a reference to a variable that holds the value from the command line. 
If the option is passed without a value, the variable gets assigned an
empty string.

The option can have "=i" after it, to say that the parm must be a
valid integer.

Examples:

Assume a program called "test" like so:

GetOptions(
    Array(
    "instance" =>    &$instance,
    "send_email" =>    &$email,
    "days=i" =>    &$days
    )
);

Example 1:
test --instance=twprod --send_email --days=5 foo.txt
    $instance = "twprod"
    $send_email = "";
    $days = 5;
    global $argv contains only foo.txt

Example 2:
test --instance=twprod
    $instance = "twprod"
    $send_email and $days are untouched (and probably have no value)

Example 3:
test --instance=twprod --days=yesterday
    $instance = twprod
and the following error is printed to stderr:
    Value "yesterday" invalid for option days (number expected)

Note that behavior is based almost entirely on what Getopt::Long in Perl
does: http://search.cpan.org/doc/GSAR/perl-5.6.1/lib/Getopt/Long.pm

*/

function GetOptions( $specs ) {
    $ranclean = true;

    $constraints = Array();
    foreach ( $specs as $spec=>$ref ) {
    $elements = explode( "=", $spec, 2 );
    if ( count($elements)>1 ) {
        List( $name, $constraint ) = $elements;
        $constraints[$name] = $constraint;
        $specs[$name] = &$specs[$spec];
        unset( $specs[$spec] );
    }
    }
   
    global $argv;
    unset( $argv[0] );

    $keys = array_keys( $argv );
    foreach ( $keys as $offset ) {
    $val = $argv[$offset];
    if ( substr( $val, 0, 2 ) == "--" ) {
        $parm = substr( $val, 2 );
        $parts = explode( "=", $parm, 2 );

        $name = $parts[0];
        $value = (count($parts)>1) ? $parts[1] : 1;

        if ( substr( $name, 0, 2 ) == "no" ) {
        $maybe = substr( $name, 2 );
        if ( array_key_exists( $maybe, $specs ) ) {
            $name = $maybe;
            $value = 0;
        }
        }

        if ( array_key_exists($name, $specs) ) {
        if ( array_key_exists( $name, $constraints ) ) {
            // For now, the only constraint type is =i
            $valid = is_numeric($value) && (intval($value) == $value);
            if ( !$valid ) {
            warn( "Value \"$value\" invalid for option \"$name\" (number expected)" );
            $ranclean = false;
            }
        } else {
            $valid = true;
        }

        if ( $valid ) {
            $specs[$name] = $value;
            unset( $argv[$offset] );
        }
        } else {
        warn( "Unknown parm $parm" );
        $ranclean = false;
        } // not valid
    } // if --
    } // foreach

    return $ranclean;
}

?>

I think there must be some good reason, but ...

pudge on 2002-10-16T02:11:34

what is it?