Curl Delete function dumps json to browser - how to fix - codeigniter

The following function transfers a curl delete request to an api, and returns the response to php.
The api returns a json array for all requests (get, post, put and delete), and everything works fine for everything except delete requests.
The following curl function doesn't seem to be working properly:
function curl_delete($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_URL,$url);
$result = curl_exec($ch);
curl_close($ch);
return $result; // <-- Function ALWAYS returns whether this is here or not??!..
}
This is how I call the function from PHP:
// [DELETE API URL]:
$url = 'http://localhost/website/api/users/user/id/123';
$html = json_decode(curl_delete($url), true);
If you look at the function (above), whether or not I include the return statement (at the end of the function), the result of the curl call (the jsonified array) always gets dumped to the browser after the function has completed - which is not what I want.
If I then say echo count($html), the correct length of the returned result will print, and the $html array is working fine, however I can't seem to prevent it from automatically dumping to the screen.
This does not happen for any of the other curl functions, which just work as expected.
QUESTION:
Is this normal behaviour? How do I prevent the json from dumping to the screen?
PS Using Codeigniter & Phil Sturgeon's REST Server

You should try Phil Sturgeon's cURL library for Codeigniter and its method simple_delete() :
$this->load->library('curl');
$url = 'http://localhost/website/api/users/user/id/123';
$response = $this->curl->simple_delete($url);
$html = json_decode($response, TRUE);
If it does not solve your problem, maybe you will have to take a closer look at your REST server.

Related

How to send multiple files under the same name using CURL in php7+

Hi am trying to send multiple files in a php Curl operation. I am using PHP7.2 and trying to send 15 images under the same key.
If I am trying to send just 1 file its working just fine.
$post["image"] = new \CurlFile('image_full_path.png', 'image/png', 'file.png');
But when I am trying to put multiple files its not working anymore.
Already tried
$post["image[0]"] = new \CurlFile('image_full_path.png', 'image/png', 'file.png');
And
$post["image_0"] = new \CurlFile('image_full_path.png', 'image/png', 'file.png');
Does not work
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"url");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: multipart/form-data"));
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$response = curl_exec($ch);
$path = '/var/www/download/download.pdf';
file_put_contents($path, $response);
echo $response;
I believe you just need to create an associative array to send multiple images with the same key.
$post["image"] = [
new \CurlFile('image_full_path1.png', 'image/png', 'file1.png'),
new \CurlFile('image_full_path2.png', 'image/png', 'file2.png'),
];
It seems like the issue is with my destination of the request. The end point of the curl is written on Python Flask and it seems like if we send it like we do in php, flask dont understand it.
So in php
image[0] => 'image1.png'
image[1] => 'image2.png'
Can be valid and we will get both the files under image key in the request,
in python they are coming in different keys like
image[0] and image[1].
If we are tring to look for image in the request it will give an error, but image[0] and image[1] as a string are working fine.
The solution was to send the files as base 64encoded url in an associative array.
P.S. I am not an expert in Python, so my explanation can be wrong. If some one knows python and is aware if this issue please comment here.
Thank you.

Return a file in my controller that is downloaded from an API

I would like to return a file in my controller that is downloaded from an API (who needs a basic auth).
This API returns the file and the problem is I can't use ajax because of Access-Control-Allow-Origin, even when I add the basic auth in the header, it returns this error. And I don't have access to this API so I can't change it the config.
So I found another way! I call this API from my controller with the header and the basic auth. It's working! I can access this API and I don't have the error message: Access-Control-Allow-Origin.
But the problem is the API returns heavy files, and I have this exception OutOfMemoryException. It's normal.
So I would like to returns in my controller just a redirect link to this API with the header and basic auth to download the file. Do you think it's possible?
An example of what I want (But it's not working):
public function indexAction()
{
// API
$url = "http://api-who-callback-a-file.com/api/file";
//Create header
$curl = curl_init();
$url = sprintf("%s?%s", $url, http_build_query(false));
// Optional Authentication:
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "admin:admin");
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// Get file (Problem here because the file is to heavy to be downloaded by the server)
$result = curl_exec($curl);
curl_close($curl);
// Return the file
return $this->file($result);
}
In this example, it's not working because the server download the file and it's too heavy. Me I just want to return the URL with the Header to the client, and he will download the file.
Thank you

Is it possible to hide passed parameters in url while using redirect in controller? Yii 1.1

