Jump to content

Uploading Image with PHP from non-root folder


Go to solution Solved by ginerjm,

Recommended Posts

I’ve got the basics of how file uploads in PHP work. Once the submit button has been clicked, I grab the important stuff like the file size and file extension and check to make sure the user isn’t uploading anything too big or weird. After that, you give the file a new name, then move it into a folder called “uploads” located in your root folder.
 

All resources I’ve found online say to use the move_uploaded_file() command to move the uploaded file from its temporary location ($_FILES['file']['tmp_name']) to that uploads folder. The problem is, all those resources give examples of rather small projects with all files located right in the root folder. In my case, the scripting file is not located directly in the root folder but within a folder called scripts in the root folder.

- MyProject 
   - pages 
   - scripts 
      - function.php 
   - style 
   - uploads

 

I’ve tried calling that move_uploaded_file() function with the destination as "uploads/ and as "../uploads/" (with the two dots in front) but neither work.

//Getting file and its name
$file = $_FILES["projImg"];
$fileName = $_FILES["projImg"]["name"];

//Getting temporary location of file and file extension (ie jpg, png, etc)
$fileTmpName = $_FILES["projImg"]["tmp_name"];
$fileNameSplit = explode('.', $fileName);
$fileExt = strtolower(end($fileNameSplit));

//Giving file new name based on time created
$fileNameNew = uniqid('', true).".".$fileExt; 

//Setting file new destination
$fileDestination = "../uploads/".$fileNameNew; 

//Trying to move file from temporary location to new destination, NOT WORKING :(
move_uploaded_file($fileTmpName, $fileDestination);

 

I think the problem is honestly that I can’t have dots within that move_uploaded_file() function. Whenever I echo $fileDestination, it gives me ../uploads/616deb42769007.77898958.jpg, instead of MyProject/uploads/616deb42769007.77898958.jpg.

The dots aren’t working within the function, so there must be some rule as to how to put relative file locations within that particular function. But I can’t find such a rule, which is why I’ve turned to this site after three days now of being stuck.

Is there something special I have to do to get the right relative location of the uploads folder?

Edited by AnxiousInSeattle
Realized that I didn't show where I was getting $fileName from

The dots are simply pointing to one folder up from the current loc.  If you have a folder MyProject under your root folder then why not specify that one?  Use the document root setting in $_SERVER and add MyProjects...... to it.  

PS - to what are you referring when you say 'root'?  The html root or the root of your domain?

@ginerjm

When I say root, I'm referring to the folder that all my project files are in. So in:

- MyProject 
   - pages 
   - scripts 
      - function.php 
   - style 
   - uploads

the "root" is MyProject.

 

I am aware of what the dots mean. The uploads folder is on the same level as the scripts folder, so if I’m in function.php, one dot to leave the file itself which puts me in the scripts folder, then one more dot to leave the scripts folder, then a slash to go into the uploads folder. It works for other functions like in the header() function to load another page, but not in the move_uploaded_file() function for some reason.

 

I don't understand what you mean by the $_SERVER stuff. Please elaborate.

  • Solution

Root to the rest of us is a specific term that is related to the domain or the html web root.  So I am assuming that your root myprojects folder is under the true html root folder.  So if you want your php commands to locate the folder you want you need to probably specify $_SERVER['DOCUMENT_ROOT']  as I mentioned along with the /MyProjects/../...... path to your desired folders.  

$_SERVER['DOCUMENT_ROOT'] . '/MyProjects'

would position in what you are calling root.  If you other folders are beneath that then add them to it with a leading backslash of course.

 

Hope this is what you are looking for.

  • Like 1

@ginerjm

Uhh, I'm not quite sure that my MyProject (singular, not plural by the way) folder is under the "true html root folder," because I'm not sure what that means.

For context anyway, I run Manjaro Linux (apparently based on Arch Linux), and since I'm using a lot of php, I had to download xampp and all my files have to be based out of its folder. So basically, the file I'm in right now (named addimg.php) is at location:

/opt/lampp/htdocs/MyProject/scripts/addimg.php

where / is the home folder. Like, when I go to just "/" on my file explorer, it just says that it's my internal hard drive.

The fact that I run Linux also means I can't use backslashes (\). Always has to be forward slashes.

 

