1: <?php
2:
3: /**
4: * A utility class controlling the build-in HTTP server in PHP
5: *
6: * @package alpha::util
7: * @since 1.2.2
8: * @author John Collins <dev@alphaframework.org>
9: * @version $Id: AlphaPHPServerUtils.inc 1745 2014-03-29 15:19:05Z alphadevx $
10: * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
11: * @copyright Copyright (c) 2014, John Collins (founder of Alpha Framework).
12: * All rights reserved.
13: *
14: * <pre>
15: * Redistribution and use in source and binary forms, with or
16: * without modification, are permitted provided that the
17: * following conditions are met:
18: *
19: * * Redistributions of source code must retain the above
20: * copyright notice, this list of conditions and the
21: * following disclaimer.
22: * * Redistributions in binary form must reproduce the above
23: * copyright notice, this list of conditions and the
24: * following disclaimer in the documentation and/or other
25: * materials provided with the distribution.
26: * * Neither the name of the Alpha Framework nor the names
27: * of its contributors may be used to endorse or promote
28: * products derived from this software without specific
29: * prior written permission.
30: *
31: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
32: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
33: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
34: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35: * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
36: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
39: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
42: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44: * </pre>
45: *
46: */
47: class AlphaPHPServerUtils {
48:
49: /**
50: * Starts a new HTTP server at the hostname and port provided, and returns the process ID (PID) of
51: * the service if it was started successfully.
52: *
53: * @param string $host The hostname or IP address
54: * @param int $port The port number to use
55: * @param string $docRoot The file path to directory containing the documents we want to serve
56: * @return int The PID of the new server
57: * @throws AlphaException
58: */
59: public static function start($host, $port, $docRoot) {
60: // we are on Windows
61: if (mb_strtoupper(mb_substr(PHP_OS, 0, 3)) === 'WIN') {
62: // Command that starts the built-in web server
63: $command = sprintf(
64: 'php -S %s:%d -t %s',
65: $host,
66: $port,
67: $docRoot
68: );
69:
70: $descriptorspec = array (
71: 0 => array("pipe", "r"),
72: 1 => array("pipe", "w"),
73: );
74:
75: // Execute the command and store the process ID of the parent
76: $prog = proc_open($command, $descriptorspec, $pipes, '.', NULL);
77: $ppid = proc_get_status($prog)['pid'];
78:
79: // this gets us the process ID of the child (i.e. the server we just started)
80: $output = array_filter(explode(" ", shell_exec("wmic process get parentprocessid,processid | find \"$ppid\"")));
81: array_pop($output);
82: $pid = end($output);
83: }else{ // we are on Linux
84: // Command that starts the built-in web server
85: $command = sprintf(
86: 'php -S %s:%d -t %s >/dev/null 2>&1 & echo $!',
87: $host,
88: $port,
89: $docRoot
90: );
91:
92: // Execute the command and store the process ID
93: $output = array();
94: exec($command, $output);
95: $pid = (int) $output[0];
96: }
97:
98: if(!isset($pid))
99: throw new AlphaException("Could not start the build-in PHP server [$host:$port] using the doc root [$docRoot]");
100: else
101: return $pid;
102:
103: }
104:
105: /**
106: * Stops the server running locally under the process ID (PID) provided.
107: *
108: * @param int $PID The PID of the running server we want to stop
109: */
110: public static function stop($PID) {
111: // we are on Windows
112: if (mb_strtoupper(mb_substr(PHP_OS, 0, 3)) === 'WIN') {
113: exec("taskkill /F /pid $PID");
114: }else{ // we are on Linux
115: exec("kill -9 $PID");
116: }
117: }
118:
119: /**
120: * CHecks to see if there is a server running locally under the process ID (PID) provided.
121: *
122: * @param int $PID The PID of the running server we want to check
123: * @return bool True if there is a server process running under the PID, false otherwise
124: */
125: public static function status($PID) {
126: $output = array();
127: // we are on Windows
128: if (mb_strtoupper(mb_substr(PHP_OS, 0, 3)) === 'WIN') {
129: exec("tasklist /fi \"PID eq $PID\"", $output);
130:
131: if(isset($output[0]) && $output[0] == 'INFO: No tasks are running which match the specified criteria.')
132: return false;
133: else
134: return true;
135: }else{ // we are on Linux
136: exec("ps -ef | grep $PID | grep -v grep", $output);
137:
138: if(count($output) == 0)
139: return false;
140: else
141: return true;
142: }
143: }
144:
145: }
146:
147: ?>