Forum Moderators: coopster
Uploaded files show in the proper directory.
But now I am left with a strange issue where I cannot access these uploaded images. I receive a HTTP 403 Forbidden error.
For what it is worth, I use Yahoo Web Hosting.
My goal is to be able to save these images to my directory, insert the file name and location into my database, and ultimately to call and display these images on a webpage.
Here is the exact code:
<?php
$directory_self = str_replace(basename($_SERVER['PHP_SELF']), '', $_SERVER['PHP_SELF']);
$uploadsDirectory = $_SERVER['DOCUMENT_ROOT'].'inserted/uploaded_files/';
$uploadForm = 'http://' . $_SERVER['HTTP_HOST'].'/upload.form';
$uploadSuccess = 'http://' . $_SERVER['HTTP_HOST'].'/upload.success.php';
// fieldname used within the file <input> of the HTML form
$fieldname = 'file'; // fieldname used within the file <input> of the HTML form
$fieldname = 'file';
// Now let's deal with the upload
// possible PHP upload errors
$errors = array(1 => 'php.ini max file size exceeded',
2 => 'html form max file size exceeded',
3 => 'file upload was only partial',
4 => 'no file was attached');
// check the upload form was actually submitted else print form
isset($_POST['submit'])
or error('the upload form is neaded', $uploadForm);
// check for standard uploading errors
($_FILES[$fieldname]['error'] == 0)
or error($errors[$_FILES[$fieldname]['error']], $uploadForm);
// check that the file we are working on really was an HTTP upload
@is_uploaded_file($_FILES[$fieldname]['tmp_name'])
or error('not an HTTP upload', $uploadForm);
// validation... since this is an image upload script we
// should run a check to make sure the upload is an image
@getimagesize($_FILES[$fieldname]['tmp_name'])
or error('only image uploads are allowed', $uploadForm);
// make a unique filename for the uploaded file and check it is
// not taken... if it is keep trying until we find a vacant one
$now = time();
while(file_exists($uploadFilename = $uploadsDirectory.$now.'-'.$_FILES[$fieldname]['name']))
{
$now++;
}
// now let's move the file to its final and allocate it with the new filename
@move_uploaded_file($_FILES[$fieldname]['tmp_name'], $uploadFilename)
or error('receiving directory insuffiecient permission', $uploadForm);
// If you got this far, everything has worked and the file has been successfully saved.
// We are now going to redirect the client to the success page.
header('Location: ' . $uploadSuccess);
// make an error handler which will be used if the upload fails
function error($error, $location, $seconds = 5)
{
header("Refresh: $seconds; URL=\"$location\"");
echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'."\n".
'"http://www.w3.org/TR/html4/strict.dtd">'."\n\n".
'<html lang="en">'."\n".
'<head>'."\n".
'<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">'."\n\n".
'<link rel="stylesheet" type="text/css" href="stylesheet.css">'."\n\n".
'<title>Upload error</title>'."\n\n".
'</head>'."\n\n".
'<body>'."\n\n".
'<div id="Upload">'."\n\n".
'<h1>Upload failure</h1>'."\n\n".
'<p>An error has occured: '."\n\n".
'<span class="red">' . $error . '...</span>'."\n\n".
' The upload form is reloading</p>'."\n\n".
' </div>'."\n\n".
'</html>';
exit;
} // end error handler
?>
But now I am left with a strange issue where I cannot access these uploaded images.
$uploadsDirectory = $_SERVER['DOCUMENT_ROOT'].'inserted/uploaded_files/';
Suplement to my reply in your other thread:
- How are you accessing these images?" If you are going to
example.com/inserted/uploaded_files/
And hoping to view all uploaded files, it may be simply that directory indexing is disabled for this directory - which is a good thing. You don't want someone snooping around in your directories.
If you do this
example.com/inserted/uploaded_files/sample.jpg
and get a 403, see other thread - it's likely a permissions issue or not going where you think they are going. The reason I say that is this:
$_SERVER['DOCUMENT_ROOT']
is not always the domain root. (Thx to phranque for the reminder.) With virtual hosting, you may have
[user account root]
cgi-bin
usr
public_html
public_html/sample.com
public_html/sampletoo.com
public_html/sample3.com
stats
error_log
(etc.)
In which case $_SERVER['DOCUMENT_ROOT'] may very likely be public_html, not public_html/domain name. Anything outside of public_html is likely disallowed, with the exception of cgi-bin (which PHP guys and gals never use.:-) )
Based on your response, I did the following:
1) looked for .htaccess and found that Yahoo does not allow access to them.
2) used ftp to upload a specific image directly...this showed up in the same directory as other files loaded via my form. And the file added via FTP was accessible.
3) entered the complete path in my browser...I was shown all the uploaded files resided in the directory, yet the only file I was able to access was the file loaded via FTP.
I guess I am looking at a permissions issue...is there any way to resolve this issue?
Or is this a hosting issue?
I would normally suggest checking the permissions of the parent directory(ies) first, but if you can view all contents, the directory is already read by all (this is not great, by the way, but you wouldn't change it using permissions, you'd change the domain or specific directory configuration to disable directory indexing.)
Review the chmod command [us3.php.net], (there are nuances you need to know) and how to use it. If you need more help understanding permissions, Google for chmod (the PHP chmod and the actual server command are the same name, but not the same thing.) Immediately after executing move_upload_file(), add a line to set the permissions on the uploaded file to read by all, write and execute by owner only.
$thisFile = $_SERVER['DOCUMENT_ROOT'].'inserted/uploaded_files/' . $filename;
chmod("$thisFile", 0644);
Note that we use the full server path as it's a system command, not a URL.
That should do it.
If i have a script, would I not have to have execute permissions as well to run that script?
You're mixing up the files with the scripts. First, (I am pretty sure, someone correct me) PHP scripts don't **need** execute permissions. With a Perl script, for example, you need to set permissions to execute or it will 500 error. This is one of the things administrators always liked about PHP - no more phone calls for "my script won't work" when it's just execute permissions.
Second, permissions are a multidimensional "array" if you will, usually expressed in columns for owner, group, other, and rows for read, write, execute. Do a G search for chmod to see what they all mean.
The problem you are having: your script, which is likely running under the owner "user account" or "Apache," writes a file. That file is now owned by that owner with **only** the owner having read/write/execute permissions on the file.
Along comes "everyone" or "world" (i.e., you in a browser, public access) and tries to view (read) the file, and there are no read permissions for "world." So they get denied.
For world or group, you should not need execute permissions on a file that only needs to be read. Always leave read/write/execute on for owner.
However - hopefully this won't confuse you, but follow the logic - let's say you have a script that opens and prints the files to your browser. If you want to protect the true location of your files, this is a very good approach.
This "reader" script is also under the same "owner" as your upload script. So this SCRIPT would be able to open the files and print them to the browser. This would allow you to leave the permissions alone, restricting "direct" access, making for increased security in respect to those files.
A scenario, only view images if logged in, done all the time on message boards.