通过 PHP 的 exec 在 Windows 中无法识别真正的命令
Genuine command is not recognized in Windows via PHP's exec
问题:-
我正在尝试使用 PHP 和 windows 中的 mysqldump 备份 MySQL 数据库。当我使用 wamp 服务器时,以下脚本会根据需要 提供出色的转储 。
<?php
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '';
$dbname = 'avita';
$path = "c:/program files/mysql/mysql server 5.5/bin/";
$backup_file = "d:/avita/".$dbname . date("Y-m-d-H-i-s") . '.sql';
$command = $path."mysqldump -u$dbuser ". "avita 2>&1 $backup_file";
exec($command, $output);
print_r($output);
?>
同样可以使用windows命令行完成,没有任何问题:-
问题是当我运行在同一台机器上使用PHP-MySQL-Apache手动安装时,输出如下所示:-
输出:-
Array ( [0] => 'c:/program' is not recognized as an internal or
external command, 1 => operable program or batch file. )
我应该怎么做才能解决这个问题?
有几个重叠的误解。
%PATH%
(或在 *nix 环境中为 $PATH
)。手动命令行工作的唯一原因是因为您已经更改到 MySQL 目录,并且 Windows 检查 当前 目录。尝试 运行 mysqldump
(就像上面一样,没有任何目录限定符)当你的提示只是:
C:\>
发生了什么事?它没有用,但为什么?
接下来,回想一下 PHP 的 exec()
是 shell 的薄包装。让我们假设您是 运行 和 shell 被赋予上面的脚本。缺少已知目录,假设我们在根目录中:
C:\>c:/program files/mysql/mysql server 5.5/bin/mysqldump.exe
`c:/program` is not recognized as an internal or external command,
operable program or batch file
完全相同的问题! ... 所以发生了什么事?引用。 shell 将空格解释为标记定界符,因此 shell 抱怨 c:/program
不是有效的可执行文件。用引号试试,现在 shell 理解整个 "weird" 带空格的路径都是第一个参数,实际上是我们想要的可执行文件的路径:
C:\>"c:/program files/mysql/mysql server 5.5/bin/mysqldump.exe"
然后突然如预期般工作了!
PHP 有一系列 "paper cuts,",其中之一是 "sane" 处理这样的可执行文件。 PHP 在这里类似于 C,因为您必须自己进行转义。考虑:
$command_parts = [
escapeshellarg("${path}mysqldump.exe"),
escapeshellarg("-u$dbuser"),
"avita", # no escapeshellarg here, as avita is visually "clean"
"2>&1", # no escapeshellarg here, as 2>&1 is visually "clean"
escapeshellarg($backup_file)
];
$command = implode(' ', $command_parts);
exec( $command );
从这里开始,您的脚本应该会按预期运行。
问题:-
我正在尝试使用 PHP 和 windows 中的 mysqldump 备份 MySQL 数据库。当我使用 wamp 服务器时,以下脚本会根据需要 提供出色的转储 。
<?php
$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = '';
$dbname = 'avita';
$path = "c:/program files/mysql/mysql server 5.5/bin/";
$backup_file = "d:/avita/".$dbname . date("Y-m-d-H-i-s") . '.sql';
$command = $path."mysqldump -u$dbuser ". "avita 2>&1 $backup_file";
exec($command, $output);
print_r($output);
?>
同样可以使用windows命令行完成,没有任何问题:-
问题是当我运行在同一台机器上使用PHP-MySQL-Apache手动安装时,输出如下所示:-
输出:-
Array ( [0] => 'c:/program' is not recognized as an internal or external command, 1 => operable program or batch file. )
我应该怎么做才能解决这个问题?
有几个重叠的误解。
%PATH%
(或在 *nix 环境中为$PATH
)。手动命令行工作的唯一原因是因为您已经更改到 MySQL 目录,并且 Windows 检查 当前 目录。尝试 运行mysqldump
(就像上面一样,没有任何目录限定符)当你的提示只是:C:\>
发生了什么事?它没有用,但为什么?
接下来,回想一下 PHP 的
exec()
是 shell 的薄包装。让我们假设您是 运行 和 shell 被赋予上面的脚本。缺少已知目录,假设我们在根目录中:C:\>c:/program files/mysql/mysql server 5.5/bin/mysqldump.exe `c:/program` is not recognized as an internal or external command, operable program or batch file
完全相同的问题! ... 所以发生了什么事?引用。 shell 将空格解释为标记定界符,因此 shell 抱怨
c:/program
不是有效的可执行文件。用引号试试,现在 shell 理解整个 "weird" 带空格的路径都是第一个参数,实际上是我们想要的可执行文件的路径:C:\>"c:/program files/mysql/mysql server 5.5/bin/mysqldump.exe"
然后突然如预期般工作了!
PHP 有一系列 "paper cuts,",其中之一是 "sane" 处理这样的可执行文件。 PHP 在这里类似于 C,因为您必须自己进行转义。考虑:
$command_parts = [ escapeshellarg("${path}mysqldump.exe"), escapeshellarg("-u$dbuser"), "avita", # no escapeshellarg here, as avita is visually "clean" "2>&1", # no escapeshellarg here, as 2>&1 is visually "clean" escapeshellarg($backup_file) ]; $command = implode(' ', $command_parts); exec( $command );
从这里开始,您的脚本应该会按预期运行。