Anyway, I will have to host this on an external server later, so I can't depend on the files on my computer not related to my project. Everytime I refer to another file, I always have to move within the MyProject folder. That is, I can't use the actual file location of /op/lampp... because it would just break my code when I run it on the server.

Hoping that was fine, I did the following:

$_SERVER['DOCUMENT_ROOT'] = '/MyProject';
fileDestination = $_SERVER['DOCUMENT_ROOT']."/uploads/".$fileNameNew;
move_uploaded_file($fileTmpName, $fileDestination);

(I also tried $_SERVER['DOCUMENT_ROOT'] . '/MyProject'; by the way)

The "/uploads/" part turns red for some reason, but I don't get an error and it runs. But, even though it runs without error, it doesn't work. My uploads folder is still empty :(

 

I hope that maybe my more in-depth explanation of my device and project file structure gives you any other context that you may have been missing, and you'd be able to help me out. This is my third day of being stuck on this problem, and I have no one around me to turn to for help.

Please let me know if you have any other suggestions. If you don't, please inform me of that as well. I'd rather know if I should just give up, than continuously refresh this page hoping for a reply...

Thanks.

So unfortunately there's three different "roots". Which one someone means depends on context.

1. When it comes to files and directories in Linux, / is the root. Not "home" - that's where your personal files are, and is typically /home/something.
2. When it comes to figuring out where stuff is when you're dealing with PHP code, the "root" means the place where your web server starts holding files. That would be /opt/lampp/htdocs.
3a*. When it comes to URLs and other things you see when you're browsing a website, the root is also / according to what's in your browser's address bar. Not including the http(s) or domain name but the first slash right after.

The second and third are closely related: the root of where your web server is hosting files is /opt/lampp/htdocs and that is the same as / in the address bar. Unless you tell your server differently, if you go to http://localhost/MyProject/uploads/whatever.ext then the web server is going to look for the web root (/opt/lampp/htdocs) + the path portion of the URL (/MyProject/uploads/whatever.ext) and try to find a file named /opt/lampp/htdocs/MyProject/uploads/whatever.ext.

What ginerjm is talking about is the second one, and whose value you can get in PHP with $_SERVER["DOCUMENT_ROOT"]. You do not set that value yourself. PHP gives it to you for free.

If you want to take a file upload and always place it in the root of your web site + /MyProject/uploads/ then you need the DOCUMENT_ROOT plus that path part (and probably plus a file name itself).

$fileDestination = $_SERVER["DOCUMENT_ROOT"] . "/MyProject/uploads/" . $fileNameNew;

Now here you've got a slight problem: that /MyProject piece. That's not going to be there in the real site, but you have it in your setup.
You have two basic choices for how to deal with that:

1. Tell your web server to host files out of MyProject. That requires going into the server configuration and changing some values. There's a right way and a wrong way of doing this, so rather than deal with that, just ignore this option.
2. Put all your MyProject files into the htdocs directory. This is really easy. The downside is that you can't have multiple websites anymore because http://localhost is always going to be what's in /opt/lampp/htdocs and that's always going to be the "MyProject" stuff.

Once you've moved the files you can get rid of the "MyProject" stuff in your code and your local site will be one step closer to working like the real site will.

$fileDestination = $_SERVER["DOCUMENT_ROOT"] . "/uploads/" . $fileNameNew;

* There's a 3b option where you might say "well no, I consider the root of my site to be http://localhost/MyProject". Saying things like that is an easy way to get everybody confused so stick with 1, 2, and 3a.

  • Like 1

Thank you so much for your help!!

It worked, but I'm new here (probably painfully obvious) and I'm not sure which answer I should mark as the solution... ginerjm for suggesting the right answer even though I didn't understand it or requinix for being able to explain giner's answer. Please let me know!

Appreciate the credit Requinix.  Hopefully OP will make sense of what we are telling him about 'roots'.

OP  - one thing that needs stressing.  Your statement

Quote

$_SERVER['DOCUMENT_ROOT'] = '/MyProject';

is something that you should NEVER do.  The global array $_SERVER (along with many others) is not for changing.  It is for reading only in order to gather info that you are seeking, not to save info that you want to use.

On my host my domain was setup by my provider to give me a 'root' of "/home/albany/public_html".  If I had wanted to setup all my 'stuff' in a myproject folder then I would append that to my provided root path to give me "/home/albany/public_html/myproject".

  • Like 1
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.