How can I send an imagic-image with http post without writing image to a disk? The code below isn't working.
// function returns an Imagick Object
$image = $this->generateLvlImage($avatarUrl, $lvl);
// I want to send it with http post
$postRequest = new \HttpRequest($uploadUrl, \HttpRequest::METH_POST);
$postRequest->addRawPostData('photo='.(string)$image);
try {
$postRequest->send();
if ($postRequest->getResponseCode() === 200) {
$response = $postRequest->getResponseBody();
} else {
throw new \Exception('post.failed');
}
} catch (\HttpException $e) {
throw new \Exception($e->getMessage());
}
It's really hard to say for sure without knowing exactly who/what you're attempting to submit it to. Typically, you would base64_encode the image and then base64_decode it on the other end.
$postRequest->addRawPostData('photo='.base64_encode($image->getImageBlob()));
Edit: If you want to send it via multi-part form data then I couldn't give you an answer without plagiarising someoneelses work, so here is a tutorial on it: http://blog.cloudspokes.com/2013/01/reblog-post-multipartform-data-with.html
Related
Introduction
I have a base64 image string retrieved from a database: $imageBase64Str
I need to retrieve the mime from this content and display the image. This is what the following code does:
function imgMime($imgBytes){
if(is_null($imgBytes)){
return(false);
}
if(strlen($imgBytes)<12){
return(false);
}
$file = tmpfile();
if(!fwrite($file,$imgBytes,12)){
fclose($file);
return(false);
}
$path = stream_get_meta_data($file)['uri'];
$mimeCode=exif_imagetype($path);
fclose($file);
if(!$mimeCode){
return(false);
}
return(image_type_to_mime_type($mimeCode));
}
$imageBytes=base64_decode($imageBase64Str,true);
if(!$imageBytes){
throw new Exception("cannot decode image base64");
}
$imageMime=imgMime($imageBytes);
if(!$imageMime){
throw new Exception("cannot recognize image mime");
}
header('Content-type: '.$imageMime);
echo($imageBytes);
Question
The issue I have with this solution is that it requires me to write the 12 first bytes of the content to a temporary file. I am wondering whether there could be a simple way to avoid this without having to maintain a set of mimes manually. Also, I would like to avoid calling an external program (through exec for example) so that my code remains portable.
Ideally
I wish there was a php function like exif_imagetype_from_bytes. My imgMime function would be simpler:
function imgMime($imgBytes){
if(is_null($imgBytes)){
return(false);
}
if(strlen($imgBytes)<12){
return(false);
}
$mimeCode=exif_imagetype($imgBytes);
if(!$mimeCode){
return(false);
}
return(image_type_to_mime_type($mimeCode));
}
$imageBytes=base64_decode($imageBase64Str,true);
if(!$imageBytes){
throw new Exception("cannot decode image base64");
}
$imageMime=imgMime($imageBytes);
if(!$imageMime){
throw new Exception("cannot recognize image mime");
}
header('Content-type: '.$imageMime);
echo($imageBytes);
Edit: Solution based on selected answer
Thanks a lot to #Kunal Raut for the answer that allowed me to come up with the following solution:
function imgMime($imgBytes){
if(is_null($imgBytes)){
return(false);
}
if(strlen($imgBytes)<12){
return(false);
}
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime=$finfo->buffer($imgBytes);
if(strncmp($mime, "image/", 6) != 0){
return(false);
}
return($mime);
}
$imageBytes=base64_decode($imageBase64Str,true);
if(!$imageBytes){
throw new Exception("cannot decode image base64");
}
$imageMime=imgMime($imageBytes);
if(!$imageMime){
throw new Exception("cannot recognize image mime");
}
header('Content-type: '.$imageMime);
echo($imageBytes);
This solution is a lot more elegant IMHO.
The issue I have with this solution is that it requires me to write the 12 first bytes of the content to a temporary file. I am wondering whether there could be a simple way to avoid this without having to maintain a set of mimes manually.
This is because of this part of your code
if(!fwrite($file,$imgBytes,12)){
fclose($file);
return(false);
}
It makes you write minimum 12 bytes of data in the file and then lets the execution move forward.You can skip this if() and solve your first problem.
I wish there was a php function like exif_imagetype_from_bytes. My imgMime function would be simpler
Yes there is such function which returns you the type of the base64_decoded string.
finfo_buffer()
For more details regarding this function Click Here.
Use of function
Check out this
I'm using microsoft's graph api to upload files to onedrive. If the upload is successful, I'd like to delete the local file. My code is as follows:
public function testMoveFile()
{
$graph = new Graph();
$graph->setAccessToken($acccess_token);
$response = $graph->createRequest("PUT", "/drives/$drive_id/items/root:/$filename:/content")
->attachBody($content)
->execute();
if ($response->getStatusCode() > 201) {
var_dump($response);
} else {
// remove the file
}
}
The problem is that there doesn't appear to be a getter for the response http status code. When I use var_dump() to examine $response, I can see that there is a private property called _httpStatusCode, but when I try to access it, I get an error because it is private. When I looked through the unit tests, I don't see any checking. Is there another way to do it?
This was easier than I thought. To get the status code, you have to
if ($response->getStatus() > 201) {
I am trying to communicate to a php server from my gwt project.
I already got a GET request to work, however, my POST request doesn't work so far.
Here's my code:
Button synchronize = new Button("synchronize ",
new ClickHandler() {
public void onClick(ClickEvent event) {
String myurl = URL
.encode("php/test.php");
RequestBuilder builder = new RequestBuilder(
RequestBuilder.POST, myurl);
JSONObject jsonValue = new JSONObject();
jsonValue.put("name", new JSONString("Abc"));
builder.setHeader("Content-Type", "application/json");
try {
Request request = builder.sendRequest(jsonValue.toString(),
new RequestCallback() {
public void onError(Request request,
Throwable exception) {
processResponse("ERROR");
}
public void onResponseReceived(
Request request,
Response response) {
if (200 == response.getStatusCode()) {
processResponse(response
.getText());
} else {
processResponse("ERROR");
}
}
});
} catch (RequestException e) {
processResponse("ERROR");
}
}
});
public void processResponse(String responseString) {
Window.alert(responseString);
}
I can see that the post request goes out and the request payload is a json-object. However, when I try to access the data in the php script, I get the error that the index name is undefined.
Here's the PHP:
<?php
echo $_POST["name"];
?>
Is there something wrong with my PHP?
Does anyone have a working example for this?
While I haven't checked the PHP documentation so far, I tend to remember, that $POST contains the post request's variables, especially useful in a x-www-form-urlencoded request. .. Checked it, yes. I am right :-)
What you actually want is to read the body of the post request and parse it's JSON content to a PHP array or hash.
To read the body see here: How to get body of a POST in php?
$entityBody = file_get_contents('php://input');
Parsing json is described here: Parsing JSON file with PHP
I will not quote the code from there, as it maybe does not exactly fit your needs, but you look for json_decode($json, TRUE).
this might be a bit of a novice question and here is my situation:
i have a upload form for uploading images. and in my editAction i do:
if ($request->isPost()) {
if (isset($_POST['upload_picture']) && $formImageUpload->isValid($_POST)) {
//here i will add the picture name to my database and save the file to the disk.
}
}
$picVal = $this->getmainPic(); // here i do a simple fetch all and get the picture that was just uploaded
$this->view->imagepath = $picVal;
what happens is that the newly uploaded picture doesn't show. I checked the database and the dick and the file is there.
im thinking the problem might be the order of the requests or something similar.
any ideas?
edit: another thing is that in order to make the new image come up i have to do a SHIFT+F5 and not only press the browser refresh button
edit2: more code
i first call the upload to disk function then if that returns success addthe file to the database
$x = $this->uploadToDiskMulty($talentFolderPath, $filename)
if($x == 'success'){
$model->create($data);
}
the upload function
public function uploadToDiskMulty($talentFolderPath, $filename)
{
// create the transfer adapter
// note that setDestiation is deprecated, instead use the Rename filter
$adapter = new Zend_File_Transfer_Adapter_Http();
$adapter->addFilter('Rename', array(
'target' => $filename,
'overwrite' => true
));
// try to receive one file
if ($adapter->receive($talentFolderPath)) {
$message = "success";
} else {
$message = "fail";
}
return $message;
}
If the picture only appears when you do SHIFT+F5 that means it's a caching problem. Your browser doesn't fetch the image when you upload it. Do you use the same file name?
I've got problems with PHP PEAR and HTTP PUT. I want to create a HTTP PUT request and attach a file to it and send it to a REST service. Here's my current code:
require_once ('includes/HTTP_Request/Request.php');
$url = 'http://myurl.com/';
$req =& new HTTP_Request();
$req->setMethod(HTTP_REQUEST_METHOD_PUT);
$req->setURL($url);
$req->addHeader('Content-type', 'multipart/form-data');
$tmp_file = 'temp.rdf';
$result = $req->addFile('metadata', $tmp_file, 'text/xml');
if (PEAR::isError($result))
{
echo $result->getMessage();
}
$response = $req->sendRequest();
if (PEAR::isError($response)) {
echo $response->getMessage();
} else {
echo $req->getResponseBody();
}
This code should work correctly, but obviously is doesn't. I always get the respond by the REST repository that the header doesn't contain multipart/form-data.
Does anyone know what I can do to get the code to work? Thanks in anticipation!
Use setBody( string $body) instead of addFile.
Sets the request body (for POST, PUT
and similar requests)