-1

我正在编写一个 PHP 脚本来自动执行mysqldump命令。我选择的方法是使用exec( $exec_string . ' 2>&1' ). 此脚本必须在 Windows 和 *nix 平台上运行。

遗憾的是,有些密码包含可怕的 $ 符号,因此必须引用 `-p'password contains$'。

以下是我迄今为止注意到的挑战:

  • 在 *nix 上,您必须使用单引号,否则会将 $ 扩展为变量。
  • 在 Windows 上,您必须使用双引号,因为单引号按字面意思处理
  • 转义 $ 不是一种选择,因为在 Windows 上,反斜杠仅在双引号 (\") 之前被解释为转义字符,因此 \$ 将按字面意思解释
  • 我不知道如何可靠地检测操作系统以便能够在单引号和双引号之间“交互”切换。

我是否缺少一个可以跨平台工作的技巧?

4

3 回答 3

0

您可以从 PHP 脚本中转储:

 <?php

$dumpSettings = array(
    'include-tables' => array('table1', 'table2'),
    'exclude-tables' => array('table3', 'table4'),
    'compress' => CompressMethod::GZIP, /* CompressMethod::[GZIP, BZIP2, NONE] */
    'no-data' => false,             /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_no-data */
    'add-drop-table' => false,      /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_add-drop-table */
    'single-transaction' => true,   /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_single-transaction */
    'lock-tables' => false,         /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_lock-tables */
    'add-locks' => true,            /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_add-locks */
    'extended-insert' => true       /* http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_extended-insert */
);

$dump = new MySQLDump('database','database_user','database_pass','localhost', $dumpSettings);
$dump->start('forum_dump.sql.gz');

https://github.com/clouddueling/mysqldump-php

于 2013-08-14T17:31:24.900 回答
0

我最终采用的方法并不疯狂(MySQLDump 类似乎是比 exec() 更强大的方法),但在这里它以防万一它对任何人都有帮助。

尽管我不想进行操作系统检测,但乍一看,我似乎无法解决报价解释中的问题。令人高兴的是,操作系统检测相对容易,如果您准备做出一些假设,例如“如果它不在 Windows 上运行,那么它在某种 *nix 服务器上”。

这是我的基本方法,我相信它会被激怒。

// Inside class
protected $os_quote_char = "'"; // Unix default quote character

// Inside constructor
// Detect OS and set quote character appropriately
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
    $this->os_quote_char = '"';

// Method for adding quotes
/**
 * Adds the OS non-interpreted quote character to the string(s), provided each string doesn't already start with said quote character.
 *
 * The quote character is set in the constructor, based on detecting Windows OSes vs. any other (assumed to be *nix).
 * You can pass in an array, in which case you will get an array of quoted strings in return.
 *
 * @param string|array $string_or_array
 * @return string|array
 */
protected function os_quote( $string_or_array ){
    $quoted_strings = array();
    $string_array = (array) $string_or_array;

    foreach ( $string_array as $string_to_quote ){
        // don't quote already quoted strings
        if ( substr( $string_to_quote, 0, 1 ) == $this->os_quote_char )
            $quoted_strings[] = $string_to_quote;
        else
            $quoted_strings[] = $this->os_quote_char . $string_to_quote . $this->os_quote_char;
    }

    if ( is_array( $string_or_array ) )
        return $quoted_strings;
    else
        return $quoted_strings[0];
}

// Actual usage example:
if ( function_exists( 'exec' ) ){
    list( $user, $pwd, $host, $db, $file ) = $this->os_quote( array( DB_USER, DB_PASSWORD, DB_HOST, DB_NAME, $backup_file.'.sql' ) );

    $exec = $this->get_executable_path() . 'mysqldump -u' . $user . ' -p' . $pwd . ' -h' . $host . ' --result-file=' . $file .  ' ' . $db . ' 2>&1';
    exec ( $exec, $output, $return );
}
于 2013-08-14T18:55:05.690 回答
-1

很难猜测,你在说什么限制,但我怀疑其中一些是错误的

passthru('mysqldump -uddd -p"pass\'word$" ddd');

在 Windows 和 FreeBSD 下为我工作,以及在各自 shell 中的命令本身

于 2013-08-14T17:51:00.217 回答