Hello everybody, i was struggling to figure out whether i can upload a file to a remote server using file_get_contents function.

i know i can post data! using the stream_context_create function. but i don't know if i can use this to post a file.

i don't prefer to use curl but if it's the only option i would appreciate someone explaining me how to achieve that with curl

the whole thing is about posting a file forom website A to website B which has the file called upload.php that will recieve the file and store it.

thanks for your help in advance.

    AL-Kateb wrote:

    the whole thing is about posting a file forom website A to website B which has the file called upload.php that will recieve the file and store it.

    So you're uploading a file by POST'ing it in a form to a PHP script (rather than using the PUT method)? I would probably suggest using cURL as well (it's not that scary of an extension, honestly 😉).

    If you were truly opposed to doing so, you might be able to create a stream context like this:

    $postdata = http_build_query(
        array(
            'var1' => 'form variable1',
            'file' => file_get_contents('path/to/file')
        )
    );
    
    $opts = array('http' =>
        array(
            'method'  => 'POST',
            'header'  => 'Content-type: application/x-www-form-urlencoded',
            'content' => $postdata
        )
    );
    
    $context  = stream_context_create($opts);

      So you're uploading a file by POST'ing it in a form to a PHP script (rather than using the PUT method)?

      I'm not sure about that! though when i tried your code the target page will still deal with the posted data in the $POST global did not move it to the $FILE global like when you are uploading it from a form which is exactly what I'm after, posting a file from php file instead than posting it from a form. and on the target page i will be dealing with it like any uploaded file.

      well.. curl can be scary sometimes : ) that's why i wanted an example for using it. and one more thing, some providers will not install it so i thought file_get_contents might be a good replacement

      in the method you wrote i guess i will be only able to post text data not images and other type of files.

      waiting for your reply
      thanks again

        AL-Kateb wrote:

        in the method you wrote i guess i will be only able to post text data not images and other type of files.

        What makes you say that?

          cos i tried writing the posted data $_POSt['file'] to a file "new.jpg" and it does not work! i thought it should not be anyway. we are using file_get_contents? can it handle images?

          but anyway i tried writing the data using fwrite and it did not work.

            I'm not sure what you're saying. The part where you include which file is to be uploaded to the remote PHP script is here:

            $postdata = http_build_query(
                array(
                    'var1' => 'form variable1',
                    'file' => file_get_contents('path/to/file')
                )
            );

            You'd change the '/path/to/file' to the appropriate path to whatever type of file you want to send.

              AL-Kateb wrote:

              $POSt['file']

              Uploaded files are in the $FILES array (see POST method uploads). To move it somewhere else when it has been uploaded, use [man]move_uploaded_file[/man].

              This is on Server B, of course.

                You'd change the '/path/to/file' to the appropriate path to whatever type of file you want to send.

                That's exactly what I'm doing, am i missing something regarding headers here?

                the file is being posted yes! but as text and in the $POST array not as a file in the $FILES array.

                Uploaded files are in the $_FILES array (see POST method uploads). To move it somewhere else when it has been uploaded, use move_uploaded_file.

                This is on Server B, of course.

                i did print_r for both the $FILES and the $POST arrays no data in the $FILES array! it's empty .. instead the data is in the $POST array and that makes sense cos what we did when we did file_get_contents and assigned it to the index file! all we did is that we assigned the fetched data inside the file right? we did not send the file as it is so how would PHP know we are intending to send a file here not the data it contains?

                  btw i did that with curl and it is working fine! but i was wondering if there is a way to do it with file_get_uploads.

                  here is the code i used:

                  $post = array();
                  $post['file_name'] = "@someimage.png";
                  $post['submit'] = "UPLOAD";
                  
                  $ch = curl_init();
                  $fullurl = "http://somesite.com/tests/takepost.php";
                  curl_setopt($ch, CURLOPT_URL, $fullurl );
                  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
                  curl_setopt($ch, CURLOPT_POST, 1 );
                  curl_setopt($ch, CURLOPT_POSTFIELDS, $post );
                  
                  $response = curl_exec( $ch );

                    Well, it would have to be the receiving server that gets the file. To do that it would have to know when to get it and what exactly to ask for. (Not to mention being allowed to get it - perhaps you don't want just anyone being able to request the file.)

                    So at some point the sending server will have to tell the receiving server what file it should get. But if the sending server is going to do that, it might as well send the file itself. And you're still in the situation where the sending server has to create something and send it to the receiving server.

                    So I'd go with one of the solutions here. It's the sending server that constructs a POST request that contains the file it's sending (the whole file, not just the name); the receiving server receives this request and processes in the usual fashion. The choice is who to construct that request: an http stream context (the sleekest solution); a cURL request (that thing needs a better interface); or you could go old school and do the whole protocol by hand and use fsockopen (but if cURL is scary...).

                      an http stream context (the sleekest solution)

                      as i said earlier i have no problem dealing with curl! at least not regarding the ease! but the availability. with curl it worked just fine. and with the request there will be cookies sent containing username and password. so not everyone can actually post a file .. just like any normal website with login feature where users get to upload files to.

                      the question was all about achieving this without using curl! say you are developing a software that will be widely used! it would not be a good idea to say ur software won't work unless curl extension is installed cos some providers don't install it.

                      so do u know how to do this like u said by creating http stream context? the method bradgrafelman mentioned will work fine with text files cos what it does is it gets the file contents and store it in a variable and POST this data using file_get_contets but this does not actuall "send" the file but it sends its contents.

                      probably i can never achieve this with file_get_contents?

                        AL-Kateb wrote:

                        this does not actuall "send" the file but it sends its contents.

                        What else is there to "send" about a file other than its contents?

                          What else is there to "send" about a file other than its contents?

                          in the php manual it says:

                          file_get_contents() is the preferred way to read the contents of a file into a string. It will use memory mapping techniques if supported by your OS to enhance performance.

                          how do you manage to store an image in a string? so reading the text file contents will work as it's only text and it can be stored in a string! so instead of sending the file you are sending the text it contains.

                          I'm not an expert but i think its like if you opened an image with a text editor and saved it as!

                          if you know a way to send the actual file instead of the data it contains which will be sent as a string then please tell me about it! (without using curl or other non-default extensions)

                            AL-Kateb wrote:

                            how do you manage to store an image in a string?

                            Same way you store any other data in a string, including text files. A string doesn't have to consist of only ASCII characters, you know.

                            AL-Kateb wrote:

                            so reading the text file contents will work as it's only text and it can be stored in a string!

                            Nope, binary data can be stored in a string as well. In fact, text is simply binary data that can be represented by ASCII characters humans can read.

                            AL-Kateb wrote:

                            so instead of sending the file you are sending the text it contains.

                            Again, data is data... doesn't matter if it's an ASCII character that you can read or not - it's all the same.

                              Same way you store any other data in a string, including text files. A string doesn't have to consist of only ASCII characters, you know.

                              and on the target page what do i do to store this posted data in a file say jpeg file?

                              by using fwrite? do i need to pass the data through any function before storing it in a file using fwrite?

                              btw i tried fwrite and wrote the posted data with fwrite and it came out corrupted (i tested it on an image).

                              and more important that all if it's like ure posting a file or uploading it should it be in the $FILES instead of the $POST array?

                                AL-Kateb wrote:

                                and on the target page what do i do to store this posted data in a file say jpeg file?

                                by using fwrite? do i need to pass the data through any function before storing it in a file using fwrite?

                                You shouldn't need to do anything to the data... it should be properly decoded when PHP parses the urlencoded string (assuming the content type was correctly set to 'application/x-www-form-urlencoded).

                                AL-Kateb wrote:

                                i tried fwrite and wrote the posted data with fwrite and it came out corrupted (i tested it on an image).

                                Any chance you could attach the original JPEG as well as the one you tried to recreate after POST'ing the image?

                                  i deleted it actually, am gonna test it on another file and attach it here in the next post thanks for your quick replies though.

                                    sorry! my fault i was trying it on a large file it seems but it never displayed me any memory errors though display errors is on but anyway i tried it now on a smaller file and it worked just fine! _

                                    sorry to waste your time cos of a mistake on my side.
                                    but i wanted to ask one last question regarding this. is there a way to make this handled like an uploaded file? not on the $POST array but in he $FILES array? like when using curl?

                                      AL-Kateb;10951173 wrote:

                                      is there a way to make this handled like an uploaded file? not on the $POST array but in he $FILES array? like when using curl?

                                      Yes; you'd have to use the "multipart/form-data" encoding type. See this page for a description of this type as well as some format examples. The relevant one, I believe, would be this:

                                         Content-Type: multipart/form-data; boundary=AaB03x
                                      
                                         --AaB03x
                                         Content-Disposition: form-data; name="submit-name"
                                      
                                         Larry
                                         --AaB03x
                                         Content-Disposition: form-data; name="files"; filename="file1.txt"
                                         Content-Type: text/plain
                                      
                                         ... contents of file1.txt ...
                                         --AaB03x--

                                      Takes a bit more work to construct the request, but it is possible to do.

                                        Thanks a lot for your help i will look it through to figure out how to do this

                                        thanks again

                                          Write a Reply...