ProcessUtils.php 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <?php
  2. namespace Illuminate\Support;
  3. /**
  4. * ProcessUtils is a bunch of utility methods.
  5. *
  6. * This class was originally copied from Symfony 3.
  7. */
  8. class ProcessUtils
  9. {
  10. /**
  11. * Escapes a string to be used as a shell argument.
  12. *
  13. * @param string $argument
  14. * @return string
  15. */
  16. public static function escapeArgument($argument)
  17. {
  18. // Fix for PHP bug #43784 escapeshellarg removes % from given string
  19. // Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
  20. // @see https://bugs.php.net/bug.php?id=43784
  21. // @see https://bugs.php.net/bug.php?id=49446
  22. if ('\\' === DIRECTORY_SEPARATOR) {
  23. if ('' === $argument) {
  24. return '""';
  25. }
  26. $escapedArgument = '';
  27. $quote = false;
  28. foreach (preg_split('/(")/', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {
  29. if ('"' === $part) {
  30. $escapedArgument .= '\\"';
  31. } elseif (self::isSurroundedBy($part, '%')) {
  32. // Avoid environment variable expansion
  33. $escapedArgument .= '^%"'.substr($part, 1, -1).'"^%';
  34. } else {
  35. // escape trailing backslash
  36. if ('\\' === substr($part, -1)) {
  37. $part .= '\\';
  38. }
  39. $quote = true;
  40. $escapedArgument .= $part;
  41. }
  42. }
  43. if ($quote) {
  44. $escapedArgument = '"'.$escapedArgument.'"';
  45. }
  46. return $escapedArgument;
  47. }
  48. return "'".str_replace("'", "'\\''", $argument)."'";
  49. }
  50. /**
  51. * Is the given string surrounded by the given character?
  52. *
  53. * @param string $arg
  54. * @param string $char
  55. * @return bool
  56. */
  57. protected static function isSurroundedBy($arg, $char)
  58. {
  59. return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];
  60. }
  61. }