Python to PHP on server send image - php

I have a raspberry pi running a lamp stack, an arduino and a camera hooked up. The end goal is that when my arduino takes a photo, it then writes an image to a php address which is then emailed.
Right now, I'm trying to get the image to get placed in the right place.
Here's my php snippet:
<?php
print_r($_FILES);
move_uploaded_file($_FILES["file"]["tmp_name"], "/var/www/images/mypic.jpg");
?>
My python code is doing:
import requests
r = requests.get('https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png')
r2 = requests.post('http://192.168.1.100/accept_image.php', data = r.content)
I realize the image is going to get overwritten. That's not a problem. I can always add a timestamp later etc etc.
However, this gives me an error code. I'm a beginner at php and use python mainly for scientific computing so not sure if I'm passing the picture correctly. I know that the ip is correct as I can connect to it and it's all in network.
I have looked at this Python script send image to PHP but am still getting stuck.
EDIT:
Upon further debugging:
print_r($_POST);
returns an empty array. Not sure why?

To have a file accessible to PHP in $_FILES, you must use HTML-form style encoding of files (multipart/form-data). This is different from a standard POST request including the content in the request body. This method is explained in http://php.net/manual/en/features.file-upload.post-method.php - the key here is:
PHP is capable of receiving file uploads from any RFC-1867 compliant browser.
What's you're trying to do is not sending it the RFC-1867 way, but a plain-old POST request.
So you have two options:
Send the data from Python using multipart/form-data encoding. It shouldn't be too hard but requires some work on the Python side.
Just grab the data on the PHP side not from $_FILES but by directly reading it from the POST body, like so:
.
$data = file_get_contents('php://input');
file_put_contents("/var/www/images/mypic.jpg", $data);
It's more of a memory hog on the PHP side, and means you need to do some validation that you actually got the data, but is quite simpler.
To clarify, in PHP $_POST is only populated when the Content-type request header is multipart/form-data or application/x-www-form-urlencoded (and of course the data is encoded in the proper way).
If you get a POST request with anything else in the body, you can read it directly by reading from the php://input stream, and you're responsible for handling / decoding / validating it.

Related

Inserting a curl response as a variable into HTML

I'm using Consuls KV store to store some data. You can retrieve these values through a simple HTTP API curl command such as:
curl https://consul.rocks/v1/kv/my-key?raw
To return the unencoded value
Is there anyway I can inject/insert the returned value as a variable into some HTML. I have no experience of front-end web development so unsure if this is applicable or feasible
You can implement curl values using PHP. Assuming you are new to web-development, I suggest you read about backend as well since it is critical for what you want to do.
Here is a rundown of what you need to do:
We want to insert an PHP tag into the document to get the curl value, so change the file extension to .php. Remember that you need to have php installed on you're server for this to work.
In the element where you want the curl value to be placed in, insert the following:
<?php echo curl_exec(curl_init("https://consul.rocks/v1/kv/my-key?raw")); ?>

How to get the name of a file sent to a php://input via wget post-file

I wrote a script that receives an image file through file_get_contents('php://input') and does some other magic. The file is sent from a client using the wget post-file=blahblah.blah command and it's all working fine.
The issue that I have is that I need to use the name of the received image file as a string for processing purposes and file_get_contents() gives me the content of the file but not the name of it.
Would anyone know how I can get the name?
Any answer that can put me in the right direction would be well appreciated.
You can't. The --post-file option to wget sends the contents of the file as a raw POST request; it does not treat it as a file upload, so the name of the file is not transmitted. Per the wget manual page:
--post-data=string
--post-file=file
Use POST as the method for all HTTP requests and send the specified
data in the request body. --post-data sends string as data,
whereas --post-file sends the contents of file. Other than that,
they work in exactly the same way. In particular, they both expect
content of the form "key1=value1&key2=value2", with percent-
encoding for special characters; the only difference is that one
expects its content as a command-line parameter and the other
accepts its content from a file. In particular, --post-file is not
for transmitting files as form attachments: those must appear as
"key=value" data (with appropriate percent-coding) just like
everything else.
There are numerous ways to go about getting the file name. I believe the classic way would be using url parameters ( POST your file to example.com/your-script.php?name=some-file-name-here ) but an alternative and possibly cleaner way would be using custom http headers: 'X-Filename: your-file-name'.
wget --header "X-Filename: your-file-name" --post-file /your/file
Then in PHP check for the headers ( using apache_request_headers() for example ).
PHP has a built in superglobal variable $_FILES, it works similar to $_POST.
$_FILES['/*the html object name goes here*/']['name']
The ['name'] part of the array returns the actual name of the file uploaded from the html object name.
So to clarify, if your html was <input type="file" name="screenshot" />
your PHP would be $name = $_FILE['screenshot']['name']
$name now stores the string that holds the name of the file.

Save binary request body as file

