Replace value with associative array text keys - php

I am trying to replace the value of $row['roles'] with an array:
$row['roles'] = array(
"admin" => true,
"user" => true
);
Or
$row['roles'] = array("admin", "user"); // I think this is not posible, since php autogenerates the index keys.
This is the code I have that is not working for me:
$row['roles'] = '["admin","user"]';
$roles = json_decode($row['roles'], true);
foreach($roles as $role){
$row['roles'][$role] = true; // Warning illegal string offset 'admin'
}
var_dump($row['roles']); // string '1"admin","user"]' (length=16)
Does anyone have any idea how to generate such array from the json string?
I have also tried generating the array with explode, but all I get is an indexed array array(1=>admin,2=>user)
I would like to do a if(isset($row['admin']) check.

The reason why you have an error "Warning illegal string offset 'admin'" is that your array is not initialized as key => value array, so you can't use "admin" as a key.
Just reinitialize your array with this : $row['roles'] = [];
And your code will be working.
$row['roles'] = '["admin","user"]';
$roles = json_decode($row['roles'], true);
$row['roles'] = [];
foreach($roles as $role){
$row['roles'][$role] = true;
}
var_dump($row['roles']);
But depending on your real needs, I think that it should be really more simple.

Related

PHP check if array contains any key other than some whitelisted

I would like to check all keys of a global GET array and do something, if it contains keys, other than some whitelisted ones from an array.
Let's say the current url is:
.../index.php?randomekey1=valueX&randomkey2=valueY&acceptedkey1=valueZ&randomkey3=valueA&acceptedkey2=valueB
Just for better visualization:
These GET parameters are all available in the global GET variable which looks something like this:
$GET = array(
"randomekey1" => "valueX",
"randomkey2" => "valueY",
"acceptedkey1" => "valueZ",
"randomkey3" => "valueA",
"acceptedkey2" => "valueB"
);
The keys I accept and want to let pass, I put into an array too:
$whitelist = array(
"acceptedkey1",
"acceptedkey2",
"acceptedkey3",
);
Now I want to check whether $GET contains any key other than the whitelisted. So in the URL example from above it should return "true", because there are keys in the $GET array which aren't in the whitelist.
Not only the existence of such an unknown (none whitelisted) key should trigger a true, but please also its emptyness!
Another example would be the following url:
.../index.php?acceptedkey1=valueZ&acceptedkey3=valueB
This should return false, because no other key other than the ones in the whitelist were found.
Unfortunately I was not able to find any modification of the in_array function or array_search which would fit these requirements, because as far as I know these functions are only looking for something specific, whereas in my requirements I am also looking for something specific (the whitelist keys), but at the same tme I have to check if some unknown keys exist.
Thank you.
It seems you want to determine whether an array contains keys that don't exist in a whitelist.
One way to find the difference between arrays is to use array_diff():
array_diff ( array $array1 , array $array2 [, array $... ] ) : array
Returns an array containing all the entries from array1 that are not present in any of the other arrays.
So, it can be used to return all keys from the URL that are not present in the whitelist:
$extrasExist = !empty( array_diff( array_keys($GET), $whitelist ) );
var_dump($extrasExist);
Here's a demonstration:
$get1 = array(
"randomekey1" => "valueX",
"randomkey2" => "valueY",
"acceptedkey1" => "valueZ",
"randomkey3" => "valueA",
"acceptedkey2" => "valueB"
);
$get2 = array(
"acceptedkey1" => "valueZ",
"acceptedkey2" => "valueB"
);
$whitelist = array(
"acceptedkey1",
"acceptedkey2",
"acceptedkey3"
);
$extrasExist = !empty(array_diff(array_keys($get1),$whitelist));
var_dump($extrasExist);
$extrasExist = !empty(array_diff(array_keys($get2),$whitelist));
var_dump($extrasExist);
bool(true)
bool(false)
Everything in PHP doesn't have to be all "lets find function that does exactly what I'm looking for". Just do a simple foreach loop, which can accomplish what you're looking for:
function clear_filter() {
$whitelist = array( "project", "table_name", "filterDates", );
foreach ($_GET as $gkey => $gval) {
if (!in_array($gkey, $whitelist)) {
return false;
}
}
return true;
}
You can also write it more simply, with one foreach loop like below:
function isValid() {
// Copy the array
$temp = $_GET;
// Loop through the array, and remove any whitelisted elements
foreach ($whitelist as $wkey) {
unset($temp[$wkey]);
}
// If count($temp) > 0, there are non whitelisted entries in the array.
return count($temp) === 0;
}
You can use the following function.
$check = checkWhitliest( $_GET, $whitelist ) );
var_dump ($check );
You can call the above function as
function checkWhitliest( $array, $whitelist ) {
$allKeys = array_keys ( $array); //Get all Keys from the array.
$diff = array_diff( $allKeys, $whitelist); //Get the values which are not in whitelist.
if( count ( $diff ) > 0 ) { //If the count is greater than 0, then there are certain extra kesy in $_GET
return true;
}
return false;
}
There are only two techniques that I would recommend for this task and both make key comparisons for performance reasons. Using array_diff() or in_array() will always be slower than array_diff_key() and isset(), respectively, because of how PHP treats arrays as hash maps.
If you don't mind iterating the entire $GET array (because its data is relatively small), then you can concisely flip the whitelist array and check for any key differences.
var_export(
(bool)array_diff_key($GET, array_flip($whitelist))
);
If performance is more important than code brevity, then you should craft a technique that uses a conditional break or return as soon as a non-whitelisted key is encountered -- this avoids doing pointless iterations after the outcome is decided.
$hasNotWhitelisted = false;
$lookup = array_flip($whitelist);
foreach ($GET as $key => $value) {
if (isset($lookup[$key])) {
$hasNotWhitelisted = true;
break;
}
}
var_export($hasNotWhitelisted);
Or
function hasNotWhitelisted($array, $whitelist): bool {
$lookup = array_flip($whitelist);
foreach ($array as $key => $value) {
if (isset($lookup[$key])) {
return true;
}
}
return false;
}
var_export(hasNotWhitelisted($GET, $whitelist));
All of the above techniques deliver a true result for the sample data. Demo of all three snippets.

