php input validation check and simplexml_load_string - php

if(isset(file_get_contents("php://input"))) {
$credentialsXML = simplexml_load_string(file_get_contents("php://input"));
}
how can we check if php://input exists and then go ahead with parsing, as there are cases where php://input would be empty, and I simply don't need to call simplexml_load_string

Why don't you do:
$input = file_get_contents('php://input');
if (!empty($input)) {
$credentialsXML = simplexml_load_string($input);
}

Related

loop a file_get_contents until getting a non empty JSON in php

I have the following code:
<?php
$json = file_get_contents("https://api.nanopool.org/v1/eth/payments/0x218494b2284a5f165ff30d097d3d7a542ff0023B");
$decode = json_decode($json,true);
foreach($decode['data'] as $val){
echo date('Y-m-d',$val['date']).' -- '.$val['amount'].' -- '.$val['txHash'].' -- '.$val['confirmed'];
echo "<br/>";
}
The API used (nanopool) being extremely unreliable, I get a non empty json (success) every 2 to 10 calls.
I tried to loop the file_get_contents (do... while) until getting a non empty json without success. What can you recommend to loop until I get an answer?
Maybe you can try something like this, still I don't recommend using this within a synchronous script (eg a web page) because you can't control the time needed to get a successfull answer.
<?php
function getFileFTW($url)
{
$fuse = 10;//maximum attempts
$pause = 1;//time between 2 attempts
do {
if($fuse < 10)
sleep($pause);
$s = #file_get_contents($url);
}
while($s===false && $fuse--);
return $s;
}
$json = getFileFTW("https://api.nanopool.org/v1/eth/payments/0x218494b2284a5f165ff30d097d3d7a542ff0023B");
if($json) {
$decode = json_decode($json,true);
//...
}
else {
//json not loaded : handle error
}

php: receive json from POST and save to file

I want to receive a POST request from a JS client with a json body (i.e. this is not form data), and save the .gigs (javascript) array to a file, after checking the .password field. This is all my code (based on Receive JSON POST with PHP)
$json_params = file_get_contents("php://input");
if (strlen($json_params) > 0 && isValidJSON($json_params)){
/* json_decode(..., true) returns an 'array', not an 'object'
* Working combination: json_decode($json_params) WITH $inp->password
*/
$inp = json_decode($json_params);
} else {
echo "could not decode POST body";
return;
}
$password = $inp->password;
// echo $password;
if ($password == "****") {
$gigs = $inp['gigs'];
// WAS $res = file_put_contents('gigs.json', json_encode($gigs), TEXT_FILE);
$res = file_put_contents('gigs.json', json_encode($gigs));
if ($res > 0) {
echo "Success";
return;
} else {
if (!$res) {
http_response_code(500);
echo "file_put_contents error:".$res;
return;
} else {
http_response_code(500);
echo "Error: saved zero data!";
return;
}
}
}
else {
// http_response_code(403); // (2)
echo "Password invalid";
return;
}
What I find is that
if I comment out the if statement and uncomment echo $password; then the right password is there
if I uncomment line 2, which I want to do, then I get back a 500 and the error logs refer an Illegal string offset 'password' in line (1) above. Without that I get back a "Success" (all for the same password).
I don't understand what is happening, nor how to get 200, 403 and 500 error messages safely.
Note
$json_params = file_get_contents("php://input");
If your scripts are running upon regular HTTP requests, passing data like it comes from HTML form, them you should consider using $_POST for your content, not php://input. If you expect JSON in request body, then I'd be fine, yet I'd also check content type for application/json.
Next:
$inp = "I never got set";
if (strlen($json_params) > 0 && isValidJSON($json_params)){
$inp = json_decode($json_params, true);
}
$password = $inp->password;
$password = $inp['password'];
This is pretty broken. First, see json_decode() arguments (2nd) -> you are decoding to array (true), not object (false), so only $password = $inp['password']; will work in your case. Also the whole code will fail when your input data is invalid as in that case $np is rubbish string, not the array you try to read later on. Use null as default value and check for that prior further use.
Next:
$res = file_put_contents('gigs.json', json_encode($gigs), FILE_TEXT);
there's no FILE_TEXT option for file_put_contents(). Nor you'd need one.
Once you correct these you'd be fine. Also print_r() and var_dump() may be the functions you wish to get familiar with for your further debugging.
In general http://php.net/ -> lookup for functions you are about to use.

Removing specific elements from JSON encoded array by use of PHP

