Array key exists but can't be read from a cookie - php

This is a weird one, so bear with me. Asking you guys really is my last resort.
To be clear, I'm using Kohana 3.3, although I'm not even sure that's related to the problem.
I'm using a cookie to track read items on a website. The cookie contains a json_encoded array. Adding to that array isn't a problem, objects are added every time a new item is read. An item in the array contains an object with the last_view_date and a view_count For the sake of updating the view count, I need to check whether the item has been read already using array_key_exists and then add to the view count. Here's how I'm setting the cookie:
// Get the array from the cookie.
$cookie_value = Cookie::get_array('read_items');
// Update the view_count based on whether the id exists as a key.
$view_count = (array_key_exists($item->id, $cookie_value)) ?
$cookie_value[$item->id]['view_count'] + 1 : 1;
// Create the item to be added to the cookie.
$cookie_item = array(
'last_view_date' => time(),
'view_count' => $view_count
);
// Push $cookie_item to the cookie array.
Cookie::push('read_items', $item->id, $cookie_item);
I've added two methods to Kohana's Cookie class, Cookie::push and Cookie::get_array, used in the code above:
class Cookie extends Kohana_Cookie {
public static function push($cookie_name, $key, $value)
{
$cookie_value = parent::get($cookie_name);
// Add an empty array to the cookie if it doesn't exist.
if(!$cookie_value)
{
parent::set($cookie_name, json_encode(array()));
}
else
{
$cookie_value = (array)json_decode($cookie_value);
// If $value isn't set, append without key.
if(isset($value))
{
$cookie_value[$key] = $value;
}
else
{
$cookie_value[] = $key;
}
Cookie::set($cookie_name, json_encode($cookie_value));
}
}
public static function get_array($cookie_name)
{
return (array)json_decode(parent::get($cookie_name));
}
}
Now, here's my problem. Running a var_dump on $cookie_value outputs the following:
array(1) {
["37"]=>
object(stdClass)#43 (2) {
["last_view_date"]=>
int(1359563215)
["view_count"]=>
int(1)
}
}
But when I try to access $cookie_value[37], I can't:
var_dump(array_key_exists(37, $cookie_value));
// Outputs bool(false);
var_dump(is_array($cookie_value));
// Outputs bool(true);
var_dump(count($cookie_value));
// Outputs int(1);
var_dump(array_keys($cookie_value));
// Outputs:
// array(1) {
// [0]=>
// string(2) "37"
// }
Added debugging code:
var_dump(isset($cookie_value["37"]));
// Outputs bool(false).
var_dump(isset($cookie_value[37]));
// Outputs bool(false).
var_dump(isset($cookie_value[(string)37]));
// Outputs bool(false).
I hope it's clear enough.

Take a look at json_decode. Currently, you're casting the result to an array. If you pass true as the second parameter to json_decode, you'll get an array back instead of a stdObject.
The problem may also be related to you checking int vs string keys. You could test by running this code on your server:
<?php
$one = array("37" => "test");
$two = array(37 => "test");
var_dump(array_key_exists(37,$one)); // true or false?
var_dump(array_key_exists(37,$two)); // true
?>

Access the value using:-
$cookie_value["37"]
"37" (key) is in string format.. You are specifying it as integer ($cookie_value[37])

Related

What is the correct syntax for detecting an empty 2D array in PHP?

What is the correct syntax to detect an empty 2 Dimensional array in PHP? I have attempted to do so myself using the functions "isset()" and "!empty()" for both "2dArray[0]" and "2dArray[0][0]", but even with an empty array the result comes back positive. Here is a snippet of code from one of the times where I tried this:
if(isset($strengths[0][0]) || isset($sizes[0][0]))
{
print_r($strengths[0][0]);
echo "<br>blah<br>";
print_r($sizes[0][0]);
}
Yet the arrays are both empty. Using print_r we can even see that the arrays return nothing. Here is a picture example of a different attempt using isset(2dArray[0]):
In the picture you can see the array is also empty again.
It's important to note that I can use 2dArray[1] perfectly; it detects that there there is no second row as expected, but that means I cannot have any instances where there is only 1 row in either 2D array because it is positioned at position 0 with nothing at position 1 to be detected anyway.
What am I doing wrong?
Edit 1:
The code:
var_dump($strengths[0][0]);
var_dump($sizes[0][0]);
returns:
array(0) { }
array(0) { }
and the code:
var_dump($strengths[0]);
var_dump($sizes[0]);
returns:
array(1) { [0]=> array(0) { } }
array(1) { [0]=> array(0) { } }
Edit 2:
This is my init:
$sizes[][] = array();
This is where data is set:
foreach($products as $product)
{
//product information
foreach($mods as $mod)
{
//mod information
//when array is empty $mods is empty
if ($modType == "SIZE")
{
$sizes[$si][0] = $modValue . $modValueSuffix;
$sizes[$si][1] = $modPrice;
$sizes[$si][2] = $modID;
$si++;
$strengthOrSize = true;
}
}
}
I believe I should have done $sizes[] = array(); for a 2D array. I overlooked this because it's such a short piece of code I did not give it much attention.
You can do this to detect if the sub array is empty:
$arr = [[]];
if (!count($arr[0])) {
// do stuff
}