PHP populate multi dimensional array using 2 methods and loop, 1 depending on the other

I'm trying to build my first multidimensional array - which I understand ok using hardcoded values, but trying to fill the array with values is getting me tied in knots.
I've got 2 resultsets that I'm using to build the array.
I have a method $hostnames that returns all 'hostnames' as an object
$hostnames = $server_model->get_hostnames();
I have a method $usernames that returns all 'users' of the 'hostname' that is specified above.
$usernames = $userlogons_model->get_users_by_hostname($hostname->hostname);
First, I'm building the array:
$hostnames = array(
$host => $hostname,
$users => array(
$key => $username
)
);
Then I am populating the arrays:
$hostnames = $server_model->get_hostnames_for_costs();
foreach ($hostnames as $hostname) {
$usernames = $userlogons_model->get_users_by_hostname($hostname);
echo $hostname->hostname;
foreach ($usernames as $user){
echo $user->username;
}
}
My editor is showing undefined variables where I'm declaring the arrays in the first block. I'm getting no output - Surely a syntax error and I'm struggling. Help would be appreciated !
Cheers, Mike
In PHP there's no need to "build" an array and then populate it. You can create the array as you populate it.
In your first block, it is throwing errors because it doesn't know what $host, $hostname, $users, $key or $username is, i.e. they are undefined.
I'm not sure what structure you want your final array to be as I'm not sure what $key, $host, etc. is meant to be and there's a million ways to create an array depending on what you need, but here's an example of what you can do:
// Get all hostnames
$hostnames = $server_model->get_hostnames_for_costs();
// Iterate through each hostname
foreach ($hostnames as $hostname)
{
// Get all users of the hostname
$usernames = $userlogons_model->get_users_by_hostname($hostname);
// Iterate through each user and append it to the user array
$user_arr = array();
foreach($usernames as $user)
{
// Append the user to the user array
$user_arr[] = $user;
}
// Add the user array to your
$my_arr[] = array (
'host' => $hostname,
'users' => $user_arr
);
}
echo var_dump($my_arr);

return data using variable variables

$raw_data = array ('data' => array ('id' => 'foo'));
$fields = array ('id_source' => "data['id']");
foreach ($raw_data as $data) {
foreach ($fields as $key => $path) {
var_dump ($data['id']);
var_dump ($$path);
}
}
The first var_dump gives me the correct value of foo. However, the second one gives me Undefined variable: data['id']. Can anyone tell me why that would be the case, especially since the first var_dump worked confirming the variable $data['id'] is set.
I realized this example is basic and I could just do $data[$key] and change $fields = array ('id_source' => 'id'); but I want to be able to go deeper into the multidimensional arrays when needed. That is why I'm trying to do my original approach.

