Last active
June 7, 2016 12:02
-
-
Save nothrem/44e31e5f84c3f16fdd9d1be2ffa3f906 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Use as standalone function or static method of any object. | |
* Set default $shardLevel to a value relevant for your usercase (e.g. +3 for MD5 filenames, -2 for ID filenames, etc.) | |
*/ | |
/** | |
* Creates subfolders for storing files to prevent folder overloading by too many files. | |
* | |
* @param mixed $filename (required) Basic filename without extension. Can be anything convertable to string valid for filenaming. | |
* @param string $root (optional, default: '/') Where to start creating the subfolders. Set false to skip folder creation. | |
* @param string $ext (optional, default: none) Extension for the file. | |
* @param number $shardLevel (optional, default: -3) Maximum number of subfolders to create. | |
* For positive numbers will use letters from the beginning of the $filename, for negative numbers will use letters from the end of the $filename. | |
* Zero disables sharding and will only ensure $root folder exists and will create filepath from $root, $filename and $ext. | |
* Use PHP_INT_MAX or -PHP_INT_MAX for unlimited number of folders. Recommended maximum is 64 or less (based on OS limits). | |
* @return array | |
* shards Created subfolders in $root from member id (e.g. '5/4/3/' for ID 12345). | |
* filename Filename with extension from member id | |
* filepath Path of shards and filename | |
* rootpath Full path including root | |
* root Content of $root (so you don't need to keep it separately) | |
* @throws Exception When filename is empty. | |
*/ | |
function shardFilename($filename, $root = '/', $ext = '', $shardLevel = 3) { | |
$filename = '' . $filename; //convert to string | |
if (empty($filename)) { | |
throw new Exception('Missing filename for sharding.'); | |
} | |
$len = strlen($filename); | |
$path = ''; | |
for ($i = 0; $i < abs($shardLevel); ++$i) { | |
if (($len - $i) < 2) { //do not shard for last letter | |
break; //e.g. 3/2/123.tmp for short name but 5/4/3/12345.tmp for longer | |
} | |
$path .= $filename[$shardLevel > 0 ? $i : $len - $i - 1] . '/'; | |
} | |
if (false !== $root && !is_dir($root . $path)) { | |
$umask = umask(0); //allow to create folder with all rights | |
mkdir($root . $path, 0777, true); | |
umask($umask); //return previous limits | |
} | |
return array( | |
'root' => $root, | |
'shards' => $path, | |
'filename' => $filename . $ext, | |
'rootpath' => $root . $path . $filename . $ext, | |
'filepath' => $path . $filename . $ext, | |
); | |
} | |
/* EXAMPLE: | |
file_put_contents(shardFilename('12345', UPLOAD_PATH, '.tmp', 3)['rootpath'], $data); //will save to '/upload/1/2/3/12345.tmp' | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment