View file vendor/symfony/console/Input/StringInput.php

File size: 2.24Kb
  1. <?php
  2.  
  3. /*
  4. * This file is part of the Symfony package.
  5. *
  6. * (c) Fabien Potencier <fabien@symfony.com>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11.  
  12. namespace Symfony\Component\Console\Input;
  13.  
  14. use Symfony\Component\Console\Exception\InvalidArgumentException;
  15.  
  16. /**
  17. * StringInput represents an input provided as a string.
  18. *
  19. * Usage:
  20. *
  21. * $input = new StringInput('foo --bar="foobar"');
  22. *
  23. * @author Fabien Potencier <fabien@symfony.com>
  24. */
  25. class StringInput extends ArgvInput
  26. {
  27. public const REGEX_STRING = '([^\s]+?)(?:\s|(?<!\\\\)"|(?<!\\\\)\'|$)';
  28. public const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
  29.  
  30. /**
  31. * @param string $input A string representing the parameters from the CLI
  32. */
  33. public function __construct(string $input)
  34. {
  35. parent::__construct([]);
  36.  
  37. $this->setTokens($this->tokenize($input));
  38. }
  39.  
  40. /**
  41. * Tokenizes a string.
  42. *
  43. * @throws InvalidArgumentException When unable to parse input (should never happen)
  44. */
  45. private function tokenize(string $input): array
  46. {
  47. $tokens = [];
  48. $length = \strlen($input);
  49. $cursor = 0;
  50. while ($cursor < $length) {
  51. if (preg_match('/\s+/A', $input, $match, 0, $cursor)) {
  52. } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, 0, $cursor)) {
  53. $tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, \strlen($match[3]) - 2)));
  54. } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, 0, $cursor)) {
  55. $tokens[] = stripcslashes(substr($match[0], 1, \strlen($match[0]) - 2));
  56. } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, 0, $cursor)) {
  57. $tokens[] = stripcslashes($match[1]);
  58. } else {
  59. // should never happen
  60. throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10)));
  61. }
  62.  
  63. $cursor += \strlen($match[0]);
  64. }
  65.  
  66. return $tokens;
  67. }
  68. }