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 public function addSuffix(string $suffix) 36 { 37 $this->suffixes[] = $suffix; 38 } 39 40 /** 41 * Finds an executable by name. 42 * 43 * @param string $name The executable name (without the extension) 44 * @param string|null $default The default to return if no executable is found 45 * @param array $extraDirs Additional dirs to check into 46 * 47 * @return string|null 48 */ 49 public function find(string $name, string $default = null, array $extraDirs = []) 50 { 51 if (ini_get('open_basedir')) { 52 $searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs); 53 $dirs = []; 54 foreach ($searchPath as $path) { 55 // Silencing against https://bugs.php.net/69240 56 if (@is_dir($path)) { 57 $dirs[] = $path; 58 } else { 59 if (basename($path) == $name && @is_executable($path)) { 60 return $path; 61 } 62 } 63 } 64 } else { 65 $dirs = array_merge( 66 explode(\PATH_SEPARATOR, getenv('PATH') ?: getenv('Path')), 67 $extraDirs 68 ); 69 } 70 71 $suffixes = ['']; 72 if ('\\' === \DIRECTORY_SEPARATOR) { 73 $pathExt = getenv('PATHEXT'); 74 $suffixes = array_merge($pathExt ? explode(\PATH_SEPARATOR, $pathExt) : $this->suffixes, $suffixes); 75 } 76 foreach ($suffixes as $suffix) { 77 foreach ($dirs as $dir) { 78 if (@is_file($file = $dir.\DIRECTORY_SEPARATOR.$name.$suffix) && ('\\' === \DIRECTORY_SEPARATOR || @is_executable($file))) { 79 return $file; 80 } 81 } 82 } 83 84 return $default; 85 } 86} 87