Completed
Push — master ( 603564...3d1dbb )
by Michael
03:27
created

Console_GetoptPlus_Getopt::parseLongOption()   D

Complexity

Conditions 12
Paths 160

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 14
nc 160
nop 1
dl 0
loc 24
rs 4.8205
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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', ':' => 'mandatory',
159
        '==' => 'optional', '::' => 'optional',
160
        );
161
162
    /**
163
     * Creates the option shorcut names
164
     *
165
     * @param  array  $longOptionsDef the long option names
166
     * @param  string $ambiguity      directive to handle option names ambiguity
167
     * @return array  the option shorcuts and the ambigous options
168
     * @access public
169
     */
170
    public function createShorcuts($longOptionsDef, $ambiguity)
171
    {
172
        $shortcuts = array();
173
        $ambigous = array();
174
175
        if ($ambiguity == 'shortcuts') {
176
            foreach(array_keys($longOptionsDef) as $name) {
177
                // splits the option name in characters to build the name
178
                // substring combinations, e.g. foo => f, fo, foo
179
                $subName = '';
180
                foreach(str_split($name) as $char) {
181
                    $subName .= $char;
182
183
                    if (isset($ambigous[$subName])) {
184
                        // adds the shortcut to the list of ambigous shortcuts
185
                        $ambigous[$subName][] = $name;
186
                    } else if (isset($shortcuts[$subName])) {
187
                        // there is already a shortcut, adds the previous one
188
                        // and the current one in the list of ambigous shortcuts
189
                        $ambigous[$subName] = array($shortcuts[$subName], $name);
190
                        unset($shortcuts[$subName]);
191
                    } else {
192
                        // creates the shorcut entry
193
                        $shortcuts[$subName] = $name;
194
                    }
195
                }
196
            }
197
            // checks if some options are ambigous, e.g. --foo --foobar
198
            $names = array_intersect_key($longOptionsDef, $ambigous) and
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...
199
            self::exception('ambigous', key($names));
200
        }
201
202
        return array($shortcuts, $ambigous);
203
    }
204
205
    /**
206
     * Parses the command line
207
     *
208
     * See getopt() for a complete description.
209
     *
210
     * @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...
211
     * @param  array   $args         the arguments
212
     * @param  string  $shortOptions the short options definition, e.g. "ab:c::"
213
     * @param  array   $longOptions  the long options definition
214
     * @param  string  $ambiguity    directive to handle option names ambiguity
215
     * @return array   the parsed options, their arguments and parameters
216
     * @access public
217
     * @static
218
     */
219
    public static function doGetopt($version = null, $args = array(),
220
        $shortOptions = '', $longOptions = array(), $ambiguity = '')
221
    {
222
        $getopt = new self;
223
224
        return $getopt->process($args, $shortOptions, $longOptions,
225
            $ambiguity, $version);
0 ignored issues
show
Bug introduced by
It seems like $version defined by parameter $version on line 219 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...
226
    }
227
228
    /**
229
     * Wraps the exception call
230
     *
231
     * @return void
232
     * @access private
233
     * @throws Console_GetoptPlus_Exception Exception
234
     * @static
235
     */
236
    private static function exception()
237
    {
238
        $error = func_get_args();
239
        throw new Console_GetoptPlus_Exception($error);
240
    }