compare elements of array and based on comparison retrieve array data

I have two arrays, there is one element which is 'name' common in first and second array. Now, I want to retrieved values from second array if first array value match to second one.
code for first array:
$rs = array();
foreach ( $ex_array as $data ) {
$rs[] = array( 'name' => $data['name'] );
}
Second Array:
$entries_data = array();
foreach ( $array as $entry ) {
$name = $entry['name']['value'];
$email = $entry['email']['value'];
$entries_data[] = array(
'name' => $name,
'email' => $email
);
}
Problem is, there is only multiple names in first array, and then i have to compare first array names with the second one array, if there is match then whole data is retrieved from second array for specific name. I am trying to do this by using in_array function for search names in second array but can't fetch whole values. Any suggestions or help would be grateful for me.
is_array() is used for 1d arrays which isnt ur case use this function taken from the php documentation comments and edited by me to work for ur example
function in_multiarray($elem, $array)
{
$top = sizeof($array) - 1;
$bottom = 0;
while($bottom <= $top)
{
if($array[$bottom]['name'] == $elem)
return true;
else
if(is_array($array[$bottom]['name']))
if(in_multiarray($elem, ($array[$bottom]['name'])))
return true;
$bottom++;
}
return false;
}

Adding values to an array

I what to get a value returned from a object method and put it into an array. The codes is as follows:
$additionalTestConfirmation = array();
$additionalTests = $this->getAdditionalTestsSelected();
foreach($additionalTests as $availableTest)
{
$additionalTestConfirmation = $availableTest->getName();
}
$appointment = $this->getAppointment();
$tokens = array(
'%DATE%' => $this->getAppointment()->getDate(),
'%LOCATION%' => $this->getAppointment()->getLocation(),
'%TIME%' => $this->getTime(),
'%ROOM%' => $this->getRoom(),
'%NAME%' => ($this->getUser() ? $this->getUser()->getFullName() : null),
'%TZ%' => $this->getAppointment()->getShowTimeZone() ? $this->getAppointment()->getTimeZone() : '',
'%AdditionalTestsSelected%' => $additionalTestConfirmation,
);
For the codes above, I got a system error message: Notice: Array to string conversion in /Users/alexhu/NetBeansProjects/menagerie/svn/trunk/apps/frontend/modules/legacy/legacy_lib/lib/classes/AppointmentTime.php on line 379.
How do I avoid this and get the $availableTest->getName() returned value I want. thanks
When you assign elements to an array, you must either specify an index, or use empty square brackets ([]) to add an item:
foreach($additionalTests as $availableTest) {
$additionalTestConfirmation[] = $availableTest->getName();
// or array_push($additionalTestConfirmation, $availableTest->getName());
// see: http://us3.php.net/array_push
}
See the docs for more: http://php.net/manual/en/language.types.array.php
EDIT
Also, on this line:
'%AdditionalTestsSelected%' => $additionalTestConfirmation,
... you are passing an array into this index. If the code afterword expects this to be a string, that could cause the errors. *This is not causing the error - it is perfectly acceptable to put an array in another array. As I mentioned, though, it really depends on what the code that uses the $tokens array will do and expect. If it expects a plain string for the AdditionalTestsSelected index, you might need to do this:
'%AdditionalTestsSelected%' => implode(',', $additionalTestConfirmation)
... to make the value a comma-delimited list.
Also note, at the end of that line you have an extra comma.
In order to add each $availableTest->getName() to the array $additionalTestConfirmation you need to use [] on your array and the assignment operator =
foreach($additionalTests as $availableTest)
{
$additionalTestConfirmation[] = $availableTest->getName();
}
You can also use the function array_push
foreach($additionalTests as $availableTest)
{
$additionalTestConfirmation[] = $availableTest->getName();
}
after your comment I propose you this:
$appointment = $this->getAppointment();
$token = array(
'%DATE%' => $appointment->getDate(),
'%LOCATION%' => $appointment->getLocation(),
'%TIME%' => $this->getTime(),
'%ROOM%' => $this->getRoom(),
'%NAME%' => ($this->getUser() ? $this->getUser()->getFullName() : null),
'%TZ%' => $appointment->getShowTimeZone() ? $appointment->getTimeZone() : ''
);
$tokens = array();
$additionalTests = $this->getAdditionalTestsSelected();
foreach($additionalTests as $availableTest)
{
$token['%AdditionalTestsSelected%'] = $availableTest->getName();
$tokens[] = $token;
}
// here comes logic for all tokens

Categories