Why does simple PHP server not print or receive POST data? - php

I'm running a PHP server on command line with
php -S localhost:8000 index.php
and the contents of the server are
<?php
require 'vendor/autoload.php';
use Embed\Embed;
$embed = new Embed();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
flush();
ob_flush();
echo $_POST;
print($_POST);
var_dump($_POST);
// Prepare the response
$response = [
'status' => 'success',
'message' => 'why does this not reach you',
];
// Return the response as JSON
echo json_encode($response);
} else {
// Return an error response if the request method is not POST
$response = [
'status' => 'error',
'message' => 'Invalid request method. POST request expected.',
];
echo json_encode($response);
}
?>
The command line does react when requests come in like so:
[Fri Feb 3 18:11:47 2023] PHP 8.2.1 Development Server (http://localhost:8000) started
[Fri Feb 3 18:11:48 2023] 127.0.0.1:54363 Accepted
[Fri Feb 3 18:11:48 2023] 127.0.0.1:54363 Closing
but it says "Closing" almost immediately after the request comes in, and I can't get the contents of the request to print using echo, print, or var_dump. The client does get a response back but it looks like garbage:
{"_bodyBlob": {"_data": {"__collector": [Object], "blobId": "A4EEE117-0E46-46B3-9BA9-519F6B27357B", "name": "Unknown", "offset": 0, "size": 0, "type": "text/html"}}, "_bodyInit": {"_data": {"__collector": [Object], "blobId": "A4EEE117-0E46-46B3-9BA9-519F6B27357B", "name": "Unknown", "offset": 0, "size": 0, "type": "text/html"}}, "bodyUsed": false, "headers": {"map": {"connection": "close", "content-type": "text/html; charset=UTF-8", "date": "Sat, 04 Feb 2023 02:07:35 GMT", "host": "localhost:8000", "x-powered-by": "PHP/8.2.1"}}, "ok": true, "status": 200, "statusText": "", "type": "default", "url": "http://localhost:8000/"}
And I'm sending the request with React Native:
9 function getThumbnail(url){
8 fetch('http://localhost:8000/', {
7 method: 'POST',
6 headers: {
5 'Accept': 'application/json',
4 'Content-Type': 'application/json',
3 },
2 body: JSON.stringify({
1 data: url
0 })
1 })
2
3 .then((response) => {
4 console.log(response);
5 })
6 .catch((error) => {
7 console.error("got an error");
8 console.error(error);
9 });
10 }
I'm not sure what's going on because the server receives the request but doesn't seem to get any data from it, closes the connection immediately, and sends back a response that looks like garbage. Also haven't done much with PHP before so sorry if I'm missing something super basic.
I tried changing the server to print the contents of GET requests with print(implode($_GET)) and to navigate to localhost:8000 in my browser, but the contents of $_GET are empty as well:
Received GET request:

Looks like you are sending raw json data
Try something like this
$body = json_decode(file_get_contents('php://input'), true);
print_r($body );

Related

Catch request errors openapi-validation-middleware and change jsooutput

I use this repository hkarlstrom/openapi-validation-middleware to verify incoming and outgoing json requests and responses in my api build on php slim.
I want to rework the error output to another json format.
Currently it is, as example:
Error 400:
{
"message": "Request validation failed",
"errors": [
{
"name": "catalogus",
"code": "error_format",
"value": "",
"in": "query",
"type": "string",
"format": "uri"
}
]
}
I tried to catch this error so i can modify the repsonse like this:
$mw = new HKarlstrom\Middleware\OpenApiValidation(__DIR__.'/catalog_openapi.json');
$options = [
'validateRequest'=> false,
'exampleResponse' => true,
'beforeHandler' => function (\Psr\Http\Message\ServerRequestInterface $request, array $errors) : \Psr\Http\Message\ServerRequestInterface {
// Alter request modifiy the json reponse here !!!
echo "tadaaaa"; <- never outputted
return $request;
}
];
And finally in my route:
$app->get('/v1/dosomething[/{params:.*}]',\App\Action\DoSomething::class)->add($mw,$options);
But it never touches the before- or errorHandler.
Any ideas how to get this working?

How to fix "unexpected end of input" error when fetching json string output from PHP script [duplicate]

I tried a ReactJS fetch call to a REST-API and want to handle the response. The call works, i get a response, which i can see in Chrome Dev Tools:
function getAllCourses() {
fetch('http://localhost:8080/course', {
method: 'POST',
mode: 'no-cors',
credentials: 'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
objectClass: 'course',
crud: '2'
})
}).then(function (response) {
console.log(response);
return response.json();
}).catch(function (err) {
console.log(err)
});
}
When i try to handle the response, i got a "SyntaxError: Unexpected end of input" at
return response.json();
The console.log looks like this:
My Response JSON looks like this, it is valid, i checked it with jsonlint:
[
{
"0x1": {
"users": [],
"lectures": [],
"owner": "0x2",
"title": "WWI 14 SEA",
"description": null,
"objectClass": "course",
"id": "course_00001"
},
"0x2": {
"username": "system",
"lectures": [],
"course": null,
"solutions": [],
"exercises": [],
"roles": [
"0x3",
"0x4",
"0x5"
],
"objectClass": "user",
"id": "user_00001"
},
"0x3": {
"roleName": "ROLE_ADMIN",
"objectClass": "role",
"id": "role_00001"
},
"0x4": {
"roleName": "ROLE_STUDENT",
"objectClass": "role",
"id": "role_00002"
},
"0x5": {
"roleName": "ROLE_DOCENT",
"objectClass": "role",
"id": "role_00003"
}
}
]
You need to remove the mode: 'no-cors' setting from your request. Setting no-cors mode is exactly the cause of the problem you’re having.
A no-cors request makes the response type opaque. The log snippet in the question shows that. Opaque means your frontend JavaScript code can’t see the response body or headers.
https://developer.mozilla.org/en-US/docs/Web/API/Request/mode explains:
no-cors — JavaScript may not access any properties of the resulting Response
So the effect of setting no-cors mode is essentially to tell browsers, “Don’t let frontend JavaScript code access the response body or headers under any circumstances.”
People sometimes try setting no-cors mode when a response doesn’t include the Access-Control-Allow-Origin response header or else because the request is one that triggers a CORS preflight, and so your browser does an OPTIONS preflight.
But using no-cors mode isn’t a solution to those problems. The solution is either to:
configure the server to which you’re making the request such that it sends the Access-Control-Allow-Origin response header, and such that it handles OPTIONS requests
or set up a CORS proxy using code from https://github.com/Rob--W/cors-anywhere/ or such; see the How to use a CORS proxy to get around “No Access-Control-Allow-Origin header” problems section of the answer at No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
In your then you should check if the response is OK before returning response.json:
.then(function (response) {
if (!response.ok) {
return Promise.reject('some reason');
}
return response.json();
})
If you want to have the error message in your rejected promise, you can do something like:
.then(function (response) {
if (!response.ok) {
return response.text().then(result => Promise.reject(new Error(result)));
}
return response.json();
})
I know this answer might be super late and might have been resolved but i just had the same issue today and I just needed to add a ',' at the end of the headers hash and i stopped getting the error
export function addContacts(formData) {
return(dispatch) => {
dispatch({type: 'POSTING_CONTACTS'});
console.log(formData)
return fetch(uri, {
method: 'POST',
body: JSON.stringify({contact: {name: formData.name, phone_number: formData.phoneNumber}}),
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
})
.then(response => {
return response.json()
}).then(responseJSON => {
console.log(responseJSON)
return dispatch({type: 'ADD_CONTACT', payload: responseJSON});
})
}
}
You can avoid the problem with CORS policy by adding in the header of php or another server endpoint the row:
<?php
header('Access-Control-Allow-Origin: *');
//or
header('Access-Control-Allow-Origin: http://example.com');
// Reading JSON POST using PHP
$json = file_get_contents('php://input');
$jsonObj = json_decode($json);
// Use $jsonObj
print_r($jsonObj->message);
...
// End php
?>
Model of working fetch code with POST request is:
const data = {
optPost: 'myAPI',
message: 'We make a research of fetch'
};
const endpoint = 'http://example.com/php/phpGetPost.php';
fetch(endpoint, {
method: 'POST',
body: JSON.stringify(data)
})
.then((resp) => resp.json())
.then(function(response) {
console.info('fetch()', response);
return response;
});
Simply copy the following code and paste it on your web.config file under <system.webServer> tag.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>