241
242
    /**
243
     * Parses the command line
244
     *
245
     * See the definition/example in the class Doc Block.
246
     *
247
     * Example: returning an index array
248
     * <code>
249
     * array(
250
     *      [0] => array("foo" => null, "bar" => "car", "c" => null),
251
     *      [1] => array([0] => "param1", [1] => "param2")
252
     * );
253
     * </code>
254
     *
255
     * @param  array  $args         the arguments
256
     * @param  string $shortOptions the short options definition, e.g. "ab:c::"
257
     *                              <ul>
258
     *                              <li>":" : the option requires an argument</li>
259
     *                              <li>"::" : the option accepts an optional argument</li>
260
     *                              <li>otherwise the option accepts no argument</li>
261
     *                              </ul>
262
     * @param  array  $longOptions  the long options definition,
263
     *                              e.g. array("art", "bar=", "car==)
264
     *                              <ul>
265
     *                              <li>"=" : the option requires an argument</li>
266
     *                              <li>"==" : the option accepts an optional argument</li>
267
     *                              <li>otherwise the option accepts no argument</li>
268
     *                              </ul>
269
     * @param  string $ambiguity    directive to handle option names ambiguity,
270
     *                              e.g. "--foo" and "--foobar":
271
     *                              <ul>
272
     *                              <li>"loose": allowed if "--foo" does not
273
     *                              accept an argument, this is the default
274
     *                              behaviour</li>
275
     *                              <li>"strict": no ambiguity allowed</li>
276
     *                              <li>"shortcuts": implies "strict", the use of
277
     *                              partial option names is allowed,
278
     *                              e.g. "--f" or "--fo" instead of "--foo"</li>
279
     *                              </ul>
280
     * @return array  the parsed options, their arguments and parameters
281
     * @access public
282
     * @static
283
     */
284
    public static function getopt($args = array(), $shortOptions = '',
285
        $longOptions = array(), $ambiguity = '')
286
    {
287
        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...
288
    }
289
290
    /**
291
     * Parses the command line
292
     *
293
     * See getopt() for a complete description.
294
     *
295
     * @param  array  $args         the arguments
296
     * @param  string $shortOptions the short options definition, e.g. "ab:c::"
297
     * @param  array  $longOptions  the long options definition
298
     * @param  string $ambiguity    directive to handle option names ambiguity
299
     * @return array  the parsed options, their arguments and parameters
300
     * @access public
301
     * @static
302
     */
303
    public static function getopt2($args = array(), $shortOptions = '',
304
        $longOptions = array(), $ambiguity = '')
305
    {
306
        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...
307
    }
308
309
    /**
310
     * Checks if the argument is an option
311
     *
312
     * @param  string  $argument the argument, e.g. "-f" or "--foo"
313
     * @return boolean true if an option, false otherwise
314
     * @access public
315
     */
316
    public function isOption($argument)
317
    {
318
        return (bool)preg_match('~^(-\w|--\w+)$~', $argument);
319
    }
320
321
    /**
322
     * Parses a long option
323
     *
324
     * @param  string $argument the option and argument (excluding the "--" prefix),
325
     *                          e.g. "file=foo.php", "file foo.php", "bar"
326
     * @return void
327
     * @access public
328
     */
329
    public function parseLongOption($argument)
330
    {
331
        $option = explode('=', $argument, 2);
332
        $name = current($option);
333
        $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...
334
        // verifies the option is valid
335
        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...
336
        isset($this->shortcuts[$name]) and $name = $this->shortcuts[$name] or
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...
337
        isset($this->longOptionsDef[$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...
338
339
        if ($this->longOptionsDef[$name] == 'mandatory') {
340
            // the option requires an argument, e.g. --file=foo.php
341
            // tries the next argument if necessary, e.g. --file foo.php
342
            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...
343
            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...
344
            // verifies the argument is not an option itself
345
            $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...
346
        } else if ($this->longOptionsDef[$name] == 'noarg' 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...
347
            // the option may not take an optional argument
348
            self::exception('noargument', $name);
349
        }
350
        // capture the option and its argument
351
        $this->options[] = array('--' . $name, $arg);
352
    }
353
354
    /**
355
     * Parses the long option names and types
356
     *
357
     * @param  array  $options the long options, e.g. array("foo", "bar=")
358
     * @return array  the options name and type,
359
     *                e.g. array("foo"=>"noarg", "bar"=>"mandatory")
360
     * @access public
361
     */
362
    public function parseLongOptionsDef($options)
363
    {
364
        // converts to an array if there is only one option
365
        settype($options, 'array');
366
367
        $longOptionsDef = array();
368
        foreach($options as $option) {
369
            if ($option = trim($option)) {
370
                // extracts the option name and type:
371
                // 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...
372
                // verifies the option syntax is correct
373
                preg_match("~^(\w+)(==|=)?$~", $option, $match) or
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...
374
                self::exception('invalid', $option);
375
                $name = next($match);
376
                $type = next($match);
377
                // verifies the option is not a duplicate
378
                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...
379
                // captures the option name and type
380
                $longOptionsDef[$name] = $this->type[$type];
381
            }
382
        }
383
384
        return $longOptionsDef;
385
    }
386
387
    /**
388
     * Parses a short option
389
     *
390
     * @param  string $argument the option and argument (excluding the "-" prefix),
391
     *                          e.g. "zfoo.php", "z foo.php", "z".
392
     * @return void
393
     * @access public
394
     */
395
    public function parseShortOption($argument)
396
    {
397
        for ($i = 0; $i < strlen($argument); $i++) {
398
            $name = $argument{$i};
399
            $arg = null;
400
            // verifies the option is valid
401
            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...
402
403
            if ($this->shortOptionsDef[$name] == 'optional') {
404
                // the option may take an optional argument, e.g. -zfoo.php or -z
405
                if (($arg = substr($argument, $i + 1)) !== false) {
406
                    // the remainder of the string is the option argument
407
                    $this->options[] = array($name, $arg);
408
                    return;
409
                }
410
            } else if ($this->shortOptionsDef[$name] == 'mandatory') {
411
                // the option requires an argument, -zfoo.php or -z foo.php
412
                if (($arg = substr($argument, $i + 1)) === false) {
413
                    // nothing left to use as the option argument
414
                    // the next argument is expected to be the option argument
415
                    // verifies there is one and it is not an option itself
416
                    list(, $arg) = each($this->args);
417
                    (is_null($arg) or $this->isOption($arg)) and
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...
418
                    self::exception('mandatory', $name);
419
                }
420
                $this->options[] = array($name, $arg);
421
                return;
422
            }
423
            // else: the option is not expecting an argument, e.g. -h
424
            // TODO: verify that if followed by a non option which is interpreted
425
            // as the end of options, there is indeed no option after until
426
            // possibly -- or -
427
            // capture the option and its argument
428
            $this->options[] = array($name, $arg);
429
        }
430
    }
431
432
    /**
433
     * Parses the short option names and types
434
     *
435
     * @param  string $options the short options, e.g. array("ab:c::)
436
     * @return array  the options name and type,
437
     *                e.g. array("a"=>"noarg", "b"=>"mandatory", "c"=>"optional")
438
     * @access public
439
     */
440
    public function parseShortOptionsDef($options)
441
    {
442
        // expecting a string for a the short options definition
443
        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...
444
        // trims and extracts the options name and type
445
        // 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...
446
        $options = trim($options);
447
        preg_match_all("~(\w)(::|:)?~", $options, $matches, PREG_SET_ORDER);
448
449
        $check = '';
450
        $shortOptionsDef = array();
451
        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...
452
            $check .= current($match);
453
            $name = next($match);
454
            $type = next($match);
455
            // verifies the option is not a duplicate
456
            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...
457
            // captures the option name and type
458
            $shortOptionsDef[$name] = $this->type[$type];
459
        }
460
        // checks there is no syntax error the short options definition
461
        $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...
462
463
        return $shortOptionsDef;
464
    }
465
466
    /**
467
     * Parses the command line
468
     *
469
     * See getopt() for a complete description.
470
     *
471
     * @param  array   $args         the arguments
472
     * @param  string  $shortOptions the short options definition, e.g. "ab:c::"
473
     * @param  array   $longOptions  the long options definition, e.g. array("foo", "bar=")
474
     * @param  string  $ambiguity    directive to handle option names ambiguity
475
     * @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...
476
     * @return array   the parsed options, their arguments and parameters
477
     * @access public
478
     */
479
    public function process($args = array(), $shortOptions, $longOptions,
480
        $ambiguity = '', $version = 2)
481
    {
482
        settype($args, 'array');
483
        in_array($ambiguity, array('loose', 'strict', 'shortcuts')) or
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...
484
        $ambiguity = 'loose';
485
486
        if ($version < 2) {
487
            // preserve backwards compatibility with callers
488
            // that relied on erroneous POSIX fix
489
            // note: ported from Console/Getopt
490
            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...
491
            settype($args, 'array');
492
        }
493
        $this->args = $args;
494
        // parses the options definitions, create shorcuts or check ambiguities
495
        $this->shortOptionsDef = $this->parseShortOptionsDef($shortOptions);
496
        $this->longOptionsDef = $this->parseLongOptionsDef($longOptions);
497
        list($this->shortcuts, $this->ambigous) = $this->createShorcuts($this->longOptionsDef, $ambiguity);
498
        $this->verifyNoAmbiguity($this->longOptionsDef, $ambiguity);
499
500
        $this->options = array();
501
        $parameters = array();
502
        while (list($i, $arg) = each($this->args)) {
503
            if ($arg == '--') {
504
                // end of options
505
                // the remaining arguments are parameters excluding this one
506
                $parameters = array_slice($this->args, $i + 1);
507
                break;
508
            } else if ($arg == '-') {
509
                // the stdin flag
510
                // the remaining arguments are parameters including this one
511
                $parameters = array_slice($this->args, $i);
512
                break;
513
            } else if (substr($arg, 0, 2) == '--') {
514
                // a long option, e.g. --foo
515
                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...
516
                    $this->parseLongOption(substr($arg, 2));
517
                } else {
518
                    // not expecting long options, the remaining arguments are
519
                    // parameters including this one stripped off of --
520
                    $parameters = array_slice($this->args, $i);
521
                    $parameters[0] = substr($parameters[0], 2);
522
                    break;
523
                }
524
            } else if ($arg{0} == '-') {
525
                // a short option, e.g. -h
526
                $this->parseShortOption(substr($arg, 1));
527
            } else {
528
                // the first non option
529
                // the remaining arguments are parameters including this one
530
                $parameters = array_slice($this->args, $i);
531
                break;
532
            }
533
        }
534
535
        return array($this->options, $parameters);
536
    }
