generate two files with different extensions with the same unique id - php

I believe it's a matter of logic but I can't solve it.
I have a code that converts any video file to mp4, but at the moment I'm only converting to .gif. I wanted to know how I can generate a .mp4 and a .gif file with the same unique id.
I tried something like this
$finalFilePath = $targetDir . uniqid() . ".gif" ".mp4";
However, I was not successful.
It is only one file generator
In this case a uniqueid.gif file that is actually mp4.
and the intention is to generate both with the same unique id.
Thank you very much in advance.
Any help is welcome.
update more content to ask --->
Hello, using this code below I can generate the 2 files, but the problem is, two files are generated but both should have the same uniqid. however they are generated with different names, I'm having difficulties in creating a variable that stores only one uniqid this is my big problem.
if(move_uploaded_file($videoData["tmp_name"], $tempFilePath)) {
$finalFilePath = $targetDir . uniqid() . ".gif" ;
$finalFilePath2 = $targetDir . uniqid() . ".mp4";
if(!$this->insertVideoData($videoUploadData, $finalFilePath)) {
echo "Insert query failed\n";
return false;
}
if(!$this->convertVideoToMp4($tempFilePath, $finalFilePath2)) {
echo "Upload failed\n";
return false;
}
Function Upload.
public function upload($videoUploadData) {
$targetDir = "uploads/videos/";
$videoData = $videoUploadData->videoDataArray;
$tempFilePath = $targetDir . uniqid() . basename($videoData["name"]);
$tempFilePath = str_replace(" ", "_", $tempFilePath);
$isValidData = $this->processData($videoData, $tempFilePath);
if(!$isValidData) {
return false;
}
if(move_uploaded_file($videoData["tmp_name"], $tempFilePath)) {
$finalFilePath = $targetDir . uniqid() . ".gif";
if(!$this->insertVideoData($videoUploadData, $finalFilePath)) {
echo "Insert query failed\n";
return false;
}
return true;
}
}
Function ConvertVideoToMp4
public function convertVideoToMp4($tempFilePath, $finalFilePath) {
$cmd = "$this->ffmpegPath -i $tempFilePath -pix_fmt rgb24 -r 4 -vf scale=540:-1 $finalFilePath 2>&1";
$outputLog = array();
exec($cmd, $outputLog, $returnCode);
if($returnCode != 0) {
//Command failed
foreach($outputLog as $line) {
echo $line . "<br>";
}
return false;
}
return true;
}

Call uniqid once and store it to a variable and use it how many times you want.
I think the better way to create a unique id is:
$bytes = random_bytes(16);
echo bin2hex($bytes);
random_bytes() generates cryptographically secure pseudo-random bytes. Further, passing its output to another function bin2hex(), will give you unique random string.

$id = uniqid();
$finalFilePath = $targetDir . $id . ".gif" ;
$finalFilePath2 = $targetDir . $id . ".mp4";
Simple ;)

Related

PHP unlink() problem with files named with multiple extensions

