ServeController.php
3.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\console\controllers;
use Yii;
use yii\console\Controller;
use yii\helpers\Console;
/**
* Runs PHP built-in web server
*
* In order to access server from remote machines use 0.0.0.0:8000. That is especially useful when running server in
* a virtual machine.
*
* @author Alexander Makarov <sam@rmcreative.ru>
* @since 2.0.7
*/
class ServeController extends Controller
{
const EXIT_CODE_NO_DOCUMENT_ROOT = 2;
const EXIT_CODE_NO_ROUTING_FILE = 3;
const EXIT_CODE_ADDRESS_TAKEN_BY_ANOTHER_SERVER = 4;
const EXIT_CODE_ADDRESS_TAKEN_BY_ANOTHER_PROCESS = 5;
/**
* @var int port to serve on.
*/
public $port = 8080;
/**
* @var string path or [path alias](guide:concept-aliases) to directory to serve
*/
public $docroot = '@app/web';
/**
* @var string path to router script.
* See https://secure.php.net/manual/en/features.commandline.webserver.php
*/
public $router;
/**
* Runs PHP built-in web server
*
* @param string $address address to serve on. Either "host" or "host:port".
*
* @return int
*/
public function actionIndex($address = 'localhost')
{
$documentRoot = Yii::getAlias($this->docroot);
if (strpos($address, ':') === false) {
$address = $address . ':' . $this->port;
}
if (!is_dir($documentRoot)) {
$this->stdout("Document root \"$documentRoot\" does not exist.\n", Console::FG_RED);
return self::EXIT_CODE_NO_DOCUMENT_ROOT;
}
if ($this->isAddressTaken($address)) {
$this->stdout("http://$address is taken by another process.\n", Console::FG_RED);
return self::EXIT_CODE_ADDRESS_TAKEN_BY_ANOTHER_PROCESS;
}
if ($this->router !== null && !file_exists($this->router)) {
$this->stdout("Routing file \"$this->router\" does not exist.\n", Console::FG_RED);
return self::EXIT_CODE_NO_ROUTING_FILE;
}
$this->stdout("Server started on http://{$address}/\n");
$this->stdout("Document root is \"{$documentRoot}\"\n");
if ($this->router) {
$this->stdout("Routing file is \"$this->router\"\n");
}
$this->stdout("Quit the server with CTRL-C or COMMAND-C.\n");
passthru('"' . PHP_BINARY . '"' . " -S {$address} -t \"{$documentRoot}\" $this->router");
}
/**
* @inheritdoc
*/
public function options($actionID)
{
return array_merge(parent::options($actionID), [
'docroot',
'router',
'port',
]);
}
/**
* @inheritdoc
* @since 2.0.8
*/
public function optionAliases()
{
return array_merge(parent::optionAliases(), [
't' => 'docroot',
'p' => 'port',
'r' => 'router',
]);
}
/**
* @param string $address server address
* @return bool if address is already in use
*/
protected function isAddressTaken($address)
{
list($hostname, $port) = explode(':', $address);
$fp = @fsockopen($hostname, $port, $errno, $errstr, 3);
if ($fp === false) {
return false;
}
fclose($fp);
return true;
}
}