I have the following code which uploads images to a rackspace cdn account.
error_reporting(E_ALL);
ini_set('display_errors', 1);
// include the API
require("cloudfiles.php") ;
// cloud info
$username = ''; // username
$key ='' ; // api key
$container = ''; // container name
ob_start();
$localfile = $_FILES['media']['tmp_name'];
$filename = $_FILES['media']['name'];
ob_flush();
// Connect to Rackspace
$auth = new CF_Authentication($username, $key);
$auth->authenticate();
$conn = new CF_Connection($auth);
// Get the container we want to use
$container = $conn->create_container($container);
// store file information
ob_flush();
// upload file to Rackspace
$object = $container->create_object($filename);
$object->load_from_filename($localfile);
$uri = $container->make_public();
//print "Your URL is: " . $object->public_uri();
$imagePageUrl = $object->public_uri();
//echo '<mediaurl>' . $imagePageUrl . '</mediaurl>';
ob_end_flush();
//echo '<mediaurl>' . $imagePageUrl . '</mediaurl>';
echo '<mediaurl>http://url.com/'.$filename.'</mediaurl>';
So each time i am uploading an image, say, image.jpg, it is overwriting the previous image.jpg in the container. I want to prevent that. Even if the filename is the same, is there a way to convert the filename to a random name, characters and then upload it?
Help plz.
Reading the other answers, while time() approach seems good, it does not provide real unique ids, its accuracy is only 1 second.
But PHP provides a way for having real unique IDS which is more accurate and provide a better solution. You could use it like:
$filename=uniqid().$_FILES['media']['tmp_name'];
Of course changing $_FILES['media']['tmp_name'] for whatever you prefer.
ok ... some code is missing ...
but you can try to give the new filename (uploaded image)... one name that is unique
simple example:
$filename = time()."-".$_FILES['media']['tmp_name'];
like this way your images will be named like '1333221458-my_image.jpg'
You can add the time to the filename, so assuming you will always have a .jpg:
$filename=explode(".",$filename);
$filename[0].="_".time();
$filename=implode(".",$filename);
Related
this script harvests links out of a seed url and only prints them in command shell (or browser) rather than saving elsewhere. I want the script to store any outputs in .txt file within the folder where the script resides. I need suggestions what could be the efficient way to do that. Please give me hints.
<?php
# Initialization
include("LIB_http.php"); // http library
include("LIB_parse.php"); // parse library
include("LIB_resolve_addresses.php"); // address resolution library
include("LIB_exclusion_list.php"); // list of excluded keywords
include("LIB_simple_spider.php"); // spider routines used by this app.
set_time_limit(3600); // Don't let PHP timeout
$SEED_URL = "http://www.schrenk.com"; // First URL spider downloads
$MAX_PENETRATION = 1; // Set spider penetration depth
$FETCH_DELAY = 1; // Wait one second between page fetches
$ALLOW_OFFISTE = false; // Don't allow spider to roam from the SEED_URL's domain
$spider_array = array();
# Get links from $SEED_URL
echo "Harvesting Seed URL \n";
$temp_link_array = harvest_links($SEED_URL);
$spider_array = archive_links($spider_array, 0, $temp_link_array);
# Spider links in remaining penetration levels
for($penetration_level=1; $penetration_level<=$MAX_PENETRATION; $penetration_level++)
{
$previous_level = $penetration_level - 1;
for($xx=0; $xx<count($spider_array[$previous_level]); $xx++)
{
unset($temp_link_array);
$temp_link_array = harvest_links($spider_array[$previous_level][$xx]);
echo "Level=$penetration_level, xx=$xx of ".count($spider_array[$previous_level])." <br>\n";
$spider_array = archive_links($spider_array, $penetration_level, $temp_link_array);
}
}
?>
Use file_put_contents PHP function with enable append file flag.
$file = 'file_name.txt';
file_put_contents($file, $text_to_write_to_file, FILE_APPEND);
Ref: http://www.php.net/manual/en/function.file-put-contents.php
I would recommend first creating a variable to store the output in the script. So at the top (under the $spider_array=array() ) add:
$output = "";
The change all the lines with echo to be $output .=
This will store all the content sent to the screen or the browser into the $output variable.
Now at the bottom of the script, after everything has been scraped and the spider is finished, save the output to a file:
$filename = date('Y_m_d_H_i_s') . '.txt';
$filepath = dirname(__FILE__);
file_put_contents($filepath . '/' . $filename, $output);
This should save the output in a file within the same folder as the script with a date/time file name. (This code was written using examples from php.net, exact implementation may need a bit of debugging, but this should get you close enough.
I hope someone can help me with this php code.
At the moment its just saving an image with the file name "img.png" to the server but with every time a new canvas screenshot is taken the image is just overwritten.
My aim is to create a new unique (like numbered chronological by time taken) file name for the images with every new screenshot and save it on the server.
Here the php code so far:
$data = $_REQUEST['base64data'];
echo $data;
$image = explode('base64,',$data);
file_put_contents('img.png', base64_decode($image[1]));
Thank you.
regards
Try
$filename = 'img_'.date('Y-m-d-H-s').'.png';
file_put_contents($filename, base64_decode($image[1]));
This will save your file with a filename containing the current date and time, e.g.
img_2013-09-19-21-50.png
Try using a session variable to increment a counter like so:
<?php
session_start();
if(!isset($_SESSION['counter'])){
$_SESSION['counter'] = 0;
}
$_SESSION['counter']++;
$data = $_REQUEST['base64data'];
echo $data;
$image = explode('base64,',$data);
file_put_contents('img'.$_SESSION['counter'].'.png', base64_decode($image[1]));
?>
There's several ways to do it, but the easiest is just to add a timestamp/datestamp to the image name. Format the name as you want.
$img_name = 'img'.date('YmdHisu').'.png'; // Date & time with microseconds
$img_name = 'img'.time().'.png'; // unix timestamp
Leave the base64data structure use this one it will work fine.
$fileName = preg_replace('#[^a-z.0-9]#i', '', $fileName);
$image = explode(".", $fileName);
It will give a random number to each image file.
either create a UID using uniqid() function for the filename or create a folder with the name of the username who is uploading the file and leave the original filename. The disadvantage of the first one is that you will have to save the original filename somewhere to show to the user.
https://stackoverflow.com/a/4371988/2701758
**
/* simply for local time first give your continent then '/' then your country's
capital.
*/
date_default_timezone_set('Asia/Dhaka');
$now = new DateTime();
$now = $now->format("Y-m-d H:i:s.u");
$new_name = $now.$image;
/*what you want to add just write with dot,such
$new_name = 'img'.$now.$image;
*/
**
I have the right PHP scripting to create a random number and make a new folder on the server with that # as it's name. If the folder exists the script stops. What I can't figure out though is how to direct the script to generate a new random # if the folder already exists and try again until it finds a unused number/folder. I think a do while is what I'm looking for but not sure if I have written it correctly or not (Don't want to test it on the server for fear of creating a forever looping mkdir command).
Here is the one off code being used
<?php
$clientid = rand(1,5);
while (!file_exists("clients/$clientid"))
{
mkdir("clients/$clientid", 0755, true);
exit("Your new business ID is($clientid)");
}
echo ("The client id is $clientid");
?>
Here is the do while I am contemplating - is this correct or do I need to do this a different way?
<?php
$clientid = rand(1,5);
do {mkdir("clients/$clientid", 0755, true);
exit("Your new business ID is($clientid)");}
while (!file_exists("clients/$clientid"));
echo ("The client id is $clientid");
?>
The problem is that you only generate a new number once, outside the loop. This means that you end up with a loop that never terminates. Invert the loop and and generate a new number each iteration:
$clientid = rand(1,5);
while (file_exists("clients/$clientid"))
{
// While we are in here, the file exists. Generate a new number and try again.
$clientid = rand(1,5);
}
// We are now guaranteed that we have a unique filename.
mkdir("clients/$clientid", 0755, true);
exit("Your new business ID is($clientid)");
I would do something like this:
<?php
$filename = md5(time().rand()) . ".txt";
while(is_file("clients/$filename")){
$filename = md5(time().rand()) . ".txt";
}
touch("clients/$filename");
useful tip for when your testing code on a while loop; create variable as a safety count and increment it then if your other logic causes an infinite problem it breaks out, like this:
$safetyCount = 0;
while (yourLogic && $safeCount < 500){
//more of your logic
$safetyCount++;
}
obviously if you need 500 lower / higher then set it to whatever, this just makes sure you'll not kill your machine. :)
I am currently in the process of writing a mobile app with the help of phonegap. One of the few features that I would like this app to have is the ability to capture an image and upload it to a remote server...
I currently have the image capturing and uploading/emailing portion working fine with a compiled apk... but in my php, I am currently naming the images "image[insert random number from 10 to 20]... The problem here is that the numbers can be repeated and the images can be overwritten... I have read and thought about just using rand() and selecting a random number from 0 to getrandmax(), but i feel that I might have the same chance of a file overwriting... I need the image to be uploaded to the server with a unique name every-time, no matter what... so the php script would check to see what the server already has and write/upload the image with a unique name...
any ideas other than "rand()"?
I was also thinking about maybe naming each image... img + date + time + random 5 characters, which would include letters and numbers... so if an image were taken using the app at 4:37 am on March 20, 2013, the image would be named something like "img_03-20-13_4-37am_e4r29.jpg" when uploaded to the server... I think that might work... (unless theres a better way) but i am fairly new to php and wouldn't understand how to write something like that...
my php is as follows...
print_r($_FILES);
$new_image_name = "image".rand(10, 20).".jpg";
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);
Any help is appreciated...
Thanks in advance!
Also, Please let me know if there is any further info I may be leaving out...
You may want to consider the PHP's uniqid() function.
This way the code you suggested would look like the following:
$new_image_name = 'image_' . date('Y-m-d-H-i-s') . '_' . uniqid() . '.jpg';
// do some checks to make sure the file you have is an image and if you can trust it
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);
Also keep in mind that your server's random functions are not really random. Try random.org if you need something indeed random. Random random random.
UPD: In order to use random.org from within your code, you'll have to do some API requests to their servers. The documentation on that is available here: www.random.org/clients/http/.
The example of the call would be: random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new. Note that you can change the min, max and the other parameters, as described in the documentation.
In PHP you can do a GET request to a remote server using the file_get_contents() function, the cURL library, or even sockets. If you're using a shared hosting, the outgoing connections should be available and enabled for your account.
$random_int = file_get_contents('http://www.random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new');
var_dump($random_int);
You should use tempnam() to generate a unique file name:
// $baseDirectory Defines where the uploaded file will go to
// $prefix The first part of your file name, e.g. "image"
$destinationFileName = tempnam($baseDirectory, $prefix);
The extension of your new file should be done after moving the uploaded file, i.e.:
// Assuming $_FILES['file']['error'] == 0 (no errors)
if (move_uploaded_file($_FILES['file']['tmp_name'], $destinationFileName)) {
// use extension from uploaded file
$fileExtension = '.' . pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
// or fix the extension yourself
// $fileExtension = ".jpg";
rename($destinationFileName, $destinationFileName . $fileExtension);
} else {
// tempnam() created a new file, but moving the uploaded file failed
unlink($destinationFileName); // remove temporary file
}
Have you considered using md5_file ?
That way all of your files will have unique name and you would not have to worry about duplicate names. But please note that this will return same string if the contents are the same.
Also here is another method:
do {
$filename = DIR_UPLOAD_PATH . '/' . make_string(10) . '-' . make_string(10) . '-' . make_string(10) . '-' . make_string(10);
} while(is_file($filename));
return $filename;
/**
* Make random string
*
* #param integer $length
* #param string $allowed_chars
* #return string
*/
function make_string($length = 10, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') {
$allowed_chars_len = strlen($allowed_chars);
if($allowed_chars_len == 1) {
return str_pad('', $length, $allowed_chars);
} else {
$result = '';
while(strlen($result) < $length) {
$result .= substr($allowed_chars, rand(0, $allowed_chars_len), 1);
} // while
return $result;
} // if
} // make_string
Function will create a unique name before uploading image.
// Upload file with unique name
if ( ! function_exists('getUniqueFilename'))
{
function getUniqueFilename($file)
{
if(is_array($file) and $file['name'] != '')
{
// getting file extension
$fnarr = explode(".", $file['name']);
$file_extension = strtolower($fnarr[count($fnarr)-1]);
// getting unique file name
$file_name = substr(md5($file['name'].time()), 5, 15).".".$file_extension;
return $file_name;
} // ends for is_array check
else
{
return '';
} // else ends
} // ends
}
I have a project that needs to create files using the fwrite in php. What I want to do is to make it generic, I want to make each file unique and dont overwrite on the others.
I am creating a project that will record the text from a php form and save it as html, so I want to output to have generated-file1.html and generated-file2.html, etc.. Thank you.
This will give you a count of the number of html files in a given directory
$filecount = count(glob("/Path/to/your/files/*.html"));
and then your new filename will be something like:
$generated_file_name = "generated-file".($filecount+1).".html";
and then fwrite using $generated_file_name
Although I've had to do a similar thing recently and used uniq instead. Like this:
$generated_file_name = md5(uniqid(mt_rand(), true)).".html";
I would suggest using the time as the first part of the filename (as that should then result in files being listed in chronological/alphabetic order, and then borrow from #TomcatExodus to improve the chances of the filename being unique (incase of two submissions being simultaneous).
<?php
$data = $_POST;
$md5 = md5( $data );
$time = time();
$filename_prefix = 'generated_file';
$filename_extn = 'htm';
$filename = $filename_prefix.'-'.$time.'-'.$md5.'.'.$filename_extn;
if( file_exists( $filename ) ){
# EXTREMELY UNLIKELY, unless two forms with the same content and at the same time are submitted
$filename = $filename_prefix.'-'.$time.'-'.$md5.'-'.uniqid().'.'.$filename_extn;
# IMPROBABLE that this will clash now...
}
if( file_exists( $filename ) ){
# Handle the Error Condition
}else{
file_put_contents( $filename , 'Whatever the File Content Should Be...' );
}
This would produce filenames like:
generated_file-1300080525-46ea0d5b246d2841744c26f72a86fc29.htm
generated_file-1300092315-5d350416626ab6bd2868aa84fe10f70c.htm
generated_file-1300109456-77eae508ae79df1ba5e2b2ada645e2ee.htm
If you want to make absolutely sure that you will not overwrite an existing file you could append a uniqid() to the filename. If you want it to be sequential you'll have to read existing files from your filesystem and calculate the next increment which can result in an IO overhead.
I'd go with the uniqid() method :)
If your implementation should result in unique form results every time (therefore unique files) you could hash form data into a filename, giving you unique paths, as well as the opportunity to quickly sort out duplicates;
// capture all posted form data into an array
// validate and sanitize as necessary
$data = $_POST;
// hash data for filename
$fname = md5(serialize($data));
$fpath = 'path/to/dir/' . $fname . '.html';
if(!file_exists($fpath)){
//write data to $fpath
}
Do something like this:
$i = 0;
while (file_exists("file-".$i.".html")) {
$i++;
}
$file = fopen("file-".$i.".html");