Completed
Push — master ( 72613d...069c91 )
by Michael
02:16
created

Console_GetoptPlus_Getopt::parseLongOptionsDef()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 23
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 6
nop 1
dl 0
loc 23
rs 8.5906
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 100 and the first side effect is on line 37.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * Console Getopt
5
 *
6
 * All rights reserved.
7
 * Redistribution and use in source and binary forms, with or without modification,
8
 * are permitted provided that the following conditions are met:
9
 * + Redistributions of source code must retain the above copyright notice,
10
 * this list of conditions and the following disclaimer.
11
 * + Redistributions in binary form must reproduce the above copyright notice,
12
 * this list of conditions and the following disclaimer in the documentation and/or
13
 * other materials provided with the distribution.
14
 * + The names of its contributors may not be used to endorse or promote
15
 * products derived from this software without specific prior written permission.
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 *
28
 * @category  Console
29
 * @package   Console_GetoptPlus
30
 * @author    Michel Corne <[email protected]>
31
 * @copyright 2008 Michel Corne
32
 * @license   http://www.opensource.org/licenses/bsd-license.php The BSD License
33
 * @version   SVN: $Id: Getopt.php 48 2008-01-10 15:32:56Z mcorne $
34
 * @link      http://pear.php.net/package/Console_GetoptPlus
35
 */
36
37
require_once 'Console/GetoptPlus/Exception.php';
38
require_once XOOPS_ROOT_PATH . '/modules/extgallery/class/pear/PEAR.php';
39
40
/**
41
 * Parsing of a command line.
42
 *
43
 * See more examples in docs/examples.
44
 *
45
 * Code Example 1:
46
 * <code>
47
 * require_once 'Console/GetoptPlus.php';
48
 *
49
 * try {
50
 *    $shortOptions = "b:c::";
51
 *    $longOptions = array("foo", "bar=");
52
 *    $options = Console_Getoptplus::getopt($config, $shortOptions, $longOptions);
53
 *    // some processing here...
54
 *    print_r($options);
55
 * }
56
 * catch(Console_GetoptPlus_Exception $e) {
57
 *    $error = array($e->getCode(), $e->getMessage());
58
 *    print_r($error);
59
 * }
60
 * </code>
61
 *
62
 * Code Example 2:
63
 * <code>
64
 * require_once 'Console/GetoptPlus/Getopt.php';
65
 *
66
 * try {
67
 *    $shortOptions = "b:c::";
68
 *    $longOptions = array("foo", "bar=");
69
 *    $options = Console_GetoptPlus_Getopt::getopt($config, $shortOptions, $longOptions);
70
 *    // some processing here...
71
 *    print_r($options);
72
 * }
73
 * catch(Console_GetoptPlus_Exception $e) {
74
 *    $error = array($e->getCode(), $e->getMessage());
75
 *    print_r($error);
76
 * }
77
 * </code>
78
 *
79
 * Run:
80
 * <pre>
81
 * #xyz --foo -b car -c
82
 * #xyz --foo -b car -c param1
83
 * #xyz --foo -b car -cbus param1
84
 * #xyz --foo -b car -c=bus param1
85
 * #xyz --bar car param1 param2
86
 * #xyz --bar car -- param1 param2
87
 * #xyz --bar=car param1 param2
88
 * </pre>
89
 *
90
 * @category  Console
91
 * @package   Console_GetoptPlus
92
 * @author    Michel Corne <[email protected]>
93
 * @copyright 2008 Michel Corne
94
 * @license   http://www.opensource.org/licenses/bsd-license.php The BSD License
95
 * @version   Release:
96
 * @package   _version@
97
 * @link      http://pear.php.net/package/Console_GetoptPlus
98
 * @see       Console_Getopt
99
 */
