StringInput.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. <?php
  2. namespace Symfony\Component\Console\Input;
  3. /*
  4. * This file is part of the Symfony framework.
  5. *
  6. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  7. *
  8. * This source file is subject to the MIT license that is bundled
  9. * with this source code in the file LICENSE.
  10. */
  11. /**
  12. * StringInput represents an input provided as a string.
  13. *
  14. * Usage:
  15. *
  16. * $input = new StringInput('foo --bar="foobar"');
  17. *
  18. * @author Fabien Potencier <fabien.potencier@symfony-project.com>
  19. */
  20. class StringInput extends ArgvInput
  21. {
  22. const REGEX_STRING = '([^ ]+?)(?: |(?<!\\\\)"|(?<!\\\\)\'|$)';
  23. const REGEX_QUOTED_STRING = '(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')';
  24. /**
  25. * Constructor.
  26. *
  27. * @param string $input An array of parameters from the CLI (in the argv format)
  28. * @param InputDefinition $definition A InputDefinition instance
  29. */
  30. public function __construct($input, InputDefinition $definition = null)
  31. {
  32. parent::__construct(array(), $definition);
  33. $this->tokens = $this->tokenize($input);
  34. }
  35. /**
  36. * @throws \InvalidArgumentException When unable to parse input (should never happen)
  37. */
  38. protected function tokenize($input)
  39. {
  40. $input = preg_replace('/(\r\n|\r|\n|\t)/', ' ', $input);
  41. $tokens = array();
  42. $length = strlen($input);
  43. $cursor = 0;
  44. while ($cursor < $length) {
  45. if (preg_match('/\s+/A', $input, $match, null, $cursor)) {
  46. } elseif (preg_match('/([^="\' ]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) {
  47. $tokens[] = $match[1].$match[2].stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2)));
  48. } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) {
  49. $tokens[] = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
  50. } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) {
  51. $tokens[] = stripcslashes($match[1]);
  52. } else {
  53. // should never happen
  54. // @codeCoverageIgnoreStart
  55. throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
  56. // @codeCoverageIgnoreEnd
  57. }
  58. $cursor += strlen($match[0]);
  59. }
  60. return $tokens;
  61. }
  62. }