JSON malformed exception (Android Kotlin Retrofit PHP MySQL) - php

I am developing an app with Kotlin-PHP-MySql.
I will be appreciated if someone has an idea why I get this exception "com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path" when I call createUser function.
I don't get an exception when I call getUser function with Same api.
I checked these two functions in postman. JSONs are formatted properly. Begins with
{ "key" : "value", "key1" : "value1", .... }
This is my api:
interface Api {
...
#POST("/api/v1/users/register_user.php")
suspend fun createUser(
#Body userDto: UserInfoPreviewDto
) : QueryResponse
#POST("/api/v1/users/get_user.php")
suspend fun getUser(
#Body jsonObject : JsonObject
) : UserDto
}
and my Retrofit instance:
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(RamonApiUser::class.java)
and my server-side php code is
register_user.php file:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-
Headers, Authorization, X-Requested-With");
include_once("../../config/database.php");
include_once("../../classes/user.php");
$db = new Database();
$connection = $db->connect();
$user = new User($connection);
if($_SERVER['REQUEST_METHOD'] === "POST") {
$data = json_decode(file_get_contents("php://input"));
$user->username = $data->username;
$user->password = $data->password;
$user->fullname = $data->fullname;
$user->email = $data->email;
if($user->register()) {
http_response_code(200);
$result = array(
"status" => "200",
"message" => "saved"
);
echo json_encode($result);
}
else {
http_response_code(500);
echo json_encode(array(
"status" => "500",
"message" => "Error 500"
));
}
}
else {
http_response_code(503);
echo json_encode(array(
"status" => "503",
"message" => "Error 503"
));
}
this my get_user.php file:
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers,
Authorization, X-Requested-With");
include_once("../../config/database.php");
include_once("../../classes/user.php");
$db = new Database();
$connection = $db->connect();
$user = new User($connection);
if($_SERVER['REQUEST_METHOD'] === "POST") {
$param = json_decode(file_get_contents("php://input"));
if(!empty($param->id)) {
$user->id = $param->id;
$user_data = $user->getById();
if (!empty($user_data)) {
http_response_code(200);
$user_data['isPublicProfile'] = (bool)$user_data['isPublicProfile'];
$user_data['isLastOnlineVisible'] =
(bool)$user_data['isLastOnlineVisible'];
$user_data['isPhoneNumberVisible'] =
(bool)$user_data['isPhoneNumberVisible'];
echo json_encode($user_data);
}
}
}
else {
http_response_code(503);
echo json_encode(array(
"status" => "0",
"message" => "503 error"
));
}
getById() function in user.php :
public function getById() {
$sqlQuery = "SELECT * FROM ". $this->table_name ." WHERE id = ? LIMIT 0,1";
$obj = $this->conn->prepare($sqlQuery);
$obj->bind_param("i", $this->id);
$obj->execute();
$data = $obj->get_result();
return $data->fetch_assoc();
}
I have QueryResponse data class in the client-side with the fields status and message. user->register() returns true or false . I think the problem is with my json_encode method. I also tried this:
I created a QueryReponse php class with fields status and message and encode this object like this:
$query_response = new QueryResponse();
$query_response->status = "200";
$query_response->message = "registration successful";
$echo json_encode($query_response);
it didn't help either.

I created another file called get_query_response.php. Just to make sure that my QueryResponse classes are OK and doesn't throw exceptions.
get_query_response.php:
....
include_once("../../config/database.php");
include_once("../../classes/query_response.php");
$db = new Database();
$connection = $db->connect();
$query_response = new QueryResponse($connection);
if($_SERVER['REQUEST_METHOD'] === "POST") {
$query_response->id = 1;
$query_response_data = $query_response->getById();
// I fetch query_response_data from mysql
if (!empty($query_response_data)) {
http_response_code(200);
$result = array(
"status" => "500",
"message" => "save successfully"
);
echo json_encode($result); // doesn't throw exception.
works fine
//echo json_encode($query_response_data);
//when i use this line, it doesn't throw exception
//either. works fine
}
}
I call this file get_query_response.php from my api like this:
interface MyApi {
...
#POST("/api/v1/users/get_query_response.php")
suspend fun getQueryResponse() : QueryResponse
...
}
No errors, no exceptions. Both echo json_encode($result) and echo json_encode($query_response_data) works fine.
The only difference between two register_user.php and get_query_response.php files is this line:
$data = json_decode(file_get_contents("php://input"));
I don't get the reason why these two files behave differently. They are almost identical. Why does not this code work in register_user.php?
$result = array(
"status" => "200",
"message" => "saved successfully"
);
echo json_encode($result);
I finally solved the problem. It was my data class UserInfo. One field of the class was being assigned null during instantiation. Api is sending a class which two properties of that class has null values. The problem is solved by assigning values to those properties.

