-1

コマンドを自動化するための PHP スクリプトを作成していますmysqldump。私が選択した方法は、を使用してexec( $exec_string . ' 2>&1' )います。このスクリプトは、Windows および *nix プラットフォームで動作する必要があります。

悲しいことに、一部のパスワードには恐ろしい $ 記号が含まれているため、「-p'passwordcontaining$」を引用符で囲む必要があります。

これまでに指摘した課題は次のとおりです。

  • *nix では、一重引用符を使用する必要があります。そうしないと、$ が変数として展開されます。
  • Windows では、一重引用符は文字どおりに扱われるため、二重引用符を使用する必要があります。
  • $ のエスケープはオプションではありません。Windows ではバックスラッシュは二重引用符 (\") の前にある場合にのみエスケープ文字として解釈されるため、\$ は文字どおりに解釈されます。
  • OSを確実に検出して、一重引用符と二重引用符を「インタラクティブに」切り替える方法がわかりません。

クロスプラットフォームで機能する、見逃しているトリックはありますか?

4

3 に答える 3

0

私が最終的に採用したアプローチに夢中になっているわけではありません (MySQLDump クラスは exec() よりも堅牢なアプローチのようです)。

OS の検出はしたくありませんでしたが、一見したところ、引用符の解釈の問題を解決できるようには見えません。幸いなことに、OS の検出は比較的簡単です。たとえば、「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、およびそれぞれのシェルでのコマンド自体で私のために働いた

于 2013-08-14T17:51:00.217 に答える