Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion features/server.feature
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@require-php-5.4
@require-php-7.2
Feature: Serve WordPress locally

Scenario: Vanilla install
Expand All @@ -16,6 +16,20 @@ Feature: Serve WordPress locally
And I run `cmp /tmp/license.txt license.txt`
Then STDOUT should be empty

Scenario: Passthrough arguments to PHP binary
Given a WP install
And a mem.php file:
"""
<?php echo ini_get('memory_limit'); ?>
"""
And I launch in the background `wp server --host=localhost --port=8182 -- -dmemory_limit=256M`

When I run `curl -sS localhost:8182/mem.php`
Then STDOUT should be:
"""
256M
"""

Scenario: Access wp-login.php
Given a WP install
And I launch in the background `wp server --host=localhost --port=8182`
Expand Down
3 changes: 0 additions & 3 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,3 @@ parameters:
scanFiles:
- vendor/php-stubs/wordpress-stubs/wordpress-stubs.php
treatPhpDocTypesAsCertain: false
ignoreErrors:
- identifier: missingType.parameter
- identifier: missingType.return
13 changes: 1 addition & 12 deletions server-command.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,4 @@
require_once $wpcli_server_autoloader;
}

WP_CLI::add_command(
'server',
'Server_Command',
array(
'before_invoke' => function () {
$min_version = '5.4';
if ( version_compare( PHP_VERSION, $min_version, '<' ) ) {
WP_CLI::error( "The `wp server` command requires PHP {$min_version} or newer." );
}
},
)
);
WP_CLI::add_command( 'server', 'Server_Command' );
44 changes: 35 additions & 9 deletions src/Server_Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ class Server_Command extends WP_CLI_Command {
* [--config=<file>]
* : Configure the server with a specific .ini file.
*
* [<passthrough>...]
* : Optional arguments to pass to the PHP binary. Any arguments after `--`
* will be passed through to the `php` command.
*
* ## EXAMPLES
*
* # Make the instance available on any address (with port 8080)
Expand All @@ -57,9 +61,20 @@ class Server_Command extends WP_CLI_Command {
* Document root is /
* Press Ctrl-C to quit.
*
* # Pass extra parameters to the PHP binary
* $ wp server --docroot=public -- -dzend_extension=xdebug.so
* PHP 7.4.0 Development Server started at Wed Nov 10 18:00:00 2025
* Listening on http://localhost:8080
* Document root is /var/www/public
* Press Ctrl-C to quit.
*
* @when before_wp_load
*
* @param array<string> $args Positional arguments passed through to the PHP binary.
* @param array{host: string, port: string, docroot?: string, config?: string} $assoc_args Associative arguments passed to the command.
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PHPDoc array-shape for $assoc_args doesn't match the actual values used in this method: port is an int by default, and both docroot and config can be false (see $defaults). With phpstan.neon.dist no longer suppressing missing types, this mismatch can lead to incorrect static analysis results. Update the PHPDoc to reflect the real types (e.g., port: int|string, docroot: string|false, config: string|false).

Suggested change
* @param array{host: string, port: string, docroot?: string, config?: string} $assoc_args Associative arguments passed to the command.
* @param array{host: string, port: int|string, docroot?: string|false, config?: string|false} $assoc_args Associative arguments passed to the command.

Copilot uses AI. Check for mistakes.
* @return void
*/
public function __invoke( $_, $assoc_args ) {
public function __invoke( $args, $assoc_args ) {
$defaults = array(
'host' => 'localhost',
'port' => 8080,
Expand All @@ -86,14 +101,25 @@ public function __invoke( $_, $assoc_args ) {
if ( ! file_exists( $router_path ) ) {
WP_CLI::error( "Couldn't find router.php" );
}
$cmd = Utils\esc_cmd(
'%s -S %s -t %s -c %s %s',
WP_CLI::get_php_binary(),
$assoc_args['host'] . ':' . $assoc_args['port'],
$docroot,
$assoc_args['config'],
Utils\extract_from_phar( $router_path )
);

// Build the command with passthrough arguments
$cmd_format = '%s';
$cmd_args = array( WP_CLI::get_php_binary() );

// Add passthrough arguments before the -S flag
if ( ! empty( $args ) ) {
$cmd_format .= str_repeat( ' %s', count( $args ) );
$cmd_args = array_merge( $cmd_args, $args );
}

// Add the server flags
$cmd_format .= ' -S %s -t %s -c %s %s';
$cmd_args[] = $assoc_args['host'] . ':' . $assoc_args['port'];
$cmd_args[] = $docroot;
$cmd_args[] = $assoc_args['config'];
$cmd_args[] = Utils\extract_from_phar( $router_path );

$cmd = Utils\esc_cmd( $cmd_format, ...$cmd_args );
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Utils\esc_cmd( $cmd_format, ...$cmd_args ) uses argument unpacking (...), which is only available starting with PHP 5.6. This package explicitly supports PHP 5.4+ (see the server-command.php version check / feature tag), so this will cause a parse error on PHP 5.4/5.5. Use a PHP 5.4-compatible approach to pass a dynamic argument list (e.g., call_user_func_array() with the format string prepended to the args array).

Suggested change
$cmd = Utils\esc_cmd( $cmd_format, ...$cmd_args );
$esc_cmd_args = $cmd_args;
array_unshift( $esc_cmd_args, $cmd_format );
$cmd = call_user_func_array( 'WP_CLI\Utils\esc_cmd', $esc_cmd_args );

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot This is incorrect. We require PHP 7.2+. Remove that check from server-command.php

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 820f666. Removed the before_invoke PHP 5.4 version check from server-command.php and updated the @require-php-5.4 Behat feature tag to @require-php-7.2 to match the actual requirement.


$descriptors = array( STDIN, STDOUT, STDERR );

Expand Down
Loading