Related

Http failure during parsing for - angular http post to php

I am able to consume the php endpoint from postman. I try to do the same from angular post, I get this error - Http failure during parsing for. Even though everything looks perfect to me, the problem is surprising. Here is my snippet
php file
<?php
header('Access-Control-Allow-Origin: *');
// check for post
if ($_SERVER['REQUEST_METHOD']=='POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$conn = new db_CONNECT();
$cone=$conn->con;
//escpae the strings to be inserted to DB
$escapedname = mysqli_real_escape_string($cone, $name);
$escapedemail = mysqli_real_escape_string($cone, $email);
$escapedsubject= mysqli_real_escape_string($cone, $subject);
$escapedmessage = mysqli_real_escape_string($cone, $message);
// mysql inserting a new row
$sql = "INSERT INTO contacts(name, email, subject, message) VALUES ('$escapedname', '$escapedemail', '$escapedsubject', '$escapedmessage')";
// $result= $cone -> query($sql);
// $affected = $cone -> affected_rows;
if (mysqli_query($cone,$sql)) {
echo "Information saved successfully.";
} else {
echo "Not successful";
}
} else {
echo "Some field missing.";
}
?>
here is the angular snippet
saveContactDetails = function () {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
data.append('name', this.contactDeJson.name);
data.append('email', this.contactDeJson.email);
data.append('subject', this.contactDeJson.subject);
data.append('message', this.contactDeJson.message);
this.http
.post('http://localhost:80/'+'api/create_contact.php', data.toString(), {headers: myheader})
Please why am I getting this error
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost/api/create_contact.php","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost/api/create_contact.php",
I believe the issue is that your angular script is expecting a json response (the default responseType), but not receiving the correct headers or data. In stead of just echoing out your result in php, I would make a function that can handle sending the response. Something like this:
function sendJsonResponse(data, status = 200) {
header('Content-Type: application/json', true, status);
echo json_encode($data);
exit();
}
In stead of of doing this:
echo "Not successful";
You can now do this:
sendJsonResponse("Not successful", 500);
This should give you more valuable information in the frontend. And the response should now be formatted correctly, and no longer produce the parse error in angular that you are getting now.
I believe you are trying to send some query parameters using data variable. You could actually send a JS object as the parameters. Try the following
private saveContactDetails() {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const data = {
'name': this.contactDeJson.name,
'email': this.contactDeJson.email,
'subject': this.contactDeJson.subject,
'message': this.contactDeJson.message
}
this.http.post('http://localhost:80/'+'api/create_contact.php', { params: data }, { headers: myheader })
}

Post request is working in postman but not in ajax giving 405 method not found error

I am using localhost server with apache and mysql on xampp. I am implementing a login functionality for which php code is present in my api. When i make a POST request with POSTMAN result comes appropriately but when i make a ajax request i am getting 405 method not allowed error.
I think the headers are appropriately set but still i don't know why error is coming. I would highly appreciate if someone can point out why exactly is error coming and provide a solution code if possible.
this is my js code
```var sendRequest = function(formData) {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
response = JSON.parse(this.responseText);
console.log("request sent succesfully..");
return response;
}
if (this.readyState == 4 && this.status == 401) {
response = false;
return response;
}
};
request.open("POST","../api/objects/user/login.php",true);
request.setRequestHeader("content-type", "application/json");
request.send(formData);
};```
this is my php code.
<?php
// required headers
header("Access-Control-Allow-Origin:
http://http://127.0.0.1:8080/login.html" );
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-
Headers, Authorization, X-Requested-With");
include_once '../../config/database.php';
include_once 'user.php';
//files for json web token
include_once '../../config/core.php';
include_once '../../libs/php-jwt-master/src/BeforeValidException.php';
include_once '../../libs/php-jwt-master/src/ExpiredException.php';
include_once '../../libs/php-jwt-
master/src/SignatureInvalidException.php';
include_once '../../libs/php-jwt-master/src/JWT.php';
use \Firebase\JWT\JWT;
$db = new Database();
$conn = $db->getConnection();
$user = new User($conn);
$data = json_decode(file_get_contents("php://input"));
$user->email = $data->email;
$email_exists = $user->emailExists();
if($email_exists && password_verify($data->password, $user->password))
{
$token = array(
"iss" => $iss,
"aud" => $aud,
"iat" => $iat,
"nbf" => $nbf,
"data" => array(
"id" => $user->id,
"firstname" => $user->firstname,
"lastname" => $user->lastname,
"email" => $user->email
)
);
http_response_code(200);
//generate JWT
$jwt = JWT::encode($token, $key);
echo json_encode(
array(
"message" => "Succesful Login",
"jwt" => $jwt
)
);
}
else {
http_response_code(401);
echo json_encode(array("message" => "Login failed"));
}
?>
postman result on sending email and password as json
{
"message": "Succesful Login",
"jwt":
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3QiLCJhdWQiOiJodHRwOlwvXC9sb2NhbGhvc3QiLCJpYXQiOjEzNTY5OTk1MjQsIm5iZiI6MTM1NzAwMDAwMCwiZGF0YSI6eyJpZCI6IjIiLCJmaXJzdG5hbWUiOiJwcmFuYXYiLCJsYXN0bmFtZSI6ImFyb3JhIiwiZW1haWwiOiJhcm9yYS5wcmFuYXYuMjAwMEBnbWFpbC5jb20ifX0.npQWi4HP_QlGmmlkaPve3MBdn8u_yD_MxplUSKebNOY"
}
error shown by browser
login.js:25 POST http://127.0.0.1:8080/api/objects/user/login.php 405 (Method Not Allowed)

Unexpected 's' in json When

i try to build restAPI
when i check my code on postMan i got error that data incomplete
this is my code for create file
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
include_once 'database.php';
include_once 'inquery.php';
$database = new Database();
$db = $database->getConnection();
$product = new Inquery($db);
$jsn = file_get_contents("php://input");
$data = json_decode($jsn);
if(
!empty($data->enqType) &&
!empty($data->title) &&
!empty($data->deptid) &&
!empty($data->enq_body)&&
!empty($data->taskPriority)
){
$t = time();
$product->enqType = $data->enqType;
$product->title = $data->title;
$product->deptid = $data->deptid;
$product->enq_body = $data->enq_body;
$product->taskPriority = $data->taskPriority;
$product->addedDate = $t;
$product->addedBy = 0;
if($product->create()){
http_response_code(201);
echo json_encode(array("message" => "Product was created."));
} else{
http_response_code(503);
echo json_encode(array("message" => "Unable to create product."));
}
}
else{
http_response_code(400);
echo json_encode(array("message" => "Unable to create product. Data is incomplete."));
}?>
this is my json file that contains what i need
{
"title" : "title1",
"enqType" : 1,
"deptid" : 3,
"enq_body" : "some text",
"taskPriority" : 1}
i try all things, i see that this code dosen't accept string
in my checks i recived this errors :
unexpected 's' in the image shared below:

How to fix CORS error in PHP? (CORS did not succeed)

So I'm trying to make an endpoint to access my database with and it works just fine in postman, but when calling the GET request on my website i get a CORS error:
Query for foreign site blocked: The same origin policy does not allow remote resource reading http://IPGOESHERE/cordova/endpoint/log.php?id=-1. (Cause: The CORS query failed).)
I've tried googling but was unable to find anything useful.
My server-sided code is in 2 files which i have included below:
models/Log.php:
class Log {
// database connection and table name
private $conn;
private $table_name = "logging";
// object properties
public $ID;
public $UserID;
public $Handling;
public $Date;
// constructor with $db as database connection
public function __construct($db) {
$this->conn = $db;
}
// read products
function read($id)
{
$query = "SELECT * FROM " . $this->table_name;
if ($id != '-1') {
// select query
$query .= " WHERE logging.ID = ".$id;
}
// prepare query statement
$stmt = $this->conn->prepare($query);
// execute query
$stmt->execute();
return $stmt;
}
}
log.php
// required headers
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");
header("Content-Type: application/json; charset=UTF-8");
// database connection will be here
include_once '../database.inc';
include_once '../models/Log.php';
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$id = $_GET['id'];
$database = new Database();
$db = $database->getConnection();
$Log = new Log($db);
// query products
$stmt = $Log->read($id);
$num = $stmt->rowCount();
// check if more than 0 record found
if ($num > 0) {
$products_arr = array();
$products_arr["records"] = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
extract($row);
$product_item = array(
"ID" => $ID,
"UserID" => $UserID,
"Handling" => $Handling,
"Date" => $Date,
);
array_push($products_arr["records"], $product_item);
}
// set response code - 200 OK
http_response_code(200);
// show products data in json format
echo json_encode($products_arr);
} else {
// set response code - 404 Not found
http_response_code(404);
// tell the user no products found
echo json_encode(
array("message" => "No log found")
);
}
}
Turns out it was due to php not allowing me to use the class name "Log" renamed everything called log & it now works flawlessly.

