2012-05-16 68 views
0

交互式提示我试图执行从Web界面的几个的PostgreSQL数据库命令。 我使用proc_open()来管道到Windows命令提示符。 因为psql的(和所有其他Postgres的命令),不接受的密码作为一个选项,我必须将密码写流。 下面的代码会导致浏览器挂起。资源不被创建,或者密码没有正确传输。任何建议都欢迎在这一点上。与proc_open()上的psql查询

$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);       
} 

[。你会发现疯狂的两双,引用的命令 - 这显然需要某种原因窗口]

变通解决这个问题,欢迎:

  • 我以前使用的系统()和exec()尝试,但放弃了,因为他们不处理交互提示。在交互中使用php有没有更好的选择?
  • pg_query()是与Postgres数据库交互的主命令,但的pg_dump和pg_restore的操作不被支持。是否有另一种方法来备份和恢复二进制postgres .backup文件,可以用PHP来完成?
+1

您可以使用'PGPASSWORD'环境变量或'〜/ .pgpass'作为密码(http://stackoverflow.com/a/7184288/479863),但不了解PHP-isms。 –

回答

0

作为@ C-Ramseyer一派建议,通过proc_open()模拟交互式提示是由非起动器周围搞乱。 PostgreSQL提供了两种方法来通过交互提示来避开密码。方法(1)将其作为环境变量提供,如其他答案所示。方法(2)是在DB用户的%appinfo% directiory中创建一个pgpass.conf文件。 (要在Windows命令提示符下找到该目录,请执行echo %appinfo%。)请参阅postgresql以了解如何创建此单线程conf文件。这些方法都不适用于我,原因我仍然不明白。

为了解决这个问题,我不得不修改ph_hda.conf文件(PostgreSQL的客户端身份验证配置文件)来禁用验证。该文件位于postgresql/data目录中。我注释掉两行的默认设置在底部,并与

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

代替他们现在如果我叫的Postgres从PHP我包括--no-password选项和吸盘工作。请注意,这个解决方案并不安全,只对我而言有意义,因为它用于内部公司应用程序,并且机器脱机运行。此方法不应用于生产站点,您的数据库将被黑客入侵。这里是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个星期来解决这个问题,所以我希望它能帮助别人。

3

不要乱搞密码提示,最好把条目放入%APPDATA%\postgresql\pgpass.conf。格式是

hostname:port:database:username:password 

确保选择运行的网络服务器进程的用户的%APPDATA%

如果你确实想要与提示进行交互,你可以试试Expect库,人们经常使用这个库来做这样的工作...免责声明:我从来没有在Windows上使用它,也不知道它有多好那里,或者真的有必要。也许你的fwrite只是缺少一个终止的换行符。

+0

该解决方案让我有部分途径,但随后Windows DB套接字开始返回错误。查看我的答案,找出最终解决问题的解决方案。 –