I am creating a web page that will allow comparisons of MySQL global variables for two or more instances. The user will select the instance's and a php function with use mysqli to get the results.
The results will come in the below format:
Array (
[0] => Array ( [VARIABLE_NAME] => activate_all_roles_on_login [host1:3306] => OFF )
[1] => Array ( [VARIABLE_NAME] => admin_address [host1:3306] => 0.0.0.1 )
)
Array (
[0] => Array ( [VARIABLE_NAME] => activate_all_roles_on_login [host1:3307] => OFF )
[1] => Array ( [VARIABLE_NAME] => admin_address [host1:3307] => 0.0.0.1 )
)
Array (
[0] => Array ( [VARIABLE_NAME] => activate_all_roles_on_login [host3:3308] => OFF )
[1] => Array ( [VARIABLE_NAME] => admin_address [host3:3308] => 0.0.0.2 )
)
I am wanting to combine these on the variable name value, like below:
[0] => Array ( [VARIABLE_NAME] => activate_all_roles_on_login [host1:3306] => OFF [host1:3307] => OFF [host3:3308] => OFF )
I've tried using array_combine, but that only made more of a mess.
The end goal of this is to make an array that can be easily turned into a table like below:
I would recommend you to try to implement it with pure SQL, however if you must to do it with PHP, here are some solutions.
Your array:
$queryResult = [
[
['VARIABLE_NAME' => 'activate_all_roles_on_login', 'host1:3306' => 'OFF'] ,
['VARIABLE_NAME' => 'admin_address', 'host1:3306' => '0.0.0.1'] ,
],
[
['VARIABLE_NAME' => 'activate_all_roles_on_login', 'host1:3307' => 'OFF'],
['VARIABLE_NAME' => 'admin_address', 'host1:3307' => '0.0.0.2'] ,
],
[
['VARIABLE_NAME' => 'activate_all_roles_on_login', 'host1:3308' => 'OFF'] ,
['VARIABLE_NAME' => 'admin_address', 'host1:3308' => '0.0.0.3'] ,
]
];
If you are sure that 'activate_all_roles_on_login' would always be on the first place in result, your task can be done in one line:
var_dump(array_merge(...array_column($queryResult, 0)));
However, if your query result may vary, you can try something like this:
$result = [];
foreach ($queryResult as $row) {
$subresult = array_column($row, null, 'VARIABLE_NAME');
if (isset($subresult['activate_all_roles_on_login'])) {
$result[] = $subresult['activate_all_roles_on_login'];
}
}
var_dump(array_merge(...$result));
Edit:
Also it can be done with two loops (which is kind of slower I guess):
foreach ($queryResult as $row) {
foreach ($row as $entry) {
if (isset($entry['VARIABLE_NAME']) && $entry['VARIABLE_NAME'] === 'activate_all_roles_on_login') {
$result[] = $entry;
}
}
}
var_dump(array_merge(...$result));
I believe the answer from MERGE-ARRAY-WITH-COMMON-VALUE will allow me to accomplish what I am after.
Related
I am trying to add my data to my array inside my foreach loop.
I have almost done it successfully, except the array is too in-depth.
It's showing array->array->{WHAT I WANT}
When I need array->{WHAT I WANT}
Example, I'm needing it to be like:
Array
(
[home] => Array
(
[0] => Dashboard\Main#index
[1] => GET
)
[home/] => Array
(
[0] => Dashboard\Main#index
[1] => GET
)
)
When at the moment, it's showing:
Array
(
[0] => Array
(
[services/content-writing] => Array
(
[0] => Dashboard\Services#contentwriting
[1] => GET
)
)
[1] => Array
(
[services/pbn-links] => Array
(
[0] => Dashboard\Services#pbnlinks
[1] => GET
)
)
)
The code I'm currently using inside my foreach loop is:
$realArray = array();
// Services exist
if($services)
{
// Sort them into our array
foreach ($services as $service) {
$servicePageName = $service->page_name;
$serviceName = str_replace(' ', '', strtolower($service->name));
$realArrayNew = array(
"services/$servicePageName" => ["Dashboard\Services#$serviceName", 'GET']
);
array_push($realArray, $realArrayNew);
//'home' => ['Dashboard\Main#index', 'GET'],
}
}
return $realArray;
The servicePageName variable must be the key field on the realArray to get the results you want.
I'm presuming you input object array looks something like this:
[
(int) 0 => object(stdClass) {
name => 'contentwriting'
page_name => 'content-writing'
},
(int) 1 => object(stdClass) {
name => 'pbnlinks'
page_name => 'pbn-links'
}
]
If we do this:
$realArray = [];
if ($services) {
foreach ($services as $service) {
$servicePageName = $service->page_name;
$serviceName = str_replace(' ', '', strtolower($service->name));
$realArray["services/$servicePageName"] = [
0 => "Dashboard\Services#$serviceName",
1 => "GET"
];
}
}
This is what we get on realArray:
[
'services/content-writing' => [
(int) 0 => 'Dashboard\Services#contentwriting',
(int) 1 => 'GET'
],
'services/pbn-links' => [
(int) 0 => 'Dashboard\Services#pbnlinks',
(int) 1 => 'GET'
]
]
This portion of the code inserts a new subarray to your main array:
$realArrayNew = array(
"services/$servicePageName" => ["Dashboard\Services#$serviceName", 'GET']
);
array_push($realArray, $realArrayNew);
Replace it all with:
$realArray["services/$servicePageName"] = ["Dashboard\Services#$serviceName", 'GET'];
That way your top level will have service names as keys.
I have a large array converted from a JSON structure with an unknown number of elements and sublevels.
Something like:
$marr = array
(
"Order" => array
(
"Details" => array
(
"Document" => array
(
"Number" => "1585636772",
"Date" => "2014-12-31"
),
"Delivery" => array
(
"Date" => "2015-01-02",
"TrackingCode" => "5703",
"Name" => "Example Name",
"Address" => "Example Address"
)
)
)
);
And on the other hand, I have an array of items I need to compare and find out if they are in the array above. This "indexer" will always mirror the same structure above (it's generated before the comparison step) because I thought that would help me ensure a proper comparison in an easier way.
Something like:
$indexer = array
(
"Order" => array
(
"Details" => array
(
"Document" => array
(
"Date" => "variable_name_1"
),
"Delivery" => array
(
"Date" => "variable_name_2"
)
)
)
);
I'm not entirely sure how best to compare these. I have looked into array_walk_recursive() which only returns the leaf values and I have tried to write my own attempts at a basic recursive function that would perform a foreach() which would then try to do something like:
if( isset($marr["Order"]["Details"]["Document"]["Date"]) )
{
$store[ $indexer["Order"]["Details"]["Document"]["Date"] ] = $marr["Order"]["Details"]["Document"]["Date"];
}
So that at the end I would have a basic array that stored all values found on $marr under an alias that was listed on $indexer. Like this:
$store["variable_name_1"] = "2014-12-31";
$store["variable_name_2"] = "2015-01-02";
This has been a headache for two days now and I can't seem to figure out the best way to go through this. I'm trying to walk through $indexer to reach its ending, obtain the "variable name", and then compare with $marr to store its data, but I always seem to lose the parent nodes of $indexer while trying to do this recursively. I would appreciate any advice at all.
You could use this recursive function:
function storeFromIndex($marr, $indexer) {
if (!is_array($indexer)) {
return array($indexer => $marr);
}
$store = [];
foreach($indexer as $key => $subindexer) {
$store = array_merge($store, storeFromIndex($marr[$key], $subindexer));
}
return $store;
}
And then call it like this:
$store = storeFromIndex($marr, $indexer);
With the example data given, $store will be:
array (
'variable_name_1' => '2014-12-31',
'variable_name_2' => '2015-01-02',
)
Here I would like to suggest do not maintain indexer, you can use iterator and create new array using associated keys.
For example have a look on below solution:
$array = array
(
"Order" => array
(
"Details" => array
(
"Document" => array
(
"Number" => "1585636772",
"Date" => "2014-12-31"
),
"Delivery" => array
(
"Date" => "2015-01-02",
"TrackingCode" => "5703",
"Name" => "Example Name",
"Address" => "Example Address"
)
)
)
);
$new_array = array();
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
foreach ($iterator as $key => $value) {
$keys = array();
$keys[] = $key;
for ($i = $iterator->getDepth() - 1; $i >= 0; $i--) {
$keys[] = $iterator->getSubIterator($i)->key();
}
$key_paths = array_reverse($keys);
$new_array[implode('_', $key_paths)] = $value;
}
print_r($array);
print_r($new_array);
Output:
Array
(
[Order] => Array
(
[Details] => Array
(
[Document] => Array
(
[Number] => 1585636772
[Date] => 2014-12-31
)
[Delivery] => Array
(
[Date] => 2015-01-02
[TrackingCode] => 5703
[Name] => Example Name
[Address] => Example Address
)
)
)
)
Array
(
[Order_Details_Document_Number] => 1585636772
[Order_Details_Document_Date] => 2014-12-31
[Order_Details_Delivery_Date] => 2015-01-02
[Order_Details_Delivery_TrackingCode] => 5703
[Order_Details_Delivery_Name] => Example Name
[Order_Details_Delivery_Address] => Example Address
)
I have 2 arrays:
Array
(
[0] => Array
(
[id] => 1
[fieldname] => banana
[value] => yellow
)
)
Array
(
[0] => Array
(
[id] => 1
[fieldname] => rome
[value] => city
)
[1] => Array
(
[id] => 2
[fieldname] => bla
[value] => yes
)
)
I want to create a new array that contains only elements where "id" is different. In other words I want to get this output:
Array
(
[0] => Array
(
[id] => 2
[fieldname] => bla
[value] => yes
)
)
[id] => 2 was the only different [id] so I keep it.
Said that I've already managed to achieve my goal with an inefficient pile of foreach, if statements and temp variables. I really don't want to use a wall of code for this very small thing so I started to look for a native PHP function with no success. What's the easiest way to get the result? Is it possible that I strictly need to use a foreach with so many if?
You can use array_udiff with a function.
Computes the difference of arrays by using a callback function for
data comparison.
Returns an array containing all the values of the first array that are not
present in any of the other arguments.
The code:
// Setup two arrays as per your question
$array1 = array (
'0' => array (
'id' => '1',
'fieldname' => 'banana',
'value' => 'yellow',
)
);
$array2 = array (
'0' => array (
'id' => '1',
'fieldname' => 'rome',
'value' => 'city',
),
'1' => array (
'id' => '2',
'fieldname' => 'bla',
'value' => 'yes',
)
);
// Setup the callback comparison function
function arrayCompare($array2, $array1) {
return $array2['id'] - $array1['id'];
}
// Use array_udiff() with the two arrays and the callback function
$arrayDiff = array_udiff($array2, $array1, 'arrayCompare');
print_r($arrayDiff);
The above code returns the following:
Array (
[1] => Array (
[id] => 2
[fieldname] => bla
[value] => yes
)
)
This should do it. Not super short and it does use a temporary variable, so perhaps not what you were looking for. I've named the two arrays one and two.
$ids = array();
$result = array();
foreach ($one as $x) {
$ids[$x['id']] = 1; //This way, isset($x['id']) vill return true
}
foreach ($two as $x) {
if (!isset($ids[$x['id']])) {
$result[] = $x;
}
}
I would be surprised if there wasn't an even more compact way to do it.
EDIT: This is an alternative variant with nested for each. Not particularly short either.
$result = array();
foreach ($one as $x) {
foreach ($two as $y) {
if ($x['id'] == $y['id']) {
//A match, lets try the next $x
continue 2;
}
}
//No matching id in $two
$result[] = $x;
}
I have one multidimensional array as shown below(PHP) :
Array
(
[144320] => Array
(
[3568728] => Array
(
[30832] => 30832
)
[3568884] => Array
(
[30827] => 30827
[30828] => 30828
[30830] => 30830
[30831] => 30831
[30832] => 30832
[30837] => 30837
[30838] => 30838
[30839] => 30839
[30826] => 30826
[30808] => 30808
[30806] => 30806
[30807] => 30807
[30698] => 30698
[30601] => 30601
[30697] => 30697
)
)
[144330] => Array
(
[3568731] => Array
(
[30827] => 30827
[30839] => 30839
[30838] => 30838
[30837] => 30837
[30832] => 30832
[30831] => 30831
[30828] => 30828
[30830] => 30830
[30826] => 30826
[30806] => 30806
[30808] => 30808
[30807] => 30807
[30698] => 30698
[30697] => 30697
[30601] => 30601
)
)
[144218] => Array
(
[3568753] => Array
(
[30808] => 30808
)
)
[144216] => Array
(
[3568732] => Array
(
[30808] => 30808
)
)
)
This array is populated by following code:
$sql = "SELECT * FROM `bf_alert_stack` WHERE `type` = 'immediately' order by created desc";
$q = db_query($sql);
$user_alerts = array();
while ($row = db_fetch_array($q))
{
$user_alerts [$row['uid']] [$row['alert_id']] [$row['nid']] = $row['nid'];
}
From the above user_alerts array I want to rearrange the [$row['nid']] array and for rearrangement I want capture [$row['nid']] array and after capturing it into another array I want to re-arrange $row['nid'] array I want to update this $row['nid'] array into original user_alerts array.
How I can do this? I am not getting any search for this on google so just placed this on appropriate place.
The best you can do is to get it ordered from the query with something like:
SELECT * FROM `bf_alert_stack` WHERE `type` = 'immediately'
ORDER BY created desc, nid
But if you don't have access, or need the original sort for other reason, you need to iterate recursively over the array and reassign the last sortered level to the original array with PHP ksort method:
http://www.php.net/manual/en/function.ksort.php
foreach($user_alerts as $uid=>$user_alert) {
foreach($alert as $alert_id=>$nids) {
$user_alerts[$uid][$alert_id] = ksort($nids);
}
}
Hope it helps!
I've got an multi-array (currently with objects) that I want to reorder based on a specific key/value.
Array
(
[0] => stdClass Object
(
[task_id] => 1
[task_title] => Title
[users_username] => John
)
[1] => stdClass Object
(
[task_id] => 2
[task_title] => Title
[users_username] => John
)
[2] => stdClass Object
(
[task_id] => 3
[task_title] => Title
[users_username] => Mike
)
)
I'd like to reorder it to get multi-arrays by user_name, so I can cycle through the task by username.
Array
(
[John] => Array
(
[0] => Array
(
[task_id] => 1
[title] => Title
)
[1] => Array
(
[task_id] => 2
[title] => Title
)
)
[Mike] => Array
(
[0] => Array
(
[task_id] => 3
[title] => Title
)
)
)
Is it possible to recreate my array to an array like that above?
Updated version of the code
<?php
$it0 = (object) array('task_id' => 1,'task_title' => 'Title','users_username' => 'John');
$it1 = (object) array('task_id' => 2,'task_title' => 'Title','users_username' => 'John');
$it2 = (object) array('task_id' => 3,'task_title' => 'Title','users_username' => 'Mike');
$array = array($it0,$it1,$it2);
$return = array();
foreach($array as $id => $value){
$return[$value->users_username][] = array('task_id' => $value->task_id,'title' => $value->task_title);
}
var_dump($return);
Yes, it is possible.
You'll have to loop through your current array and create a new array to do it.
example:
$new_array = array();
foreach ($array as $row)
{
$new_row = array(
'task_id' => $row->task_id,
'title' => $row->task_title,
);
$name = $row->users_username;
if (isset($new_array[$name]))
{
$new_array[$name][] = $new_row;
}
else
{
$new_array[$name] = array($new_row);
}
}
Now $new_array contains the new array exactly like the one you're asking for.
Then you can sort it with
ksort($new_array);
There may be another way to do this, with some built-in function, but sometimes I'd rather just do it myself, and know how it is working, without having to look up the documentation.
The approach:
Iterate through all of the first array, looking at [users_username] and putting them into a new array.
Code:
$dst_array = array();
foreach ($src_array as $val)
{
$user = $val->users_username;
// TODO: This check may be unnecessary. Have to test to find out.
// If this username doesn't already have an array in the destination...
if (!array_key_exists($user, $dst_array))
$dst_array[$user] = array(); // Create a new array for that username
// Now add a new task_id and title entry in that username's array
$dst_array[$user][] = array(
'task_id' => $val->task_id
'title' => $val->title
);
}
Just something like this (maybe not 100% PHP code):
foreach ( $obj : $oldArray ) {
$newTask['task_id'] = $obj->task_id;
$newTask['title'] = $obj->title;
$newArray[$oldName][] = $newTask;
}
If you want to order it; you can just call a order function afterwards.