I adopted code from https://stackoverflow.com/a/44553006/8719001
but can't figure out why when uploading the same file "test.jpg" several times it only counts up once, creating "test-1.jpg" but not more ie. test-2.jpg, test-3.jpg.
Can anybody spot the issue and help please?
$keepFilesSeperator = "-";
$keepFilesNumberStart = 1;
if (isset($_FILES['upload'])) {
// Be careful about all the data that it's sent!!!
// Check that the user is authenticated, that the file isn't too big,
// that it matches the kind of allowed resources...
$name = $_FILES['upload']['name'];
//If overwriteFiles is true, files will be overwritten automatically.
if(!$overwriteFiles)
{
$ext = ".".pathinfo($name, PATHINFO_EXTENSION);
// Check if file exists, if it does loop through numbers until it doesn't.
// reassign name at the end, if it does exist.
if(file_exists($basePath.$name))
{
$operator = $keepFilesNumberStart;
//loop until file does not exist, every loop changes the operator to a different value.
while(file_exists($basePath.$name.$keepFilesSeperator.$operator))
{
$operator++;
}
$name = rtrim($name, $ext).$keepFilesSeperator.$operator.$ext;
}
}
move_uploaded_file($_FILES["upload"]["tmp_name"], $basePath . $name);
}
your while loop condition has a problem
while( file_exists( $basePath.$name.$keepFilesSeperator.$operator ) )
the $name variable still contains the full name of file, in this case test.jpg, you're testing a value like /home/test.jpg-1 so finally the while loop is never executed as the file test.jpg-1 never exists, that's why you always get the test-1.jpg on disk and not a ...-2.jpg or ...-3.jpg
Related
I have to write a script that checks the progress of a file transfer that a background batch is doing. I know the number of files that the folder need to have to have the "complete" status. I'm trying the following in a background PHP:
$id = $_GET['id'];
$qtd = $_GET['qtd'];
checkProgress($id, $qtd);
function checkProgress($qtd, $id) {
$dirWav = "D:\\path\\to\\wav\\".$id."\\";
$dirMP3 = "D:\\path\\to\\mp3\\".$id."\\";
$progWav = array_diff( scandir($dirWav), array(".", "..") );
$progMP3 = array_diff( scandir($dirMP3), array(".", "..") );
$numWav = count($progWav);
$numMP3 = count($progMP3);
if ($numMP3 < $qtd OR $numWav < $qtd) {
sleep(5);
checkProgress($qtd, $id); //Here i'm trying to do it in a recursive way
} else {
//End script, record to the DB
}
}
I'm sure that the folder beign checked are empty on start, and that the batch is running flawless. But at the start of the script, it automatically goes to the end (I used a mkdir to check it in a lazy way).
How can I achieve what I want? I cannot check it via cronjob or something like that.
This is Powershell but I'd guess the overall function would apply to a batch file. Take input as two paths, run a FOR loop to count the files and compare. See here for counting files in a FOR loop.
Function Count-Folders{
Param
(
[parameter(Mandatory=$true,Position=1)][string]$source,
[parameter(Mandatory=$true,Position=2)][string]$dest
)
$path = #(gci -Path $source -dir)
$path2 = #(gci -Path $dest -dir)
If($path.Length -eq $path2.Length){
"Matches"
} Else{
"input folder counts do not match, check again!!!"
}
Ok guys so heres another debug nightmare that I've come across and can't seem to figure out exactly what is going on here -_-
Basically what is happening is that this code returns JSON to my ajax request. Which involves originally an array from the php.
array(
"public_html"=>
array(
"public_html"=>
array(//...other files actually in public html),
),
0 =>
array(
"filename":".ftpquota",
"filesize": 12kb
),
);
So as you can see it's creating a public_html index then adding another with the same name with the actual files inside public_html this is not what I want, I want the original public_html to come back as the files in public_html
/*
Iterates over files and directories recursively
*/
function ftpFileList($ftpConnection, $path="/") {
//create general array to pass back later
$files = array();
//grabs the contents of $path
$contents = ftp_nlist($ftpConnection, $path);
//explode the $path to get correct index to fill in
$secondaryPath = explode('/',$path);
//test if the last index in the array is blank
//if it is pop it from the array
if($secondaryPath[count($secondaryPath) - 1] == "")
array_pop($secondaryPath);
//if the array is larger than or equal to one
if(count($secondaryPath) >= 1){
//we will rewrite $secondaryPath to the last index (actual file name)
$secondaryPath = $secondaryPath[count($secondaryPath) - 1];
}else{
//if it isn't anything we'll make it the path that we originally passed
$secondaryPath = $path;
}
//check for contents
if($contents){
//iterate over the contents
foreach($contents as $currentFile) {
//if the current file is not . or .. we don't need that at all
if($currentFile !== "." && $currentFile !== ".."){
//if there is a period in the currentFile this means it's a file not a directory
if( strpos($currentFile,".") == 0 ) {
if($files[""]){
if($secondaryPath == $currentFile)
$files[""][$secondaryPath][] = ftpFileList($ftpConnection, $path.$currentFile.'/');
else
$files[""][$secondaryPath][$currentFile] = ftpFileList($ftpConnection, $path.$currentFile.'/');
}else{
$files[$secondaryPath][] = ftpFileList($ftpConnection,$path.$currentFile.'/');
}
}else{
//here we know the $currentFile is a file
if($currentFile !== "." && $currentFile !== ".."){
//file in the correct index with a new index which is an array with information
$files[$secondaryPath][] = array(
"file"=>$currentFile,//file name
"filesize"=>humanFileSize(ftp_size($ftpConnection,"/".$path.$currentFile)),//human readable file size
"creation_date"=>date("F d Y g:i:sa",ftp_mdtm($ftpConnection,"/".$path.$currentFile)),//date in a human readable format
"full_path"=>"/".$path.$currentFile//full path of the file so we can access this later
);
}
}
}
}
return $files;//return the array
}
}
I'm hoping this is partially easy to understand, I made a bunch of notes for debugging purposes. I need to iterate and get the files correctly in a nice JSON file so I can iterate over that with JS. It's hard to debug this with the internet I have and testing it in the IDE I am using, I only have a chromebook. (if anyone knows of a good app to use for the chromebook. )
I am using this script to delete picture from my server. But at the same time I want to protect the files in my server. Not accidentally delete but I noticed that if I typed the file index.pHp or index.Php is deleted from my server. Although setting it will not delete why php or this method not know between lowercase and uppercase.
What is not done right?
<?php
error_reporting (0);
$thefile = $_GET ['filetodel'];
$filename = "$thefile";
//$filename = "picture1.jpg";
/*protect some files*/
if ($thefile=='index.php' or $thefile=='INDEX.PHP' or $thefile=='UPLOADS.ZIP' or $thefile=='uploads.zip' or $thefile=='del.php'or $thefile=='DEL.PHP' or $thefile==NULL or $thefile=='.htaccess' or $thefile=='.HTACCESS' )
{
exit("<h2>cannot delete $thefile</h2>");
}
if ($thefile=="$thefile")
{
if (file_exists($filename))
{
unlink ("$thefile");
echo "<h2> file $thefile is delete</h2>";
}
else
{
echo "<h2>The<br>";
echo "$filename<br>";
echo "Does not exist</h2>";
}
}
?>
Just convert the input to lowercase and test it once, rather than worrying about every possible mix of case:
if (strtolower($thefile) == 'index.php') {
// ...
}
For the next iteration, you could store your protected files in an array:
$protected_files = array('index.php', 'uploads.zip', 'del.php', '.htaccess');
if (in_array(strtolower($thefile), $protected_files) || $thefile==NULL) {
// ...
}
the problem is here:
if ($thefile=="$thefile")
as if your 1st condition for file check is false than the second condition is
if ($thefile=="$thefile")
which is always true so it will unlink the file
Also add one line as below just before 1st condition
$thefile = strtolower($thefile);
I'm facing a strange situation here: I have an advanced multipart file upload script, which, for example, checks for duplicate filenames by scanning the destination folder and then renames the duplicate names with iteration number. Now, the problem here is, that for some reason, script passess with green lights if no duplicates are submitted, but if duplicate is inputted, script will return false in move_upload_file part, but however, still manage to create the proper duplicate into destination folder. I was just wondering, why and how the move_upload_file function returns false, but still proceeds moving the file?
Here is simplified snippet of the script, just trying to point you out to the problem:
<?php
//I'll loop all the files, which are submitted (in array)
foreach($_FILES['myFiles']['tmp_name'] as $key => $tmp_path) {
//Alot of stuff (most likely unrelated) happens here
//filepath contains both destination folder and filename
$filepath = $destination_folder.$filename;
if (file_exists($filepath)) {
$duplicate_filename = true;
//Some more stuff happens here. Then comes the actual moving part. Before this we have found duplicates
//for this upload file and counted proper duplicate value.
$file_increment = $num_of_filename_duplicates + 1;
while ($duplicate_filename == true) {
if(file_exists($filepath)) {
//Separate filename parts and make new duplicate name with increment value
$info = pathinfo($filename);
$basename = basename($filename,'.'.$info['extension']);
$newfilename = $basename."(".$file_increment.").".$info['extension'];
$filepath = $destination_folder.$newfilename;
//Now, this returns me false, but still creates the file into destination
if(move_uploaded_file($tmp_path, $filepath)) {
$file_success = true;
$file_increment++;
}
//So thats why this is true and I'll get the file_error
else {
$file_error = "File error: Uploading of the file failed.";
break;
}
}
else {
$duplicate_filename = false;
}
}
}
}
?>
The only reasons can be:
1) If filename is a valid upload file, but cannot be moved for some
reason, no action will occur, and move_uploaded_file() will return
FALSE. Additionally, a warning will be issued.
2) If filename is not a valid upload file, then no action will occur, and
move_uploaded_file() will return FALSE.
Your case seems to be 2. Try to set the following at the top of your script to see errors:
error_reporting(E_ALL);
ini_set("display_errors", 1);
Don't try to find some magic. Just debug your code.
I'm trying to get my script to find all of the PHP files in my include directory and put them in to an array (I've done the array part). Then, the script does a for loop to check if the GET request matches the current position value in the array (or whatever you want to call it).
But, if it doesn't find it at all.. it will include the default page, but obviously if it does it'll include the file it matched.
The problem is.. the break command isn't working at all. So, it's including the default page if it's been matched. Please help.
<?php
if(!defined("PLUGIN")){
echo "You cannot view this file directly.";
} else {
$glob = glob("inc/*.php");
$count = count($glob);
for($i=0;$i<$count;$i++){
$explode = explode("/", $glob[$i]);
$explode2 = explode(".", $explode[1]);
if($_GET["page"] == $explode2[0]){
include $glob[$i];
break;
} include_once "default.php";
}
}
?>
As it stands now, your loop will include the default page on EVERY iteration of the loop, until it matches that get/explode combination.
As well, using explode for analyzing file paths is poor practice. Instead, use path_info():
$found = false;
foreach ($glob as $file) {
$basename = path_info($file, PATHINFO_FILENAME);
if ($basename == $_GET['page']) {
$found = true;
break;
} else {
include($basename); // probably need to adjust this to make it a full filename
}
}
if (!$found) {
include('default.php'); // include this only if no other match was found.
}