Turn string into multi dimensional array with keys and values - php

I am coding a PHP function, and I would like to ask a question. I have a problem with exploding a string in a particular way. I have tried to explain as well as I can down below.
What is this?
Well.. I am working on a solution to decrease the number of tables on my website. I can turn the table for admin rights into one field in the user table. However, I will then need to explode the text field into an array when loading the website. The code is looking like:
<?php
$string = "server1=(ban=(perm=false,normal=true),edit=true,delete=false),adminlog=true,server2=(ban=(perm=false,normal=true),edit=false,delete=true)";
function parseRights( $s="" ){
$context = array();
// code here
}
print_r(parseRights($string));
?>
Basically, I would want the result to be:
Array
(
[server1] => Array
(
[ban] => Array
(
[perm] => false
[normal] => true
)
[edit] => true
[delete] => false
)
[adminlog] => true
[server2] => Array
(
[ban] => Array
(
[perm] => false
[normal] => false
)
[edit] => false
[delete] => true
)
)
True and false should be PHP true and false. If written out like that, I know it will show 1 where true are, and nothing where 0 are.. but it's just to show you what I would like the array to look like after run through the function. I would like it to be able to create an "infinite" array, with each new parentheses creating a new array. Of cource I would gladly accept other ways to distinguish the correct rights if the function would work in the same manner.

Just to help you along a little. Better would be to have related tables that store each functional piece, such as a ban table and permission table both related to the servers table or something similar. If you're not going to store this properly in the database, at least save some trouble:
$array = array('server1'=>array('ban'=>array('perm'=>false,'normal'=>true),'edit'=>true,'delete'=>false));
$string = json_encode($array);
echo $string;
/*
{"server1":{"ban":{"perm":false,"normal":true},"edit":true,"delete":false}}
*/
$new_array = json_decode($string, true);
var_export($new_array);
/*
array
(
'server1' =>
array (
'ban' =>
array (
'perm' => false,
'normal' => true,
),
'edit' => true,
'delete' => false,
),
)
*/
See how the JSON string looks eerily similar to your string? You could also use serialize() but JSON is standardized and portable.
Also, var_dump() and var_export() will show that true and false are actually stored, print_r() just doesn't display the proper type.

Related

How to Reference/pull/sort by a specific key in a multidimensional array

I am writing a page that pulls images and image data out of a multidimensional array. I need to be able to click a button that calls a function to sort out the images by tags(IE tag_GlassDoor & tag_GlassWall) - basically to show only images that do or do not have that particular element (in this case im using 0 and 1 for yes and no), such as a glass door. I can currently make that array display the data, but I cant figure out how to sort the data by one of the array keys, or even really the syntax to pull a single value out at will.
$arrImages[] =
[
'img_sm'=>'image1.jpg',
'tag_GlassDoor'=>0,
'tag_GlassWall'=>1,
];
$arrImages[] =
[
'img_sm'=>'image2.jpg',
'tag_GlassDoor'=>1,
'tag_GlassWall'=>1,
];
Filtering is the answer, it can be used to filter one dimensional Arrays and multidimensional arrays.
the general implementation would be something like this:
$arr = array(
array(
'image' => "data",
'hasObject' => 1
),
array(
'image' => "data",
'hasObject' => 0
),
);
$finteredArray = array_filter($arr, function ($r) {
return (bool) $r['hasObject'];
});
print_r($finteredArray);
// it outputs:
// Array ( [0] => Array ( [image] => data [hasObject] => 1 ) )

Looping through a Snowflake with PHP (Discord.php)