Why is my variable variable not referencing the json data?

I have tried to understand and solve this issue to no end. I think I'm close in that I suspect I'm simply referencing my json data incorrectly, but I cannot figure out how to do it right. Here's the use case.
I'm building a simple ledger system to track crypto transactions. The system also does some nice tallying of coin totals, calculates coin values in USD, and caculates overall portfolio value etc.
I let the user track coins of their choice that sit in an array called $coins. The $coins array is initialized earlier in my code via a database call and contains $coin->ID and the $coin->symbol.
To determine coin values in USD, I make a call out to CryptoCompare using their API, which, after grabbing the coin symbols from my $coins array, looks something like this:
https://min-api.cryptocompare.com/data/pricemulti?fsyms=ADA,BTC,ETH,LTC&tsyms=USD
Just pop that URL into a browser to view the results set.
$price_request_data stores that data after being decoded.
Now my problem arises when I try to reference the JSON data via my $coins loop. I can reference the data just fine if I use a direct reference such as:
$price_request_data->BTC->USD
That produces a value of 15592.
But obviously I want to loop through my $coins loop and dynamically create variables for each coin to hold its respective price. When I try to reference the JSON data in this way, it fails to retrieve the price ( 15592) and instead returns 0.
// ----------------------------------------------------------
// GET CURRENT PRICES
$apiurl = "https://min-api.cryptocompare.com/data/pricemulti?fsyms=ADA,BTC,ETH,LTC&tsyms=USD";
$price_request = wp_remote_get( $apiurl );
if( is_wp_error( $price_request ) ) {
return false;
}
$price_request_body = wp_remote_retrieve_body( $price_request );
$price_request_data = json_decode( $price_request_body );
if( ! empty( $price_request_data ) ) {
echo $price_request_data->BTC->USD . "<br />"; // PRODUCES 15592
foreach( $coins as $coin ) {
$pricereqdata = "price_request_data->" . $coin->symbol . "->USD";
echo $$pricereqdata; // PRODUCES 0
// Generate the variable name string i.e. "curpricebtc"
$curprice = "curprice" . strtolower( $coin->symbol );
// Format the current coin's price
$$curprice = number_format( ceil_dec( $$pricereqdata, 2 ), 2, ".", "" );
}
}
This is the vardump of $price_request_data:
object(stdClass)#1527 (4) {
["ADA"]=>
object(stdClass)#1528 (1) {
["USD"]=>
float(0.4469)
}
["BTC"]=>
object(stdClass)#1535 (1) {
["USD"]=>
float(15592)
}
["ETH"]=>
object(stdClass)#1536 (1) {
["USD"]=>
float(757.13)
}
["LTC"]=>
object(stdClass)#1539 (1) {
["USD"]=>
float(291.21)
}
}
I'm using PHP7 and I know some reference rules changed, but I was not able to determine if that's my issue. I swear it's just the way I'm referencing it with a variable variable, but I'm not experienced enough to know why.
Any wisdom is much appreciated.
OK:
Q: Does "$price_request_data" equal {"ADA":{"USD":0.4738},"BTC":{"USD":15486.46},"ETH":{"USD":786.47},"LTC":{"USD":306.48}} (or equivalent)?
<= Your comment, "// WORKS", implies "yes"
Q: Where is "$coin" initializated? What is its value?
Q: What is a value of "$pricereqdata"?
Q: Does "$$pricereqdata" create a new variable for you? What is it? What is its value?
In other words, exactly what do you mean by "// FAILS"???

How to get one part of a multidimensional array using php?

I have a problem with a multidimensional array, I want to save specific parts of an array to later show the information on the page but I just cant get it to work
this is the Array when I var_dump it:
array(1) {
["500040477"]=> array(1) {
["statistics"]=> array(1) {
["all"]=> array(1) {
["frags"]=> int(23816)
}
}
}
}
now I want to get the frags and be able to save the int in a extra array/variable
I tried a lot and nothing works even the "common" method to access it doesn't work :(
In the case showed in your example:
$frags = $nameOfYourArray["500040477"]["statistics"]["all"]["frags"];
For arrays with the first key with different name (instead of 500040477):
$arrayFirstkey = current($array);
$frags = $arrayFirstkey["statistics"]["all"]["frags"];
See current PHP function.
If you want to save specific parts of an array ,you can write your own function for this
//first param arra ,second param key
function findByKey($array,$k) {
if(isset($array[$k])) {
return $array[$k];
}
else {
if(is_array($array)) return findByKey(current($array),$k);
else return "Key don't exist";
}
}
You can use above function to get specific array value using key .As your question
findByKey($yourarray,"frags");

