?
Solved

php creating an api post problem

Posted on 2016-08-23
9
Medium Priority
?
74 Views
Last Modified: 2016-08-26
Hi
it is the first time i learn how to write an api. i have the folder structure of: apihub/v1/api.php

the GET part works: i get all the customers and a customer according to an id. i have issue with POST variables.

i read that instead of reading POST array one should use : file_get_contents("php://input")

so i have this code:
    $customer = json_decode(file_get_contents("php://input"));

    var_dump($this->get_request_method());
    var_dump($customer);

Open in new window


and when i use the chrome extension i get NULL, but if i don't use the json_decode i so get the json string. what am i missing here? and how can i use that, cause according to it i want to write the query to the database.
post data stringgetting null with the decode
best regards
0
Comment
Question by:derrida
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +1
9 Comments
 
LVL 35

Assisted Solution

by:gr8gonzo
gr8gonzo earned 1000 total points
ID: 41767178
So the content type of the request is going to determine whether or not you get a $_POST array. When you're POSTing a web form, browsers usually submit a content type of "application/x-www-form-urlencoded" which tells PHP, "Hey, the content inside the POST data is simply a list of fields and their values from a web form." PHP then knows to transform that content ("foo=1&bar=abc") into $_POST ($_POST["foo"] = 1, $_POST["bar"] = "abc").

If you're dealing with situations where the content type isn't passed or the content type value does not specify form encoding, then PHP will not auto-populate the $_POST variable.

In those scenarios, the only way to access the raw post data is from that special php://input stream.

If it's form-encoded data but is missing the right content type, you can use this common little one-liner
to re-create the $_POST array:
parse_str(file_get_contents("php://input"), $_POST);

To be honest, that seems to match the type of data you're showing in the screenshots. Your first screenshot doesn't show JSON data - it shows form-encoded data, so the above line would give you a $_POST array with your values.

Now, if the POSTed data really is something else, like JSON or XML (maybe you want to accept those types of content as alternatives), then you'd use the methods you've described in your post (file_get_contents() to retrieve the raw string, then json_decode to convert the string into an object).

If it's really JSON and you're getting a null in response, then that means PHP couldn't decode the JSON for some reason. Maybe it's malformed or something. PHP is extremely finicky when it comes to decoding JSON - it'll either work perfectly or not at all. So if you get a null, then the best thing to do is to make sure you separate out the file_get_contents and json_decode lines, trim and then dump out the string so you can paste it into a JSON checker:

$raw_post_data = file_get_contents("php://input");    // Get the raw POST data
$raw_post_data = trim($raw_post_data);                      // Get rid of any surrounding whitespace
file_put_contents("last_request.json",$raw_post_data); // Write a new file containing the POST data
$decoded_object = json_decode($raw_post_data);
var_dump($decoded_object);
0
 
LVL 13

Expert Comment

by:Abhijeet Rananaware
ID: 41767224
Try to verify data your are posting is in a correct format. I was getting the same error when the issue was with the  JSON format.

http://json.parser.online.fr/
1
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 41767495
Have you tried var_dump($_POST)?  Or maybe var-dump($_REQUEST)?  The latter should also include the $_GET and $_COOKIE information.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 1

Author Comment

by:derrida
ID: 41768212
hi
gr8gonzo good explanation, yet with your separation, i still get NULL. and with the chrome browser extention i do use: application/x-www-form-urlencoded

ray: i attach the image of bar_dump post. the values are there. so somehow the json_decode return NULL and i don't understand why.
should i just use regular post array, in order to query the database? therefore skeep the decode or totally the file_get_contents? again, the question is why i get the NULL.

post values
0
 
LVL 111

Expert Comment

by:Ray Paseur
ID: 41768865
json_decode return NULL and i don't understand why.
PHP has ways of discerning the errors in JSON strings.

It would be easier for us to help you if you would post the test data and code snippets instead of pictures  of test data and code!  We could use copy / paste to ensure we were working with the same test data set you're using.  Please have a look at var_export().

Here is my teaching example showing how to decode json strings and detect errors, if any.
<?php // demo/json_decode_show_errors.php
/**
 * JSON stands for JavaScript Object Notation
 * http://json.org/
 *
 * JSON support in PHP does not have very good error handling
 *
 * JSON strings are all UTF-8
 * http://www.experts-exchange.com/articles/11880/Unicode-PHP-and-Character-Collisions.html
 *
 * PHP man page references
 * http://php.net/manual/en/json.constants.php
 * http://php.net/manual/en/function.json-decode.php
 * http://php.net/manual/en/function.json-encode.php
 * http://php.net/manual/en/function.json-last-error.php
 * http://php.net/manual/en/function.json-last-error-msg.php
 */
