web-dev-qa-db-ja.com

PHPのgetopt()を使用した後、どの引数が残っているかをどのように判断できますか?

OK、つまりPHPには組み込みの getopt() 関数があり、ユーザーが提供したプログラムオプションに関する情報を返します。何かが足りない場合を除いて、それは完全に中断されています!マニュアルから:

オプションの解析は、最初に見つかった非オプションで終了し、その後はすべて破棄されます。

したがって、getopt()は、validおよびparsedオプションのみを含む配列を返します。 _$argv_を見ると、元のコマンドライン全体を見ることができますが、これは変更されていませんが、そのコマンドのwhereをどのように判断しますか-行getopt()は引数の解析を停止しましたか?コマンドラインの残りの部分を他のもの(ファイル名など)として扱いたい場合は、これを知っておくことが重要です。

ここに例があります...

次の引数を受け入れるようにスクリプトを設定するとします。

_Usage: test [OPTION]... [FILE]...

Options:
  -a  something
  -b  something
  -c  something
_

次に、次のようにgetopt()を呼び出すことができます。

_$args = getopt( 'abc' );
_

そして、次のようなスクリプトを実行した場合:

_$ ./test.php -a -bccc file1 file2 file3
_

次の配列が返されることを期待する必要があります。

_Array
(
    [a] =>
    [b] =>
    [c] => Array
        (
            [0] =>
            [1] =>
            [2] =>
        )
)
_

だから問題はこれです:3つの解析されていない、オプションではないFILE引数が_$argv[ 3 ]_で始まることを一体どうやって知ることになっていますか?

25
edam

PHP 7.1以降、getoptはオプションのby-refパラメータ&$optindをサポートします。これには、引数の解析が停止したインデックスが含まれます。これは、フラグとフラグを混在させる場合に便利です。位置引数。例:

user@Host:~$ php -r '$i = 0; getopt("a:b:", [], $i); print_r(array_slice($argv, $i));' -- -a 1 -b 2 hello1 hello2
Array
(
    [0] => hello1
    [1] => hello2
)
4
adsr

Getoptを使用する必要があるとは誰も言いませんでした。あなたは好きな方法でそれをすることができます:

$arg_a = null; // -a=YOUR_OPTION_A_VALUE
$arg_b = null; // -b=YOUR_OPTION_A_VALUE
$arg_c = null; // -c=YOUR_OPTION_A_VALUE

$arg_file = null;  // -file=YOUR_OPTION_FILE_VALUE

foreach ( $argv as $arg )
{
    unset( $matches );

    if ( preg_match( '/^-a=(.*)$/', $arg, $matches ) )
    {
        $arg_a = $matches[1];
    }
    else if ( preg_match( '/^-b=(.*)$/', $arg, $matches ) )
    {
        $arg_b = $matches[1];
    }
    else if ( preg_match( '/^-c=(.*)$/', $arg, $matches ) )
    {
        $arg_c = $matches[1];
    }
    else if ( preg_match( '/^-file=(.*)$/', $arg, $matches ) )
    {
        $arg_file = $matches[1];
    }
    else
    {
        // all the unrecognized stuff
    }
}//foreach

if ( $arg_a === null )    { /* missing a - do sth here */ }
if ( $arg_b === null )    { /* missing b - do sth here */ }
if ( $arg_c === null )    { /* missing c - do sth here */ }
if ( $arg_file === null ) { /* missing file - do sth here */ }

echo "a=[$arg_a]\n";
echo "b=[$arg_b]\n";
echo "c=[$arg_c]\n";
echo "file=[$arg_file]\n";

私はいつもそのようにそれをします、そしてそれは働きます。さらに、私はそれでやりたいことが何でもできます。

2
Artur

以下を使用して、コマンドラインオプションに続く引数を取得できます。これは、PHPのgetopt()を呼び出す前または後に使用でき、結果は変わりません。

_# $options = getopt('cdeh');

$argx = 0;

while (++$argx < $argc && preg_match('/^-/', $argv[$argx])); # (no loop body)

$arguments = array_slice($argv, $argx);
_

_$arguments_には、先行オプションに続く引数が含まれるようになりました。または、引数を別の配列に配置したくない場合は、_$argx_が最初の実際の引数のインデックスです:_$argv[$argx]_。

先行オプションの後に引数がない場合は、次のようにします。

  • _$arguments_は空の配列_[]_であり、
  • count($arguments) == 0、および
  • _$argx == $argc_。
2
Brian Howell

GetOptionKitを見て、フラグの解析を取り除きます。

http://github.com/c9s/GetOptionKit

GetOptionKitは、コマンドラインスクリプトに簡単に統合できます。型制約、値検証などをサポートします。

0
c9s