This is my first post, I do a lot of reading here, so hopefully I avoid embarrassing myself. I've done a lot of searching on the topic, with little results, given that I am new to PHP it doesn't help either, and documentation is sparse on the topic.
The Discord API for PHP is limited to certain pieces of data which you can request, what I am attempting to do is: fetch the members, check what roles they have, and if they have it, count them.
Currently with the API you can count all members within a guild, however you cannot count all members within a guild with a specific role. My end conclusion is to loop through the snowflake and handle the comparisons myself.
This code returns the snowflake (up to 1000) for a guild:
<?php
$json_options = [
"http" => [
"method" => "GET",
"header" => "Authorization: Bot TOKENREDACTED"
]
];
$json_context = stream_context_create($json_options);
$json_get = file_get_contents('https://discordapp.com/api/guilds/GUILDIDREDACTED/members?limit=1000', false, $json_context);
$json_decode = json_decode($json_get, true);
print_r($json_decode);
?>
And the snowflake I am trying to loop through looks like this:
Array
(
[0] => Array
(
[nick] => nickname
[user] => Array
(
[username] => username
[discriminator] => 7697
[id] => 123456789012345
[avatar] => 32ad726b873445fff9145e47144a9465
)
[roles] => Array
(
[0] => 123456789012345678
[1] => 123456789012345678
)
[mute] =>
[deaf] =>
[joined_at] => 2018-05-18T07:22:49.562000+00:00
)
[1] => Array (annnd repeat for the next member)
As you can see the snowflake is quite complicated in terms of arrays.
What I am trying to do here is loop through each array entry ([0],[1],[2] etc.) then to the roles. If the [user] has the role ID 123456789012345678 (for example) then add that member to a count to print, if there's no match then it'll simply ignore that and move onto the next one. But I'm not really sure where to start with this. Any help or direction is appreciated, thank you.
You can use array-filter and get only the element you need with in-array and then count them using simple count method. Consider the following:
$arr = array_filter($json_decode, function($e) {return in_array("123456789012345678", $e['roles']);});
echo count($arr);
If the your "RoleId" is dynamic you can do:
$myRole = "123456789012345678";
$arr = array_filter($json_decode, function($e) use ($myRole) {return in_array($myRole, $e['roles']);});
If you also want to display the username you can do:
foreach($arr as $e) {echo $e['user']['username'];}
This is probably really, really bad practice, especially for a first post. #wesley murch thank you very much for the direction, I got it now. Also, feel free to reply so I can mark you as the answer. Here is the working code which I would like to share with everyone, and a following explanation of what the code does:
<?php
$json_options = [
"http" => [
"method" => "GET",
"header" => "Authorization: Bot Your-Discord-Bot-Token-Here"
]
];
$json_context = stream_context_create($json_options);
$json_get = file_get_contents('https://discordapp.com/api/guilds/your-guild-id-here/members?limit=1000', false, $json_context);
print_r(substr_count ( $json_get ,'Role-Id-To-Look-For'));
?>
This code will query the API for the snowflake, it then converts that snowflake to a string, and counts the occurrences of which that role is contained in the snowflake. In this case, I have 12 people with this role, I can confirm that it successfully returned a value of 12. In this usage case it wasn't necessarily a matter of parsing the array, I was able to just check the snowflake as a string for the ID I was looking for. This usage case is limited in the fact that it won't necessarily return any details of the members which have the role, so I wouldn't say it completely covers every single usage case.

Renaming array keys that differ on each run

This is driving me mad.. I have a PHP script that returns an array in the form $key => $value and I want to rename the key so that I can display it in a table header. I saw there are several ways of doing this but I'm not sure they are what I need... Either that or I haven't understood the examples correctly which is the likely problem.
Basically my array keys differ each time I iterate over a foreach loop and also some can be blank. How can I get round this?
The first output might look like this:
'_can_chaccess' => false,
'_can_chown' => false,
'_can_delete' => false,
'_can_modify' => false,
'_can_read' => true,
'assigned_to_name_879' => 'Unassigned',
'id' => 1,
'type' => 'Private::Reporting::DataViewModel::DataView_223_42858',
'type_877' => 'Email',
The next run through, I might get this:
'_can_chaccess' => false,
'_can_chown' => false,
'_can_delete' => false,
'_can_modify' => false,
'_can_read' => true,
'assigned_to_name_793' => 'Consultants',
'id' => 1,
'object_reference_794' => 'CASE-1004',
'summary_795' => 'Deployment of New System for HQ (Project)',
'type' => 'Private::Reporting::DataViewModel::DataView_200_42858',
),
As you can see, some keys rename the same e.g. id, type. But the most important ones that I am interested in change each time e.g. Assigned To Name.
Any ideas?
Where do you receive your data from?
You can either somehow modify the source of your data, so if it were a query (what I do not assume here), you have the SELECT ... AS ... statement.
First you do need to know how to interpret the changing keys. If e.g. "assigned_to_name_879" and "assigned_to_name_793" is the same field, you can define a canonical function, which mapps both inputs to a unique output.
The output of the cannonical function and as well the other array keys can serve as keys for an additional array, which contains the table headers of your output.
So your current array is the value's array, and by hand you define a header's array:
array(
'assigned_to_name_879' => 'Name assignment'
);
This dynamic way of storing the table headers in an array only makes sense if you are using the array twice. Otherwise you could simply write the header in the html-code which you do output.
I've managed to figure it out using the below:
$mappings_array = array();
foreach ($report['data'][0] as $key => $value) {
$workbooks->log('Old Key', $key);
preg_match_all('([^_\d]+)', $key, $new_key);
$workbooks->log('New Key', $new_key);
$str = implode(" ", $new_key[0]);
$capitalised = ucwords($str);
array_push($mappings_array,$capitalised);
}
Maybe it's not the best solution but it works :) I get the following output:
> New array: «array (
0 => 'Can Chaccess',
1 => 'Can Chown',
2 => 'Can Delete',
3 => 'Can Modify',
4 => 'Can Read',
5 => 'Id',
6 => 'Total Type',
7 => 'Type',
8 => 'Type',
)

