Add the possibility to bind ServeCommand to all interfaces#871
Add the possibility to bind ServeCommand to all interfaces#871
ServeCommand to all interfaces#871Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the ServeCommand developer server CLI to make it easier to bind to all network interfaces and to improve the startup output when running on a wildcard bind address.
Changes:
- Changed the default bind host from
127.0.0.1tolocalhost, and introducedLOOPBACK_HOSTS/WILDCARD_HOSTSconstants to classify hosts. - Added support for passing
--hostwithout a value to bind to all interfaces (intended to map to0.0.0.0). - When bound to a wildcard host, the command now prints “Remote address” URLs for detected local network IPv4 addresses.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Ignore parsing errors to handle passing `--host` without a value as a flag to bind to all interfaces | ||
| @$this->climate->arguments->parse(); | ||
|
|
||
| if ($this->climate->arguments->get('help')) { | ||
| $this->climate->usage($argv); | ||
| exit(0); | ||
| } | ||
|
|
||
| /** @var string */ | ||
| $host = $this->climate->arguments->get('host'); | ||
| $host = $this->climate->arguments->defined('host') | ||
| ? ($this->climate->arguments->get('host') ?: '0.0.0.0') // Bind to all interfaces if `--host` is passed without a value | ||
| : $this->host; |
There was a problem hiding this comment.
@ error suppression won’t prevent League\CLImate\Arguments::parse() from throwing InvalidArgumentException (as other commands already expect/catch), so --host passed without a value will likely still crash parsing. Also, parse() is called without $argv, meaning __invoke($argv) won’t be honored consistently. Consider passing $argv to parse() and handling the specific “missing value for --host” case via try/catch (or by pre-processing $argv to rewrite bare --host into --host=0.0.0.0), while still surfacing other parse errors to the user.
| if (($interfaces = net_get_interfaces()) === false) { | ||
| return []; | ||
| } | ||
|
|
||
| $localNetworkIps = []; | ||
|
|
||
| foreach ($interfaces as $interface) { | ||
| if (!isset($interface['unicast'])) { | ||
| continue; | ||
| } | ||
| foreach ($interface['unicast'] as $data) { | ||
| if ( | ||
| $data['family'] === AF_INET // IPv4 addresses only | ||
| && !in_array($data['address'], self::LOOPBACK_HOSTS, true) // Exclude loopback address | ||
| ) { |
There was a problem hiding this comment.
net_get_interfaces() (and the AF_INET constant) require the sockets extension; the project doesn’t declare ext-sockets in composer requirements, so this can fatally error on systems without it (especially when binding to a wildcard host, which is now a supported path). Please guard with function_exists('net_get_interfaces') / defined('AF_INET') (or extension_loaded('sockets')) and return an empty list (or a helpful message) when unavailable.
This pull request improves the usability of the
ServeCommandby making it easier to bind the server to all network interfaces and providing clearer feedback when running in this mode. The changes also enhance the output by listing accessible remote addresses when the server is bound to a wildcard host.Usability improvements:
'127.0.0.1'to'localhost', and new constantsLOOPBACK_HOSTSandWILDCARD_HOSTShave been introduced to clarify host types.--hostto be passed without a value, causing the server to bind to all interfaces (0.0.0.0).Output enhancements:
getLocalNetworkIps()was added to retrieve local network IP addresses, excluding loopback interfaces.