Reputation: 424
I have a file uploader and I want the filenames to auto increment number. I don't feel the need to use a database to do this and I want to keep the code relatively clean, I'm pretty new in file upload and management in PHP so I'm not exactly sure what to do. Could anyone direct me in the right path?
Here is my current code, it just uses an md5 of a bunch of seeds.
<?php
if(isset($_FILES['imagedata']['tmp_name']))
{
// Directory related to the location of your gyazo script
$newName = 'images/' . substr(md5(rand() . time()), 0, 20) . '.png';
$tf = fopen($newName, 'w');
fclose($tf);
move_uploaded_file($_FILES['imagedata']['tmp_name'], $newName);
// Website
echo 'http://davidknag.com/' . $newName;
}
?>
Upvotes: 3
Views: 8057
Reputation: 1
A little late in the game but this pair of functions does the trick and follows the familiar format of the filename followed by "(n)" and then the file extension:
incrementFileName() returns the updated filename incremented by 1 with input filename and destination directory. splitLast() is a modification of explode to only split on the last occurrence of some substring.
function incrementFileName($name,$path){
if (!array_search($name,scandir($path))) {
return $name;
} else {
$ext=splitLast($name,".")[1];
$baseFileName=splitLast(splitLast($name,".")[0],"(")[0];
$num=intval(splitLast(splitLast($name,"(")[1],")")[0])+1;
return incrementFileName($baseFileName."(".$num.").".$ext,$path);
}
}
function splitLast($string,$delim) {
$parts = explode($delim, $string);
if (!$parts || count($parts) === 1) {
$before=$string;
$after="";
} else {
$after = array_pop($parts);
$before=implode($delim, $parts);
}
return array($before,$after);
}
When handling upload, set your filename with it:
$fileName = incrementFileName($_FILES['file']['name'], $path);
This will return someFileName(1).jpg or someFileName(2).jpg etc.
Upvotes: 0
Reputation: 424
function enc($length = "string") {
if(!is_numeric($length) || $length > 255 || $length < 1){
$length = rand("3","6");
}
// $randomID = substr(uniqid(sha1(crypt(md5("".time("ysia", true)."".rand())))), 0, $length);
$randomID = genUnique($length);
$count = 0;
while(glob("$randomID.*") || fetch("select * from `short` where `short` = '$randomID'") || fetch("select * from `images` where `name` = '$randomID'") || glob("img/$randomID.*") || is_numeric($randomID)){
if($count > 20){
$length++;
}
$randomID = genUnique($length);
$count++;
}
return $randomID;
}
this code is pretty old (not even using mysqli), but i figured i'd include it first
<?php
include_once "functions.php";
if(!isset($_REQUEST['api'])){
notfound("");
}
$con = connect();
$key = $_REQUEST['api'];
$ver = $_REQUEST['version'];
if($ver != "10-26-2016" || $key == "zoidberg")
{
die("Please upgrade your in4.us.exe by logging in and clicking download.");
}
if($key == "nokey"){
die("You need to keep the exe with the ini file to pair your api key. Copy ini file to same directory or redownload.");
}
$key = mysql_real_escape_string($key);
$findkey = fetch(" SELECT * from `users` where `key` = '$key' ");
if(!is_array($findkey)){
die("No user with that API Key found. Configure the INI File using your api key on in4.us");
}
$user = $findkey['username'];
if(isset($_FILES['imagedata']['tmp_name'])){
$newName = enc();
$tf = fopen("img/".$newName.".png", 'w');
fclose($tf);
move_uploaded_file($_FILES['imagedata']['tmp_name'], "img/".$newName.".png");
$domain = $_SERVER['HTTP_HOST'];
date_default_timezone_set('America/New_York');
$mysqldate = date("Y-m-d H:i:s");
$qry = mysql_query("INSERT INTO `images` (`name`, `added`, `dateadded`) VALUES ('$newName', '$user', '$mysqldate');");
if(!qry){
die('Invalid query: ' . mysql_error());
}
echo "http://$domain/$newName.png";
disconnect($con);
}else{
notfound("");
}
?>
Upvotes: -1
Reputation: 3032
You can try the code below. It creates a file with .png extension and unique name in outdir/
$filename = uniqFile('outdir', '.png');
move_uploaded_file($_FILES['imagedata']['tmp_name'], $filename);
function uniqFile($dir, $ext)
{
if (substr($dir, -1, 1) != '/')
{
$dir .= '/';
}
for ($i=1; $i<999999; $i++)
{
if (!is_file($dir . $i . $ext))
{
return $i . $ext;
}
}
return false;
}
Upvotes: 1
Reputation: 19985
You can just have a basic text file in the given folder. Store the number in there. Read it out and increment it as needed.
It would be easiest to make a function like getNextNumber() that did the above and then you could use it as needed. You could also do this in a $_SERVER[] variable, but it would need to be reloaded from the file on server restart.
<?PHP
// a basic example
function getNextNumber() {
$count = (int)file_get_contents('yourFile.txt');
$count+=1;
file_put_contents('yourFile.txt',$count);
return $count;
}
?>
Note that if you are using this a great deal, you'll need a more advanced sequence generator since this will perform 2 file IO's on each call.
Upvotes: 2
Reputation: 13257
<?php
if(isset($_FILES['imagedata']['tmp_name'])) {
// Directory related to the location of your gyazo script
$fileCount = count (glob ('images/*.png'));
$newName = 'images/' . ( $fileCount + 1) . '.png';
$tf = fopen($newName, 'w');
fclose($tf);
move_uploaded_file($_FILES['imagedata']['tmp_name'], $newName);
// Website
echo 'http://davidknag.com/' . $newName;
}
It just counts all .png files in the directory, increments that number by 1 and uses that as its filename.
Note that if you're storing a very large amount of files (say 10.000s), it's faster to use Joseph Lusts' method, but otherwise this will work jus tfine.
Upvotes: 3