Mp3 File Upload In Php.....

Discussion in 'PHP' started by flawlessking, Jan 3, 2009.

Thread Status:
Not open for further replies.
  1. #1
    hi guys m new to php n was trying to make one basic php upload script so i took the tuts from w3schools, for jpeg, png its working fine but for mp3 it show invalid file please help me thru this following code...............



    <?php
    if ((($_FILES["file"]["type"] == "image/png")
    || ($_FILES["file"]["type"] == "audio/mp3")
    || ($_FILES["file"]["type"] == "image/pjpeg"))
    && ($_FILES["file"]["size"] < 2000000))
    {
    if ($_FILES["file"]["error"] > 0)
    {
    echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
    }
    else
    {
    echo "Upload: " . $_FILES["file"]["name"] . "<br />";
    echo "Type: " . $_FILES["file"]["type"] . "<br />";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

    if (file_exists("upload/" . $_FILES["file"]["name"]))
    {
    echo $_FILES["file"]["name"] . " already exists. ";
    }
    else
    {
    move_uploaded_file($_FILES["file"]["tmp_name"],
    "upload/" . $_FILES["file"]["name"]);
    echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
    }
    }
    }
    else
    {
    echo "Invalid file";
    }
    ?>
     
    flawlessking, Jan 3, 2009 IP
  2. crivion

    crivion Notable Member

    Messages:
    1,669
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    210
    Digital Goods:
    3
    #2
    crivion, Jan 3, 2009 IP
  3. BMR777

    BMR777 Well-Known Member

    Messages:
    145
    Likes Received:
    8
    Best Answers:
    1
    Trophy Points:
    140
    #3
    Don't listen to Crivion, the advise he posted will allow a user to upload ANY file to your server, including a PHP file or something else malicious.

    Try the following PHP code I wrote:

    <?php
    
    //**********************************************************************************************
    
    
    echo "Please wait while we attempt to upload your file...<br><br>";
    
    //**********************************************************************************************
    
    
    $target_path = "uploads/";
    
    $flag = 0; // Safety net, if this gets to 1 at any point in the process, we don't upload.
    
    $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."<br>";
    echo "Filesize: ".$filesize."<br>";
    echo "Type: ".$mimetype."<br><br>";
    
    }
    
    //First generate a MD5 hash of what the new file name will be
    //Force a MP3 extention on the file we are uploading
    
    $hashedfilename = md5($filename);
    $hashedfilename = $hashedfilename.".mp3";
    
    //Check for empty file
    if($filename == ""){
    $error = "No File Exists!";
    $flag = $flag + 1;
    
    }
    
    //Now we check that the file doesn't already exist.
    $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 - Only allow files with MP3 extention onto server...
    
    $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++;
    }
    }
    
    
    //Now we check the filesize.  If it is too big or too small then we reject it
    //MP3 files should be at least 1MB and no more than 6.5 MB
    
    if($filesize > 6920600){
    //File is too large
    
    if($flag == 0){
    $error = "The file you are trying to upload is too large!  
    Your file can be up to 6.5 MB in size only.  
    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, actually 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!<br>";
    if($error != ""){
    echo $error;
    }
    }
    
    ?>
    PHP:
    It's got a lot of security measures / checks in place to make sure your site doens't get hacked. Uploaded MP3 files are renamed as well as checked for filesize, file extension and content to make sure the file being uploaded to your site really is an MP3. :)

    BMR777
     
    BMR777, Jan 3, 2009 IP
  4. Danltn

    Danltn Well-Known Member

    Messages:
    679
    Likes Received:
    36
    Best Answers:
    0
    Trophy Points:
    120
    #4
    @Crivion: My God, that code is a hacker's paradise. He could upload .php or any other sort of file which your server would happily execute.

    Preserved your code as best possible, whilst simplifying it for you and adding validating + extra features (allows mp3s and pngs like your original post. Very easy to add more types.
    <?php
    
    $si = array( '', 'k', 'm', 'g' ); // You should extend this.
    define( 'BRNL', '<br />' . "\n" ); // Ja
    $types = array( 'audio/mp3' => 'mp3', 'image/png' => 'png' ); // Guess
    
    if ( isset($_POST['submit'] /* Whatever you have assigned to submit button/checker */ ) )
    {
        extract( $_FILES['file'], EXTR_PREFIX_ALL, 'file' );
        if ( in_array($file_type, array_keys($types)) and in_array(array_pop(explode('.', $file_name)), array_values($types)) and $file_size < 50000000 )
        {
            if ( $file_error > 0 )
                echo 'Return Code: ' . $file_error . BRNL;
            else
            {
                echo 'Upload: ' . $file_name . BRNL;
                echo 'Type: ' . $file_type . BRNL;
                echo 'Size: ' . round( $file_size / pow(1024, floor($l = log($file_size, 1024))), 2 ) . ' ' . $si[$l] . 'b' . BRNL;
                echo 'Temp file: ' . $file_tmp_name . BRNL;
    
                if ( file_exists('./upload/' . $file_name) )
                    echo $file_name . ' already exists. ';
                else
                {
                    move_uploaded_file( $file_tmp_name, './upload/' . $file_name );
                    echo 'Stored in: ' . 'upload/' . $file_name;
                }
    
            }
        }
        else
            echo 'Invalid file.';
    }
    else
        echo 'No file.';
    PHP:
     
    Danltn, Jan 3, 2009 IP
  5. crivion

    crivion Notable Member

    Messages:
    1,669
    Likes Received:
    45
    Best Answers:
    0
    Trophy Points:
    210
    Digital Goods:
    3
    #5
    I know guys, but I gave a simple reference for him and he didn't said the upload page will be public
    I thought its for an admin area protected and I am sure he doesn't want to upload a .php or other malicious code to himself right
     
    crivion, Jan 3, 2009 IP
  6. flawlessking

    flawlessking Well-Known Member

    Messages:
    136
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    101
    #6
    thx BMR777,crivion and Danltn your help is really appreciated
     
    flawlessking, Jan 4, 2009 IP
  7. Scottie1972

    Scottie1972 Peon

    Messages:
    1
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    I haqve this script that I have been working on but now I've hit a snag.
    The form is pretty simple with on exception. It uses a value array to add a certain number of inputs on the form.
    //AddSongs.php Form
    
    echo "<form method='POST' enctype='multipart/form-data' action='UploadMp3.php?id=$id'>";
    
    mysql_select_db("music", $con);
    $result2  = mysql_query("SELECT * FROM albums WHERE ID ='$id'");
    while($row = mysql_fetch_array($result2))
    {
    $numtrk = $row['numtrks'];
    }
    
    $maxtrks=$numtrk;  // Maximum number of images value to be set here
    for($i=1; $i<=$maxtrks; $i++)
    {
    echo "<tr>";
    echo "<td colspan=4 width=500>";
    echo "Title $i: <br><center>";
    echo "<input type='text' name='trktitle1' size=25 value='$i' /> <b>-</b> ";
    echo "<input type=file name='uploadedfile[]' /></center>";
    echo "</td>";
    echo "</tr>";
    }
    
    echo "<tr>";
    echo "<td colspan=4 align=center>";
    echo "<input type='submit' name='submit' value='Add Songs: $albumtitle Album' />";
    echo "</td>";
    echo "</tr>";
    
    echo "</table>";
    echo "</form>";
    
    PHP:
    As you can see the $maxtrks=$numtrk var tells the page how many inputs to implament when the page is loaded for the album.

    Now here is where I am having the trouble.
    How do I get the array to work in the MP3_Process.php?

    I have tried variation(sp) of this script that I found from you other post.

    http://forums.digitalpoint.com/showthread.php?t=1174500

    But I could never get it work at all.

    What needs to happen other then getting the array to work out, is to
    hash MD5 the filename then it moves the newfile to a directory that is made from another script that I have..

    If I add a new Band to the database, the script creates a folder in the
    /Albums/ folder.. name after the band's name.
    Then I have another form that allows me to add Albums to the Band.
    When this script is fired, it creates a folder named after the Album title in the
    Albums/$bandname/$albumtitle

    Now I need help on the script that uploads multiple mp3 files to that Band/Album/*.mp3 folder.

    Any ideas?

    Scottie
     
    Scottie1972, Aug 24, 2009 IP
  8. kblessinggr

    kblessinggr Peon

    Messages:
    539
    Likes Received:
    13
    Best Answers:
    0
    Trophy Points:
    0
    #8
    Security by Obscurity is not Security at all.

    If you're gona publish that on your blog, least make some kind of note to look into securing the script when on the web, or least mention something like turning off execute permission on the upload folder, or upload into a non-web-accessible folder.

    This is all you said:

    No mentions of being behind protected area or anything like that.
     
    kblessinggr, Aug 24, 2009 IP
  9. ghamal

    ghamal Peon

    Messages:
    1
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #9
    Thank you for this script BMR777! I've only tried it inside a developer enviroment(localhost) but It works great in IE6 and Google Chrome (after adding $mimetype != "audio/mp3" to the if() function checking for mime types.)

    However it fails on Firefox as Firefox wants to assign the mime type "application/octet-stream" to an mp3 I'm trying to upload. I could rewrite the code to allow that but that would allow all sorts of files into my upload directory. Anyone know what is the safest way to work around this?
     
    ghamal, Feb 20, 2010 IP
  10. inveni0

    inveni0 Peon

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #10
    I just wanted to add something to BMR777's code. The hashed file name should include a timestamp so that people naming their MP3 something common (like mysong.mp3) aren't rejected. It's easy to rename a file--true--but this breaks the user experience and can cause some confusion. Here is the new hashed file name code:

    
    //First generate a MD5 hash of what the new file name will be
    //Force a MP3 extention on the file we are uploading
    
    $hashedfilename = md5($filename.time());
    $hashedfilename = $hashedfilename.".mp3";
    
    Code (markup):
    With the above edit, the user's chances of being rejected for a common file name are slim to nil.
     
    inveni0, Mar 21, 2011 IP
  11. AustinQPT

    AustinQPT Member

    Messages:
    75
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    43
    #11
    That is a nice workaround but I think using a unique id or at least ip from the user would ensure they do not upload the same file twice saving time and money. If you do not have a unique session id you can assign here is the script reworked to incorporate ip.

    If you are positive you want to use time please use mktime it is much faster and accurate. I agree that encoding is a must to avoid dupes on a server wide basis.

    
    $ip = $_SERVER["REMOTE_ADDR"];
    $hashedfilename = md5($filename.$ip);
    $hashedfilename = $hashedfilename.".mp3";
    
    Code (markup):
     
    AustinQPT, Mar 21, 2011 IP
  12. inveni0

    inveni0 Peon

    Messages:
    2
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #12
    That's fair, but if you're worried about duplicate files and such to that extent, then the best option would be to implement a database to help manage the files. You could record IP, content hash, etc. It would be a piece of cake to check for duplicates.

    Another option would be to check each existing file against the uploaded file using something like getID3, but that would be resource intensive.
     
    inveni0, Mar 22, 2011 IP
  13. aerecords

    aerecords Peon

    Messages:
    3
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #13
    how would i do it so that after this the script extracts the ID3 data and puts it into a database?
     
    aerecords, Sep 15, 2011 IP
  14. HuggyEssex

    HuggyEssex Member

    Messages:
    297
    Likes Received:
    4
    Best Answers:
    2
    Trophy Points:
    45
    #14
    Just to note on the checking if the file already exists, you should always use is_file() rather is file_exists() as the last option will return true as the directory is there.

    Glen
     
    HuggyEssex, Sep 16, 2011 IP
  15. themullet

    themullet Member

    Messages:
    110
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    26
    #15
    themullet, Sep 16, 2011 IP
  16. thebeaird

    thebeaird Peon

    Messages:
    1
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #16
    I just added $hashedfilename into the query that inserted my $_POSTed data into the database.. that should do it!

    What would be the best practice to thriple up this code to allow it to upload three files instead of just one??
     
    thebeaird, Oct 14, 2011 IP
Thread Status:
Not open for further replies.