I need to send HTTP POST data to a webpage. My host is missing some extensions (I'm not sure which ones). I tried cURL and fopen, neither of them work.
What are other ways to send data?
Edit: By the way, I can send $_GET data as well. So as long as I can open a url (eg. file_get_contents), it's works.
Checkout the very powerful PHP stream functions.
However, if the file/stream and cURL functions are disabled - then make them on the frontend using AJAX requests. jQuery is good at this as long as the data isn't sensitive.
I built an entire blog system using just jQuery JSONP requests on the frontend since I wanted to move the load to the user instead of my server.
This may work. The context is not really needed, but allows you to set custom timeout and user-agent.
/* Set up array with options for the context used by file_get_contents(). */
$opts = array(
'http'=>array(
'method' => 'GET',
'timeout' => 4,
'header' => "Accept-language: en\r\n" .
"User-Agent: Some UA\r\n"
)
);
/* Create context. */
$context = stream_context_create($opts);
/* Make the request */
$response = #file_get_contents('http://example.com/?foo=bar', null, $context);
if($response === false) {
/* Could not make request. */
}
You can use http_build_query() to build your query string from an array.
Related
I'm passing from http to https, and therefore I have to add a StreamContext to several read_file and get_file_contents calls.
I need to replace
read_file('http://'.$host.$uri);
by
$stream_context = stream_context_create([
/* some lenghty options array */
]);
read_file('https://'.$host.$uri, false, $stream_context);
Now my question: Is a $stream_context reusable like this:
$stream_context = stream_context_create([
/* some lenghty options array */
]);
read_file('https://'.$host.$uri, false, $stream_context);
get_file_contents($another_url, false, $stream_context);
read_file($even_another, false, $stream_context);
or do I need to recreate a new StreamContext for each URL ?
Asked differently: Is a stream context just a descriptor for parameters and options, or does it get bound to the resource when using it ?
Edit: It seems from the comments, that one can reuse StreamContext often, but not always. This is not quite satisfactory as an answer.
When can or should it be reused, and when can't it be reused ? Can someone shed some light on the internal working of StreamContext. The documentation looks quite sparse to me.
stream contexts are re-usable and they can be re-used always, not often.
The comment from #ilpaijin pointing to "unpredicted behaviour comment" is simple a misunderstanding of the author leaving the comment.
When you specify your context for HTTP wrapper, you specify the wrapper as HTTP regardless of schema you are targeting, meaning there is no such thing as HTTPS wrapper.
If you try to do the following:
"https" => [
// options will not be applied to HTTPS stream as there is no such wrapper (https)
]
The correct way:
"http" => [
// options will apply to http:// and https:// streams.
]
When should/could re-use?
It's really up to you and up to the logic you are trying to implement.
Don't forget you have default context set for all native PHP wrappers.
The example you have posted where you have the same context stream being passed to 3 different call s is unnecessary, simple use stream_context_set_default and set the default context for request originating from your code.
There are certain situations where you set the default but for one particular request you want to have different context, this would be a good idea to create another stream and pass it in.
Does the stream context contain state, like for instance cookies or tls initial negotiation that are passes from one call to another?
Stream context does not contain state, however you could achieve a mock like this with additional code. Any state, let it be cookie or TLS handshake, are simply request headers. You would need to read that information from incoming request and set it in the stream, and then pass that stream to other request, thus mocking "the state" of parent request. That being said - don't do it, just use CURL.
On a side, the real power of streams is creating your own/custom stream. The header manipulation and state control are much easier (and better) achieved with CURL.
It apparently serves as a connection object (same logic like with database connection) and can be reused in a similar way:
<?php
$default_opts = array(
'http'=>array(
'method'=>"GET",
'header'=>"Accept-language: en\r\n" .
"Cookie: foo=bar",
'proxy'=>"tcp://10.54.1.39:8000"
)
);
$alternate_opts = array(
'http'=>array(
'method'=>"POST",
'header'=>"Content-type: application/x-www-form-urlencoded\r\n" .
"Content-length: " . strlen("baz=bomb"),
'content'=>"baz=bomb"
)
);
$default = stream_context_get_default($default_opts);
$alternate = stream_context_create($alternate_opts);
/* Sends a regular GET request to proxy server at 10.54.1.39
* For www.example.com using context options specified in $default_opts
*/
readfile('http://www.example.com');
/* Sends a POST request directly to www.example.com
* Using context options specified in $alternate_opts
*/
readfile('http://www.example.com', false, $alternate);
?>
It appears that you can. I used xdebug_debug_zval and ran some simple tests to see if PHP was retaining it internally (I used PHP 7.1.3 with xdebug on an internal development server)
$context = stream_context_create(['https' => ['method' => 'GET']]);
xdebug_debug_zval('context');
$stream = file_get_contents('https://secure.php.net/manual/en/function.file-get-contents.php', false, $context);
xdebug_debug_zval('context');
$stream = fopen('https://secure.php.net/', 'r', false, $context);
xdebug_debug_zval('context');
What I got back was
context:
(refcount=1, is_ref=0)resource(2, stream-context)
context:
(refcount=1, is_ref=0)resource(2, stream-context)
context:
(refcount=2, is_ref=0)resource(2, stream-context)
Interestingly, the second call increased the refcount, meaning it was passed by reference internally. Even unsetting $stream didn't remove it or prevent me from calling it again.
Edit
Since the question was modified...
A context creates a resource data type. Because it contains an instance of PHP data, it is passed by reference implicitly, meaning that PHP is passing the internal data directly and not simply making a copy of it. There's no native way to destroy a context.
I agree with above answers, stream_context_create() will create and return handle to resource by taking option parameters for a connection. This can be re-used to different resources, as it is a handle. Does not matter, where it is used but needs to have handle within the request.
I am using PHP to get JSON from a remote server via file_get_contents command. Here is the piece of code I used:
$opts = array(
'https'=>array(
'method'=>'GET',
'header'=>'Accept-language: en\r\n' .
'Authorization: MAC ["3","ios2.5.0","123","123abc","123=","abc="]\r\n' .
'User-Agent: abc/1.1.1 iOS/10.0.2 iPhone/iPhone7,1\r\n'
)
);
$context = stream_context_create($opts);
$file = file_get_contents('https://www.google.com/v11/file?search=ios&with=users%2Cfiles%2Cquestions', false, $context);
echo $file;
I did a quick debugging:
Using Postman I was able to get the json file with the same header.
I tried a different json from a different url, it works.
I tried a local file, it works.
You have to understand what file_get_contents is. This command is a request to get the file on the server, in this case it is requesting to get https://www.google.com/v11/file/index.html on the server as in one single step. Since your url seems to use header to verify your origin, it might be an ajax request, meaning the server components didn't set up to allow an output from file_get_contents requests, instead they probably accept cURL requests.
So you can use:
curl_exec()
I have been given a URL that I need PHP to post data to, anonymously, without the end user knowing about it.
The exact structure is:
https://example.com/api/rest/example/createSubscription?email=1#1.com&subscriberNumber=12345JD&subscriberGroup=shop&firstName=Joe&lastName=Bloggs&offerCode=ex1&licenseParameters="STARTDATE%3D2014-08-11%26ENDDATE%3D2014-09-11"
Obviously this is a dynamic URL and I have set it up to be. I am not sure about the best way to approach this issue. Would it be a PUT http_request? I have tried that using the following but it returns a 400 error.
$url = 'https://example.com/api/rest/example/createSubscription?email=1#1.com&subscriberNumber=12345JD&subscriberGroup=shop&firstName=Joe&lastName=Bloggs&offerCode=ex1&licenseParameters="STARTDATE%3D2014-08-11%26ENDDATE%3D2014-09-11"';
$options = array(
'method' => 'PUT',
'timeout' => 15,
'header' => "Content-type: html/txt",
);
$response = http_request($url, $options);
As for your last comment, if the subscription is created simply opening the url in the browser then it is a GET request.
You can perform a GET request using file_get_contents
It's really strange you use PUT method with GET paramater.
After checking php manual here you don't use correctly this methode. that's why the server can't understand your request.
you can look after this function to do a PUT request
I would like to get the resulting web page of a specific form submit. This form is using POST so my current goal is to be able to send POST data to an url, and to get the HTML content of the result in a variable.
My problem is that i cannot use cUrl (not enabled), that's why i ask for your knowledge to know if an other solution is possible.
Thanks in advance
See this, using fsockopen:
http://www.jonasjohn.de/snippets/php/post-request.htm
Fsockopen is in php standard library, so all php fron version 4 has it :)
try file_get_contents() and stream
$opts = array( 'http'=>array('method'=>"POST", 'content' => http_build_query(array('status' => $message)),));
$context = stream_context_create($opts);
// Open the file using the HTTP headers set above
$file = file_get_contents('http://www.example.com/', false, $context);
I need a function that I can use in my script to contact another script to send it some GET data. But I need to be able to set a timeout so that it only loads for a few seconds, then continues with the rest of the script. I know I could easily use cURL to do this, but I'd like to know if there are any alternatives?
You can specify a timeout for the standard file access functions (like file_get_contents()) using stream_context_create():
<?php
$opts = array(
'http'=>array(
'method'=>"GET",
'timeout' => 5
)
);
$context = stream_context_create($opts);
$fp = fopen('http://www.example.com', 'r', false, $context);
fpassthru($fp);
fclose($fp);
?>
See the list of context options for an explanation on the timeout option.
This requires, of course, that you can access external URLs using fopen() and consorts.
The nice thing about curl, is it lets you uses threads even though php doesn't support them. So you can make the call to curl_multi, give it a callback, and let the rest of the script run. This way your regular processing isn't blocked. This reduces the need for a short timeout.