I am trying to execute a few PostgreSQL DB commands from a web interface.
I use proc_open() to pipe to the Windows command prompt.
Because psql (and all other postgres command) do not accept the password as an option, I must send the password to the write stream.
The code below causes the browser to hang. Either the resource is not be created, or the password is not being piped properly. Any suggestions are welcome at this point.
$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);
}
[You’ll notice the crazy double-double-quoting in the command — this is apparently needed for windows for some reason.]
Work-arounds to this problem are welcome:
- I previously tried using system() and exec() but gave up since they don’t handle interactive prompt. Is there a better option in php for interactive?
- pg_query() is the main command for interacting with the postgres DB, but pg_dump and pg_restore operations are not supported. Is there another way to backup and restore from binary postgres .backup files that can be accomplished with php?
As @c-ramseyer suggested, messing around with simulating an interactive prompt via
proc_open()was a non-starter. PostgreSQL offers two methods to get around providing the password through the interactive prompt. Method (1) is to provide it as environment variables, as suggested by the other answer. Method (2) is to create apgpass.conffile in the DB user’s%appinfo%directiory. (To find that directory doecho %appinfo%from windows command prompt.) See postgresql for how to make this one-liner conf file. Neither of these methods worked for me, for reasons I still don’t understand.To solve the problem, I had to modify the
ph_hda.conffile (PostgreSQL Client Authentication Configuration File) to disable authentication. That file is located in thepostgresql/datadirectory. I commented out the 2 lines of default settings at the bottom and replaced them withNow if I call postgres from php I include the
--no-passwordoption and the sucker works. Note that this solution is not secure, and only makes sense in my case because it is being used for an internal company application, with machines running offline. This method should not be used for a production site, your DB will get hacked. Here’s the php code.It took me close to 2 weeks to solve this, so I hope it helps someone.