Setting the file. One moment.
Subchapter 12.3
references/wordpress-annotations.mdMarkdown3 KBView on GitHub
These patterns help PHPStan understand WordPress code where runtime behavior and dynamic typing make inference difficult.
PHPStan cannot infer valid request parameters from REST API schemas. Provide explicit type hints for request params.
/**
* Handle REST API request.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Response object on success, error on failure.
*
* @phpstan-param WP_REST_Request<array{
* post?: int,
* orderby?: string,
* meta_key?: string,
* per_page?: int,
* status?: array<string>
* }> $request
*/
public function get_items( $request ) {
$post_id = $request->get_param( 'post' );
// PHPStan now knows $post_id is int|null.
}For complex schemas, define reusable types.
/**
* @phpstan-type PostRequestParams array{
* title?: string,
* content?: string,
* status?: 'publish'|'draft'|'private',
* meta?: array<string, mixed>
* }
*
* @phpstan-param WP_REST_Request<PostRequestParams> $request
*//**
* Handle status transitions.
*
* @param string $new_status
* @param string $old_status
* @param WP_Post $post
*/
function handle_transition( string $new_status, string $old_status, WP_Post $post ): void {
// ...
}
add_action( 'transition_post_status', 'handle_transition', 10, 3 );/**
* @return array<WP_Post> WP_Post objects.
*/
function get_custom_posts(): array {
$posts = get_posts( [ 'post_type' => 'custom_type', 'numberposts' => -1 ] );
return $posts;
}
/**
* @return array<object{id: int, name: string}> Database results.
*/
function get_user_data(): array {
global $wpdb;
$results = $wpdb->get_results( "SELECT id, name FROM users", OBJECT );
return $results ?: [];
}Docblocks for apply_filters() and do_action() are validated. The type of the first @param is definitive.
If a third party returns the wrong type for a filter, a PHPStan error is expected and does not require defensive code.
/**
* Allows hooking into formatting of the price.
*
* @param string $formatted The formatted price.
* @param float $price The raw price.
* @param string $locale Locale to localize pricing display.
* @param string $currency Currency symbol.
*/
return apply_filters( 'autoscout_vehicle_price_formatted', $formatted, $price, $locale, $currency );/**
* Process a scheduled email.
*
* @param array{user_id: int, email: string, data: array<string, mixed>} $args
*/
function process_scheduled_email( array $args ): void {
$user_id = $args['user_id'];
// ...
}
as_schedule_single_action(
time() + 3600,
'process_scheduled_email',
[
'user_id' => 123,
'email' => 'user@example.com',
'data' => [ 'key' => 'value' ],
]
);