getopt.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 912 行 · 第 1/3 页

PHP
912
字号
                $flag = strtolower($flag);
                $alias = strtolower($alias);
            }
            if (!isset($this->_ruleMap[$flag])) {
                continue;
            }
            $flag = $this->_ruleMap[$flag];
            if (isset($this->_rules[$alias]) || isset($this->_ruleMap[$alias])) {
                $o = (strlen($alias) == 1 ? '-' : '--') . $alias;
                throw new Zend_Console_Getopt_Exception(
                    "Option \"$o\" is being defined more than once.");
            }
            $this->_rules[$flag]['alias'][] = $alias;
            $this->_ruleMap[$alias] = $flag;
        }
    }

    /**
     * Define help messages for options.
     *
     * The parameter $help_map is an associative array
     * mapping option name (short or long) to the help string.
     *
     * @param array $helpMap
     */
    public function setHelp($helpMap)
    {
        foreach ($helpMap as $flag => $help)
        {
            if (!isset($this->_ruleMap[$flag])) {
                continue;
            }
            $flag = $this->_ruleMap[$flag];
            $this->_rules[$flag]['help'] = $help;
        }
    }

    /**
     * Parse command-line arguments and find both long and short
     * options.
     *
     * Also find option parameters, and remaining arguments after
     * all options have been parsed.
     *
     * @throws Zend_Console_Getopt_Exception
     */
    public function parse()
    {
        $argv = $this->_argv;
        $this->_options = array();
        $this->_remainingArgs = array();
        while (count($argv) > 0) {
            if ($argv[0] == '--') {
                array_shift($argv);
                if ($this->_getoptConfig[self::CONFIG_DASHDASH]) {
                    $this->_remainingArgs = array_merge($this->_remainingArgs, $argv);
                    break;
                }
            }
            if (substr($argv[0], 0, 2) == '--') {
                $this->parseLongOption($argv);
            } else if (substr($argv[0], 0, 1) == '-') {
                $this->parseShortOptionCluster($argv);
            } else {
                $this->_remainingArgs[] = array_shift($argv);
            }
        }
        $this->_parsed = true;
    }

    /**
     * Parse command-line arguments for a single long option.
     * A long option is preceded by a double '--' character.
     * Long options may not be clustered.
     *
     * @param mixed &$argv
     * @throws Zend_Console_Getopt_Exception
     */
    protected function parseLongOption(&$argv)
    {
        $optionWithParam = ltrim(array_shift($argv), '-');
        $l = explode('=', $optionWithParam);
        $flag = array_shift($l);
        $param = array_shift($l);
        if (isset($param)) {
            array_unshift($argv, $param);
        }
        $this->parseSingleOption($flag, $argv);
    }

    /**
     * Parse command-line arguments for short options.
     * Short options are those preceded by a single '-' character.
     * Short options may be clustered.
     *
     * @param mixed &$argv
     * @throws Zend_Console_Getopt_Exception
     */
    protected function parseShortOptionCluster(&$argv)
    {
        $flagCluster = ltrim(array_shift($argv), '-');
        foreach (str_split($flagCluster) as $flag) {
            $this->parseSingleOption($flag, $argv);
        }
    }

    /**
     * Parse command-line arguments for a single option.
     *
     * @param string $flag
     * @param mixed $argv
     * @throws Zend_Console_Getopt_Exception
     */
    protected function parseSingleOption($flag, &$argv)
    {
        if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
            $flag = strtolower($flag);
        }
        if (!isset($this->_ruleMap[$flag])) {
            throw new Zend_Console_Getopt_Exception(
                "Option \"$flag\" is not recognized.",
                $this->getUsageMessage());
        }
        $realFlag = $this->_ruleMap[$flag];
        switch ($this->_rules[$realFlag]['param']) {
            case 'required':
                if (count($argv) > 0) {
                    $param = array_shift($argv);
                    $this->checkParameterType($realFlag, $param);
                } else {
                    throw new Zend_Console_Getopt_Exception(
                        "Option \"$flag\" requires a parameter.",
                        $this->getUsageMessage());
                }
                break;
            case 'optional':
                if (count($argv) > 0 && substr($argv[0], 0, 1) != '-') {
                    $param = array_shift($argv);
                    $this->checkParameterType($realFlag, $param);
                } else {
                    $param = true;
                }
                break;
            default:
                $param = true;
        }
        $this->_options[$realFlag] = $param;
    }

    /**
     * Return true if the parameter is in a valid format for
     * the option $flag.
     * Throw an exception in most other cases.
     *
     * @param string $flag
     * @param string $param
     * @throws Zend_Console_Getopt_Exception
     */
    protected function checkParameterType($flag, $param)
    {
        if (!isset($this->_rules[$flag]['param']) || $this->_rules[$flag]['param'] == 'none') {
            if (isset($param)) {
                throw new Zend_Console_Getopt_Exception(
                    "Option \"$flag\" requires no parameter.",
                    $this->getUsageMessage());
            } else {
                return true;
            }
        } else if (!isset($param) && $this->_rules[$flag]['param'] == 'optional') {
            return true;
        } else if (!isset($param) && $this->_rules[$flag]['param'] == 'required') {
            throw new Zend_Console_Getopt_Exception(
                "Option \"$flag\" requires a parameter.",
                $this->getUsageMessage());
        }
        switch ($this->_rules[$flag]['paramType']) {
            case 'string':
                break;
            case 'word':
                if (preg_match('/\W/', $param)) {
                    throw new Zend_Console_Getopt_Exception(
                        "Option \"$flag\" requires a single-word parameter, but was given \"$param\".",
                        $this->getUsageMessage());
                }
                break;
            case 'integer':
                if (preg_match('/\D/', $param)) {
                    throw new Zend_Console_Getopt_Exception(
                        "Option \"$flag\" requires an integer parameter, but was given \"$param\".",
                        $this->getUsageMessage());
                }
                break;
            default:
                throw new Zend_Console_Getopt_Exception(
                    "Unknown parameter type: \"{$this->_rules[$flag]['paramType']}\".");
        }
        return true;
    }

    /**
     * Define legal options using the gnu-style format.
     *
     * @param string $rules
     */
    protected function addRulesModeGnu($rules)
    {
        $ruleArray = array();

        /**
         * Options may be single alphanumeric characters.
         * Options may have a ':' which indicates a required string parameter.
         * No long options or option aliases are supported in GNU style.
         */
        preg_match_all('/([a-zA-Z0-9]:?)/', $rules, $ruleArray);
        foreach ($ruleArray[1] as $rule) {
            $r = array();
            $flag = substr($rule, 0, 1);
            if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
                $flag = strtolower($flag);
            }
            $r['alias'][] = $flag;
            if (substr($rule, 1, 1) == ':') {
                $r['param'] = 'required';
                $r['paramType'] = 'string';
            } else {
                $r['param'] = 'none';
            }
            $this->_rules[$flag] = $r;
            $this->_ruleMap[$flag] = $flag;
        }
    }

    /**
     * Define legal options using the Zend-style format.
     *
     * @param array $rules
     * @throws Zend_Console_Getopt_Exception
     */
    protected function addRulesModeZend($rules)
    {
        foreach ($rules as $ruleCode => $helpMessage)
        {
            $tokens = preg_split('/([=-])/',
                $ruleCode, 2, PREG_SPLIT_DELIM_CAPTURE);
            $flagList = array_shift($tokens);
            $delimiter = array_shift($tokens);
            $paramType = array_shift($tokens);
            if ($this->_getoptConfig[self::CONFIG_IGNORECASE]) {
                $flagList = strtolower($flagList);
            }
            $flags = explode('|', $flagList);
            $rule = array();
            $mainFlag = $flags[0];
            foreach ($flags as $flag) {
                if (empty($flag)) {
                    throw new Zend_Console_Getopt_Exception(
                        "Blank flag not allowed in rule \"$ruleCode\".");
                }
                if (strlen($flag) == 1) {
                    if (isset($this->_ruleMap[$flag])) {
                        throw new Zend_Console_Getopt_Exception(
                            "Option \"-$flag\" is being defined more than once.");
                    }
                    $this->_ruleMap[$flag] = $mainFlag;
                    $rule['alias'][] = $flag;
                } else {
                    if (isset($this->_rules[$flag]) || isset($this->_ruleMap[$flag])) {
                        throw new Zend_Console_Getopt_Exception(
                            "Option \"--$flag\" is being defined more than once.");
                    }
                    $this->_ruleMap[$flag] = $mainFlag;
                    $rule['alias'][] = $flag;
                }
            }
            if (isset($delimiter)) {
                switch ($delimiter) {
                    case self::PARAM_REQUIRED:
                        $rule['param'] = 'required';
                        break;
                    case self::PARAM_OPTIONAL:
                    default:
                        $rule['param'] = 'optional';
                }
                switch (substr($paramType, 0, 1)) {
                    case self::TYPE_WORD:
                        $rule['paramType'] = 'word';
                        break;
                    case self::TYPE_INTEGER:
                        $rule['paramType'] = 'integer';
                        break;
                    case self::TYPE_STRING:
                    default:
                        $rule['paramType'] = 'string';
                }
            } else {
                $rule['param'] = 'none';
            }
            $rule['help'] = $helpMessage;
            $this->_rules[$mainFlag] = $rule;
        }
    }

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?