Creating a folder in PHP if it doesn't exist: best practices 2025

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

«Create a folder if it doesn't already exist»: How not to reinvent the wheel in 2025

\n\n

Have you ever written a script that needs to save files and suddenly got the error Warning: mkdir(): No such file or directory? If so — you are not alone. The question «Create a folder if it doesn't already exist» on Stack Overflow has gathered thousands of views, and for good reason. It seems simple, right? But in practice, beginners (and not only) often stumble upon pitfalls: permissions, recursive creation, race conditions.

\n\n

In this article, we will break down PHP best practices for creating folders for 2025. You will learn how to properly use mkdir(), avoid common mistakes, and write reliable code that won't fail at the worst possible moment. Let's go!

\n\n

Why is the question «Create a folder if it doesn't exist» so popular?

\n\n

Every second web project works with files in some way: uploading avatars, generating reports, caching, logging. And everywhere you need to ensure the target directory exists. If it doesn't — the script will throw an error, the user will see «500 Internal Server Error», and you will be debugging at three in the morning.

\n\n

The problem is that the PHP function mkdir() does not automatically create a folder if the parent directory is missing. Many developers write something like:

\n\n
if (!file_exists($path)) {\n    mkdir($path);\n}\n
\n\n

And this works… until a race condition occurs. If two scripts simultaneously check if the folder exists and both try to create it — one of them will fail with an error. In 2025, as website load increases, such bugs become critical.

\n\n

The mkdir() function in PHP: a detailed breakdown

\n\n

Let's recall the signature:

\n\n
mkdir(string $directory, int $permissions = 0777, bool $recursive = false, resource $context = ?): bool\n
\n\n
    \n
  • $directory — path to the folder to be created.
  • \n
  • $permissions — access permissions (default 0777, but the umask is applied).
  • \n
  • $recursive — if true, creates all missing parent directories.
  • \n
  • $context — stream context (rarely used).
  • \n
\n\n

The main secret is the $recursive parameter. Most problems are solved by it. But let's take it step by step.

\n\n

Simple method: is_dir() + mkdir()

\n\n

The most obvious and correct way to check if a folder exists is to use is_dir(), not file_exists(). Why? Because file_exists() will also return true for a file with that name, which will lead to an error.

\n\n
$dir = '/path/to/upload';\n\nif (!is_dir($dir)) {\n    mkdir($dir, 0755, true);\n}\n
\n\n

Here we:

\n
    \n
  • Check that the directory does not exist and is not a file.
  • \n
  • Create the folder with permissions 0755 (owner can do everything, others can read and execute).
  • \n
  • Use true for recursive creation — if the parent folder /path/to doesn't exist, it will also be created.
  • \n
\n\n

This method covers 90% of cases. But what if two requests execute this code simultaneously?

\n\n

Protection against race conditions

\n\n

In high-load systems, two scripts may try to create the folder at the same time. To avoid an error, use @ (error suppression) or, better yet, check the result of mkdir():

\n\n
$dir = '/path/to/cache';\n\nif (!is_dir($dir)) {\n    // Try to create. If another process already created the folder — no problem\n    if (!mkdir($dir, 0755, true) && !is_dir($dir)) {\n        throw new \\RuntimeException('Failed to create directory: ' . $dir);\n                

Blogs

Book Recommendations