From 4115ca3bd9b5563598c377b10cd6eb3ce37c069e Mon Sep 17 00:00:00 2001 From: Alexey Melnichuk Date: Mon, 5 Jun 2017 17:47:38 +0300 Subject: [PATCH] Fix. Find php interpreter when use CGI/FastCGI mode. (#2640) Prev version has bug when extension_dir has relative path (e.g. `ext`) `basedir('ext')` returns not empty string by dot symbol `.` so it going to infinity loop. Also official distro of PHP has no executable binaries with version (phpX.exe) only `php.exe`. Tested on OpenServer with PHP 5.3-7.1 under Apache/Nginx. And also on manual install of Nginx 1.11 / PHP 5.4 --- resources/switch.php | 89 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 17 deletions(-) diff --git a/resources/switch.php b/resources/switch.php index ceea9ac879..28b47ffb2f 100644 --- a/resources/switch.php +++ b/resources/switch.php @@ -1280,15 +1280,16 @@ if (!function_exists('switch_conf_xml')) { //prepare the php variables if (stristr(PHP_OS, 'WIN')) { - $bindir = find_php_by_extension(); - if(!$bindir) - $bindir = getenv(PHPRC); + $php_bin = win_find_php('php.exe'); + if(!$php_bin){ // relay on system path + $php_bin = 'php.exe'; + } $secure_path = path_join($_SERVER["DOCUMENT_ROOT"], PROJECT_PATH, 'secure'); $v_mail_bat = path_join($secure_path, 'mailto.bat'); $v_mail_cmd = '@' . - '"' . str_replace('/', '\\', path_join($bindir, 'php5.exe')) . '" ' . + '"' . str_replace('/', '\\', $php_bin) . '" ' . '"' . str_replace('/', '\\', path_join($secure_path, 'v_mailto.php')) . '" '; $fout = fopen($v_mail_bat, "w+"); @@ -1297,7 +1298,7 @@ if (!function_exists('switch_conf_xml')) { $v_mailer_app = '"' . str_replace('/', '\\', $v_mail_bat) . '"'; $v_mailer_app_args = ""; - unset($v_mail_bat, $v_mail_cmd, $secure_path, $bindir, $fout); + unset($v_mail_bat, $v_mail_cmd, $secure_path, $php_bin, $fout); } else { if (file_exists(PHP_BINDIR.'/php')) { define("PHP_BIN", "php"); } @@ -1510,6 +1511,7 @@ if(!function_exists('path_join')) { else $prefix = ''; } $path = trim( $path, '/' ); + $path = trim( $path, '\\' ); } if($prefix === null){ @@ -1522,22 +1524,75 @@ if(!function_exists('path_join')) { } } -if(!function_exists('find_php_by_extension')) { - // Tested on WAMP and OpenServer - function find_php_by_extension(){ - $bin_dir = get_cfg_var('extension_dir'); - - while($bin_dir){ - $bin_dir = dirname($bin_dir); - $php_bin = path_join($bin_dir, 'php.exe'); - if(file_exists($php_bin)) - break; +if(!function_exists('win_find_php')) { + function win_find_php_in_root($root, $bin){ + while(true) { + $php_bin = path_join($root, $bin); + if(file_exists($php_bin)){ + $php_bin = str_replace('/', '\\', $php_bin); + return $php_bin; + } + $prev_root = $root; + $root = dirname($root); + if((!$root)&&($prev_root == $root)){ + return false; + } } + } - if(!$bin_dir) + //Tested on WAMP and OpenServer + //Can get wrong result if `extension_dir` set as relative path. + function win_find_php_by_extension($bin_name){ + $bin_dir = get_cfg_var('extension_dir'); + return win_find_php_in_root($bin_dir, $bin_name); + } + + // Works since PHP 5.4 + function win_find_php_by_binary($bin_name){ + if(!defined('PHP_BINARY')){ return false; + } + $bin_dir = realpath(PHP_BINARY); + if(!$bin_dir){ + $bin_dir = PHP_BINARY; + } + $bin_dir = dirname($bin_dir); + return win_find_php_in_root($bin_dir, $bin_name); + } - return $bin_dir; + function win_find_php_by_phprc($bin_name){ + $bin_dir = getenv(PHPRC); + if(!$bin_dir){ + return false; + } + $bin_dir = realpath($bin_dir); + return win_find_php_in_root($bin_dir, $bin_name); + } + + //on Windows PHP_BIN set in compile time to c:\php + //It possible redifine it in env, but not all installation do it + function win_find_php_by_bin($bin_name){ + if(!defined('PHP_BIN')){ + return false; + } + $bin_dir = realpath(PHP_BIN); + if(!$bin_dir){ + $bin_dir = PHP_BIN; + } + $bin_dir = dirname($bin_dir); + return win_find_php_in_root($bin_dir, $bin_name); + } + + function win_find_php($bin_name){ + $php_bin = win_find_php_by_binary($bin_name); + if($php_bin) return $php_bin; + $php_bin = win_find_php_by_extension($bin_name); + if($php_bin) return $php_bin; + $php_bin = win_find_php_by_bin($bin_name); + if($php_bin) return $php_bin; + $php_bin = win_find_php_by_phprc($bin_name); + if($php_bin) return $php_bin; + return false; } }