PHP 8.0: Built-in web server supports dynamic port selection
The built-in server in PHP 8.0 supports dynamic port selection.
php -S localhost:0
With the port 0
specified, an unused port is picked by the operating system, and the built-in web server will be bound to that port number.
> php -S localhost:0
[Thu Oct 1 02:35:59 2020] PHP 8.0.0 Development Server (http://localhost:11583) started
For every run of this command, a random unused port will be selected by the operating system. Note that this behavior can be different from one operating system to another.
Obtain the allocated port number
To obtain the selected port number within the application being run, use $_SERVER['SERVER_PORT']
super global variable.
Port 0
Port 0 is an IANA reserved port number. While not a standard, many operating systems support binding a service to port 0, which requests the next available port from the system. This functionality is available in most operating systems TCP/IP stacks, including Windows and Linux.
PHP historically disallowed binding to port 0, but from PHP 8.0 and forward, it is now possible to specify port 0 for the built-in server, and it will use an available unoccupied non-system (> 1024) port number.
In other languages
Built-in servers such as Node JS server and Python server already support this pattern to pick a port number dynamically.
- Python:
sock.bind(('',0))
- Node JS:
server.listen(0, 127.0.0.1)
- Rust:
TcpListener::bind("127.0.0.1:0").unwrap()
Backwards Compatibility Impact
"Binding" to port 0 is not allowed in PHP versions prior to 8.0, and result in an error:
> php -S localhost:0
Invalid address: localhost:0
Sockets extension can bind to port 0 in all PHP versions, and it might help to find a free port, after which it can be used to start a PHP server.
$socket = \socket_create_listen(0);
\socket_getsockname($socket, $addr, $port);
\socket_close($socket);
echo $port;
Note that in PHP 8, socket
extension uses \Socket
class objects instead of resource
data types for its primary data type.