So I want to get the saved database option and then update it with the API return and then save the option in the database again, but I'm having some issues.
So I have the following method:
public static function refresh_access_token(string $user_id, string $access_token): bool
{
if (!$authenticated_users = get_option('instagram_authenticated_users')) {
return false;
}
// The code for the cURL request is here (It's not needed for this question).
$array = json_decode($curl_exec);
foreach ($authenticated_users as $user) {
if ($user['user_id'] === (int) $user_id) {
$user['access_token'] = $array->access_token;
$user['access_token_expiration'] = time() + $array->expires_in;
$user['last_updated'] = (string) time();
}
}
return update_option('instagram_authenticated_users', $user);
}
The cURL response $array gives me the following:
$array = {stdClass} [3]
access_token = "IGQVJVV1YzUEdMb1lDajNZAcmRxakR3V0dkOXUyWHdtSGM0ZAHFYempkX0VHYVlKYTVYMkNxYVVpNVFuclZAlWVRsbmktNjN2cG1ISEJ4T2VJWUd0M2JBMGcyUlFXOWFlTjdEVDhKaEJB"
token_type = "bearer"
expires_in = {int} 5099901
Now within $authenticated_users, I have an array of arrays which outputs:
$authenticated_users = {array} [2]
[0] = {array} [5]
username = "semi_test1"
user_id = {int} 17841449642220098
access_token = "IGQVJWMDJnblBnUGMtMTVFa1NpUGdValNBVUZAyZAWM2OTdSSkRFdmNUbnVOQXJqeFhwbDVmT0c3aXJfamFYdnZANSlpXc3Mwc05PS0tMSzNsbXhES0tkTzNoOEY3RFRIb3dsblBiTXN3"
access_token_expiration = {int} 1651281005
last_updated = {int} 1646181108
[1] = {array} [5]
username = "semi_test2"
user_id = {int} 17841400835712753
access_token = "IGQVJVN3VOaUJrU2NzdGxWVTlwaXFLT2h1bnpFU3FKaEpOUGNPeWh2SkpjdHpnRXkyaGJ3NDZArXzJvRWFHdVRqZAEFfN0RodjV4cHQ2YTliSmhyVThUSjlCc1paLV9Fd2dqbzI1b25B"
access_token_expiration = {int} 1651281136
last_updated = {int} 1646181136
Now I'm looking at my $user_id param and using the foreach to compare them to the user_id inside an array, and if it matches, update the values inside the array and then update the options, but also retain the other array that hasn't been changed.
I've tried everything and it doesn't seem like it's working and the update_option('instagram_authenticated_users') doesn't update the values and it retains the same data.
So I want get_option('instagram_authenticated_userss') when called after the update to be the following with the new data (The second index should have been updated):
$authenticated_users = {array} [2]
[0] = {array} [5]
username = "semi_test1"
user_id = {int} 17841449642220098
access_token = "IGQVJWMDJnblBnUGMtMTVFa1NpUGdValNBVUZAyZAWM2OTdSSkRFdmNUbnVOQXJqeFhwbDVmT0c3aXJfamFYdnZANSlpXc3Mwc05PS0tMSzNsbXhES0tkTzNoOEY3RFRIb3dsblBiTXN3"
access_token_expiration = {int} 1651281005
last_updated = {int} 1646181108
[1] = {array} [5]
username = "semi_test2"
user_id = {int} 17841400835712753
access_token = "IGQVJYOEdqQ0hpbmZAHWlFsdDdMNHdUN1hmenhlV2ZAYOTBtMTJiaFhtSjhyUW9DVm9UREtLZAlFQVHhuVE1XUUFBNUF5SHoxdWRJNXd5dUF6ZAkNKeEtNYmVzRzNTWXdGSmhldG9ILTdn" (NEW VALUE)
access_token_expiration = {int} 1651282134 (NEW VALUE)
last_updated = {int} 1646181136 (NEW VALUE)
Can someone spot that I might be doing wrong?
The problem is your foreach is not creating references. You have to explicitly tell it to on which variables.
This solution doesn't try to add in the code you need where you want it to retain both the previous and the current access tokens. But this solution does you show how to change an array "in-place" using foreach, which will correct (or help) in correcting the problem of having the changes stored to the db.
Replace your foreach statement with:
foreach ($authenticated_users as &$user) {
That ampersand on &$user will make the difference: it will create $user by reference. Any changes to it will change $authenticated_users too.
Example:
$a = array("1","apple","3","pear");
foreach ($a as $p) {
if ($p == "apple") $p = "sauce";
}
print_r($a);
/* Outputs:
Array
(
[0] => 1
[1] => apple
[2] => 3
[3] => pear
)
*/
foreach ($a as &$p) {
if ($p == "apple") $p = "sauce";
}
print_r($a);
/* Outputs:
Array
(
[0] => 1
[1] => sauce
[2] => 3
[3] => pear
)
*/
The second foreach changes the source array because of the ampersand sign on $p in the foreach statement.
In this way, the same approach could work for you.
So this is an alternative to using the '&' to pass things by reference, and mutate the original array.
public static function refresh_access_token(string $user_id, string $access_token): bool
{
if (!$authenticated_users = get_option('instagram_authenticated_users')) {
return false;
}
// The code for the cURL request is here (It's not needed for this question).
$array = json_decode($curl_exec);
$newAuthenticatedUsers = [];
foreach ($authenticated_users as $user) {
if ($user['user_id'] === (int) $user_id) {
$user['access_token'] = $array->access_token;
$user['access_token_expiration'] = time() + $array->expires_in;
$user['last_updated'] = (string) time();
}
$newAuthenticatedUser[] = $user;
}
return update_option('instagram_authenticated_users', $newAuthenticatedUser);
}
If you understand what you are doing, and why in this circumstance it works, then great. You also could just as easily use a for loop and update the original array without a foreach at all:
$sizeOf = count($authenticated_users);
for ($i=0; $i < sizeOf; $i++) {
if ($authenticated_users[$i]['user_id'] === (int)$user_id) {
$authenticated_users[$i]['access_token'] = $array->access_token;
$authenticated_users[$i]['access_token_expiration'] = time() + $array->expires_in;
$authenticated_users[$i]['last_updated'] = (string) time();
}
}
return update_option('instagram_authenticated_users', $authenticated_users);
Keep in mind, per my example in the comments, that an array of objects (which is very common when dealing with ORM's and database fetching libraries) is already passed by reference, and you don't want to use a reference in a foreach.
Related
I have a pretty large array that I would need to parse, but the request changes depending on enabled/disabled parameters.
For example:
$array['a'][1]['b'][1]['c'][1] = 'asd';
$str = $array['a'][1];
dd($str);
This would give me:
Array
(
[b] => Array
(
[1] => Array
(
[c] => Array
(
[1] => asd
)
)
)
)
Which, of course, is correct. But now, if I know, that I need also the next parameter, I would need to add that like $str = $array['a'][1]['b'];.
But since there are way too many combinations, I wondered, if I can construct the call manually, something like this":
$str = $array['a'][1];
if ($b) {
$str .= ['b'][1];
}
if ($c) {
$str .= ['c'][1];
}
dd($str);
Any hints will be appreciated.
PS: I know I can do this with eval, but was really looking for a better solution:
eval("\$str = \$array$str;");
dd($str);
It can be done with Reference
$string = "['a'][1]['b'][1]";
// Maybe, not optimal, but it's not the point of the code
preg_match_all('/\[\'?([^\]\']+)\'?\]/', $string, $steps);
// "Root" of the array
$p = &$array;
foreach($steps[1] as $s) {
// Next step with current key
if (isset($p[$s]) && is_array($p)) $p = &$p[$s];
else throw new Exception("No such item");
}
// Target value
$str = $p;
demo
I want sorting multidimensional array. But I must to change format value to sorting before then get back format in beginning.
This my array (multidimensional)
$db = [['1','00:01:13.145'], ['2','00:02:19.145'],
['3','00:02:13.235'], ['4','00:01:44.020'],
['5','00:02:25.035'], ['6','00:01:11.031']];
For example can help you to answer, I Know a part how to sorting array time and to get format back again:
This my array (single)
$db2 = ['00:01:13.145','00:02:19.145',
'00:02:13.235','00:01:44.020',
'00:02:25.035','00:01:11.031'];
Function to sorting this
$rep = str_replace(':','', str_replace('.','', $db2));
echo arr($rep);
function arr($array) {
$return = array();
foreach($array as $row) {
$return[] = (int)$row;
sort($return);
}
return $return;
}
The output will be
Array ( [0] => 111031 [1] => 113145 [2] => 144020 [3] => 213235 [4] => 219145 [5] => 225035 )
Second, I know how to get format again, example:
$int = 111031;
$str = substr_replace(substr_replace($int,".",-3,-3),":",-6,-6);
echo substr_replace($str,'00:0',-9,-9);
from (int)111031 the output will be 00:01:11.031
Pleas help me to solve this
This should work for you:
Here we simply use usort() to use our own custom compare function. In this function we first explode() the time by a dot, so we get the time and the milliseconds separately. After this we convert the time into a timestamp with strtotime() and multiply it by 1,000 so we can add the milliseconds to it.
With this we have converted the time into milliseconds and we can simply compare the numbers and sort by the milliseconds.
Code:
<?php
$db = [
['1','00:01:13.145'], ['2','00:02:19.145'],
['3','00:02:13.235'], ['4','00:01:44.020'],
['5','00:02:25.035'], ['6','00:01:11.031']
];
usort($db, function($a, $b){
list($timeOne, $millisecondsOne) = explode(".", $a[1]);
list($timeTwo, $millisecondsTwo) = explode(".", $b[1]);
$millisecondsOne = strtotime($timeOne) * 1000 + $millisecondsOne;
$millisecondsTwo = strtotime($timeTwo) * 1000 + $millisecondsTwo;
if($millisecondsOne == $millisecondsTwo)
return 0;
return $millisecondsOne > $millisecondsTwo ? 1 : -1;
});
print_r($db);
?>
I have created this
while ($data = mysqli_fetch_array($course_result, MYSQLI_ASSOC)) {
print_r($data['course']);
}
Which prints this:
Array (
[user_id] => 57
[course] => 6
)
Array (
[user_id] => 57
[course] => 5
)
How can I create two variables that are equal to the values of the 'course' fields.
So ideally, variable x ends up equalling to 6 and variable y equals 5 (essentially what I'm asking is how to extract the value from the mysql arrays and putting it into a variable)?
There is no something as you called "mysql_arrays". They are normal arrays.
You can do for example:
$array = array();
while ($data = mysqli_fetch_array($course_result, MYSQLI_ASSOC)) {
$array[] = $data; // probably this way and not $array[] = $data['course'];
}
$x = $array[0]['course'];
$y = $array[1]['course'];
I would suggest you using an array instead of a variable to store the values.
$arr= array();
while ($data = mysqli_fetch_array($course_result, MYSQLI_ASSOC)) {
$arr[] = $data['course'];
}
Speculating a bit as don't have the full picture but I guess you're after something like this.
Get an array of the courses from your data
$data = array_map(function($value) {
return $value['course'];
}, $data);
If there are only ever two results, assign each one to a variable :
list($x, $y) = $data;
If there are more than two results, you have an array of courses in $data from your query results.
I have an array called $friend_array. When I print_r($friend_array) it looks like this:
Array ( [0] => 3,2,5 )
I also have a variable called $uid that is being pulled from the url.
On the page I'm testing, $uid has a value of 3 so it is in the array.
However, the following is saying that it isn't there:
if(in_array($uid, $friend_array)){
$is_friend = true;
}else{
$is_friend = false;
This always returns false. I echo the $uid and it is 3. I print the array and 3 is there.
What am I doing wrong? Any help would be greatly appreciated!
Output of
Array ( [0] => 3,2,5 )
... would be produced if the array was created by something like this:
$friend_array = array();
array_push($friend_array, '3,2,5');
print_r($friend_array);
Based on your question, I don't think this is what you meant to do.
If you want to add three values into the first three indexes of the array, do the following:
$friend_array = array();
array_push($friend_array, '3');
array_push($friend_array, '2');
array_push($friend_array, '5');
or, as a shorthand for array_push():
$friend_array = array();
$friend_array[] = '3';
$friend_array[] = '2';
$friend_array[] = '5';
Array ( [0] => 3,2,5 ) means that the array element 0 is a string 3,2,5, so, before you do an is_array check for the $uid so you have to first break that string into an array using , as a separator and then check for$uid:
// $friend_array contains as its first element a string that
// you want to make into the "real" friend array:
$friend_array = explode(',', $friend_array[0]);
if(in_array($uid, $friend_array)){
$is_friend = true;
}else{
$is_friend = false;
}
Working example
Looks like your $friend_array is setup wrong. Each value of 3, 2, and 5 needs its own key in the array for in_array to work.
Example:
$friend_array[] = 3;
$friend_array[] = 2;
$firned_array[] = 5;
Your above if statement will then work correctly.
I am using the following code to populate an array:
$number = count ($quantitys);
$count = "0";
while ($count < $number) {
$ref[$count] = postcodeUnknown ($prefix, $postcodes[$count]);
$count = $count +1;
}
postcodeUnknown returns the first row from a mysql query, using a table prefix and an element from an array named postcodes. $postcodes contains strings that should return a different row each time though the loop.
Which I'd expect to create an array similar to:
Array ([0] =>
Array ([0] => some data [1] => more data)
[1] =>
Array ([0] => second row [1] => even more...)
)
But it's not. Instead it's creating a strange array containing the first results over and over until the condition is met, eg:
simplified result of print_r($ref);
Array (
[0] => Array ([0] => some data [1] => more data)
)
Array(
[0] => Array (
[0] => the first arrays content...
[1] => ...repeated over again until the loop ends
)
)
And I'm at a loss to understand why. Anyone know better than me.
Try
$number = count ($quantitys);
$count = "0";
while ($count < $number) {
$ref1[$count] = postcodeUnknown ($prefix, $postcodes[$count]);
$ref2[] = postcodeUnknown ($prefix, $postcodes[$count]);
$ref3[$count][] = postcodeUnknown ($prefix, $postcodes[$count]);
$count = $count +1;
}
echo "<pre>";
print_r($ref1);
print_r($ref2);
print_r($ref3);
echo "</pre>";
Try that to see if any of those get an output you are looking for.
Uh, add a print to postcodeUnknown and check if its actually passing different postcodes or the same thing all the time?
ie
function postcodeUnkown($a,$b){
echo var_dump($a).var_dump($b);
//the rest
}
Also, why two different variables? ($quantitys and $postcodes).
Also, you might want to replace the while loop with for:
for($i=0;$i<$number;$i++){
$ref[$i] = postcodeUnknown ($prefix, $postcodes[$i]);
}
your variable count should not be a string, try this
$number = count ($quantitys);
$count = 0;
while ($count < $number) {
$ref[$count] = postcodeUnknown ($prefix, $postcodes[$count]);
$count = $count +1;
}