I have a JSON file that looks a little like this:
[
{
"uniqid":"sd54sd54f",
"Make":"Toyota",
"Start Prod":258147369,
"End Prod":369147258
},
{
"uniqid":"6sdf46sd",
"Make":"BMW",
"Start Prod":789456123,
"End Prod":159487263
},
]
What I need to do is remove an entire entry (uniqid, make, start prod and end prod) based on a uniqid that will be passed in through an HTTP POST request. So far all I have is:
$var1 = $_GET['uniqid'];
$file = 'cars.json';
$json = json_decode(file_get_contents($file), true); //im not sure if file_get_contnets is necessary...
$unset_queue = array();
foreach ( $json as $i => $item )
{
if ($item->uniquid == $var1)
{
$unset_queue[] = $i;
}
}
foreach ( $unset_queue as $index )
{
unset($json->json[$index]);
}
$json = array_values($json);
$new_json_string = json_encode($json);
When I run the code, I get no errors but the item is not removed...
EDIT: Here is the output issue at this point. Note the numbering of each car:
{"1":
{
"uniqid":"sd54sd54f",
"make":"Toyota",
"start prod":"258147369",
"end prod":"369147258"
},
"2":
{
"uniqid":"5372ab2109b05",
"make":"6sdf46sd",
"start prod":"789456123",
"end prod":"159487263"},
}
}
You have mentioned that you will be passing your request through HTTP POST. In that case , in order to make your code to work, you should change $var1 = $_GET['uniqid']; to $var1 = $_POST['uniqid'];
You can use a simple function with the JSON variable passed by reference:
function removeNode($uniqid, &$json) {
$json = json_decode($json, true); // get associative array from json
foreach($json as $key => $each) { // loop through
if($each['uniqid'] == $uniqid) // find matching unique
unset($json[$key]); // remove node from array
}
$json = json_encode($json); // re-encode array as json
}
And use like this:
removeNode('6sdf46sd', $json);
Example: https://eval.in/150341
Specific use case for you:
$var1 = $_POST['uniqid']; // you're posting the data right?
$file = 'cars.json';
$json = file_get_contents($file);
removeNode($var1, $json);
echo $json; // updated JSON
// or if you want to update the file:
// file_put_contents($file, $json);
Well, there are a couple of things wrong:
You are not checking that your code does what you think it does. It is important to check for errors.
You can unset the item inside the first loop. The second loop is not necessary.
Inside the second loop you are accessing an object and property that does not exist. When you decoded the JSON you specifically told it to return arrays.
First of all you should put this at the top of your script:
error_reporting(-1);
ini_set('display_errors', 'On');
That will show you every single error that occurs.
Second, you should fix your code. I just rewrote and commented your code. It is easier to show you than explain.
// Make sure that you are notified of all errors
error_reporting(-1);
ini_set('display_errors', 'On');
// Get 'uniqid' from POST/GET array; show error if
// it is not set
$var1 = filter_input(INPUT_POST, 'uniqid', FILTER_UNSAFE_RAW);
if ($var1 === null) {
die('The "uniqid" parameter is not set');
}
// Read data from file; show error if it does not work
$data = file_get_contents('cars.json');
if ($data === false) {
die('An error occurred when opening "cars.json"');
}
// Decode JSON; show error if invalid JSON
$json = json_decode($data, true);
if ( ! isset($json[0]['uniqid'])) {
die("The JSON was not decoded correctly");
}
// Go over each item in the array
foreach ($json as $key => $value) {
// If the 'uniqid' equals GET parameter
if ($value['uniqid'] == $var1) {
// Then unset it using the item's $key position
unset($json[$key]);
}
}
// Encode it again
$new_json_string = json_encode($json);
If it is a GET request then you can use this instead:
// ...
$var1 = filter_input(INPUT_GET, 'uniqid', FILTER_UNSAFE_RAW);
// ...
When you are done with the code, and you make it live, you should disable errors:
ini_set('display_errors', 'Off');
That makes sure that people cannot see the errors. Error messages often include file names and such, which is not something people should see.
$inputDatabase = array_values(json);

php unset causing internal server error

function deleteThing() {
if($_REQUEST ['entry'] == "") {
exit;
}
$entry = $_REQUEST ['entry'];
$file = 'entries.json';
$json = json_decode(file_get_contents($file));
unset($json[$entry]);
file_put_contents($file, json_encode($json));
}
This code is trying to delete a JSON sub item at the index $entry which is passed as a number. I'm unsure if im using unset properly or not
it seems that you need to try like this:
passing second parameter as true will return array that you have used.
$json = json_decode(file_get_contents($file),true);//assign as array
if(isset($json[$entry])) { //check if it is set
unset($json[$entry]);
}
if you not willing to using second param as true then you will get object.In that case you need to access like this:
$json->{$entry}
I think you are unsetting a variable not set at all.
May be $json is not getting value.
Do this:
$json = json_decode(file_get_contents($file));
if (! empty($json[$entry])) {
unset($json[$entry]);
}

Illegal array-declaration in PHP?

Why doesn't this validate with the W3C validator:
3 variables from form.html going into form.php:
<?php
$stuff1 = $_POST["stuff1"];//catch variables
$stuff2 = $_POST["stuff2"];
$stuff3 = $_POST["stuff3"];
$myStuff[0] = $stuff1;//put into array
$myStuff[1] = $stuff2;
$myStuff[2] = $stuff3;
?>
Why doesn't this validate with the W3C validator:
You may be misunderstanding something here. PHP code is generated on the server side, and outputs HTML (or not). Your abovementioned script will not pass any HTML validator, because to the validator, it will be empty. PHP and the W3C validator have nothing to do with each other.
If you are getting a PHP error message, please post it.
It seems to be fine but try this too:
$stuff1 = $_POST["stuff1"];
$stuff2 = $_POST["stuff2"];
$stuff3 = $_POST["stuff3"];
$myarray = array();
$myarray[] = $stuff1;
$myarray[] = $stuff2;
$myarray[] = $stuff3;
print_r($myarray);
Also make sure that you put your fields inside a form eg form tag.
Note that php code is not something to be validated by the W3C validator, it is server-side generated code.
Try declaring your array:
$stuff1 = $_POST["stuff1"];//catch variables
$stuff2 = $_POST["stuff2"];
$stuff3 = $_POST["stuff3"];
$myStuff = array();
$myStuff[0] = $stuff1;//put into array
$myStuff[1] = $stuff2;
$myStuff[2] = $stuff3;
and note Pekka's answer about the difference between PHP (server-side) and HTML (client-side).
Try var_dump($_POST)
or a bit of validation
if (isset() && !empty($_POST["stuff1")) {
$myStuff[0] = $_POST["stuff1"];
} else {
echo '$_POST["stuff1"] error';
}
Check everything is being sent across correctly...

Categories