Php downloading

thenewprogrammer

New Member
Messages
45
Reaction score
0
Points
0
Trying to do something like rapidshare but on a loss for how to do it. Right now i have download page that makes links for all the users files they uploaded. But what i want to do is have the file on a download page like rapidshare which has custom download page when i go to the link instead of downloading it directly when i type the link in.


example of what i want to do:
http://rapidshare.com/files/315820206/crash.jpg.html


download.php
Code:
user = $session->username;
 
 $sql = "SELECT * FROM users WHERE username='$user'";
 $result= mysql_query($sql);
 $row= mysql_fetch_row($result);
 
 $path0= "../uploads/users/files/fi/";
 $path1 = $row[6];
 $path2 = $path0 . $path1;
// open this directory 
$myDirectory = opendir($path2);
// get each entry
while($entryName = readdir($myDirectory)) {
 $dirArray[] = $entryName;
}
// close directory
closedir($myDirectory);
// count elements in array
$indexCount = count($dirArray);
Print ("$indexCount files<br>\n");
// sort 'em
sort($dirArray);
// print 'em
print("<TABLE border=1 cellpadding=5 cellspacing=0 class=whitelinks>\n");
print("<TR><TH>Filename</TH><th>Filetype</th><th>Filesize</th></TR>\n");
// loop through the array of files and print them all
for($index=0; $index < $indexCount; $index++) {
        if (substr("$dirArray[$index]", 0, 1) != "."){ // don't list hidden files
  print("<TR><TD><a href=\"$path2/$dirArray[$index]\">$dirArray[$index]</a></td>");
  print("<td>");
  
  $ext = pathinfo($dirArray[$index], PATHINFO_EXTENSION); // When you set an option, the function returns a string
 if ($ext === 'jpg') {
 echo "jpg";
 } else if ($ext === 'png') {
 echo "png";
 } else if ($ext === 'gif') {
 echo "gif";
 } else if ($ext === 'php') {
 echo "php";
 } else if ($ext === 'zip') {
 echo "zip";
 } else {
 return false;
 }
  print("</td>");
  print("<td>");
  print(filesize($path2."/".$dirArray[$index].'')); 
  print("</td>");
  print("</TR>\n");
 }
}
print("</TABLE>\n");
 
Last edited:

misson

Community Paragon
Community Support
Messages
2,572
Reaction score
72
Points
48
First, take a close look at the ToS. X10 is not to be used for file storage. If you want a download site, store the files on RapidShare (or whatever site you prefer) and link to the download pages.

State what you have in addition to what you want. If something isn't working, this means state what you want to happen and what actually happens. If you just can't think of how to do something, state what you've been able to do. Be explicit; our part is to bridge the gap, not find the shore, though we may have suggestions for a better place to cross.

If you don't want to link directly to the files, link to a separate download script. The download script could link to the file, or redirect to the file, or dump the file's contents with readfile, after setting suitable headers such as "Content-type" (if it's installed, the Fileinfo extension can be of help). readfile is potentially a big security hole; if you use it, make sure the visitor is accessing a file you want to give them access to. On the other hand, if files are directly downloadable (which they are, if they're within the web folders), visitors can create their own links and bypass your download script.

PHP:
$sql = "SELECT * FROM users WHERE username='$user'";
Fetch only the columns you need. In fact, you should almost never "SELECT *", as it makes more work for you should you alter a table. It's appropriate in a script that makes no assumptions about table structure (such as phpMyAdmin's table browser), but little outside of that. Try something like:
Code:
SELECT upload_dir FROM users WHERE username=?

PHP:
$path0= "../uploads/users/files/fi/";
$path1 = $row[6];
$path2 = $path0 . $path1;
You don't need all the temporary variables. Do this in one line:

PHP:
$path= "../uploads/users/files/fi/" . $row['upload_dir'];


PHP:
// loop through the array of files and print them all
for($index=0; $index < $indexCount; $index++) {
	if (substr("$dirArray[$index]", 0, 1) != "."){ // don't list hidden files
The double quotes are completely unnecessary, since there's nothing else in the string. Either of the following are equivalent to the substr call and better.

PHP:
substr($dirArray[$index], 0, 1);
$dirArray[$index][0];
The second line works because strings can be treated like arrays of characters under limited circumstances. In this case, it's the one I recommend.

PHP:
		$ext = pathinfo($dirArray[$index], PATHINFO_EXTENSION); // When you set an option, the function returns a string
		if ($ext === 'jpg') {
			echo "jpg";
		} else if ($ext === 'png') {
			echo "png";
		...
If you find yourself writing a sequence of "if" statements that are that similar, there's a better way. Actually, if you find yourself writing a sequence of any similar statements, there's a better way (programs are well suited for abstracting similarity in order to reduce repetition). You could use a switch:
PHP:
switch($ext) {
case 'gif':
case 'jpg':
case 'png':
case 'zip':
    echo $ext;
	break;
default:
	return false;
}
or (my recommendation) an array:
PHP:
static $validExts = array('gif' => 1, 'jpg' => 1, 'png' => 1, 'zip' => 1);
...
    if (isset($validExts[$ext])) {
        echo $ext;
    } else {
        ...
    }
or (in this case) a regexp:
PHP:
if (preg_match('/^(gif|jpg|png|zip)$/', $ext)) {
    ...
Notice that I took out the 'php' extension. It's highly dangerous to let users upload any server side scripts, unless the directory is outside the web folders (another reason to put the upload directory outside the web folders), or all scripts are disabled within the directory. Users can archive PHP and other dangerous file types in zip files. I also recommend allowing 'bmp', 'jpeg', 'gz', 'bz2', 'rar' and '7z'. If you don't lowercase extensions upon uploading, make sure your code is case insensitive; simply wrap a call to strtolower around the call to pathinfo.

Also, returning when the file extension isn't on the whitelist will leave you with a malformed table. Better to determine if the file extension is valid before printing any part of the row, and simply continue if it isn't, skipping the current iteration.
 
Top