537
538
    /**
539
     * Reads the command arguments
540
     *
541
     * @return array  the arguments
542
     * @access public
543
     * @static
544
     */
545
    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...
546
    {
547
        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...
548
549
        is_array($args = $argv) or
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...
550
        is_array($args = $_SERVER['argv']) or
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...
551
        is_array($args = $GLOBALS['HTTP_SERVER_VARS']['argv']) or
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...
552
        self::exception('noargs');
553
554
        return $args;
555
    }
556
557
    /**
558
     * Verifies there is no ambiguity with option names
559
     *
560
     * @param  array   $longOptionsDef the long options names and their types
561
     * @param  string  $ambiguity      directive to handle option names ambiguity,
562
     *                                 See getopt() for a complete description
563
     * @return boolean no ambiguity if true, false otherwise
564
     * @access public
565
     */
566
    public function verifyNoAmbiguity($longOptionsDef, $ambiguity)
567
    {
568
        settype($longOptionsDef, 'array');
569
570
        foreach($longOptionsDef as $name => $type) {
571
            foreach($longOptionsDef as $name2 => $type2) {
572
                if ($name != $name2) {
573
                    if ($ambiguity == 'loose' and $type == 'noarg') {
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...
574
                        // according to Getopt.php, CVS v 1.4 2007/06/12,
575
                        // _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...
576
                        // ambiguity of a long option name with another one is
577
                        // ignored if this option does not expect an argument!
578
                        continue;
579
                    }
580
                    // checks options are not ambigous, e.g. --foo --foobar
581
                    strpos($name2, $name) === false 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...
582
                }
583
                // else: there is no ambiguity between an option and itself!
584
            }
585
        }
586
587
        return true;
588
    }
589
}
590
591
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
592