error_reporting(E_ALL);
echo '<pre>';

// SEE TEST DATA AT http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_28523915.html#a40339939
$jso = <<<EOD
{"id":"tag:search.twitter.com,2005:389903668427763712","objectType":"activity","actor":{"objectType":"person","id":"id:twitter.com:91239297","link":"http://www.twitter.com/OGkush103","displayName":"WalkingLick74","postedTime":"2009-11-20T01:21:39.000Z","image":"https://si0.twimg.com/profile_images/378800000593715086/755411d8bdc495472c2d7ed50e319582_normal.jpeg","summary":"Self-Made, Self Paid..... I always had the mind to get it like a man, head first bout my younging Ean! #YOLO","links":[{"href":null,"rel":"me"}],"friendsCount":468,"followersCount":677,"listedCount":0,"statusesCount":25504,"twitterTimeZone":"Alaska","verified":false,"utcOffset":"-28800","preferredUsername":"OGkush103","languages":["en"],"location":{"objectType":"place","displayName":"Boston George Crib"},"favoritesCount":26},"verb":"post","postedTime":"2013-10-15T00:00:53.000Z","generator":{"displayName":"Twitter for iPhone","link":"http://twitter.com/download/iphone"},"provider":{"objectType":"service","displayName":"Twitter","link":"http://www.twitter.com"},"link":"http://twitter.com/OGkush103/statuses/389903668427763712","body":"You a killer you on twitter, You'n do NO talking","object":{"objectType":"note","id":"object:search.twitter.com,2005:389903668427763712","summary":"You a killer you on twitter, You'n do NO talking","link":"http://twitter.com/OGkush103/statuses/389903668427763712","postedTime":"2013-10-15T00:00:53.000Z"},"favoritesCount":0,"location":{"objectType":"place","displayName":"Mississippi, US","name":"Mississippi","country_code":"United States","twitter_country_code":"US","link":"https://api.twitter.com/1.1/geo/id/43d2418301bf1a49.json","geo":{"type":"Polygon","coordinates":[[[-91.65500899999999,30.146096],[-91.65500899999999,34.996099],[-88.097888,34.996099],[-88.097888,30.146096]]]}},"geo":{"type":"Point","coordinates":[31.99686058,-88.72688823]},"twitter_entities":{"hashtags":[],"symbols":[],"urls":[],"user_mentions":[]},"twitter_filter_level":"medium","twitter_lang":"en","retweetCount":0,"gnip":{"matching_rules":[{"tag":null}],"language":{"value":"en"}}}
EOD;

// IF DECODING SUCCEEDS
$obj = json_decode($jso);
if ($obj)
{
    // SHOW SOME PARTS OF THE OBJECT
    $x = $obj->objectType;
    $y = $obj->actor->displayName;
    echo PHP_EOL . "$x $y" . PHP_EOL;

    // ACTIVATE THIS TO SHOW THE ENTIRE OBJECT
    // var_dump($obj);
}

// IF DECODING FAILS?
if (!$obj) echo json_last_error_message();

function json_last_error_message()
{
    static $errors = array
    ( JSON_ERROR_NONE           => null
    , JSON_ERROR_DEPTH          => 'Maximum stack depth exceeded'
    , JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch'
    , JSON_ERROR_CTRL_CHAR      => 'Unexpected control character found'
    , JSON_ERROR_SYNTAX         => 'Syntax error, malformed JSON'
    , JSON_ERROR_UTF8           => 'Malformed UTF-8 characters, possibly incorrectly encoded'
    )
    ;
    // ADD THESE AT PHP 5.5+ OR USE json_last_error_msg()
    if (defined('JSON_ERROR_RECURSION'))        $errors[JSON_ERROR_RECURSION]        = 'One or more recursive references in the value to be encoded';
    if (defined('JSON_ERROR_INF_OR_NAN'))       $errors[JSON_ERROR_INF_OR_NAN]       = 'One or more NAN or INF values in the value to be encoded';
    if (defined('JSON_ERROR_UNSUPPORTED_TYPE')) $errors[JSON_ERROR_UNSUPPORTED_TYPE] = 'A value of a type that cannot be encoded was given';

    $error = json_last_error();

    return array_key_exists($error, $errors)
    ? $errors[$error]
    : "Unknown error ({$error})"
    ;
}

