file_get_contents(): stream does not support seeking - php

I'm getting this error:
`file_get_contents(): stream does not support seeking
I have no clue to fix it. There is no Resource Id or whatsoever.
This is my code:
$postData = array('name' => $name, 'description' => $description, 'date_begin' => $start, 'date_end' => $end);
$stream = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n"
. "Authorization: Basic Y3Nub2VrOnNuMDNr\r\n",
'method' => 'POST',
'content' => http_build_query($postData)
)
);
return stream_context_create($stream);
And in the file where the stream returns to. Its the function getApiContext.
$responseJson = json_decode(file_get_contents('http://10.0.0.89/api/v1/projects', false, BaseController::getApiContext(), true));
And then I get this annoying error. I know about cUrl, but I must use streams.

why have you got true on your file_get_contents offset param? perhaps you meant to put this in the json_decode if so, try this:
$responseJson = json_decode(file_get_contents('http://10.0.0.89/api/v1/projects', false, BaseController::getApiContext()),true);

It seems you are passing the fourth parameter to file_get_contents, this is not supported for remote streams (as per the documentation: http://no1.php.net/manual/en/function.file-get-contents.php)
Change your call to file_get_contents to exclude it (or pass it to json_decode if that was your intent).
$responseJson = json_decode(file_get_contents('http://10.0.0.89/api/v1/projects', false, BaseController::getApiContext()));

Related

Webservice not able to parse JSON Request from a PHP file

I'm trying to access a webservice. I'm already using this webservice from an android app but now I need to access some functions from a php document. If I use chromes advanced rest client application for testing it works fine if I select the POST option and application/x-www-form-urlencode as content-type. But when I try to access the webservice from my PHP file I get the response from the server that it can't find the value "tag". This is the code:
$data = array( 'tag' => 'something');
$options = array('http' => array(
'method' => 'POST',
'content' => $data,
'header' => "Content-Type: application/x-www-form-urlencode")
);
$context = stream_context_create($options);
$url = 'myurl';
$result = file_get_contents($url,false,$context);
$response = json_decode($result);
What is wrong with this code?
Thanks for any help!
Try this:
$data = http_build_query( array( 'tag' => 'something') );
As defined here, "Content" value must be a string: http_build_query generate the URL-encoded query string you need.

How to log into a web service with php post request

So i need to gain access to a web service containing some json, but to do so I was told to make use of PHP POST method to first log into the web service. I was giving an array with 3 types/values.
{
"Username":"user",
"password":"1234",
"LoginClient":"user"
}
I have been searching all day for a solution, but have come up short :(.
Any advice or push into a right direction would be much appreciated.
Hope I have explained this clearly enough.
you could do as follows:
$url = 'http://yourDomain.net/api/auth/';
$data = array('Username' => 'user', 'password' => '1234', 'LoginClient' => 'user');
$opts = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded\r\n",
'method' => 'POST',
'content' => http_build_query($data),
)
);
$context = stream_context_create($opts); //Creates and returns a stream context with any options supplied in options preset.
$response = file_get_contents($url, false, $context);
var_dump($response);
Or you could read about CURL as another option to make POST requests.

Wikimedia api and php

I am using the Wikimedia api and php. I need to get first main image from article and all text in article. I have got code for it, but it takes only short info and very little picture. I tried to change many parameters, but it is not working.
Code is here:
function get_wiki_url($title) {
$context = stream_context_create(array(
'http' => array(
'method'=>"POST",
'content' => $reqdata = http_build_query(array(
'action' => 'opensearch',
'search' => $title,
'prop' => 'info',
'format' => 'xml',
'inprop' => 'url'
)),
'header' => implode("\r\n", array(
"Content-Length: " . strlen($reqdata),
"User-Agent: MyCuteBot/0.1",
"Connection: Close",
""
))
)));
if (false === $response = file_get_contents("http://ru.wikipedia.org/w/api.php", false, $context)) {
return false;
}
//парсим строку
$xml = simplexml_load_string($response);
return $xml->Section->Item;
}
var_dump ($pages_data = get_wiki_url("article header"));
Your query appears to be running a search for $title (parameter action=opensearch); if you want the article and main image (I presume you want HTML, not wikitext), you need to use action=parse -- see the Mediawiki parse documentation.
Example URL for getting the Hyperloop page:
http://ru.wikipedia.org/w/api.php?action=parse&format=xml&page=Hyperloop
The documentation has details on all the options available.

PHP stream_context_create and HTTP headers - array or string, \r\n at the end, Content-Length optional?

I am troubleshooting some problems with POSTing to a remote site, specifically the remote host never returns any data (empty string).
Before I try to troubleshoot anything else, I want to make sure the calling code is actually correct. The code is:
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: application/xml",
'timeout' => 60.0,
'ignore_errors' => true, # return body even if HTTP status != 200
'content' => $send_xml
)));
$response = trim(file_get_contents($this->bulk_service_url, false, $context));
All my questions belong to the "header" option and it's values, and how to correctly format it and write it. The PHP documentation, discussion below it and even stackoverflow research yield very inconsistent results.
1) do I have to include the Content-Length header, and if not, will PHP calculate it correctly? The documentation does not include it, but I've seen many people include it manually, is it then respected or overwritten by PHP?
2) do I have to pass the header option as a string, or an associative array? Manual says string, majority pass it as a string, but this comment says that if PHP was compiled with --with-curlwrappers option, you have to pass it as an array. This is very inconsistent behavior.
3) when passing as a string, do I have to include terminating \r\n characters? Especially when specifying just one header. Manual does not provide such an example, first comment on manual page does include it, second one does not, again, no clear rule on how to specify this. Does PHP automatically handle both cases?
The server is using PHP 5.3.
You should really store your headers within code as an array and finalize the preparation just prior to sending the request...
function prepareHeaders($headers) {
$flattened = array();
foreach ($headers as $key => $header) {
if (is_int($key)) {
$flattened[] = $header;
} else {
$flattened[] = $key.': '.$header;
}
}
return implode("\r\n", $flattened);
}
$headers = array(
'Content-Type' => 'application/xml',
'ContentLength' => $dl,
);
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => prepareHeaders($headers),
'timeout' => 60.0,
'ignore_errors' => true,
'content' => $send_xml
)));
$response = trim(file_get_contents($url, FALSE, $context));
Preparing context try to add:
ContentLength: {here_calculated_length} in 'header' key preceded with \r\n
"\r\n" at the end of 'header' key.
So it should look like:
$dl = strlen($send_xml);//YOUR_DATA_LENGTH
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: application/xml\r\nContentLength: $dl\r\n",
'timeout' => 60.0,
'ignore_errors' => true, # return body even if HTTP status != 200
'content' => $send_xml
)));
Just a little improvement of the suggestion by #doublejosh, in case it helps someone:
(use of array notation and one-liner lambda function)
$headers = [
'Content-Type' => 'application/xml',
'Content-Length' => strlen($send_xml)
];
$context = stream_context_create(['http' => [
'method' => "POST",
'header' => array_map(function ($h, $v) {return "$h: $v";}, array_keys($headers), $headers),
'timeout' => 60.0,
'ignore_errors'=> true,
'content' => $send_xml
]
]);

Post JSON with PHP CURL to a Tin Can API LRS

Sorry, I can only post 2 hyperlinks so I'm going to have to remove the http : //
Background
I'm, trying to convert the code here: https://github.com/RusticiSoftware/TinCan_Prototypes/blob/92969623efebe2588fdbf723dd9f33165694970c/ClientPrototypes/StatementIssuer/StatementIssuer.java
into PHP, specifically the makeRequest function. This code posts data to a Tin Can Compliant Learner Record Store.
The current version of my PHP code is here:
tincanapi.co.uk/wiki/tincanapi.co.uk:MediaWikiTinCan
The specification for the Tin Can API which everything should conform to is here:
scorm.com/wp-content/assets/tincandocs/TinCanAPI.pdf
There is also a working java script function that Posts data in the right format here (see the XHR_request function I think):
https://github.com/RusticiSoftware/TinCan_Prototypes/blob/92969623efebe2588fdbf723dd9f33165694970c/ClientPrototypes/GolfExample_TCAPI/scripts/TCDriver.js
I don't have access to the code or server that I'm posting to, but the end result should be an output here: beta.projecttincan.com/ClientPrototypes/ReportSample/index.html
Problem
I'm trying to use Curl to POST the data as JSON in PHP. Curl is returning 'false' but no error and is not posting the data.
On the recommendation of other questions on this site, I've tried adding 'json=' to the start of the POSTFIELDS, but since the Java and JavaScript versions does have this, I'm not sure this is right.
Can anybody suggest either how I might fix this or how I might get useful errors out of curl? My backup is to output the relevant JavaScript to the user's browser, but surely PHP should be able to do this server side?
Very grateful for any help.
Andrew
At least one thing is wrong: you should not be using rawurlencode on your Authorization header value.
Consider using php streams and json_encode() and json_decode() instead. The following code works.
function fopen_request_json($data, $url)
{
$streamopt = array(
'ssl' => array(
'verify-peer' => false,
),
'http' => array(
'method' => 'POST',
'ignore_errors' => true,
'header' => array(
'Authorization: Basic VGVzdFVzZXI6cGFzc3dvcmQ=',
'Content-Type: application/json',
'Accept: application/json, */*; q=0.01',
),
'content' => json_encode($data),
),
);
$context = stream_context_create($streamopt);
$stream = fopen($url, 'rb', false, $context);
$ret = stream_get_contents($stream);
$meta = stream_get_meta_data($stream);
if ($ret) {
$ret = json_decode($ret);
}
return array($ret, $meta);
}
function make_request()
{
$url = 'https://cloud.scorm.com/ScormEngineInterface/TCAPI/public/statements';
$statements = array(
array(
'actor' => array(
'name' => array('Example Name'),
'mbox' => array('mailto:example#example.com'),
'objectType' => 'Person',
),
'verb' => 'experienced',
'object' => array(
'objectType' => 'Activity',
'id'=> 'http://www.thincanapi.co.uk/wiki/index.php?Main_Page',
'definition' => array(
'name' => array('en-US'=>'TinCanAPI.co.uk-tincanapi.co.uk'),
'description' => array('en-US'=> 'TinCanAPI.co.uk-tincanapi.co.uk'),
),
),
),
);
return fopen_request_json($statements, $url);
}
list($resp, $meta) = make_request();
var_export($resp); // Returned headers, including errors, are in $meta
We've now released an open source library specifically for PHP, it uses a similar method as the accepted answer but rounds out the rest of the library as well. See:
http://rusticisoftware.github.io/TinCanPHP/
https://github.com/RusticiSoftware/TinCanPHP

Categories