Creating a folder when I run file_put_contents()

Php

Php Problem Overview


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 Solutions


Solution 1 - Php

file_put_contents() does not create the directory structure. Only the file.

You will need to add logic to your script to test if the month directory exists. If not, use mkdir() first.

if (!is_dir('upload/promotions/' . $month)) {
  // dir doesn't exist, make it
  mkdir('upload/promotions/' . $month);
}

file_put_contents('upload/promotions/' . $month . '/' . $image, $contents_data);

Update: mkdir() accepts a third parameter of $recursive which will create any missing directory structure. Might be useful if you need to create multiple directories.

Example with recursive and directory permissions set to 777:

mkdir('upload/promotions/' . $month, 0777, true);

Solution 2 - Php

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 3 - Php

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 4 - Php

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 5 - Php

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');

Solution 6 - Php

I wrote a function you might like. It is called forceDir(). It basicaly checks whether the dir you want exists. If so, it does nothing. If not, it will create the directory. A reason to use this function, instead of just mkdir, is that this function can create nexted folders as well.. For example ('upload/promotions/januari/firstHalfOfTheMonth'). Just add the path to the desired dir_path.

function forceDir($dir){
	if(!is_dir($dir)){
		$dir_p = explode('/',$dir);
		for($a = 1 ; $a <= count($dir_p) ; $a++){
			@mkdir(implode('/',array_slice($dir_p,0,$a)));	
		}
	}
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJakeView Question on Stackoverflow
Solution 1 - PhpJason McCrearyView Answer on Stackoverflow
Solution 2 - PhpaqmView Answer on Stackoverflow
Solution 3 - PhpManojKiran AppathuraiView Answer on Stackoverflow
Solution 4 - PhpJason ChiangView Answer on Stackoverflow
Solution 5 - PhpmspidervView Answer on Stackoverflow
Solution 6 - PhpNicky SmitsView Answer on Stackoverflow