How to fetch database from external using webhook in api.ai with PHP?

I have created agent in API.AI and I have created a database in Google Cloud Platform. I am able to connect to it using Navicat Premium to update the database of the bot. Also, I am able to use webhook using Heroku with PHP scripting. And I'm able to get response successfully with this code below
<?php
$method = $_SERVER['REQUEST_METHOD'];
// Process only when method is POST
if($method == 'POST'){
$requestBody = file_get_contents('php://input');
$json = json_decode($requestBody);
$intent = $json->result->metadata->intentName;
$entertype = $json->result->contexts->entertainmentType.original;
$response = array(
"messages"=> [array(
"type"=> 1,
"platform"=> "facebook",
"title"=> 'MBO Melaka Mall',
"subtitle"=> 'Tingkat 2, Kompleks Melaka Mall, Lebuh Air Keroh, 75450 Melaka',
"imageUrl"=> "http://s-yoolk-images.s3.amazonaws.com/my/gallery_images/medium/1435340336/67323?1435340336",
"buttons"=> [ array(
"text"=> "Search in Google",
"postback"=>"https://www.google.com/search?q=mbo+melaka+mall&oq=mbo+melaka+mall&aqs=chrome..69i57j5.6761j0j7&sourceid=chrome&ie=UTF-8"
)
]
)]
);
echo json_encode($response);
}
else
{
echo "Method not allowed";
}
?>
However, after I update this, I'm not able to get any response and I got error code 500 as internal server error. Please help me.
<?php
$method = $_SERVER['REQUEST_METHOD'];
// Process only when method is POST
if($method == 'POST'){
$requestBody = file_get_contents('php://input');
$json = json_decode($requestBody);
$intent = $json->result->metadata->intentName;
$entertype = $json->result->contexts->entertainmentType.original;
$username="root";
$password="pass";
$database="qwertytrek";
$connection=mysql_connect("35.200.241.96",$username,$password);*/
if(!$connection)
{
$speech = "No Connection";
}
else
{
$speech = "Connected to Google";
}
$selectdb = mysql_select_db($connection,$database) or die("Unable to select database");
if ($selectdb)
{
//echo = "database selected";
}
echo json_encode($response);
}
else
{
echo "Method not allowed";
}
function cybercafe($user)
{
}
?>

Categories