+ Post New Thread
Results 1 to 11 of 11
Web Development Thread, PHP Issues - file uploads in Coding and Web Development; Wotcha folks - have been on a mini mission of late writing a media library for the school's website. Basically ...
  1. #1
    Marci's Avatar
    Join Date
    Jun 2008
    Location
    Wakefield, West Yorkshire
    Posts
    895
    Thank Post
    84
    Thanked 235 Times in 194 Posts
    Rep Power
    82

    PHP Issues - file uploads

    Wotcha folks - have been on a mini mission of late writing a media library for the school's website. Basically I got sick of callouts to install blah codec to play blah video etc, so decided to shunt everything over to FLV thru the browser.

    We're using a FreeBSD (with WHM / cPanel) server, and I've got Lame / ffMpeg / FLVTool2 running happily to convert files on the fly and add MetaData. I'm now trying to automate the process so that authorised users can upload their own videos, which the server will then convert and relocate. Now, my PHP skills are limited... I know how to do what I can already do, but beyond that I hit brick walls rapidly. I've got a working system in place already that scans directories for FLVs and builds playlists which then feed into JWPlayer so the whole streaming / playback side is fine. The issue now rests with getting the files on there and converted... in the past this has been done on my workstation and I've then ftp'd them up to the server, but I'm after an easier way.

    Here's what I've got at the moment...

    The Upload Form:
    Code:
    <form enctype="multipart/form-data" action="processupload.php" method="POST">
        <input type="hidden" name="MAX_FILE_SIZE" value="104857600" />
        Send this file: <input name="userfile" type="file" />
        <input type="submit" value="Send File" />
    </form>
    processupload.php:
    Code:
    <?php
    error_reporting(E_ALL);
    ini_set("session.gc_maxlifetime","10800");
    $uploaddir = '/INCOMINGPATH/';
    $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
    
    echo '<pre>';
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
        echo "File is valid, and was successfully uploaded.\n";
    } else {
        echo "File upload was unsuccesful.\n";
    }
    if (chmod($uploadfile, 0744)) {
    	echo "CHMOD was succesful. \n";
    } else {
    	echo "CHMOD failed. File is executable. \n";
    }
    
    $last_line = system('ffmpeg -i '.$uploadfile.' '.$uploadfile.'.flv', $retval);
    $last_line = system('cat '.$uploadfile.'.flv | flvtool2 -U stdin '.$uploadfile.'.flv', $retval);
    exec('rm '.$uploadfile.'');
    
    echo 'Here is some more debugging info:';
    print_r($_FILES);
    print "</pre>";
    
    ?>
    Now, here are my issues.

    1 - I need it to limit the filetypes that can be uploaded to mpg, avi or mov...
    2 - The filename of the flv file produced is currently originalfilename.originalextension.flv - I need to lose the original extension...

    Any assistance would be immensely appreciated!

  2. #2
    Jona's Avatar
    Join Date
    May 2007
    Location
    Cranleigh
    Posts
    470
    Thank Post
    14
    Thanked 50 Times in 48 Posts
    Rep Power
    23
    You can use $_FILES["userfile"]["types"] to get the file type. See this example on w3c: PHP File Upload

    The cropping part should just be string manipulation, you might be able to do it just using strstr PHP: strstr - Manual

    something like strstr($outputfilename,".",TRUE)

    Hope that helps

    Cheers
    Jona

  3. #3
    Marci's Avatar
    Join Date
    Jun 2008
    Location
    Wakefield, West Yorkshire
    Posts
    895
    Thank Post
    84
    Thanked 235 Times in 194 Posts
    Rep Power
    82
    Ta muchly!!

    So, processupload.php now reads as follows:
    Code:
    <?php
    error_reporting(E_ALL);
    ini_set("session.gc_maxlifetime","10800");
    $uploaddir = '/home/horbury/public_html/beta/dynamic/push/incoming/';
    $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
    if ((($_FILES['userfile']['type'] == "video/mpeg")
    || ($_FILES['userfile']['type'] == "video/msvideo")
    || ($_FILES['userfile']['type'] == "video/quicktime")
    || ($_FILES['userfile']['type'] == "video/x-ms-wmv"))
    && ($_FILES['userfile']['size'] < 104857600))
    {
    echo '<pre>';
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
        echo "File is valid, and was successfully uploaded.\n";
    } else {
        echo "File upload was unsuccesful.\n";
    }
    if (chmod($uploadfile, 0744)) {
    	echo "CHMOD was succesful. \n";
    } else {
    	echo "CHMOD failed. File is executable. \n";
    }
    
    $last_line = system('ffmpeg -i '.$uploadfile.' '.$uploadfile.'.flv', $retval);
    $last_line = system('cat '.$uploadfile.'.flv | flvtool2 -U stdin '.$uploadfile.'.flv', $retval);
    exec('rm '.$uploadfile.'');
    
    echo 'Here is some more debugging info:';
    print_r($_FILES);
    print "</pre>";
    }
    else { echo "Invalid filetype - you may only upload files smaller than 100Mb ending in .mpg, .avi or .mov.\n"; }
    ?>
    Am still working on the outputfilename issue... will let you know!

    I do have a further issue but that's unrelated - for some reason files over a certain size won't upload despite restrictions on the form and php being set to 100Mb, and max uploads and max posts being set to 100M in php.ini

    Will concentrate on that one later!

  4. #4
    Jona's Avatar
    Join Date
    May 2007
    Location
    Cranleigh
    Posts
    470
    Thank Post
    14
    Thanked 50 Times in 48 Posts
    Rep Power
    23
    If your thinking of user's uploading big files you'll want to provide some form of a progress bar so the user knows something is happening. I've used uber-uploader Uber-Uploader - Free File Upload Progress Bar but it's perl based so ymmv....

  5. #5
    Marci's Avatar
    Join Date
    Jun 2008
    Location
    Wakefield, West Yorkshire
    Posts
    895
    Thank Post
    84
    Thanked 235 Times in 194 Posts
    Rep Power
    82
    Outputfilename sorted... ended up using substr()...

    Code:
    <?php
    error_reporting(E_ALL);
    ini_set("session.gc_maxlifetime","10800");
    $uploaddir = '/home/horbury/public_html/beta/dynamic/push/incoming/';
    $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
    $origname = basename($_FILES['userfile']['name']);
    $newname = substr($origname, 0, -4);
    $newfile = $uploaddir . $newname;
    if ((($_FILES['userfile']['type'] == "video/mpeg")
    || ($_FILES['userfile']['type'] == "video/msvideo")
    || ($_FILES['userfile']['type'] == "video/quicktime")
    || ($_FILES['userfile']['type'] == "video/x-ms-wmv"))
    && ($_FILES['userfile']['size'] < 104857600))
    {
    echo '<pre>';
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
        echo "File is valid, and was successfully uploaded.\n";
    } else {
        echo "File upload was unsuccesful.\n";
    }
    if (chmod($uploadfile, 0744)) {
    	echo "CHMOD was succesful. \n";
    } else {
    	echo "CHMOD failed. File is executable. \n";
    }
    
    $last_line = system('ffmpeg -i '.$uploadfile.' '.$newfile.'.flv', $retval);
    $last_line = system('cat '.$newfile.'.flv | flvtool2 -U stdin '.$newfile.'.flv', $retval);
    exec('rm '.$uploadfile.'');
    
    echo 'Here is some more debugging info:';
    print_r($_FILES);
    print "</pre>";
    }
    else { echo "Invalid filetype - you may only upload files smaller than 100Mb ending in .mpg, .avi or .mov.\n"; }
    ?>
    Progress bar.... hmmm.... next job!

  6. #6

    Join Date
    Nov 2007
    Location
    Preston
    Posts
    98
    Thank Post
    2
    Thanked 4 Times in 4 Posts
    Rep Power
    14
    Id throw in a few escapeshellcmd()'s and also a switch() or preg_replace filter on the file extension...

    Passing $uploadfile into into that system() is kinda scary, what happens if someone uploads a file named 'lol;rm -rf;.flv'.

    this isnt quite as valid because you rm the uploaded file, but you should consider naming the uploaded file as something like md5($uploadfile) that way the user cant preserve the file extension, for example if they uploaded a .php and you didnt rm it then you would have a potentially dangerous php file in your webroot. You should also probably consider uploading those files in ../public_html so that users cannot access them directly and they can only interface with your application.



    Great idea btw, i think il look at doing something similar!

  7. #7
    Marci's Avatar
    Join Date
    Jun 2008
    Location
    Wakefield, West Yorkshire
    Posts
    895
    Thank Post
    84
    Thanked 235 Times in 194 Posts
    Rep Power
    82
    Heh - getting beyond me fella... show me in code I can copy and paste...

    But anyhoo, this'll be a closed system accessible only to teachers here that know the password... there's a step that CHMODs the uploaded file to prevent it being executable in the case of a php file being uploaded, but mimetype restricts phps from going up (hardly a concrete infallible method, but works for a restricted userbase)...

    The rest of the system is as follows at the mo.

    This scans folder and outputs an XML playlist... there's a separate one for each folder involved... and a separate folder for each subject area.
    Code:
    <?php
    $filter = ".flv";
    $directory = "SUBJECT/";    //<< ie: Eng / Maths / Science etc...
    $site = "http://www.site.com/video/";
    
    @$d = dir($directory);
    if ($d) {
    while($entry=$d->read()) {
    $ps = strpos(strtolower($entry), $filter);
    if (!($ps === false)) {
    $items[] = $entry;
    }
    }
    $d->close();
    sort($items);
    }
    
    header("content-type:text/xml;charset=utf-8");
    echo "<playlist version='1' xmlns='http://xspf.org/ns/0/'>\n";
    echo " <title>SUBJECT Media Playlist</title>\n";
    echo " <info>http://www.site.com</info>\n";
    echo " <trackList>\n";
    
    foreach($items as $value)
    {
      $title = preg_replace('/.flv/', '', $value);
      $title = preg_replace('/_/', ' ', $title);
      print "    <track>\n";
      print "      <title>"    . $title . "</title>\n";
      print "      <location>" . $site  . '/video/' . $directory . '/' . $value . "</location>\n";
      print "    </track>\n";
    }
    
    echo " </trackList>\n";
    echo "</playlist>\n";
    ?>
    And embedding the mediaplayer and calling the playlist:
    Code:
    <script type="text/javascript" src="http://www.site.com/js/swfobject.js"></script>
                      <div id="player">Please enable Javascript to use our Media
                        Player</div>
                      <script type="text/javascript">
    var so = new SWFObject('http://www.site.com/video/mediaplayer.swf','mpl','620','260','8');
    so.addParam('allowscriptaccess','always');
    so.addParam('allowfullscreen','true');
    so.addVariable('height','260');
    so.addVariable('width','620');
    so.addVariable('file','http://www.site.com/video/PLAYLIST.php'); // <<playlist.php = the code above
    so.addVariable('backcolor','0x000000');
    so.addVariable('frontcolor','0xffffff');
    so.addVariable('lightcolor','0xffffff');
    so.addVariable('displayheight','240');
    so.addVariable('displaywidth','350');
    so.addVariable('overstretch','fit');
    so.addVariable('showstop','true');
    so.addVariable('showdownload','false');
    so.addVariable('repeat','list');
    so.write('player');
    </script>
    The player is from This site and the JW Player
    Last edited by Marci; 15th July 2008 at 03:16 PM.

  8. #8

    Join Date
    Nov 2007
    Location
    Preston
    Posts
    98
    Thank Post
    2
    Thanked 4 Times in 4 Posts
    Rep Power
    14
    $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

    escapeshellcmd($uploadfile) otherwise if the user had a ; in the filename, when you run it through system() it will execute it as a seperate command, breaking out of your ffmpeg.

    Its always fun to be secure

  9. #9
    contink's Avatar
    Join Date
    Jul 2006
    Location
    South Yorkshire
    Posts
    3,791
    Thank Post
    303
    Thanked 327 Times in 233 Posts
    Rep Power
    118
    There's a fair number of tutorials and references on cleaning your $_FILES input so no sense in repeating that here.

    As regards your upload ceiling.. I'd look at anything that allows you to cut the upload into chunks, writing the buffer to file at each point instead of the default which is to upload the file into memory which in itself causes all manner of "fun". Can't remember how it's done but I was prompted to sort this myself when I wrote a file management system some years ago.

  10. #10

    Join Date
    Nov 2007
    Location
    Preston
    Posts
    98
    Thank Post
    2
    Thanked 4 Times in 4 Posts
    Rep Power
    14
    Quote Originally Posted by contink View Post
    There's a fair number of tutorials and references on cleaning your $_FILES input so no sense in repeating that here.
    Well he obviously didnt read one ey?

  11. #11
    Marci's Avatar
    Join Date
    Jun 2008
    Location
    Wakefield, West Yorkshire
    Posts
    895
    Thank Post
    84
    Thanked 235 Times in 194 Posts
    Rep Power
    82
    Righty... so as it currently stands...

    Code:
    <?php
    error_reporting(E_ALL);
    ini_set("session.gc_maxlifetime","10800");
    $allowable_ext = array('avi','mpg','mov','wmv');
    $pieces = explode('.', $_FILES['userfile']['name']);
    $ext = $pieces[count($pieces) - 1];
    if(!in_array($ext, $allowable_ext)) {
    echo "Invalid filetype - you may only upload files smaller than 100Mb which end in .mpg, .avi, .wmv or .mov.\n";
    exit;
    }
    $uploaddir = '/UPLOADPATH/';
    $uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
    $origname = basename($_FILES['userfile']['name']);
    $newname = substr($origname, 0, -4);
    $newfile = $uploaddir . $newname;
    $uf = escapeshellcmd($uploadfile);
    $nf = escapeshellcmd($newfile);
    if ((($_FILES['userfile']['type'] == "video/mpeg")
    || ($_FILES['userfile']['type'] == "video/msvideo")
    || ($_FILES['userfile']['type'] == "video/quicktime")
    || ($_FILES['userfile']['type'] == "video/x-ms-wmv"))
    && ($_FILES['userfile']['size'] < 104857600))
    {
    echo '<pre>';
    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
        echo "File is valid, and was successfully uploaded.\n";
    } else {
        echo "File upload was unsuccesful.\n";
    }
    if (chmod($uploadfile, 0744)) {
    	echo "CHMOD was succesful. \n";
    } else {
    	echo "CHMOD failed. File is executable. \n";
    }
    
    $last_line = system('ffmpeg -i '.$uf.' '.$nf.'.flv', $retval);
    $last_line = system('cat '.$nf.'.flv | flvtool2 -U stdin '.$nf.'.flv', $retval);
    exec('rm '.$uf.'');
    
    echo 'Here is some more debugging info:';
    print_r($_FILES);
    print "</pre>";
    }
    else { echo "Invalid filetype - you may only upload files smaller than 100Mb which end in .mpg, .avi or .mov.\n"; }
    ?>

SHARE:
+ Post New Thread

Similar Threads

  1. PHP file lists contents
    By blackcat in forum Web Development
    Replies: 1
    Last Post: 19th January 2008, 09:09 PM
  2. File Uploads
    By dan400007 in forum Coding
    Replies: 1
    Last Post: 11th December 2007, 12:23 PM
  3. My PHP config file - please ignore
    By monkey_boy in forum Other Stuff
    Replies: 0
    Last Post: 24th April 2007, 11:29 AM
  4. PHP flat file database script
    By ajbritton in forum Web Development
    Replies: 3
    Last Post: 26th October 2006, 08:51 PM

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •