]> git.openstreetmap.org Git - nominatim.git/blob - lib-php/Shell.php
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / lib-php / Shell.php
1 <?php
2
3 namespace Nominatim;
4
5 class Shell
6 {
7     public function __construct($sBaseCmd, ...$aParams)
8     {
9         if (!$sBaseCmd) {
10             throw new \Exception('Command missing in new() call');
11         }
12         $this->baseCmd = $sBaseCmd;
13         $this->aParams = array();
14         $this->aEnv = null; // null = use the same environment as the current PHP process
15
16         $this->stdoutString = null;
17
18         foreach ($aParams as $sParam) {
19             $this->addParams($sParam);
20         }
21     }
22
23     public function addParams(...$aParams)
24     {
25         foreach ($aParams as $sParam) {
26             if (isset($sParam) && $sParam !== null && $sParam !== '') {
27                 array_push($this->aParams, $sParam);
28             }
29         }
30         return $this;
31     }
32
33     public function addEnvPair($sKey, $sVal)
34     {
35         if (isset($sKey) && $sKey && isset($sVal)) {
36             if (!isset($this->aEnv)) {
37                 $this->aEnv = $_ENV;
38             }
39             $this->aEnv = array_merge($this->aEnv, array($sKey => $sVal), $_ENV);
40         }
41         return $this;
42     }
43
44     public function escapedCmd()
45     {
46         $aEscaped = array_map(function ($sParam) {
47             return $this->escapeParam($sParam);
48         }, array_merge(array($this->baseCmd), $this->aParams));
49
50         return join(' ', $aEscaped);
51     }
52
53     public function run($bExitOnFail = false)
54     {
55         $sCmd = $this->escapedCmd();
56         // $aEnv does not need escaping, proc_open seems to handle it fine
57
58         $aFDs = array(
59                  0 => array('pipe', 'r'),
60                  1 => STDOUT,
61                  2 => STDERR
62                 );
63         $aPipes = null;
64         $hProc = @proc_open($sCmd, $aFDs, $aPipes, null, $this->aEnv);
65         if (!is_resource($hProc)) {
66             throw new \Exception('Unable to run command: ' . $sCmd);
67         }
68
69         fclose($aPipes[0]); // no stdin
70
71         $iStat = proc_close($hProc);
72
73         if ($iStat != 0 && $bExitOnFail) {
74             exit($iStat);
75         }
76
77         return $iStat;
78     }
79
80     private function escapeParam($sParam)
81     {
82         return (preg_match('/^-*\w+$/', $sParam)) ? $sParam : escapeshellarg($sParam);
83     }
84 }