POST request through Guzzle php

hi i wanted to make a post request to dropbox.i found there is this guzzle which can be easily send http req using php. here the http code given by dropbox
`POST /2/files/list_folder
Host: https://api.dropboxapi.com
User-Agent: api-explorer-client
Authorization: Bearer <access-token>
Content-Type: application/json
{
"path": "",
"recursive": false,
"include_media_info": true,
"include_deleted": false,
"include_has_explicit_shared_members": false
}`
This is my php code i coded for above request;
$response=$client->request('POST','https://api.dropboxapi.com',
[
'headers'=>[
'Authorization'=>'Bearer '.$API,
'User-Agen'=>'api-explorer-client',
'Content-Type'=>'application/json'
],
'form_params'=>[
'path'=>'',
'recursive'=>'false',
'include_media_info'=> 'true',
'include_deleted'=> 'false',
'include_has_explicit_shared_members'=> 'false'
]
]);
$headers = $response->getHeaders();
$body =$response->getBody();
$print=json_decode($body,true);
//Output headers and body for debugging purposes
var_dump($headers);echo"<br><br>";
var_dump($print);?>
this should give something similar to following ,but i get a small array
{"entries": [
{
".tag": "folder",
"name": "Photos",
"path_lower": "/photos",
"path_display": "/Photos",
"id": "id:bwGPfg_v6ZUAAAAAAAAAOA"
},`
what i missed here?
PS:im new to php related stuff :)
You are sending JSON, not an HTML form. So use 'json' instead of 'form_params'.

Retrieve data from Ajax request and pass it to another api with php

I am have set up a proxy that allows me to retrieve data user side from a api only accessible server side. I have several endpoints setup and they all work just fine, but now i'm at a point where I need to send data back to the api to make a reservation. I need to
retrieve data from ajax request in proxy
send data in proxy to api
return success/error message from api to ajax request
I not sure how to do this. Here is my ajax request:
var settings2 = {
"async": true,
"crossDomain": true,
"url": "http://url?method=hello&format=json&entity=" + id,
"dataType": "json",
"data": data,
"method": "POST"
};
var a2 = $.ajax(settings2);
$.when(a2).done(function(d2) {
rp = d2;
console.log(JSON.stringify(rp));
});
and the php function and method I use for the other endpoints that only need to retrieve data from the api, it works for this:
function LocationReserve(data) {
header('Content-Type: application/json');
$url = 'api_url' . $_GET['entity'] ;
$auth = 'Authorization: key';
$ch = curl_init($url);
$options = array(
CURLOPT_HTTPHEADER => array(
$auth
),
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION, 1
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Method A: Say Hello to the API
if( strcasecmp($_GET['method'],'hello') == 0){
$response['code'] = 1;
$response['status'] = $api_response_code[ $response['code'] ]['HTTP Response'];
$response['data'] = wssLocationReserve();
}
// --- Step 4: Deliver Response
// Return Response to browser
deliver_response($_GET['format'], $response);
with this as it is I get a response back
{"code":1,"status":200,"data":"{\"Message\":\"The requested resource does not support http method 'GET'.\"}"}
I added CURLOPT_POST => true to my options and now the response is
{"code":1,"status":200,"data":"<html><head><title>411 Invalid Request</title></head><body>Invalid Request: ??</body>\r\n"}
How can I modify this to accept the data from my ajax call, send it to the api_url, and send back the response?
**EDIT example expected data by api:
{
"ReservationDay": "05/15/2015",
"Units": [{
"UnitID": 12345,
"InsuranceID": 123 (or null)
}],
"PaymentInfo": {
"FirstName": "User",
"LastName": "Userson",
"Address1": "2727 N Central Ave",
"Address2": "",
"City": "Phoenix",
"State": "AZ",
"Zip": "85022",
"Phone": "602-2877878",
"Email": "email#example.com",
"CreditCard": "6011000000000000",
"ExpirationMMYY": "1215",
"CSC": "100"
}
}
"HTTP Status Code 411 (Length Required) is sent by the server as a response when it refuses to accept a message without a content-length header, for whatever reason."
1.- Test a request sending possible missing arguments.
2.- Have you the format in which the data must be send to the second endpoint? Check the specifications of the expected data and fix your second request.

Parsing twitter post JSON in PHP

I'm trying to parse the data from the Twitter API in PHP, I would like to receive back the image url media_url_https but I can't get to it. However, I can get the text object fine.
Here's my code:
$data=json_encode($twitter_data);
foreach($data as $item) {
echo $item['text'].'<br/>IMAGE_URL: '.$item['entities']['media']['media_url_https'];
}
Here's the JSON I'm trying to parse:
[
{
"created_at":"Fri Jun 17 22:24:10 +0000 2016",
"id":743932274996056064,
"id_str":"743932274996056064",
"text":"With a heavy heart... https:\/\/t.co\/Dd1M0b7G1P",
"truncated":false,
"entities":{
"hashtags":[
],
"symbols":[
],
"user_mentions":[
],
"urls":[
],
"media":[
{
"id":743932268314497024,
"id_str":"743932268314497024",
"indices":[
22,
45
],
"media_url":"http:\/\/pbs.twimg.com\/media\/ClL6dN3WEAAWykw.jpg",
"media_url_https":"https:\/\/pbs.twimg.com\/media\/ClL6dN3WEAAWykw.jpg",
"url":"https:\/\/t.co\/Dd1M0b7G1P",
"display_url":"pic.twitter.com\/Dd1M0b7G1P",
"expanded_url":"http:\/\/twitter.com\/taylorswift13\/status\/743932274996056064\/photo\/1",
"type":"photo",
"sizes":{
"small":{
"w":680,
"h":519,
"resize":"fit"
},
"thumb":{
"w":150,
"h":150,
"resize":"crop"
},
"medium":{
"w":1200,
"h":915,
"resize":"fit"
},
"large":{
"w":2048,
"h":1562,
"resize":"fit"
}
}
}
]
},
I can't see what's wrong, I'm probably missing something simple! Any help is appreciated!

Categories