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 12namespace Symfony\Component\Process; 13 14/** 15 * Generic executable finder. 16 * 17 * @author Fabien Potencier <fabien@symfony.com> 18 * @author Johannes M. Schmitt <schmittjoh@gmail.com> 19 */ 20class ExecutableFinder 21{ 22 private $suffixes = ['.exe', '.bat', '.cmd', '.com']; 23 24 /** 25 * Replaces default suffixes of executable. 26 */ 27 public function setSuffixes(array $suffixes) 28 { 29 $this->suffixes = $suffixes; 30 } 31 32 /** 33 * Adds new possible suffix to check for executable. 34 * 35 * @param string $suffix 36 */ 37 public function addSuffix($suffix) 38 { 39 $this->suffixes[] = $suffix; 40 } 41 42 /** 43 * Finds an executable by name. 44 * 45 * @param string $name The executable name (without the extension) 46 * @param string|null $default The default to return if no executable is found 47 * @param array $extraDirs Additional dirs to check into 48 * 49 * @return string|null The executable path or default value 50 */ 51 public function find($name, $default = null, array $extraDirs = []) 52 { 53 if (ini_get('open_basedir')) { 54 $searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs); 55 $dirs = []; 56 foreach ($searchPath as $path) { 57 // Silencing against https://bugs.php.net/69240 58 if (@is_dir($path)) { 59 $dirs[] = $path; 60 } else { 61 if (basename($path) == $name && @is_executable($path)) { 62 return $path; 63 } 64 } 65 } 66 } else { 67 $dirs = array_merge( 68 explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), 69 $extraDirs 70 ); 71 } 72 73 $suffixes = ['']; 74 if ('\\' === \DIRECTORY_SEPARATOR) { 75 $pathExt = getenv('PATHEXT'); 76 $suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes); 77 } 78 foreach ($suffixes as $suffix) { 79 foreach ($dirs as $dir) { 80 if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) { 81 return $file; 82 } 83 } 84 } 85 86 return $default; 87 } 88} 89