Title: wp_mkdir_p
Published: April 25, 2014
Last modified: February 24, 2026

---

# wp_mkdir_p( string $target ): bool

## In this article

 * [Description](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#description)
 * [Parameters](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#parameters)
 * [Return](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#return)
 * [Source](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#source)
 * [Related](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#changelog)
 * [User Contributed Notes](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#user-contributed-notes)

[ Back to top](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#wp--skip-link--target)

Recursive directory creation based on full path.

## 󠀁[Description](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#description)󠁿

Will attempt to set permissions on folders.

## 󠀁[Parameters](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#parameters)󠁿

 `$target`stringrequired

Full path to attempt to create.

## 󠀁[Return](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#return)󠁿

 bool Whether the path was created. True if path already exists.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#source)󠁿

    ```php
    function wp_mkdir_p( $target ) {
    	$wrapper = null;

    	// Strip the protocol.
    	if ( wp_is_stream( $target ) ) {
    		list( $wrapper, $target ) = explode( '://', $target, 2 );
    	}

    	// From php.net/mkdir user contributed notes.
    	$target = str_replace( '//', '/', $target );

    	// Put the wrapper back on the target.
    	if ( null !== $wrapper ) {
    		$target = $wrapper . '://' . $target;
    	}

    	/*
    	 * Safe mode fails with a trailing slash under certain PHP versions.
    	 * Use rtrim() instead of untrailingslashit to avoid formatting.php dependency.
    	 */
    	$target = rtrim( $target, '/' );
    	if ( empty( $target ) ) {
    		$target = '/';
    	}

    	if ( file_exists( $target ) ) {
    		return @is_dir( $target );
    	}

    	// Do not allow path traversals.
    	if ( str_contains( $target, '../' ) || str_contains( $target, '..' . DIRECTORY_SEPARATOR ) ) {
    		return false;
    	}

    	// We need to find the permissions of the parent folder that exists and inherit that.
    	$target_parent = dirname( $target );
    	while ( '.' !== $target_parent && ! is_dir( $target_parent ) && dirname( $target_parent ) !== $target_parent ) {
    		$target_parent = dirname( $target_parent );
    	}

    	// Get the permission bits.
    	$stat = @stat( $target_parent );
    	if ( $stat ) {
    		$dir_perms = $stat['mode'] & 0007777;
    	} else {
    		$dir_perms = 0777;
    	}

    	if ( @mkdir( $target, $dir_perms, true ) ) {

    		/*
    		 * If a umask is set that modifies $dir_perms, we'll have to re-set
    		 * the $dir_perms correctly with chmod()
    		 */
    		if ( ( $dir_perms & ~umask() ) !== $dir_perms ) {
    			$folder_parts = explode( '/', substr( $target, strlen( $target_parent ) + 1 ) );
    			for ( $i = 1, $c = count( $folder_parts ); $i <= $c; $i++ ) {
    				chmod( $target_parent . '/' . implode( '/', array_slice( $folder_parts, 0, $i ) ), $dir_perms );
    			}
    		}

    		return true;
    	}

    	return false;
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-includes/functions.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/functions.php#L2043)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/functions.php#L2043-L2108)

## 󠀁[Related](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_is_stream()](https://developer.wordpress.org/reference/functions/wp_is_stream/)`wp-includes/functions.php` |

Tests if a given path is a stream URL

  |

| Used by | Description | 
| [WP_Image_Editor_Imagick::write_image()](https://developer.wordpress.org/reference/classes/wp_image_editor_imagick/write_image/)`wp-includes/class-wp-image-editor-imagick.php` |

Writes an image to a file or stream.

  | 
| [wp_privacy_generate_personal_data_export_file()](https://developer.wordpress.org/reference/functions/wp_privacy_generate_personal_data_export_file/)`wp-admin/includes/privacy-tools.php` |

Generate the personal data export file.

  | 
| [_copy_image_file()](https://developer.wordpress.org/reference/functions/_copy_image_file/)`wp-admin/includes/image.php` |

Copies an existing image file.

  | 
| [wp_crop_image()](https://developer.wordpress.org/reference/functions/wp_crop_image/)`wp-admin/includes/image.php` |

Crops an image to a given size.

  | 
| [wp_upload_bits()](https://developer.wordpress.org/reference/functions/wp_upload_bits/)`wp-includes/functions.php` |

Creates a file in the upload folder with given content.

  | 
| [wp_upload_dir()](https://developer.wordpress.org/reference/functions/wp_upload_dir/)`wp-includes/functions.php` |

Returns an array containing the current upload directory’s path and URL.

  | 
| [WP_Image_Editor::make_image()](https://developer.wordpress.org/reference/classes/wp_image_editor/make_image/)`wp-includes/class-wp-image-editor.php` |

Either calls editor’s save function or handles file as a stream.

  |

[Show 2 more](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#)

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#changelog)󠁿

| Version | Description | 
| [2.0.1](https://developer.wordpress.org/reference/since/2.0.1/) | Introduced. |

## 󠀁[User Contributed Notes](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#user-contributed-notes)󠁿

 1.   [Skip to note 4 content](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#comment-content-1355)
 2.    [Codex](https://profiles.wordpress.org/codex/)  [  10 years ago  ](https://developer.wordpress.org/reference/functions/wp_mkdir_p/#comment-1355)
 3.  [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%23comment-1355)
     Vote results for this note: 1[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%23comment-1355)
 4.  **Basic Example**
 5.      ```php
         if ( wp_mkdir_p( '/a/really/deep/sub/directory' ) ) {
           echo __( 'It worked! Now look for a directory named "a".', 'textdomain' );
         }
         ```
     
 6.   [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%3Freplytocom%3D1355%23feedback-editor-1355)
 7.   [Skip to note 5 content](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#comment-content-5059)
 8.    [JCV](https://profiles.wordpress.org/psykonevro/)  [  5 years ago  ](https://developer.wordpress.org/reference/functions/wp_mkdir_p/#comment-5059)
 9.  [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%23comment-5059)
     Vote results for this note: 1[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%23comment-5059)
 10. Should you need to create a folder with 777 permission (i.e. usefull for a cache
     folder), just do:
 11.     ```php
         $cache_folder = ABSPATH . 'cache';
         if ( ! is_dir( $cache_folder ) ) {
         		wp_mkdir_p( $cache_folder );
         		chmod( $cache_folder, 0777 );
         }
         ```
     
 12.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%3Freplytocom%3D5059%23feedback-editor-5059)
 13.  [Skip to note 6 content](https://developer.wordpress.org/reference/functions/wp_mkdir_p/?output_format=md#comment-content-4862)
 14.   [Usman Ahmed](https://profiles.wordpress.org/syedusmanahmed/)  [  5 years ago  ](https://developer.wordpress.org/reference/functions/wp_mkdir_p/#comment-4862)
 15. [You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%23comment-4862)
     Vote results for this note: 0[You must log in to vote on the helpfulness of this note](https://login.wordpress.org?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%23comment-4862)
 16. Creating a directory if doesn’t already exist.
 17.     ```php
         if ( ! is_dir( ABSPATH . 'my-folder' ) ) {
             wp_mkdir_p( ABSPATH . 'my-folder' );
         }
         ```
     
 18.  [Log in to add feedback](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F%3Freplytocom%3D4862%23feedback-editor-4862)

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_mkdir_p%2F)
before being able to contribute a note or feedback.