audio upload to folder

I have the following simple form, when I upload it goes back to upload.html, which is fine, but nothing is uploaded to the “uploads/” folder. No errors if it is the wrong file type and no results if it is the correct file type

<form name="uploadForm" method="post" action="upload.php" enctype="multipart/form-data"> Select an mp3 file only: <br> <input name="user_file" type="file" /><br> <input type="submit" name="upload" value="Upload"> </form>

and the following PHP

[php]<?php
header("*****************************");

echo “Please wait while we attempt to upload your file…

”;

$target_path = “uploads/”;

$flag = 0;

$filename = $_FILES[‘uploadedfile’][‘name’];
$filesize = $_FILES[‘uploadedfile’][‘size’];
$mimetype = $_FILES[‘uploadedfile’][‘type’];

$filename = htmlentities($filename);
$filesize = htmlentities($filesize);
$mimetype = htmlentities($mimetype);

$target_path = $target_path . basename( $filename );

if($filename != “”){

echo “Beginning upload process for file named: “.$filename.”
”;
echo “Filesize: “.$filesize.”
”;
echo “Type: “.$mimetype.”

”;
}

$hashedfilename = md5($filename.time());
$hashedfilename = $hashedfilename.".mp3";

//Check for empty file
if($filename == “”){
$error = “No File Exists!”;
$flag = $flag + 1;

}

$existname = “uploads/”.$hashedfilename;

if(file_exists($existname)){

if($flag == 0){
$error = “Your file already exists on the server!
Please choose another file to upload or rename the file on your
computer and try uploading it again!”;
}

$flag = $flag + 1;
}

//Whitelisted files

$whitelist = array(".mp3");
foreach ($whitelist as $ending) {

if(substr($filename, -(strlen($ending))) != $ending) {
$error = “The file type or extention you are trying to upload is not allowed!
You can only upload MP3 files to the server!”;
$flag++;
}
}

if($filesize > 9920600){
//File is too large

if($flag == 0){
$error = “The file you are trying to upload is too large!
Please upload a smaller MP3 file or encode your file with a lower bitrate.”;
}

$flag = $flag + 1;
}

if($filesize < 1048600){
//File is too small

if($flag == 0){
$error = “The file you are trying to upload is too small!
Your file has been marked as suspicious because our system has
determined that it is too small to be a valid MP3 file.
Valid MP3 files must be bigger than 1 MB and smaller than 6.5 MB.”;
}

$flag = $flag + 1;

}

//Check the mimetype of the file
if($mimetype != “audio/x-mp3” and $mimetype != “audio/mpeg”){

if($flag == 0){
$error = “The file you are trying to upload does not contain expected data.
Are you sure that the file is an MP3?”;
}

$flag = $flag + 1;
}

//Check that the file really is an MP3 file by reading the first few characters of the file
$f = @fopen($_FILES[‘uploadedfile’][‘tmp_name’],‘r’);
$s = @fread($f,3);
@fclose($f);
if($s != “ID3”){

if($flag == 0){
$error = “The file you are attempting to upload does not appear to be a valid MP3 file.”;
}

$flag++;
}

//All checks are done move the file

if($flag == 0){

if(move_uploaded_file($_FILES[‘uploadedfile’][‘tmp_name’], $target_path)) {

//Change the filename to MD5 hash and FORCE a MP3 extention.

if(@file_exists("uploads/".$filename)){

//Rename the file to an MD5 version
rename("uploads/".$filename, "uploads/".$hashedfilename);

echo "The file ".  basename( $filename ). " 
  has been uploaded.  Your file is <a href='uploads/$hashedfilename'>here</a>.";

}	
else{
  echo "There was an error uploading the file, please try again!";
}

} else{
echo “There was an error uploading the file, please try again!”;
}

}
else {
echo “File Upload Failed!
”;
if($error != “”){
echo $error;
}
}

?>[/php]

@ suppresses errors in PHP, I’d suggest to remove all of them as it’s something you’d rarely really want to do.

What have you done so far to debug this? You have a lot of sections that you might want to display a success
or fail display onscreen so that you can find where it is failing. Once you remove the suppression of errors, as
JimL mentioned you might find the problem. But, if not, display some data or at the least a success list so you
can see where the process fails…

Thanks all, I removed the @ symbols and fixed an mp3 error. I’m getting permission denied error. Looks like the folder isn’t writable.

Warning: move_uploaded_file(uploads/test.mp3) [function.move-uploaded-file]: failed to open stream: Permission denied in D:\Hosting\6110757\html\Test\upload.php on line 128

Great! Just go to your FTP client and change the permissions to 777 or 577 or other that allows writing to it.
Retest and see if you get further errors… (PS: I never use the @ to suppress anything, always better to write
code to check for errors and handle the display of them in a correct manner!)

Ok, so now if the file is uploaded I’m still getting an error, but the file actually uploads

