'Creating a folder when I run file_put_contents()

I have uploaded a lot of images from the website, and need to organize files in a better way. Therefore, I decide to create a folder by months.

$month  = date('Yd')
file_put_contents("upload/promotions/".$month."/".$image, $contents_data);

after I tried this one, I get error result.

Message: file_put_contents(upload/promotions/201211/ang232.png): failed to open stream: No such file or directory

If I tried to put only file in exist folder, it worked. However, it failed to create a new folder.

Is there a way to solve this problem?

php


Solution 1:[1]

modification of above answer to make it a bit more generic, (automatically detects and creates folder from arbitrary filename on system slashes)

ps previous answer is awesome

/**
 * create file with content, and create folder structure if doesn't exist 
 * @param String $filepath
 * @param String $message
 */
function forceFilePutContents ($filepath, $message){
    try {
        $isInFolder = preg_match("/^(.*)\/([^\/]+)$/", $filepath, $filepathMatches);
        if($isInFolder) {
            $folderName = $filepathMatches[1];
            $fileName = $filepathMatches[2];
            if (!is_dir($folderName)) {
                mkdir($folderName, 0777, true);
            }
        }
        file_put_contents($filepath, $message);
    } catch (Exception $e) {
        echo "ERR: error writing '$message' to '$filepath', ". $e->getMessage();
    }
}

Solution 2:[2]

i have Been Working on the laravel Project With the Crud Generator and this Method is not Working

@aqm so i have created my own function

PHP Way

function forceFilePutContents (string $fullPathWithFileName, string $fileContents)
    {
        $exploded = explode(DIRECTORY_SEPARATOR,$fullPathWithFileName);

        array_pop($exploded);

        $directoryPathOnly = implode(DIRECTORY_SEPARATOR,$exploded);

        if (!file_exists($directoryPathOnly)) 
        {
            mkdir($directoryPathOnly,0775,true);
        }
        file_put_contents($fullPathWithFileName, $fileContents);    
    }

LARAVEL WAY

Don't forget to add at top of the file

use Illuminate\Support\Facades\File;

function forceFilePutContents (string $fullPathWithFileName, string $fileContents)
    {
        $exploded = explode(DIRECTORY_SEPARATOR,$fullPathWithFileName);

        array_pop($exploded);

        $directoryPathOnly = implode(DIRECTORY_SEPARATOR,$exploded);

        if (!File::exists($directoryPathOnly)) 
        {
            File::makeDirectory($directoryPathOnly,0775,true,false);
        }
        File::put($fullPathWithFileName,$fileContents);
    }

Solution 3:[3]

I created an simpler answer from @Manojkiran.A and @Savageman. This function can be used as drop-in replacement for file_put_contents. It doesn't support context parameter but I think should be enough for most cases. I hope this helps some people. Happy coding! :)

function force_file_put_contents (string $pathWithFileName, mixed $data, int $flags = 0) {
  $dirPathOnly = dirname($pathWithFileName);
  if (!file_exists($directoryPathOnly)) {
    mkdir($dirPathOnly, 0775, true); // folder permission 0775
  }
  file_put_contents($pathWithFileName, $data, $flags);
}

Solution 4:[4]

Easy Laravel solution:

use Illuminate\Support\Facades\File;

// If the directory does not exist, it will be create
// Works recursively, with unlimited number of subdirectories
File::ensureDirectoryExists('my/super/directory');

// Write file content
File::put('my/super/directory/my-file.txt', 'this is file content');

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ManojKiran Appathurai
Solution 3 Jason Chiang
Solution 4 mspiderv