I wrote a program that reads a binary file into the RAM and then sends it using an HTTP request to my server. It uses the PUT method and the binary file is (in) the body.
Now how can I tell my server to receive and safe the file in a folder?
If possible without any additional libraries that I would need to download (unless it's more efficient).
I know, there are some similar threads to this one, but they either they where about receiving text or they were about doing it with libraries or there simply was no sufficient answer.
I'd also like to know, if it would be more efficient or smarter to use the POST method or any other instead of PUT.
You can get at the data by opening a stream to php://input, like so:
$datastr = fopen('php://input',rb);
if ($fp = fopen('outputfile.bin', "wb")){
while(!feof($datastr)){
fwrite($fp,fread($datastr,4096)) ;
}
}
As to whether to use POST or anything else depends on what is happening with the data, and whether you care about being RESTful or such. See other questions/answers, indempotency.
The advantage I would see with using POST is that it's more commonly used (on most submission forms where you upload a file), and therefore has more support from within PHP and html.

How to send data from one site and receive it on another in php

I have data in string format in a single variable in a php file on a wordpress site.
I want to fetch that variable's value through a php file on different server.
I want a way which will send that variable to my receiving php file that I have created on different server and print that values here.
In short, e.g. let there is data in mydomain1.com/send.php
which need to be stored or displayed in mydomain2.com/receive.php
But, without using form.There is no html form in sending file and also I don't want it since no redirection should be done.Just on a function execution in sending file data need to be transferred and displayed only on receiving end.
(I tried to find out solution for this using cURL.But, everywhere I found code to send data but what about receiving data, how can I capture that sent data and display at receiving end.)
If there is another solution except cURL or form submission I would appreciate.
Please help soon.
there are a lot of ways to do this, one way would be a SOAP client/server solution..:
you have basically 2 php files, one file on server1 is let say the client.php and on the other server there is the file named server.php which will receive all the data sent from client.php on server 1... here is a simple source, you need to change the URLs in the script to your server/client URLs so it works..:
client.php
<?php
//This is the SOAP Client which will call a method on Server 2 with passing some data:
//uri is the location where client.php is located, and "location" is the exact location to the client, including the name "client.php"
$client=new SoapClient(NULL,array("uri"=>"http://localhost/test","location"=>"http://localhost/test/test.php"));
$message=$client->hello("Hello World");
echo($message);
?>
server.php
<?php
//This is the SOAP Server
class server2{
public function hello($data){
return "I received following data: " . $data;
}
}
//the URI here is the location where the server.php is located.
$settings = array("uri"=>"http://localhost/test/");
$s=new SoapServer(null,$settings);
$s->setClass("server2");
$s->handle();
?>
Here's a tutorial: http://davidwalsh.name/execute-http-post-php-curl
Basically you can send the urlencoded values using CURLOPT_POSTFIELDS

PHP get PUT request body

I'm currently developing a Restful Json-API in PHP. I want to send a PUT-Request to items/:id to update a record. The data will be transferred as application/json.
I want to call the API with
curl -H "Content-Type: application/json" -X PUT -d '{"example" : "data"}' "http://localhost/items/someid"
On the server side, I'm not able the retrieve the request body. I tried
file_get_contents("php://input");
but this returns an empty string. Also a fopen()/fread() combination doesn't work.
When calling via POST, everything works great, I can read the json perfectly on the server side. But the API isn't Restful anymore. Does anyone have a solution for this? Is there another way to send and receive Json?
btw, I'm developing the API with the Slim Framework.
php://input is only readable once for PUT requests:
Note: A stream opened with php://input can only be read once; the stream does not support seek operations. However, depending on the SAPI implementation, it may be possible to open another php://input stream and restart reading. This is only possible if the request body data has been saved. Typically, this is the case for POST requests, but not other request methods, such as PUT or PROPFIND.
http://php.net/manual/en/wrappers.php.php
The Slim framework already reads the data upon request. Take the data from the Request object, into which it has been read.
On the server side, I'm not able the retrieve the request body. I tried file_get_contents("php://input");
You can only use file_get_contents( 'php://input', 'r' ); once per request. Retrieving its values will truncate the values as well, so if you call it twice, it'll return an empty string. Slim's request object contains the values you need, so:
<?php
$app = new Slim( );
$app->put( '/items/someid', function () use ( $app ) {
echo $app->request( )->put( 'example' ); // should display "data".
});
The example from the PHP manual uses fopen to access php://input in read mode. Have you tried doing it that way instead?
EDIT: The manual page for PHP:// says some stuff that seems to suggest that PUT data might not be available in some cases!
Note: A stream opened with php://input can only be read once; the
stream does not support seek operations. However, depending on the
SAPI implementation, it may be possible to open another php://input
stream and restart reading. This is only possible if the request body
data has been saved. Typically, this is the case for POST requests,
but not other request methods, such as PUT or PROPFIND.
I don't know where this will leave you regarding PUT processing. One page seems to say it's possible, the other seems to imply that it won't work under the wrong set of circumstances
I was reading the SLIM framework documentation the other day and it said that some browsers have problems with PUT and DELETE.
Excerpt:
Unfortunately, modern browsers do not provide native support for PUT requests. To work around this limitation, ensure your HTML form’s method is “post”, then add a method override parameter to your HTML form like this:
<form action="/books/1" method="post">
... other form fields here...
<input type="hidden" name="_METHOD" value="PUT"/>
<input type="submit" value="Update Book"/>
</form>
Source: http://www.slimframework.com/documentation/stable

Categories