0

WebインターフェイスからいくつかのPostgreSQLDBコマンドを実行しようとしています。proc_open()を使用してWindowsコマンドプロンプトにパイプします。psql(および他のすべてのpostgresコマンド)はパスワードをオプションとして受け入れないため、パスワードを書き込みストリームに送信する必要があります。以下のコードにより、ブラウザがハングします。リソースが作成されていないか、パスワードが適切にパイプされていません。この時点でどんな提案も歓迎します。

$cmd = '""C:\\Program files\\PostgreSQL\\9.0\\bin\\psql.exe" --host localhost --port 5432 -U postgres --dbname $database_name --command "$query""';
$p=proc_open($cmd, 
             array(array("pipe","r"), array("pipe","w"), array("pipe","w")), 
             $pipes);
if (is_resource($p)){
  fwrite($pipes[0],"mypassword");
  fclose($pipes[0]);
  proc_terminate($p);
  proc_close($p);                         
}

[コマンド内のクレイジーな二重引用符に気付くでしょう。これは、何らかの理由でWindowsに必要なようです。]

この問題の回避策は大歓迎です。

  • 以前にsystem()とexec()を使用しようとしましたが、インタラクティブプロンプトを処理しないため、あきらめました。インタラクティブのためのphpのより良いオプションはありますか?
  • pg_query()はpostgres DBと対話するためのメインコマンドですが、pg_dumpおよびpg_restore操作はサポートされていません。phpで実行できるバイナリpostgres.backupファイルからバックアップおよび復元する別の方法はありますか?
4

2 に答える 2

3

パスワード プロンプトをいじらないでください%APPDATA%\postgresql\pgpass.conf。フォーマットは

hostname:port:database:username:password

%APPDATA%Web サーバー プロセスを実行しているユーザーの を必ず選択してください。

本当にプロンプ​​トと対話することに設定されている場合は、そのようなタスクによく使用されるExpectライブラリを試すことができます...本当に必要です。たぶん、あなたの fwrite には終了改行がありません。

于 2012-05-16T20:54:33.660 に答える
0

@ c-ramseyerが示唆したように、を介してインタラクティブなプロンプトをシミュレートすることをいじくり回すことは、proc_open()初心者ではありませんでした。PostgreSQLは、インタラクティブプロンプトを介してパスワードを提供することを回避するための2つの方法を提供します。方法(1)は、他の回答で示唆されているように、環境変数として提供することです。方法(2)はpgpass.conf、DBユーザーのディレクトリにファイルを作成することです%appinfo%。(そのディレクトリを見つけるにはecho %appinfo%、Windowsコマンドプロンプトから実行します。)このワンライナーconfファイルの作成方法については、postgresqlを参照してください。私はまだ理解していない理由で、これらの方法のどちらも私にはうまくいきませんでした。

この問題を解決するには、ph_hda.confファイル(PostgreSQLクライアント認証構成ファイル)を変更して認証を無効にする必要がありました。そのファイルはpostgresql/dataディレクトリにあります。下部にある2行のデフォルト設定をコメントアウトして、次のように置き換えました。

#TYPE  DATABASE     USER        CIDR-ADDRESS       METHOD
host    all         all         127.0.0.1/32       trust     
host    all         all         ::1/128            trust

phpからpostgresを呼び出すと、--no-passwordオプションが含まれ、吸盤が機能します。このソリューションは安全ではなく、私の場合にのみ意味があることに注意してください。これは、マシンがオフラインで実行されている社内アプリケーションに使用されているためです。この方法は本番サイトには使用しないでください。DBがハッキングされます。これがphpコードです。

$commande_restore = '""'.$postgres_bin_directory.'pg_restore" --host 127.0.0.1 --port 5432 -U postgres --no-password  -d '.$database_name.' '.$restore_file.'"';
$this->execute($commande_restore);      

function execute($cmd, $env = null){
  $proc=proc_open($cmd,array(0=>array('pipe','r'),1=>array('pipe','w'),2=>array('pipe','w')),$pipes, null, $env = null);
  //fwrite($pipes[0],$stdin);  //add to argument if you want to pass stdin                  
  fclose($pipes[0]);
  $stdout=stream_get_contents($pipes[1]);        fclose($pipes[1]);
  $stderr=stream_get_contents($pipes[2]);        fclose($pipes[2]);
  $return=proc_close($proc);    
  return array( 'stdout'=>$stdout, 'stderr'=>$stderr, 'return'=>$return );
}

これを解決するのに2週間近くかかったので、誰かに役立つことを願っています。

于 2012-05-18T18:44:56.277 に答える