There was an error uploading the file, please try again!

If you try and upload the same file again, the permissions error comes back.

To debug this part, start by making a different error message for each break point.

For example if it gets to the else block after this condition:
[php]if(move_uploaded_file($_FILES[‘uploadedfile’][‘tmp_name’], $target_path)) {[/php]
Write: “Failed to move file from tmp dir to target path.”
This way you know where it is breaking.

Also the issue with the permission denied on the repeat would probably be permissions on the file itself. Instead of moving the file and renaming it. Save the file as the hash name and store the original file name, this way you don’t need to change file permissions.

JM, your logic is messy for the error-checking areas of this code. You use a variable named $flag to set if there
was an error or not. Then, you keep checking if it is zero and if not, you skip further tests. If your test fails once,
the flag is set in various ways ( $flag++; $flag=$flag+1; etc…) and it is tested by all the other tests. That is a
bit silly to keep testing the error flag. Normally for this type of error checking you would create a list of error
messages and never check the counts of them. Then, after all the tests are completed, you check once to see
if there were errors. If so, display all of them, if not, upload the file. So, the issue with your code is that the tests
that came before are marking your upload as bad. How to fix this? Well, there are two ways I can think of now.

You can drop the tests to see if there were errors during each error-check and add the error message to the
list of messages with either an array of errors or just concatenate it onto the end of the previous messages.
I like to do it this way as it is simple and creates the list of errors so it is ready to display. Here is how it works
in loose code. (You will have to customize yours to use this logic…)

$error_messages="";

$existname = “uploads/”.$hashedfilename;
if(file_exists($existname)){
$error_messages .= “File already exists on the server!”;
}
if(substr($filename, -(strlen($ending))) != $ending) {
$error_messages .= “
File not an MP3! You can only upload MP3 files to the server!”;
}
… continue for each test, then test over-all results…
if($error_messages=""){
… Here handle the file uploading code as there are no errors…
} else {
echo “You must fix these errors:
” . $error_messages;
}

As you see, this logic tests all of the possible errors and then displays them or continues on. There is no
testing of the errors at each step. The only downside is that the user sees ALL of the error messages at one
time and might be annoying. But, if they entered the wrong file, it is their fault and they should see them.

Hope this helps…

Thanks all, so far I went back and took everything to the basics.

[php]<?php

$target_path = “uploads/”;

$filename = $_FILES[‘user_file’][‘name’];
$filesize = $_FILES[‘user_file’][‘size’];
$mimetype = $_FILES[‘user_file’][‘type’];

$filename = htmlentities($filename);
$filesize = htmlentities($filesize);
$mimetype = htmlentities($mimetype);

$target_path = $target_path . basename( $filename );

if($filename != “”){

echo “Beginning upload process for file named: “.$filename.”
”;
echo “Filesize: “.$filesize.”
”;
echo “Type: “.$mimetype.”

”;
}

move_uploaded_file($_FILES[‘user_file’][‘tmp_name’], $target_path);

echo "The file ".  basename( $filename ). " 
  has been uploaded";

?>[/php]

But of course anything can be uploaded ,and the names must be unique or else a permissions error is thrown including the message "The file “. basename( $filename ). " has been uploaded”; I guess I will put things in to limit the type of file and some checking one by one. Thanks for the help so far!

Also ErnieAlex, yes the code was messy. I’m going to try and work the error messaging into a single block like you suggested.

The way I handle file uploads is to store the path and original file name in a datatable. The filename that actually get stored in the file structure is a micro timestamp. Then, the filename (orig) can be displayed (I also do it so the file cannot be directly accessed) and the file viewed.

Astonecipher, question on that… You save the filename as a timestamp, you do not place the extension in the
filename, correct? I mean, in that way the file is not easy to understand? If a hacker finds your site and the folder
and the list of files, can’t they check the internal filetype to figure out what it is? I mean, if they want it badly
enough? I need to protect some user files soon in a project I am playing with and hence the question on this!
Thanks!

The system I used it on, trying to find the module.

The gist, the file was pulled apart when uploaded. Filename, size, type timestamp, ect were stored in an uploads table. The file was moved behind the public directory. And the file was assigned to a ticket id. The ticket displayed the file names, original + the user that uploaded it, but it was actually stored using the new non-descript filename. And a file viewer script pulled the file from behind the public directory for viewing in the browser.

The ext had a mime type associated with it allowing the proper headers to be sent.

Basically what I thought you meant. I just need to hide user files uploaded from the world for security and to
protect the owners. Always on the lookout for further ideas… Thanks!

Good morning, I’ve changed and simplified the code and have this

[php] <?php

$target_path = “uploads/”;

$filename = $_FILES[‘user_file’][‘name’];
$filesize = $_FILES[‘user_file’][‘size’];
$mimetype = $_FILES[‘user_file’][‘type’];

$filename = htmlentities($filename);
$filesize = htmlentities($filesize);
$mimetype = htmlentities($mimetype);

$ip = $_SERVER[“REMOTE_ADDR”];
$hashedfilename = md5($filename.$ip);
$hashedfilename = $hashedfilename.".mp3";

$target_path = $target_path . basename( $filename );

if($filename != “”){

echo “Beginning upload process for file named: “.$filename.”
”;
echo “Filesize: “.$filesize.”
”;
echo “Type: “.$mimetype.”

”;
}

$error_messages="";

$existname = “uploads/”.$hashedfilename;

if(file_exists($existname)){
$error_messages .= “File already exists on the server!”;
}
if(substr($filename, -(strlen($ending))) != $ending) {
$error_messages .= “File is not an MP3! You can only upload MP3 files to the server!”;
}
if($mimetype != “audio/mp3” and $mimetype != “audio/mpeg”){
$error_messages .= “The file you are trying to upload does not contain expected data. Are you sure that the file is an MP3?”;
}
if ($filesize > 10485760){
$error_messages .=“The file you are trying to upload is too large! Your file can be up to 10 MB in size only. Please upload a smaller MP3 file or encode your file with a lower bitrate”;
}

if($error_messages=""){
move_uploaded_file($_FILES[‘user_file’][‘tmp_name’], $target_path);

echo "The file " . basename( $filename ) . “has been uploaded”;
}
else {
echo “You must fix these errors:
” . $error_messages;
}

?>[/php]

On the results screen, nothing uploads and this message displays

You must fix these errors:

No errors are given. Are the if/else statements accurate or should there be an else after the list of possible error messages? Also as far as adding a time stamp to the file in order to make the names unique is the code I have accurate?

EDIT: I changed some things around and have this at the moment:

[php] <?php

$target_path = “uploads/”;

$filename = $_FILES[‘user_file’][‘name’];
$filesize = $_FILES[‘user_file’][‘size’];
$mimetype = $_FILES[‘user_file’][‘type’];

$filename = htmlentities($filename);
$filesize = htmlentities($filesize);
$mimetype = htmlentities($mimetype);

$ip = $_SERVER[“REMOTE_ADDR”];
$hashedfilename = md5($filename.$ip);
$hashedfilename = $hashedfilename.".mp3";

$target_path = $target_path . basename( $filename );

if($filename != “”){

echo “Beginning upload process for file named: “.$filename.”
”;
echo “Filesize: “.$filesize.”
”;
echo “Type: “.$mimetype.”

”;
}

$error_messages="";

$existname = “uploads/”.$hashedfilename;

if(file_exists($existname)){
$error_messages .= “File already exists on the server!”;
}
elseif(substr($filename, -(strlen($ending))) != $ending) {
$error_messages .= “File is not an MP3! You can only upload MP3 files to the server!”;
}
elseif($mimetype != “audio/mp3” and $mimetype != “audio/mpeg”){
$error_messages .= “The file you are trying to upload does not contain expected data. Are you sure that the file is an MP3?”;
}
elseif ($filesize > 10485760){
$error_messages .=“The file you are trying to upload is too large! Your file can be up to 10 MB in size only. Please upload a smaller MP3 file or encode your file with a lower bitrate”;
}
if ($error_messages = “”){
echo “You must fix these errors:
” . $error_messages;
}

move_uploaded_file($_FILES[‘user_file’][‘tmp_name’], $target_path);
echo "The file " . basename( $filename ) . “has been uploaded”;

?>[/php]

Problem here is that the file does indeed get uploaded, but with these warnings and a success message:

[i]Warning: move_uploaded_file(uploads/test.mp3) [function.move-uploaded-file]: failed to open stream: Permission denied in D:\Hosting\6110757\html\Test\upload.php on line 47

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move ‘D:\Temp\php\php641F.tmp’ to ‘uploads/test.mp3’ in D:\Hosting\6110757\html\Test\upload.php on line 47

The file test.mp3 has been uploaded[/i]

The permissions of the folder being uploaded to are correct. If i upload a jpg it goes in without a problem…which is a problem. Also the uploaded mp3 file size is reduced to 0

Change your compare to if-equal in line #43 and retest… If x=y is NOT if x==y In PHP, the == is used!

ErnieAlex,

For the original code I posted that did the trick. The only problem now is that even mp3’s won’t upload.

But hey, the error messages are correct!

maybe it has something to do with renaming the file. I’ll try that

EDIT:

So I was referencing $ending, but not actually saying what $ending should be. I added

[php]$ending = “.mp3”[/php]

and the code worked.

Thanks for all of the help everyone!

Great! Always a good feeling to solve a programming puzzle, right?

We will mark this one solved. CYA in the next puzzle…

Sponsor our Newsletter | Privacy Policy | Terms of Service