Push an array in to another array

I have an array like:
$profile_typeid [] = custom_profile(
0 => "44258",
1 => "44259",
);
and another array $meta_data[], I want to push this array $profile_typeid []. Before that it should check in $meta_data[] whether it contains $profile_typeid [] or not. If not then add other wise it should overwrite.
How can I get the things in PHP
I tried like:
if(!in_array($meta_data,$profile_typeid,true)){
array_push($meta_data, $profile_typeid);
}
I have var_dump for two arrays like
`array
'custom_profile_type' =>
array
0 => string '39242' (length=5)
null`
Change:
in_array($meta_data,$profile_typeid, true)
to
in_array($profile_typeid,$meta_data)
In your syntax you are searching for the haystack in the needle. (so to speak)
http://php.net/manual/en/function.in-array.php
Update:
To add in array use array_push.
if(!in_array($profile_typeid,$meta_data)){
array_push($meta_data, $profile_typeid);
}
else{
$meta_data['custom_profile_type'] = $profile_typeid;
}
Remove the strict clause. I do not think it is needed in this context.
This should work.
You can do it using below given code ...
$profile_typeid = array(
0 => "44258",
1 => "44259",
);
$meta_data = array(
0 => "34567",
1 => "67890",
2 => "44258"
);
foreach($profile_typeid as $pro_type){
if(!in_array($pro_type,$meta_data)){
array_push($meta_data, $pro_type);
}
}
print_r($meta_data);
The in_array(array(), $array, true); // false you are using which is totally wrong please check the manual for more details http://php.net/manual/en/function.in-array.php
Good luck with that ..

Do I need to write a custom session class for CodeIgniter?

I cannot seem to get CI's session library to function the way I want it to. Essentially, I am storing 2 different categories of data within the sessions. The data within the 2 categories may contain the same value. Right now my attempt to add a key => value pair to the session is failing, as it is only allowing 1 key => value pair to be associated with the array. It overrides itself each time I do a post.
$arr = array(
'favorite_products' => array(),
'viewed_products' => array()
);
$arr["favorite_products"][] = $fav_id;
$this->session->set_userdata($arr);
This is what the array looks when I print_r it:
Array ( [favorite_products] => Array ( [4f1066c2b7fff] => 1648406 ) [viewed_products] => Array ( ))
Am I doing something wrong, or is this just the way CI's session library works?
Make sure you are destroying your session between attempts, but this code should work just fine...
$arr = array(
'favorite_products' => array(),
'viewed_products' => array()
);
$arr["favorite_products"][] = $fav_id;
$arr["favorite_products"][] = 033333; // another id
$this->session->set_userdata($arr);
should give you...
Array (
[favorite_products] => Array (
[0] => 1648406,
[1] => 033333
),
[viewed_products] => Array ()
)
If you are trying to do this between requests...
// if it doesn't already exist in the session, create an empty array.
if( ! ($favorite_products = $this->session->get_userdata("favorite_products")))
{
$favorite_products = array();
}
$favorite_products[] = "new id or info";
$this->session->set_userdata("favorite_products", $favorite_products);

Categories