Open in new window

0
 
LVL 111

Accepted Solution

by:
Ray Paseur earned 1000 total points
ID: 41768998
See if this helps make sense of things.  If your PHP script is expecting a POST request, you should use the $_POST array to find the request variables.  You can copy this script and install it on your server to see how it works.
https://iconoun.com/demo/temp_derrida.php
<?php // demo/temp_derrida.php
/**
 * https://www.experts-exchange.com/questions/28965062/php-creating-an-api-post-problem.html
 *
 * JSON stands for JavaScript Object Notation
 * http://json.org/
 *
 * JSON support in PHP does not have very good error handling
 *
 * JSON strings are all UTF-8
 * http://www.experts-exchange.com/articles/11880/Unicode-PHP-and-Character-Collisions.html
 *
 * PHP man page references
 * http://php.net/manual/en/json.constants.php
 * http://php.net/manual/en/function.json-decode.php
 * http://php.net/manual/en/function.json-encode.php
 * http://php.net/manual/en/function.json-last-error.php
 * http://php.net/manual/en/function.json-last-error-msg.php
 */
error_reporting(E_ALL);


// IF THERE IS A POST-METHOD REQUEST
if (!empty($_POST))
{
    // MAKE A JSON STRING FROM THE POST REQUEST DATA, DISPLAY THE JSON STRING
    $jso = json_encode($_POST);
    echo '<pre>';
    echo $jso;
    echo PHP_EOL;

    // DECODE THE JSON STRING
    $obj = json_decode($jso);

    // IF DECODING FAILS?
	if (!$obj) echo json_last_error_message();

	// SHOW THE OBJECT
    var_dump($obj);

    // SHOW HOW TO USE THE OBJECT
    echo PHP_EOL . "THE HIDDEN VALUE IN 'obj->secret' IS <b>$obj->secret</b>";

    echo '<pre>';
}


// CREATE A FORM TO MAKE A POST-METHOD REQUEST
$form = <<<EOD
<form method="post">
<input type="hidden" name="secret" value="foo" />
<input type="text"   name="public" placeholder="Your name" />
<input type="submit" value="Go!" />
</form>
EOD;

echo $form;


// AN ERROR DISPLAY THAT WILL WORK WITH PHP 5.3.3+
function json_last_error_message()
{
    static $errors = array
    ( JSON_ERROR_NONE           => null
    , JSON_ERROR_DEPTH          => 'Maximum stack depth exceeded'
    , JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch'
    , JSON_ERROR_CTRL_CHAR      => 'Unexpected control character found'
    , JSON_ERROR_SYNTAX         => 'Syntax error, malformed JSON'
    , JSON_ERROR_UTF8           => 'Malformed UTF-8 characters, possibly incorrectly encoded'
    )
    ;
    // ADD THESE AT PHP 5.5+ OR USE json_last_error_msg()
    if (defined('JSON_ERROR_RECURSION'))        $errors[JSON_ERROR_RECURSION]        = 'One or more recursive references in the value to be encoded';
    if (defined('JSON_ERROR_INF_OR_NAN'))       $errors[JSON_ERROR_INF_OR_NAN]       = 'One or more NAN or INF values in the value to be encoded';
    if (defined('JSON_ERROR_UNSUPPORTED_TYPE')) $errors[JSON_ERROR_UNSUPPORTED_TYPE] = 'A value of a type that cannot be encoded was given';

    $error = json_last_error();

    return array_key_exists($error, $errors)
    ? $errors[$error]
    : "Unknown error ({$error})"
    ;
}

Open in new window

On submit, outputs something like:
{"secret":"foo","public":"Ray"}
object(stdClass)#1 (2) {
  ["secret"]=>
  string(3) "foo"
  ["public"]=>
  string(3) "Ray"
}

THE HIDDEN VALUE IN 'obj->secret' IS foo

Open in new window

0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 41769064
Did you try the parse_str line I mentioned? Again, your screenshots show that you are posting form content, not JSON, so try:

$raw = file_get_contents("php://input");
parse_str($raw, $_POST);
var_dump($raw);
var_dump($_POST);
0
 
LVL 1

Author Closing Comment

by:derrida
ID: 41771591
good explanation and code example
0
 
LVL 35

Expert Comment

by:gr8gonzo
ID: 41771861
So the issue is resolved? What was the fix?
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …
Suggested Courses

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question