I am trying to pass parameter from my controller to my view.
My code is like this:
$this->redirect(array('marketingEmail/mailToSend','lot'=>$lotNum));
public function actionMailToSend()
{
$lotValue = Yii::app()->request->getQuery('lot');
$model=new Marketing();
$this->render('_mailList',array(
'lotVal'=>$lotValue,'model'=>$model,
));
}
My current url is like: http://localhost/test/marketingEmail/mailToSend/lot/1.
I want my url like: http://localhost/test/marketingEmail/mailToSend.
how can I achieve this?
No, it is not possible.
You can use session variable for your purpose. Save your id in session and get this id in your redirected page.
For more solution you can refer this URL.
No, it's impossible to make HTTP POST redirect using PHP. The only way to do it using user's browser side. For example generate page with form and submit it from window.onload.
You could perhaps use curl_exec on a REST API function that accepts a POST.
David Walsh wrote an article in 2008 entitled: Execute a HTTP POST Using PHP CURL
Quoting from the blog post:
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
Otherwise, use javascript.

Ask, how to use redirect without contition?

i have codes like this
function download(){
$id = $this->uri->segment(3);
$dat = $this->mikland->gidiklanfoto($id);
foreach ($dat as $item){
$name = $item->foto;
$data = file_get_contents(base_url()."/uploads/".$name); // filenya
force_download($name,$data);
}
redirect('cikland/viewiklan/'.$id);
}
when the function are running, redirect cannot run.,
somebody can help??
i think is a simple thing but i dont know the trick., thank's before
At the end of force_download() there is an exit() statement, so no code after a forced download will run.
And you are trying to have several files downloaded at the same time - using some sort of multipart mime type, that might or might not work, but not in the given case, because CI's force_download() does not seem to support that.
An alternative to that would be creating a temporary archive file which contains all the files for download; please have a look at the official documentation on compression and archives for that.
If you'd want to send a redirection header along with the file, you'd have to do it like this:
function download(){
// add this somewhere befor the download
header('Location: '.site_url('cikland/viewiklan/'.$id));
$id = $this->uri->segment(3);
$dat = $this->mikland->gidiklanfoto($id);
// only first item is downloaded
foreach ($dat as $item)
{
$name = $item->foto;
$data = file_get_contents(base_url()."/uploads/".$name); // filenya
force_download($name,$data);
}
}
But the question would remain how the browsers would deal with a redirect and content: most likely you would only get the redirect.
You need load url helper.
$this->load->helper('url');
after
redirect("cikland/viewiklan/$id", 'refresh');
or
redirect("cikland/viewiklan/$id", 'location', 301);
Font: http://ellislab.com/codeigniter%20/user-guide/helpers/url_helper.html
redirect() method redirects to a URL. You need to pass it a full URL (as it uses the header() function which according to the RFC for HTTP1.1 requires a full URL.
so you need to hard code the full url like the given example - redirect('http://www.yoursite.com/cikland/viewiklan/'.$id);

Avoid URL length limitation via POST

I am currently working on a web2print project based on Adobes Scene7. The full url to a print product (pdf) is very long and exceeds all browser limitation of url length. So to get the final print product I assume I have to submit the url in a different way via POST method.
There seem to be two ways: First, use a html form (method=post) and create all url parameters as (hidden) input fields. Second, make an ajax call (e.g. jQuery.ajax) with post.
Actually if I would open the print url in the browser, the ready pdf would be opened within the browser. So I need a way to send the very long url via POST to the server and open the PDF I get back from it. Testing the ajax version I ran into the same-origin-policy and get an error, as I call a url not on my local server. This must be a standard situation in web2print projects, how is this handled?
Thx in advance
Michbeck
I got the problem solved. I did it in two steps. First I use ajax to send the base url and the url parameters to a php script on my local server. It is easily done with jQuery:
jQuery.ajax({
type : "POST",
url : './includes/php/userdata.php',
data: { method: 'get_print_version',
url: base_url,
parameter: query_parameter,
num: num_parameter },
error: function(error) {
console.log("Print version failed");
},
success: function(reault) {
console.log("What is the result?");
}
});
The server script uses cURL to send the data to the final server. Therefore the base url and the parameters are not posted as one url but seperated by the use of CURLOPT_POST and CURLOPT_POSTFIELDS. The server response (a pdf) can be written to file with file_put_contents. If the PDF gets to big, you will get a memory limitation error here. Than it is better to write the answer from cURL directly to the pdf file.
if ($_method == 'get_print_version')
{
$url = $_REQUEST['url'];
$parameter = $_REQUEST['parameter'];
$num = $_REQUEST['num'];
$post = curl_init();
curl_setopt($post, CURLOPT_URL, $url);
curl_setopt($post, CURLOPT_POST, $num);
curl_setopt($post, CURLOPT_POSTFIELDS, $parameter);
/* write calendar directly to file */
$pdf = fopen('./Calendar.pdf', 'w');
curl_setopt($post, CURLOPT_FILE, $pdf);
curl_exec($post);
curl_close($post);
echo $result;
}

Resources