100
class Console_GetoptPlus_Getopt
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
101
{
102
    /**
103
     * The list of ambigous option names
104
     *
105
     * @var    array
106
     * @access private
107
     */
108
    private $ambigous;
109
110
    /**
111
     * The command arguments
112
     *
113
     * @var    array
114
     * @access private
115
     */
116
    private $args;
117
118
    /**
119
     * The long option names
120
     *
121
     * @var    array
122
     * @access private
123
     */
124
    private $longOptionsDef;
125
126
    /**
127
     * The parsed options
128
     *
129
     * @var    array
130
     * @access private
131
     */
132
    private $options;
133
134
    /**
135
     * The option shortcut names
136
     *
137
     * @var    array
138
     * @access private
139
     */
140
    private $shortcuts;
141
142
    /**
143
     * The short option names and their definition
144
     *
145
     * @var    array
146
     * @access private
147
     */
148
    private $shortOptionsDef;
149
150
    /**
151
     * The option types
152
     *
153
     * @var    array
154
     * @access private
155
     */
156
    private $type = array(// /
157
                          false => 'noarg',
158
                          '='   => 'mandatory',
159
                          ':'   => 'mandatory',
160
                          '=='  => 'optional',
161
                          '::'  => 'optional',
162
    );
163
164
    /**
165
     * Creates the option shorcut names
166
     *
167
     * @param  array  $longOptionsDef the long option names
168
     * @param  string $ambiguity      directive to handle option names ambiguity
169
     * @return array  the option shorcuts and the ambigous options
170
     * @access public
171
     */
172
    public function createShorcuts($longOptionsDef, $ambiguity)
173
    {
174
        $shortcuts = array();
175
        $ambigous  = array();
176
177
        if ('shortcuts' == $ambiguity) {
178
            foreach (array_keys($longOptionsDef) as $name) {
179
                // splits the option name in characters to build the name
180
                // substring combinations, e.g. foo => f, fo, foo
181
                $subName = '';
182
                foreach (str_split($name) as $char) {
183
                    $subName .= $char;
184
185
                    if (isset($ambigous[$subName])) {
186
                        // adds the shortcut to the list of ambigous shortcuts
187
                        $ambigous[$subName][] = $name;
188
                    } elseif (isset($shortcuts[$subName])) {
189
                        // there is already a shortcut, adds the previous one
190
                        // and the current one in the list of ambigous shortcuts
191
                        $ambigous[$subName] = array($shortcuts[$subName], $name);
192
                        unset($shortcuts[$subName]);
193
                    } else {
194
                        // creates the shorcut entry
195
                        $shortcuts[$subName] = $name;
196
                    }
197
                }
198
            }
199
            // checks if some options are ambigous, e.g. --foo --foobar
200
            $names = array_intersect_key($longOptionsDef, $ambigous) and self::exception('ambigous', key($names));
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
201
        }
202
203
        return array($shortcuts, $ambigous);
204
    }
205
206
    /**
207
     * Parses the command line
208
     *
209
     * See getopt() for a complete description.
210
     *
211
     * @param  numeric $version      the getopt version: 1 or 2
0 ignored issues
show
Documentation introduced by
Should the type for parameter $version not be numeric|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
212
     * @param  array   $args         the arguments
213
     * @param  string  $shortOptions the short options definition, e.g. "ab:c::"
214
     * @param  array   $longOptions  the long options definition
215
     * @param  string  $ambiguity    directive to handle option names ambiguity
216
     * @return array   the parsed options, their arguments and parameters
217
     * @access public
218
     * @static
219
     */
220
    public static function doGetopt(
221
        $version = null,
222
        $args = array(),
223
        $shortOptions = '',
224
        $longOptions = array(),
225
        $ambiguity = ''
226
    ) {
227
        $getopt = new self;
228
229
        return $getopt->process($args, $shortOptions, $longOptions, $ambiguity, $version);
0 ignored issues
show
Bug introduced by
It seems like $version defined by parameter $version on line 221 can also be of type null; however, Console_GetoptPlus_Getopt::process() does only seem to accept integer, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
230
    }
231
232
    /**
233
     * Wraps the exception call
234
     *
235
     * @return void
236
     * @access private
237
     * @throws Console_GetoptPlus_Exception Exception
238
     * @static
239
     */
240
    private static function exception()
241
    {
242
        $error = func_get_args();
243
        throw new Console_GetoptPlus_Exception($error);
244
    }
245
246
    /**
247
     * Parses the command line
248
     *
249
     * See the definition/example in the class Doc Block.
250
     *
251
     * Example: returning an index array
252
     * <code>
253
     * array(
254
     *      [0] => array("foo" => null, "bar" => "car", "c" => null),
255
     *      [1] => array([0] => "param1", [1] => "param2")
256
     * );
257
     * </code>
258
     *
259
     * @param  array  $args         the arguments
260
     * @param  string $shortOptions the short options definition, e.g. "ab:c::"
261
     *                              <ul>
262
     *                              <li>":" : the option requires an argument</li>
263
     *                              <li>"::" : the option accepts an optional argument</li>
264
     *                              <li>otherwise the option accepts no argument</li>
265
     *                              </ul>
266
     * @param  array  $longOptions  the long options definition,
267
     *                              e.g. array("art", "bar=", "car==)
268
     *                              <ul>
269
     *                              <li>"=" : the option requires an argument</li>
270
     *                              <li>"==" : the option accepts an optional argument</li>
271
     *                              <li>otherwise the option accepts no argument</li>
272
     *                              </ul>
273
     * @param  string $ambiguity    directive to handle option names ambiguity,
274
     *                              e.g. "--foo" and "--foobar":
275
     *                              <ul>
276
     *                              <li>"loose": allowed if "--foo" does not
277
     *                              accept an argument, this is the default
278
     *                              behaviour</li>
279
     *                              <li>"strict": no ambiguity allowed</li>
280
     *                              <li>"shortcuts": implies "strict", the use of
281
     *                              partial option names is allowed,
282
     *                              e.g. "--f" or "--fo" instead of "--foo"</li>
283
     *                              </ul>
284
     * @return array  the parsed options, their arguments and parameters
285
     * @access public
286
     * @static
287
     */
288
    public static function getopt(
289
        $args = array(),
290
        $shortOptions = '',
291
        $longOptions = array(),
292
        $ambiguity = ''
293
    ) {
294
        return self::doGetopt(1, $args, $shortOptions, $longOptions, $ambiguity);
0 ignored issues
show
Documentation introduced by
1 is of type integer, but the function expects a object<numeric>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
295
    }
296
297
    /**
298
     * Parses the command line
299
     *
300
     * See getopt() for a complete description.
301
     *
302
     * @param  array  $args         the arguments
303
     * @param  string $shortOptions the short options definition, e.g. "ab:c::"
304
     * @param  array  $longOptions  the long options definition
305
     * @param  string $ambiguity    directive to handle option names ambiguity
306
     * @return array  the parsed options, their arguments and parameters
307
     * @access public
308
     * @static
309
     */
310
    public static function getopt2(
311
        $args = array(),
312
        $shortOptions = '',
313
        $longOptions = array(),
314
        $ambiguity = ''
315
    ) {
316
        return self::doGetopt(2, $args, $shortOptions, $longOptions, $ambiguity);
0 ignored issues
show
Documentation introduced by
2 is of type integer, but the function expects a object<numeric>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
317
    }
318
319
    /**
320
     * Checks if the argument is an option
321
     *
322
     * @param  string $argument the argument, e.g. "-f" or "--foo"
323
     * @return boolean true if an option, false otherwise
324
     * @access public
325
     */
326
    public function isOption($argument)
327
    {
328
        return (bool)preg_match('~^(-\w|--\w+)$~', $argument);
329
    }
330
331
    /**
332
     * Parses a long option
333
     *
334
     * @param  string $argument the option and argument (excluding the "--" prefix),
335
     *                          e.g. "file=foo.php", "file foo.php", "bar"
336
     * @return void
337
     * @access public
338
     */
339
    public function parseLongOption($argument)
340
    {
341
        $option = explode('=', $argument, 2);
342
        $name   = current($option);
343
        $arg = next($option) or $arg = null;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
344
        // verifies the option is valid
345
        isset($this->ambigous[$name]) and self::exception('ambigous', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
346
        isset($this->shortcuts[$name]) and $name = $this->shortcuts[$name] or isset($this->longOptionsDef[$name]) or self::exception('unrecognized', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
347
348
        if ('mandatory' == $this->longOptionsDef[$name]) {
349
            // the option requires an argument, e.g. --file=foo.php
350
            // tries the next argument if necessary, e.g. --file foo.php
351
            is_null($arg) and list(, $arg) = each($this->args);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
352
            is_null($arg) and self::exception('mandatory', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
353
            // verifies the argument is not an option itself
354
            $this->isOption($arg) and self::exception('mandatory', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
355
        } elseif ('noarg' == $this->longOptionsDef[$name] and !is_null($arg)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
356
            // the option may not take an optional argument
357
            self::exception('noargument', $name);
358
        }
359
        // capture the option and its argument
360
        $this->options[] = array('--' . $name, $arg);
361
    }
362
363
    /**
364
     * Parses the long option names and types
365
     *
366
     * @param  array $options the long options, e.g. array("foo", "bar=")
367
     * @return array  the options name and type,
368
     *                        e.g. array("foo"=>"noarg", "bar"=>"mandatory")
369
     * @access public
370
     */
371
    public function parseLongOptionsDef($options)
372
    {
373
        // converts to an array if there is only one option
374
        settype($options, 'array');
375
376
        $longOptionsDef = array();
377
        foreach ($options as $option) {
378
            if ($option = trim($option)) {
379
                // extracts the option name and type:
380
                // optional argument (==), mandatory (=), or none (null)
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
381
                // verifies the option syntax is correct
382
                preg_match("~^(\w+)(==|=)?$~", $option, $match) or self::exception('invalid', $option);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
383
                $name = next($match);
384
                $type = next($match);
385
                // verifies the option is not a duplicate
386
                isset($longOptionsDef[$name]) and self::exception('duplicate', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
387
                // captures the option name and type
388
                $longOptionsDef[$name] = $this->type[$type];
389
            }
390
        }
391
392
        return $longOptionsDef;
393
    }
394
395
    /**
396
     * Parses a short option
397
     *
398
     * @param  string $argument the option and argument (excluding the "-" prefix),
399
     *                          e.g. "zfoo.php", "z foo.php", "z".
400
     * @return void
401
     * @access public
402
     */
403
    public function parseShortOption($argument)
404
    {
405
        for ($i = 0; $i < strlen($argument); $i++) {
406
            $name = $argument{$i};
407
            $arg  = null;
408
            // verifies the option is valid
409
            isset($this->shortOptionsDef[$name]) or self::exception('unrecognized', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
410
411
            if ('optional' == $this->shortOptionsDef[$name]) {
412
                // the option may take an optional argument, e.g. -zfoo.php or -z
413
                if (false !== ($arg = substr($argument, $i + 1))) {
414
                    // the remainder of the string is the option argument
415
                    $this->options[] = array($name, $arg);
416
417
                    return;
418
                }
419
            } elseif ('mandatory' == $this->shortOptionsDef[$name]) {
420
                // the option requires an argument, -zfoo.php or -z foo.php
421
                if (false === ($arg = substr($argument, $i + 1))) {
422
                    // nothing left to use as the option argument
423
                    // the next argument is expected to be the option argument
424
                    // verifies there is one and it is not an option itself
425
                    list(, $arg) = each($this->args);
426
                    (is_null($arg) or $this->isOption($arg)) and self::exception('mandatory', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
427
                }
428
                $this->options[] = array($name, $arg);
429
430
                return;
431
            }
432
            // else: the option is not expecting an argument, e.g. -h
433
            // TODO: verify that if followed by a non option which is interpreted
434
            // as the end of options, there is indeed no option after until
435
            // possibly -- or -
436
            // capture the option and its argument
437
            $this->options[] = array($name, $arg);
438
        }
439
    }
440
441
    /**
442
     * Parses the short option names and types
443
     *
444
     * @param  string $options the short options, e.g. array("ab:c::)
445
     * @return array  the options name and type,
446
     *                         e.g. array("a"=>"noarg", "b"=>"mandatory", "c"=>"optional")
447
     * @access public
448
     */
449
    public function parseShortOptionsDef($options)
450
    {
451
        // expecting a string for a the short options definition
452
        is_array($options) and self::exception('string');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
453
        // trims and extracts the options name and type
454
        // optional argument (::), mandatory (:), or none (null)
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
455
        $options = trim($options);
456
        preg_match_all("~(\w)(::|:)?~", $options, $matches, PREG_SET_ORDER);
457
458
        $check           = '';
459
        $shortOptionsDef = array();
460
        foreach ($matches as $match) {
0 ignored issues
show
Bug introduced by
The expression $matches of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
461
            $check .= current($match);
462
            $name  = next($match);
463
            $type  = next($match);
464
            // verifies the option is not a duplicate
465
            isset($shortOptionsDef[$name]) and self::exception('duplicate', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
466
            // captures the option name and type
467
            $shortOptionsDef[$name] = $this->type[$type];
468
        }
469
        // checks there is no syntax error the short options definition
470
        $check == $options or self::exception('syntax', $name);
0 ignored issues
show
Bug introduced by
The variable $name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
471
472
        return $shortOptionsDef;
473
    }
474
475
    /**
476
     * Parses the command line
477
     *
478
     * See getopt() for a complete description.
479
     *
480
     * @param  array   $args         the arguments
481
     * @param  string  $shortOptions the short options definition, e.g. "ab:c::"
482
     * @param  array   $longOptions  the long options definition, e.g. array("foo", "bar=")
483
     * @param  string  $ambiguity    directive to handle option names ambiguity
484
     * @param  numeric $version      the getopt version: 1 or 2
0 ignored issues
show
Documentation introduced by
Should the type for parameter $version not be integer?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
485
     * @return array   the parsed options, their arguments and parameters
486
     * @access public
487
     */
488
    public function process(
489
        $args = array(),
490
        $shortOptions,
491
        $longOptions,
492
        $ambiguity = '',
493
        $version = 2
494
    ) {
495
        settype($args, 'array');
496
        in_array($ambiguity, array('loose', 'strict', 'shortcuts')) or $ambiguity = 'loose';
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
497
498
        if ($version < 2) {
499
            // preserve backwards compatibility with callers
500
            // that relied on erroneous POSIX fix
501
            // note: ported from Console/Getopt
502
            isset($args[0]) and '-' != substr($args[0], 0, 1) and array_shift($args);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
503
            settype($args, 'array');
504
        }
505
        $this->args = $args;
506
        // parses the options definitions, create shorcuts or check ambiguities
507
        $this->shortOptionsDef = $this->parseShortOptionsDef($shortOptions);
508
        $this->longOptionsDef  = $this->parseLongOptionsDef($longOptions);
509
        list($this->shortcuts, $this->ambigous) = $this->createShorcuts($this->longOptionsDef, $ambiguity);
510
        $this->verifyNoAmbiguity($this->longOptionsDef, $ambiguity);
511
512
        $this->options = array();
513
        $parameters    = array();
514
        while (list($i, $arg) = each($this->args)) {
515
            if ('--' == $arg) {
516
                // end of options
517
                // the remaining arguments are parameters excluding this one
518
                $parameters = array_slice($this->args, $i + 1);
519
                break;
520
            } elseif ('-' == $arg) {
521
                // the stdin flag
522
                // the remaining arguments are parameters including this one
523
                $parameters = array_slice($this->args, $i);
524
                break;
525
            } elseif ('--' == substr($arg, 0, 2)) {
526
                // a long option, e.g. --foo
527
                if ($this->longOptionsDef) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->longOptionsDef of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
528
                    $this->parseLongOption(substr($arg, 2));
529
                } else {
530
                    // not expecting long options, the remaining arguments are
531
                    // parameters including this one stripped off of --
532
                    $parameters    = array_slice($this->args, $i);
533
                    $parameters[0] = substr($parameters[0], 2);
534
                    break;
535
                }
536
            } elseif ('-' == $arg{0}) {
537
                // a short option, e.g. -h
538
                $this->parseShortOption(substr($arg, 1));
539
            } else {
540
                // the first non option
541
                // the remaining arguments are parameters including this one
542
                $parameters = array_slice($this->args, $i);
543
                break;
544
            }
545
        }
546
547
        return array($this->options, $parameters);
548
    }
549
550
    /**
551
     * Reads the command arguments
552
     *
553
     * @return array  the arguments
554
     * @access public
555
     * @static
556
     */
557
    public static function readPHPArgv()
0 ignored issues
show
Coding Style introduced by
readPHPArgv uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
readPHPArgv uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
558
    {
559
        global $argv;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
560
561
        is_array($args = $argv) or is_array($args = $_SERVER['argv']) or is_array($args = $GLOBALS['HTTP_SERVER_VARS']['argv']) or self::exception('noargs');
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
562
563
        return $args;
564
    }
565
566
    /**
567
     * Verifies there is no ambiguity with option names
568
     *
569
     * @param  array  $longOptionsDef  the long options names and their types
570
     * @param  string $ambiguity       directive to handle option names ambiguity,
571
     *                                 See getopt() for a complete description
572
     * @return boolean no ambiguity if true, false otherwise
573
     * @access public
574
     */
575
    public function verifyNoAmbiguity($longOptionsDef, $ambiguity)
576
    {
577
        settype($longOptionsDef, 'array');
578
579
        foreach ($longOptionsDef as $name => $type) {
580
            foreach ($longOptionsDef as $name2 => $type2) {
581
                if ($name != $name2) {
582
                    if ('loose' == $ambiguity and 'noarg' == $type) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
583
                        // according to Getopt.php, CVS v 1.4 2007/06/12,
584
                        // _parseLongOption(), line #236, the possible
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
585
                        // ambiguity of a long option name with another one is
586
                        // ignored if this option does not expect an argument!
587
                        continue;
588
                    }
589
                    // checks options are not ambigous, e.g. --foo --foobar
590
                    false === strpos($name2, $name) or self::exception('ambigous', $name);
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
591
                }
592
                // else: there is no ambiguity between an option and itself!
593
            }
594
        }
595
596
        return true;
597
    }
598
}
599