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

class/pear/Console/Getopt.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
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
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));
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
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);
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);
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);
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;
344
        // verifies the option is valid
345
        isset($this->ambigous[$name]) and self::exception('ambigous', $name);
346
        isset($this->shortcuts[$name]) and $name = $this->shortcuts[$name] or isset($this->longOptionsDef[$name]) or self::exception('unrecognized', $name);
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);
352
            is_null($arg) and self::exception('mandatory', $name);
353
            // verifies the argument is not an option itself
354
            $this->isOption($arg) and self::exception('mandatory', $name);
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)
381
                // verifies the option syntax is correct
382
                preg_match("~^(\w+)(==|=)?$~", $option, $match) or self::exception('invalid', $option);
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);
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);
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);
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');
453
        // trims and extracts the options name and type
454
        // optional argument (::), mandatory (:), or none (null)
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) {
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);
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);
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
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';
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) {
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()
558
    {
559
        global $argv;
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');
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
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