Why is this json value not a PHP array key? - php

When parsing the json below, the PHP statement:
if (array_key_exists($json_a["Guids"][$g]["Broke"][$b][$a])) {
never evaluates to true despite that "Demo" is a "key" as shown from the print_r statement.
What am I doing wrong on how I'm testing to see if "Demo" or "Live" actually exists in the json? (one or the other or both may be there for any given record)
Thank you.
Json:
{
"MinimumVersion": "20191101",
"Guids": {
"0ebe7e53-12fc-4f8f-a873-4872fe30bbee": {
"Broke": {
"Yes": {
"Demo" : { "Expires" : "" },
"Live" : { "Expires" : "" }
},
"No": {
"Demo" : { "Expires" : "20191104" },
"Live" : { "Expries" : "" }
}
},
"Message": "You need to upgrade to the latest version."
}
}
}
PHP:
<?php
$string = file_get_contents("json.txt");
$json_a = json_decode($string,true);
$g = "0ebe7e53-12fc-4f8f-a873-4872fe30bbee";
$b = "No";
$a = "Demo";
echo "G: \"" . $g . "\"<br>";
echo "B: \"" . $b . "\"<br>";
echo "A: \"" . $a . "\"<br>";
if (is_array($json_a["Guids"][$g]["Broke"][$b][$a])) {
#This next line prints Array ([0] => Expires )
print_r(array_keys($json_a["Guids"][$g]["Broke"][$b][$a]));
} else {
echo "Test: false";
}
if (array_key_exists($g,$json_a["Guids"])) {
echo ("true1");
if (array_key_exists($b,$json_a["Guids"][$g]["Broke"])) {
echo ("true2");
if (array_key_exists($json_a["Guids"][$g]["Broke"][$b][$a])) {
#this never evaluates to true. Why? "Demo" is a "key" as shown from the print_r results statement above.
echo "Value:\"" . $json_a["Guids"][$g]["Broke"][$b][$a] . "\"<br>";
}
}
}
?>

You're not using array_key_exists properly for that particular case (you use it correctly elsewhere). The correct usage is
array_key_exists ( mixed $key , array $array )
so for what you want to check, you should use
array_key_exists($a, $json_a["Guids"][$g]["Broke"][$b]);

Related

Equality comparison PHP

I'm doing this comparison below: $deviceKey == 'mobile' or $deviceKey == 'desktop'
public function syncPublisherIds (string $publisherId, Request $request):array
{
file_put_contents('/var/log/php/burner.log', json_encode($request->getContent()) . PHP_EOL, FILE_APPEND);
$idSyncConfig = json_decode($request->getContent());
$idSyncResponseObject = new \stdClass();
foreach($idSyncConfig as $deviceKey => $deviceValue) {
// file_put_contents('/var/log/php/burner.log', json_encode(gettype($deviceKey)) . ' '. json_encode($deviceValue) . PHP_EOL, FILE_APPEND);
// $deviceKey = json_encode($deviceKey);
// add device type to object
if ($deviceKey == 'mobile' or $deviceKey == 'desktop') {
$idSyncResponseObject[$deviceKey] = new \stdClass();
} else {
throw ((new BadRequestException("Platforms must be of type 'mobile' or 'desktop', you sent type of: $deviceKey"))->errorize());
}
}
}
For some reason it hits the else statement when they are seemingly the same:
"Platforms must be of type 'mobile' or 'desktop', you sent type of: \"mobile\""
This is a Laravel endpoint.
<?php
function testForLuke(string $requestContent): void
{
$idSyncConfig = json_decode(stripslashes($requestContent));
//print_r([$requestContent, $idSyncConfig]);
foreach ($idSyncConfig as $deviceKey => $deviceValue) {
//print_r([$deviceKey, $deviceValue]);
if ($deviceKey === 'mobile' || $deviceKey === 'desktop') {
echo "great success with deviceKey of '${deviceKey}'!\n";
} else {
echo "error condition throw exception\n";
}
}
}
testForLuke('{ "mobile": { "id": 1 } }');
testForLuke('{ "desktop": { "id": 1 } }');
testForLuke('{ "derptop": { "id": 1 } }');
testForLuke("{ \"mobile\": { \"id\": 1 } }");
testForLuke("{ \"desktop\": { \"id\": 1 } }");
For me yields:
great success with deviceKey of 'mobile'!
great success with deviceKey of 'desktop'!
error condition throw exception
great success with deviceKey of 'mobile'!
great success with deviceKey of 'desktop'!
The code seems to be working already, but is highly dependent on the structure of the provided JSON, so depending on the structure of the request you may still have issues, let us know.
Edit: After re-looking, it seems like you've got backslashes in your JSON request. Are you encoding it yourself? If so you should use json_encode($response, JSON_UNESCAPED_SLASHES);
If you can't control how it is encoded for whatever you reason, you could consider using:
$idSyncConfig = json_decode(stripslashes($requestContent));

AND/OR comparisons starting from null, true, or false..?

I want to loop through a set of conditions, returning true only if every condition is met, collecting reasons along the way if not.
<?php
$dataval = 0;
$tests = [
[1,0,0,4,5],
[0,0,0,0,0]
];
foreach($tests as $condition) {
$retval = null;
$reasons = [];
foreach($condition as $item){
if($item == $dataval){
$retval == $retval && true;
} else {
$retval == $retval && false;
$reasons[] = "Failed to match " . $dataval . " to " . $item;
}
}
if($retval === true){
echo "All conditions met<br>";
} else {
echo "NOT all conditions met<br>";
}
echo "<pre>" . print_r($reasons, 1) . "</pre>";
}
?>
OUTPUT
NOT all conditions met
Array
(
[0] => Failed to match 0 to 1
[1] => Failed to match 0 to 4
[2] => Failed to match 0 to 5
)
NOT all conditions met
Array
(
)
No matter what the initial value of $retval, one or both tests is going to fail. If the initial value is true, both tests return true (which is incorrect); if false or null, then both return false (which is also incorrect).
Yes, I could break on the first false, but why the test failed is important, and it could fail for more than one reason so I shouldn't just break out of the loop as soon as the first failure is caught.
Is there a way to do this without adding another variable to tally up the hits and misses?
You need to initialize $retval to true. When you get a mismatch, set it to false and push the error onto the $reason array.
But don't really need the $retval variable. Just check if the array is empty.
foreach($tests as $condition) {
$reasons = [];
foreach($condition as $item){
if($item != $dataval) {
$reasons[] = "Failed to match " . $dataval . " to " . $item;
}
}
if(empty($reasons)){
echo "All conditions met<br>";
} else {
echo "NOT all conditions met<br>";
echo "<pre>" . print_r($reasons, 1) . "</pre>";
}
}

PHP Array to return a URL

I am trying to return a specific iframe URL depending ont he input of a specific number of zip codes.
Example- zip code x returns url x
zip code y returns url y
I have a list of several zip codes per URL. The URL purpose is to redirect to a specific (3rd party) page based on the location input from the user.
Here is what I have so far:
<?php
$userzip = $_POST['ZipCode'];
echo $userzip;
$array = array(
'22942' => 'URL1',
'22701' => 'URL2');
// print_r($array);
foreach( $array as $key => $value ){
// echo "Output of Key=>Value pair:\r\n";
// echo $key . "->" . $value . "\r\n";
// echo "Testing $key...\r\n\r\n";
if(preg_match('/23456/',$key)){
echo "Service exists in: $value\r\n";
break;
} else {
echo "No Match for $key.\r\n\r\n";
}
}
?>
So, my first mistake is that only the zip code entered is returned for the moment. I can comment that out but left it in to show my thinking. Help?
If I have understood your request correctly then this code should work:
<?php
$userzip = $_POST['ZipCode'];
echo $userzip;
$array = array(
'22942' => 'URL1',
'22701' => 'URL2');
// print_r($array);
foreach( $array as $key => $value ){
// echo "Output of Key=>Value pair:\r\n";
// echo $key . "->" . $value . "\r\n";
// echo "Testing $key...\r\n\r\n";
if(strstr($key, $userzip)) {
echo "Service exists in: $value\r\n";
break;
} else {
echo "No Match for $key.\r\n\r\n";
}
}
?>
To actually handle the redirect then after echo "Service exists in: $value\r\n"; you can use one of these options:
header("Location: " . $value);
Or if you want to use the iFrame approach you have mentioned in the comment then:
echo '<iframe src="'.$value.'" border="0" frameborder="0" style="width:500px; height:700px;"></iframe>';
You should try to avoid loops as much as possible. You can easily check if a key/value exists in an array with isset:
$userzip = $_POST['ZipCode'];
echo $userzip;
if( isset($zipcodesA[$userzip]) ){
echo "Service exists in A: ".$array[$userzip]."\n";
} elseif( isset($zipcodesB[$userzip]) ){
echo "Service exists in B: ".$array[$userzip]."\n";
}elseif( isset($zipcodesC[$userzip]) ){
echo "Service exists in C: ".$array[$userzip]."\n";
} else {
echo "No Match for $userzip.\n\n";
}
In this case, you have no need to check every value in the array, just if one specific exists.

make php variable from plain text get file

currently i am using the below code to get a file from a site which tells me the current server status of a game server. the file is in plain text format and out puts the following depending on server status:
ouput:
{ "state": "online", "numonline": "185" }
or
{ "state": "offline" }
or
{ "state": "error" }
file get code:
<?php
$value=file_get_contents('http:/example.com/server_state.aspx');
echo $value;
?>
I would like to turn the 'state' and 'numonline' into their own variables so i could output them using a if, like:
<?php
$content=file_get_contents('http://example.com/server_state.aspx');
$state <--- what i dont know how to make
$online <--- what i dont know how to make
if ($state == online) {
echo "Server: $state , Online: $online";
} else {
echo "Server: Offline";
)
?>
but i have no idea how to turn the 'state' and 'numonline' from the plain text into a variable of their own ($state and $online), how would i go about doing this?
Your data is JSON. Use json_decode to parse it into a usable form:
$data = json_decode(file_get_contents('http:/example.com/server_state.aspx'));
if (!$data) {
die("Something went wrong when reading or parsing the data");
}
switch ($data->state) {
case 'online':
// e.g. echo $data->numonline
case 'offline':
// ...
}
Use json_decode function:
$value = '{ "state": "online", "numonline": "185" }';
$json = json_decode($value, true);
print_r($json);
if ($json['state'] == 'online') {
echo "Server: " . $json['state'] . " , Online: " . $json['numonline'];
} else {
echo "Server: Offline";
}
Output:
Array
(
[state] => online
[numonline] => 185
)
I would like to turn the 'state' and 'numonline' into their own variables:
Maybe you are looking for extract,
Example:
$value = '{ "state": "online", "numonline": "185" }';
$json = json_decode($value, true);
extract($json);
//now $state is 'online' and $numonline is 185

Variable set to false

I wrote this REALLY simple code:
$foo=false;
echo $foo;//It outputs nothing
Why? Shouldn't it output false? What can I do to make that work?
false evaluates to an empty string when printing to the page.
Use
echo $foo ? "true" : "false";
The string "false" is not equal to false. When you convert false to a string, you get an empty string.
What you have is implicitly doing this: echo (string) $foo;
If you want to see a "true" or "false" string when you echo for tests etc you could always use a simple function like this:
// Boolean to string function
function booleanToString($bool){
if (is_bool($bool) === true) {
if($bool == true){
return "true";
} else {
return "false";
}
} else {
return NULL;
}
}
Then to use it:
// Setup some boolean variables
$Var_Bool_01 = true;
$Var_Bool_02 = false;
// Echo the results using the function
echo "Boolean 01 = " . booleanToString($Var_Bool_01) . "<br />"; // true
echo "Boolean 02 = " . booleanToString($Var_Bool_02) . "<br />"; // false

Categories