post_password_required( int|WP_Post|null $post = null ): bool
- Since
- 2.7.0
- Source
wp-includes/post-template.php:879
Checks whether a post is password protected and whether the current visitor has already supplied the correct password. It accepts a post ID, WP_Post object, or null to use the global $post, and its result runs through the 'post_password_required' filter before being returned. It does not check user capabilities, so a logged-in administrator without the password cookie still gets true unless you filter the result yourself.
Compatibility
- WordPress
- since 2.7.0
- PHP
- 7.4–8.6-dev
- 6.7.7
- 6.8.8
- 6.9.7
- 7.0.4
- 7.1.0
Present in every tracked release (6.7.7 to 7.1.0), and compiles on PHP 7.4 through 8.6-dev.
Parameters
$postint|WP_Post|nulloptional- An optional post. Global $post used if not provided.Default:
null
Return value
bool- false if a password is not required or the correct password cookie is present, true otherwise.
Code examples
Every example is editable and runs in a real WordPress booted in your browser by WordPress Playground. Press Run, then edit the code: clicking away re-runs it. Nothing is sent anywhere until you do.
Hide post content until the correct password is entered
A single-post template loop that checks the current post in the Loop before printing its content.
$query = new WP_Query( array( 'p' => 2, 'post_type' => 'post' ) );
while ( $query->have_posts() ) :
$query->the_post();
if ( post_password_required() ) {
echo esc_html( 'This post is password protected. Enter the password to view it.' );
} else {
echo esc_html( 'Title: ' . get_the_title() );
}
endwhile;
wp_reset_postdata();Calling post_password_required() with no argument only works after the_post() has set the global $post inside the loop.
Let editors bypass the password prompt on protected posts
A filter on 'post_password_required' that skips the password check for anyone who can edit posts.
add_filter(
'post_password_required',
function ( $required, $post ) {
if ( current_user_can( 'edit_posts' ) ) {
return false;
}
return $required;
},
10,
2
);
$post = get_post( 3 );
$required = post_password_required( $post );
printf(
'Password required for post %d: %s',
esc_html( $post->ID ),
esc_html( $required ? 'yes' : 'no' )
);The logged-in administrator in the sandbox has no 'wp-postpass_' cookie, so without the filter this would print 'yes'.
Common problems and fixes · 4
- Why does post_password_required() still return true for a logged-in administrator?
- Why does passing an invalid post ID silently return false instead of an error?
- I changed post_password directly with a raw SQL query, why doesn't the function see the change?
- My 'post_password_required' filter callback assumes $required starts as false, why does it misbehave?
Why does post_password_required() still return true for a logged-in administrator?
Why does passing an invalid post ID silently return false instead of an error?
I changed post_password directly with a raw SQL query, why doesn't the function see the change?
My 'post_password_required' filter callback assumes $required starts as false, why does it misbehave?
Alternatives and related functions
get_the_password_form- When you need to render the actual password prompt markup to show visitors instead of just testing whether one is needed.
current_user_can- When access should depend on the visitor's role or capability rather than on whether they know the post password.
wp_check_password- When you're validating a plaintext password against a stored hash outside the post-password cookie flow, such as in a custom login form.
get_post- When you only need the post object itself, including its post_password field, without running the cookie check.
Performance profile
How much work a call to post_password_required() does, and what it touches: the algorithmic scaling, the Zend instruction count per call across PHP versions, the hooks it hands control to, and the core code that calls it. Measured from the compiled opcodes, not a stopwatch, so every number is identical on any machine running the same PHP version, and every function in core is ranked by cost.
- Cost class
- Heavy
- Scaling
- Constant
- Instructions
- 13–47
- Plugin surface
- 1 hook
- Called by
- 37
Reaches the database via get_post().
No loop in the body: the same number of instructions runs whatever you pass in.
Executed per call on PHP 8.5, depending on the branch taken. The body compiles to 61.
Third-party callbacks on 'post_password_required' run inside this call, and their cost is not bounded by anything here.
37 places in core call this, so the cost is paid more often than your own code shows.
What it touches
- querycontent query
get_post()called directly - hookthird-party callbacks
apply_filters()called directly
Further down the call graph this can also reach option, cache, serialize and transient. Those are the worst case, several calls deep and usually down an error path, not what a normal call pays.
What one call costs · 3 distinct outcomes
One number would be a lie: the work depends on which branch runs. These are every distinct cost post_password_required() can have, taken from its control-flow graph on PHP 8.5.
| When | Instructions | Calls it makes |
|---|---|---|
| always | 13–18 | get_post(), apply_filters() |
!empty($post) && isset($value) && !$hash | 41 | get_post(), wp_unslash(), apply_filters() |
!empty($post) && isset($value) && $hash | 47 | get_post(), wp_unslash(), ->CheckPassword(), apply_filters() |
Across PHP versions
| PHP | Compiled | Executed | Branches | Notes |
|---|---|---|---|---|
| 8.6-dev | 61 | 13–47 | 3 | |
| 8.5 | 61 | 13–47 | 3 | |
| 8.4 | 61 | 13–47 | 3 | 3 fewer instructions than PHP 8.3 |
| 8.3 | 64 | 13–50 | 3 | |
| 8.2 | 64 | 13–50 | 3 | |
| 8.1 | 64 | 13–50 | 3 | |
| 7.4 | 64 | 13–50 | 3 |
An instruction is not a fixed amount of time, so a matching count is not necessarily the same speed; what it rules out is a difference in the work itself.
Hooks and filters fired · 3
3 hooks fire while post_password_required() runs, in this order:
- apply_filters( post_password_required )filterline 884 (+5 into the body)
Filters whether a post requires the user to supply a password.
- apply_filters( post_password_required )filterline 889 (+10 into the body)
Filters whether a post requires the user to supply a password.
- apply_filters( post_password_required )filterline 911 (+32 into the body)
Filters whether a post requires the user to supply a password.
Uses · 5
- get_post()Retrieves post data given a post ID or post object.
- apply_filters()Calls the callback functions that have been added to a filter hook.
- wp_unslash()Removes slashes from a string or recursively removes slashes from strings within an array.
- str_starts_with()Polyfill for `str_starts_with()` function added in PHP 8.0.
- PasswordHash::__construct()
Used by · 37
- Twenty_Fourteen_Ephemera_Widget::widget()Output the HTML for this widget.
- WP_Comments_List_Table::single_row()
- WP_List_Table::comments_bubble()Displays a comment count bubble.
- WP_Posts_List_Table::column_title()Handles the title column output.
- WP_REST_Comments_Controller::check_read_post_permission()Checks if the post can be read.
- WP_REST_Posts_Controller::prepare_item_for_database()Prepares a single post for create or update.
- WP_REST_Posts_Controller::prepare_item_for_response()Prepares a single post output for response.
- _block_bindings_post_meta_get_value()Gets value for Post Meta source.
- atom_enclosure()Displays the atom enclosure for the current post.
- comments_popup_link()Displays the link to the comments for the current post ID.
- gallery_shortcode()Builds the Gallery shortcode output.
- get_comment_excerpt()Retrieves the excerpt of the given comment.
Show all 37
- get_post_class()Retrieves an array of the class names for the post container element.
- get_the_content()Retrieves the post content.
- get_the_excerpt()Retrieves the post excerpt.
- render_block_core_comment_template()Renders the `core/comment-template` block on the server.
- render_block_core_comments_pagination()Renders the `core/comments-pagination` block on the server.
- render_block_core_comments_title()Renders the `core/comments-title` block on the server.
- render_block_core_footnotes()Renders the `core/footnotes` block on the server.
- render_block_core_latest_posts()Renders the `core/latest-posts` block on server.
- render_block_core_post_comments_form()Renders the `core/post-comments-form` block on the server.
- rss_enclosure()Displays the rss enclosure for the current post.
- twenty_twenty_one_can_show_post_thumbnail()Determines if post thumbnail can be displayed.
- twentyfifteen_entry_meta()Prints HTML with meta information for the categories, tags.
- twentyfifteen_post_thumbnail()Display an optional post thumbnail.
- twentyfourteen_post_classes()Extend the default WordPress post classes.
- twentyfourteen_post_thumbnail()Display an optional post thumbnail.
- twentynineteen_can_show_post_thumbnail()Determines if post thumbnail can be displayed.
- twentynineteen_comment_count()Prints HTML with the comment count for the current post.
- twentysixteen_entry_meta()Prints HTML with meta information for the categories, tags.
- twentysixteen_post_thumbnail()Displays an optional post thumbnail.
- twentytwenty_body_classes()Adds conditional body classes.
- twentytwenty_get_post_meta()Retrieves the post meta.
- wp_dashboard_recent_comments()Show Comments section.
- wp_handle_comment_submission()Handles the submission of a comment, usually posted to wp-comments-post.php via a comment form.
- wp_playlist_shortcode()Builds the Playlist shortcode output.
- wp_xmlrpc_server::wp_newComment()Creates a new comment.
Source code
function post_password_required( $post = null ) { $post = get_post( $post ); if ( empty( $post->post_password ) ) { /** This filter is documented in wp-includes/post-template.php */ return apply_filters( 'post_password_required', false, $post ); } if ( ! isset( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ) ) { /** This filter is documented in wp-includes/post-template.php */ return apply_filters( 'post_password_required', true, $post ); } require_once ABSPATH . WPINC . '/class-phpass.php'; $hasher = new PasswordHash( 8, true ); $hash = wp_unslash( $_COOKIE[ 'wp-postpass_' . COOKIEHASH ] ); if ( ! str_starts_with( $hash, '$P$B' ) ) { $required = true; } else { $required = ! $hasher->CheckPassword( $post->post_password, $hash ); } /** * Filters whether a post requires the user to supply a password. * * @since 4.7.0 * * @param bool $required Whether the user needs to supply a password. True if password has not been * provided or is incorrect, false if password has been supplied or is not required. * @param WP_Post $post Post object. */ return apply_filters( 'post_password_required', $required, $post );}Changelog
Introduced in 2.7.0. Unchanged from 6.7.7 through 7.1.0.
Signature, return type and hooks compared across 5 parsed releases.
About this page
- Parsed data
- Generated from the wordpress-develop 6.8.8 tag, from
src/wp-includes/post-template.php, and regenerated for each WordPress release so it tracks the code rather than a snapshot of it. - Corrections
- Something wrong on this page? Report it and it gets fixed in the next regeneration.