PHP: Check if array key has value

I have the following array($post_options), it can appear in various guises, the key is dynamic:
It might be like this:
array(1) { [95]=> string(2) "25" }
It might be like this, the key can be anything:
array(1) { [05]=> string(2) "" }
I want to add a control statement that controls upon whether or not the value in the first key element has a value.
I have this code:
if (!isset($post_options[0])) {
// value is empty
var_dump($post_options);
}
else {
// value has value
echo 'Option Selected';
}
But this is not working, it returns true when the value is set and not set. What is the solution here? Thanks
So if the array appears like this (the value of the first key is empty):
array(1) { [05]=> string(2) "" }
I want to var_dump(); in this case
Depending on your exact requirements, there are three alternatives.
array_key_exists($key, $array)
This is the simplest option. It returns true if the array has the given key, and otherwise returns false.
isset($array[$key])
Slightly more strict than array_key_exists since it also requires that the value assigned to the key is not null.
!empty($array[$key]) (note the !) This is the strictest option, as it requires the value to not be any empty value (i.e., not null, false, 0, '0', etc).
There's some other options, again, depending on exact requirements. It looks to me that you are looking for the !empty option, since it will (in particular) reject empty strings.
If you don't know the first key of array - use array_keys, for example, to get all keys of your array.
$ar = array('95' => 'val');
$keys = array_keys($ar);
$first_item = $ar[$keys[0]];
var_dump($first_item); // outputs: string(3) "val"
Another option can be a current function, which will return you current element of an array. Considering that you don't move array pointer, code can be:
$ar = array('95' => 'new_val', '02' => 'val2');
$cur = current($ar);
var_dump($cur); // outputs: string(7) "new_val"
After that you can use standard emptyfunction to check:
if (empty($cur))
or
if (empty($first_item))
try this
if (!isset($post_options[0])) { // value is empty
if(!empty($post_options[0])) {
var_dump($post_options);
}
}
isset checks whether the array position exists or not, not whether it cointains or it doesn't contain a value.
You better have a look at the empty function to do this
if (empty($post_options[0])) {
// value is empty
var_dump($post_options);
} else {
// value has value
echo 'Option Selected';
}
hope this helps

Problem with a while loop

My query does no return anything for my second index. It always sends me a message Notice: Undefined offset: 1. I tried doing with a for it is the same result, so I have read that my problem it is in the query, somebody told me let $stmt be null for freeing resources of my statement. I dont know what is wrong.
These are my methods. I dont know what to someone say use $database->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,true);
Example: $arrayDirectory[] = {'user1', 'user2'};
It must echo 1 2 but just prints me 1
for($i=0;$i<sizeof($arrayDirectory;$i++){
$res[$i] = $obj->obtainID($arrayDirectory[$i]);
echo $res[$i];
}
This is my obtainID method:
public function obtainID($user){
$conexion = $this->objConexion->configuracion();
$query = "CALL sp_xxx('$user')";
$stmt = $conexion->prepare($query);
$stmt->execute();
$resultado = $stmt->fetchColumn();
return $resultado;
}
$stmi = null where?
For one,
$arrayDirectory[] = {'user1', 'user2'};
is a syntax error. { ... } does not work for arrays in PHP. Maybe it's just a typo and you're getting PHP confused with javascsript.
But the bigger issue is the []. That tells PHP to treat $arrayDirectory as an array (fine), but PUSH as a single value whatever you're assigning.
If your code was really:
$arrayDirectory[] = array('user1', 'user2');
This would create the following structure:
array(1) {
[0]=>
array(2) {
[0]=>
string(5) "user1"
[1]=>
string(5) "user2"
}
}
Note that it's a 2-level array. A top level single-element array at index [0]. That element at 0 contains ANOTHER array, which contains your two usernames.
You should have this instead:
$arrayDirectory = array('user1', 'user2');
$res = array();
foreach($arrayDirectory as $user) {
$res[] = $obj->obtainID($user);
}
first of all you are wrong with your function, you forgot to add the ending ')' for sizeof function,also arrays aren't defined with { } you should use array( ) instead.
and finally you are doing a bad practice over there;
you should not call a function in a loop (sizeof()), like this every time the loop goes through it will initiate sizeof() function and it will take some resource, since sizeof($object) won't change while using the loop, you should save it in a variable
$sizeofobject = sizeof($object);
and use that variable in your loop instead

Categories