FileBinaryMimeTypeGuesser.php 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpFoundation\File\MimeType;
  11. use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
  12. use Symfony\Component\HttpFoundation\File\Exception\AccessDeniedException;
  13. /**
  14. * Guesses the mime type with the binary "file" (only available on *nix)
  15. *
  16. * @author Bernhard Schussek <bernhard.schussek@symfony.com>
  17. */
  18. class FileBinaryMimeTypeGuesser implements MimeTypeGuesserInterface
  19. {
  20. private $cmd;
  21. /**
  22. * Constructor.
  23. *
  24. * The $cmd pattern must contain a "%s" string that will be replaced
  25. * with the file name to guess.
  26. *
  27. * The command output must start with the mime type of the file.
  28. *
  29. * @param string $cmd The command to run to get the mime type of a file
  30. */
  31. public function __construct($cmd = 'file -b --mime %s 2>/dev/null')
  32. {
  33. $this->cmd = $cmd;
  34. }
  35. /**
  36. * Returns whether this guesser is supported on the current OS
  37. *
  38. * @return Boolean
  39. */
  40. static public function isSupported()
  41. {
  42. return !defined('PHP_WINDOWS_VERSION_BUILD');
  43. }
  44. /**
  45. * Guesses the mime type of the file with the given path
  46. *
  47. * @see MimeTypeGuesserInterface::guess()
  48. */
  49. public function guess($path)
  50. {
  51. if (!is_file($path)) {
  52. throw new FileNotFoundException($path);
  53. }
  54. if (!is_readable($path)) {
  55. throw new AccessDeniedException($path);
  56. }
  57. if (!self::isSupported()) {
  58. return null;
  59. }
  60. ob_start();
  61. // need to use --mime instead of -i. see #6641
  62. passthru(sprintf($this->cmd, escapeshellarg($path)), $return);
  63. if ($return > 0) {
  64. ob_end_clean();
  65. return null;
  66. }
  67. $type = trim(ob_get_clean());
  68. if (!preg_match('#^([a-z0-9\-]+/[a-z0-9\-]+)#i', $type, $match)) {
  69. // it's not a type, but an error message
  70. return null;
  71. }
  72. return $match[1];
  73. }
  74. }