Alice
Alice

Reputation: 424

PHP auto increment file names

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

Answers (5)

mahatrsna
mahatrsna

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

Alice
Alice

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

Tom
Tom

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

Joseph Lust
Joseph Lust

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

Jeroen
Jeroen

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

Related Questions