I'm encountering an issue I've never come across before. I have some images uploaded as JPG or PNG with a duplicate of the image in WebP format, eg in this file naming convension:
https://example.com/uploads/memory-day.png >
https://example.com/uploads/memory-day.png.webp
If I delete a file through PHP using the unlink() function like normal, it works fine for everything else until I delete the PNG duplicate image. When I do that, the WebP file is also deleted and I can't see how it's happening -- is it a weird issue in the unlink() function with a file having a double extension? I can't seem to replicate it unless it's there's a WebP file involved.
For clarity, here's the PHP code that deletes the files (and yeah, I know it needs to be a prepare statement, I haven't updated it yet):
if(isset($_POST['delete'])) {
$countG = 0;
$err = 0;
foreach($_POST['delFile'] as $actionID) {
$action_id = $conn->real_escape_string($actionID);
$query = $conn->query("SELECT `filename`, `dir` FROM `fileuploads` WHERE `id` = '$action_id'");
$delF = $query->fetch_assoc();
$filenameDel = StripSlashes($delF['filename']);
$filenameDir = StripSlashes($delF['dir']);
if(file_exists($_SERVER['DOCUMENT_ROOT'] . $filenameDir . "/" . $filenameDel)){
if(unlink($_SERVER['DOCUMENT_ROOT'] . $filenameDir . "/" . $filenameDel)) {
if(file_exists($_SERVER['DOCUMENT_ROOT'] . $filenameDir . "/auto_thumbs/" . $filenameDel)) {
unlink($_SERVER['DOCUMENT_ROOT'] . $filenameDir . "/auto_thumbs/" . $filenameDel);
}
$delquery = $conn->query("DELETE FROM `fileuploads` WHERE `id` = '$action_id'");
$countG++;
} else {
$err++;
}
} else {
$err++;
if(!file_exists($_SERVER['DOCUMENT_ROOT'] . $filenameDir . "/" . $filenameDel)) {
//Remove from db if file is not there physically
$delquery = $conn->query("DELETE FROM `fileuploads` WHERE `id` = '$action_id'");
}
}
}
if($countG > 0) {
$green = 1;
$message1 = "$countG File(s) Deleted!";
}
if($err > 0) {
$red = 1;
$message2 = "Error deleting $err files!";
error_log(print_r(error_get_last(), TRUE));
}
}

Losing variable value when trying to copy file using mailReader.php

