WordPress Strips Backslashes From Post Content Saved With wp_insert_post: Use wp_slash

If code or text you save with wp_insert_post() loses its backslashes (\d+ turns into d+, C:\Users into C:Users), the cause is not your string. These functions unslash their input, so you have to pass slashed data. Wrap the data in wp_slash() before you save it.

The symptom

I hit this while saving posts with code blocks from PHP code on a WordPress site. Commands and regular expressions in the code blocks lost every backslash, so the published code was wrong without any error or warning.

Minimal reproduction

I saved the same string three ways and read it back. The test string was C:\Users\test \d+ \n end (24 characters). I ran it on a WordPress site that reported version 7.1.3, using a throw-away draft that I then moved to the trash.

FunctionWithout wp_slash()With wp_slash()
wp_insert_post()C:Userstest d+ n end (20 characters)Unchanged, 24 characters
wp_update_post()C:Userstest d+ n endUnchanged
update_post_meta()C:Userstest d+ n endUnchanged

Every backslash was removed when the data was not slashed, and every backslash was kept when I wrapped the same data in wp_slash().

The fix

$post_id = wp_insert_post( wp_slash( array(
    'post_title'   => 'My title',
    'post_content' => $content, // may contain backslashes
    'post_status'  => 'draft',
) ), true );

The same applies to updates and to post meta.

wp_update_post( wp_slash( array(
    'ID'           => $post_id,
    'post_content' => $content,
) ) );

update_post_meta( $post_id, 'my_key', wp_slash( $value ) );

Why it happens

  • The wp_insert_post reference page shows the source marking the data array as expected to be slashed and calling wp_unslash() on it before the database write. The same page notes that the wp_insert_post_data filter receives slashed data.
  • The wp_slash reference page says to use it when preparing data for core APIs that expect slashed data.
  • So if you pass raw data, wp_insert_post() unslashes it and the backslashes are consumed as escape characters.

Things to watch for

  • Apply wp_slash() to the whole array you pass, not to individual values you also use somewhere else. It returns a new value and does not change the original.
  • The data you read back with get_post() is already unslashed, so do not wrap it in wp_slash() just to display it.
  • Code blocks are the most common place to see it, because shell commands, regular expressions and Windows paths are full of backslashes.

What I did not test

  • I tested calls from PHP code only. I did not test the REST API, WP-CLI or the block editor.
  • I tested one WordPress version (7.1.3 as reported by the site).
  • I did not test what happens when data is slashed twice.

Sources: wp_insert_post and wp_slash in the WordPress developer reference.

Leave a Comment

Discover more from AI Brief

Subscribe now to keep reading and get access to the full archive.

Continue reading