I'm using the mailReader script found here: https://github.com/stuporglue/mailreader
I am trying to copy the file(s) after upload to another folder.
The file(s) upload correctly to the folder where the script resides.
When I try to run a copy command, the filename variable is empty.
Here is the portion of the code I am working with: The last three lines are what I added.
private function saveFile($filename,$contents,$mimeType = 'unknown'){
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
while(!$unlocked_and_unique){
// Find unique
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4); // added 1-19-2016
while(file_exists($this->save_directory . $name)) {
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4);
}
// Attempt to lock
$outfile = fopen($this->save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
}else{
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
if (copy($this->save_directory.$name, "/attachments/" . TRANS_ID . "/". $name)) {
unlink( $this->save_directory.$name );
}
I receive confirmation by email that the file(s) are uploaded, then another email with the error message.
Warning: copy(/attachments/W7652222-546/1453406138_residential-print_from_td.pdf): failed to open stream: No such file or directory in /home/myhost/public_html/mailreader/mailReader.php on line 224
224 being the line number of my added code.
The source filename is missing from in front of /attachments...
Anyone have any thoughts?
$name is defined in the while loop and may not be accessible on the upper scopes my suggestion is to change your code to this:
private function saveFile($filename,$contents,$mimeType = 'unknown'){
$filename = preg_replace('/[^a-zA-Z0-9_-]/','_',$filename);
$unlocked_and_unique = FALSE;
$name = '';
while(!$unlocked_and_unique){
// Find unique
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4); // added 1-19-2016
while(file_exists($this->save_directory . $name)) {
$name = time() . "_" . $filename;
$name = substr_replace($name,".pdf",-4);
}
// Attempt to lock
$outfile = fopen($this->save_directory.$name,'w');
if(flock($outfile,LOCK_EX)){
$unlocked_and_unique = TRUE;
}else{
flock($outfile,LOCK_UN);
fclose($outfile);
}
}
fwrite($outfile,$contents);
fclose($outfile);
if (copy($this->save_directory.$name, "/attachments/" . TRANS_ID . "/". $name)) {
unlink( $this->save_directory.$name );
}
I hope this solves your problem
I ended up defining a constant of email_id in the private function saveToDb, then running a script after everything else is finished to query the table using the email_id and looping through the records moving the files.

Yii get variable from other function in same Controller

Is that possible to get variable from other function in same Controller ?
So I just updated my code ... the huge code is my real code ... so I wish to get the $hashfilename_filename to another function so I able to save it into DB
Example:
class HappyController extends Controller{
public function actionUploadFile()
{
if (isset($_FILES['Filedata']['tmp_name']) && is_uploaded_file($_FILES['Filedata']['tmp_name'])) {
$today = date("Ymd");
$slash = Yii::app()->params['slash'];
$tmp_folder = Yii::app()->params['tmp_folder'];
$tmp_folder_with_index_file = $tmp_folder . $slash . 'index.html';
$tmp_folder_with_date = Yii::app()->params['tmp_folder'] . $today;
if (!is_dir($tmp_folder_with_date)){
mkdir($tmp_folder_with_date, 0755);
copy($tmp_folder_with_index_file, $tmp_folder_with_date . $slash . 'index.html');
}
$filesize = sprintf("%u", filesize( $_FILES['Filedata']['tmp_name'] ));
$hashfilename_filename = md5(time() + 1) . '.apk';
$full_path = $tmp_folder_with_date . $slash . $hashfilename_filename;
if (!move_uploaded_file ($_FILES['Filedata']['tmp_name'], $full_path)){
$result['statusCode'] = "500";
echo json_encode($result);
die();
}
$result['statusCode'] = "200";
$result['today'] = $today;
$result['tmp_folder_with_date'] = $tmp_folder_with_date;
$result['filesize'] = $filesize;
$result['hashfilename_filename'] = $hashfilename_filename;
$result['full_path'] = $full_path;
}else{
$result['statusCode'] = "400";
}
echo json_encode($result);
die();
}
public function actionLife(){
$model = new ThisisLife();
$model->sad = $hashfilename_filename;
$model->save();
}
}
In public function actionLife , I wish to get the variable from other function, any suggestion to do that ?
try storing it in a session variable;
public function actionAbc(){
$full_path = a + b;
Yii::app()->user->setState('full_path', $full_path);
}
public function actionXyz(){
$full_path = Yii::app()->user->getState('full_path');
}
In this way you can access this variable from anywhere across whole platform.
What you are trying to do is not the right way in my opinion. The idea behind OOP i to encapsulate code belonging together. So if you need to determine a path which is needed in more than one place (or action) just extract it into its own private function within the controller. That way you could call this method from both actions and reuse your code.
If you need this variable between two calls I'd rather pass it as a GET/POST-Parameter as the otherway around you risk using the same filename again if you forget to reset the var...as it says, it lasts the whole session!
Your method could look like this:
private function generatePath()
{
$folder = Yii::app()->params['tmp_folder'] . date("Ymd");
$folderWithIndex = Yii::app()->params['tmp_folder'] . DIRECTORY_SEPARATOR . 'index.html';
if (!file_exists($folder)) {
mkdir($folder, 0755);
copy($folderWidthIndex, $folder . DIRECTORY_SEPARATOR . 'index.html');
}
$filename = md5(time() + 1) . '.apk';
return $folder . DIRECTORY_SEPARATOR . $filename;
}
The constant DIRECTORY_SEPARATOR is a php default constant to automatically fill in the "slash" of the current filesystem.
One more input: Instead of defining the path in your params, you could set it as a yii-alias. This makes life much easier in the long run. Make sure to check it out here: https://github.com/yiisoft/yii2/blob/master/docs/guide/concept-aliases.md
I hope it helped!
cheers, pascal
If you need to access variable through controllers, why don't u make it a private field in controller. So that you can access it in whole Controller class. You then may have getter, setters if needed, as it should as we are talking about OOP.

php script that gives md5 of a online file

hi i'm looking for a script that gives me the md5 of a file by link
i have all ready a script that gives the md5 of the files that are in the folder but now i wanna add a script where you paste the link to the file and it prints out the md5
if some one knows how to make this plz let me know
code that i have :
<?php
$cwd = $_SERVER['REQUEST_URI'];
$cwd = substr($cwd, 0, strrpos($cwd, '/' + 1));
function paintUndersideOfFox($c) {
global $cwd;
echo('<ul class="dirlist">');
$d = opendir($c);
while($f = readdir($d)) {
if(strpos($f, '.') === 0) continue;
$ff = $c . '/' . $f;
echo 'MD5 file hash of ' . $ff . ': ' . md5_file($ff);
echo('<li>' . $ff . '</li><br />');
if(is_dir($ff)) paintUndersideOfFox($ff);
}
echo('</ul>');
}
paintUndersideOfFox('.');
?>
Most filesystem functions apply to streams, including HTTP. Did you try this
md5_file("http://remotelocation/file")
Downloading files can be done via file_get_contents() or more securely with CURL

Check if file exist before renaming file upon upload

I need help with adding the feature to check whether a file exists when uploading.
This is how the upload.php code looks like for uploading:
$file_name = $HTTP_POST_FILES['ljudfil']['name'];
$random_digit=rand(0000,9999);
$mp3 ='.mp3';
$pdf ='.pdf';
$datum = date('Ymd');
$new_file_name=$random_digit.$file_name;
$target_path1 = $target_path . $orgnr . '_' . $gsm . $pdf;
$target_path3 = $target_path . 'AC' . $datum . $new_file_name . $mp3;
$target_path11 = $target_path4 . $orgnr . '_' . $gsm . $pdf;
$target_path33 = $target_path4 . 'AC' . $datum . $new_file_name . $mp3;
$targetljudfilftp = 'AC' . $datum . $new_file_name . $mp3;
move_uploaded_file($_FILES['avtalsfil1']['tmp_name'], $target_path1);
move_uploaded_file($_FILES["ljudfil"]["tmp_name"], $target_path3);
$sql = "INSERT INTO affarer (tid, cid, orgnr, ljudfilftp) VALUES
(CURDATE(),'$date','$cid','$orgnr', '$targetljudfilftp')";
As you can see, it renames the uploaded file including a random number.
Sometimes, it happens that it renames the file to a number that already exists.
When that happens, it overwrites the previous file on my server.
So, how can I add a function to check whether the target name exists before it is used for renaming?
You can use
if (file_exists($target_path1))
to verify whether a file exists.
You would do better, though, to change strategy and employ tempnam:
$target_path = tempnam ($target_path, 'AC' . $datum . $file_name . $mp3)
This will create a file such as "AC_2012_Anacreon.mp3_xTfKxy" but you have the guarantee of it being unique, while even using file_exists would expose you to the risk of a concurrency collision.
Of course the file no longer has a .mp3 extension, so you have to take it into account when you scan the directory and supply files for download.
A still not secure, but maybe easier way is this:
for(;;)
{
$newname = // some strategy to generate newname, including a random
if (!file_exists($newname))
touch($newname);
if (!filesize($newname))
break;
}
or you can use a lock file to guarantee no concurrency (and therefore, that file_exists will return the truth and it will stay the truth):
$fp = fopen('.flock', 'r+');
if (flock($fp, LOCK_EX))
{
for(;;)
{
$newname = // some strategy to generate newname, including a random
if (!file_exists($newname))
{
// this creates the file uniquely for us.
// all other writers will find the file already there
touch($newname);
}
}
flock($fp, LOCK_UN);
}
else
die("Locking error");
fclose($fp);
// $newname is now useable.
Use the file_exists builtin function.
You could change the way your random digists are created by using (for example) a time based method
$random_digit = microtime(TRUE);
You can use as below
$random_digit = time();
Instead off using 'rand' function which can generate a duplicated number, you can use 'uniqid'php function, it returns a unique id ( http://www.php.net/manual/en/function.uniqid.php ).
If you still want to use the 'rand' you can use 'file_exists' function with the generated file name as param ( http://www.php.net/manual/en/function.file-exists.php ), but if a file exists you must regenerate the file name, so you will iterate each time the file exists.
At last, think to use full time date('Ymdhis') format instead off date('Ymd'), it's also better to use timestamp by calling time() function ( http://www.php.net/manual/en/function.time.php )
Anas,
if (file_exists($random_digit)) {
$random_digit = rand(0000,9999);
}

Categories