Keep duplicate keys in array - php

I am getting data from whois and breaking the data up and putting it into an array with keys but some need multiple keys the same name is there anyway i can add number onto the end of the same named keys to make them unique?
here is my code so far
$test1 =$check_domain->find_whois_details("be.co");
$rows = explode("\n", $test1);
$arr = array('info'=>"");
foreach($rows as $row) {
$posOfFirstColon = strpos($row, ":");
if($posOfFirstColon === FALSE)
$arr['info'] .= $row;
else
$arr[substr($row, 0, $posOfFirstColon)] = trim(substr($row, $posOfFirstColon+1));
}
$a = array_map('trim', array_keys($arr));
$b = array_map('trim', $arr);
$arr = array_combine($a, $b);
print($arr["Registry Expiry Date"]);

It seems like a more manageable solution would be to change your storage structure to a multidimensional array rather than a flat array.
$arr[substr($row, 0, $posOfFirstColon)][] = trim(substr($row, $posOfFirstColon+1));
In this structure, each name would correspond to an array containing one or more values. This way, the key retains its original value, which would become less meaningful if you appended some arbitrary value to it to keep it unique.
This may not work for your specific scenario, but it's generally a better representation for grouping a set of data by a specific property.

bool array_key_exists ( mixed $key , array $array )
array_key_exists — Checks if the given key or index exists in the array
<?php
$search_array = array('first' => null, 'second' => 4);
// returns true
array_key_exists('first', $search_array);
?>
Using this function, you can check if the key is already existing, in that case just concatenate a number after the key you're inserting !

Related

PHP - Get first and last key and value from array

From a given array (eg: $_SERVER), I need to get the first and last key and value. I was trying use array_shift to get first value and key but what I get is value.
Here is the $_SERVER array:
print_r($_SERVER, true))
And I tried with:
echo array_shift($_SERVER);
With PHP >= 7.3 you can get it fast, without modification of the array and without creating array copies:
$first_key = array_key_first($_SERVER);
$first_value = $_SERVER[$first_key];
$last_key = array_key_last($_SERVER);
$last_value = $_SERVER[$last_key];
See array_key_first and array_key_last.
It's not clear if you want the value, or the key. This is about as efficient as it gets, if memory usage is important.
If you want the key, use array_keys. If you want the value, just refer to it with the key you got from array_keys.
$count = count($_SERVER);
if ($count > 0) {
$keys = array_keys($_SERVER);
$firstKey = $keys[0];
$lastKey = $keys[$count - 1];
$firstValue = $array[$firstKey];
$lastValue = $array[$lastKey];
}
You can't use $count - 1 or 0 to get the first or last value in keyed arrays.
You can do a foreach loop, and break out after the first one:
foreach ( $_SERVER as $key => $value ) {
//Do stuff with $key and $value
break;
}
Plenty of other methods here. You can pick and choose your favorite flavor there.
Separate out keys and values in separate arrays, and extract first and last from them:
// Get all the keys in the array
$all_keys = array_keys($_SERVER);
// Get all the values in the array
$all_values = array_values($_SERVER);
// first key and value
$first_key = array_shift($all_keys);
$first_value = array_shift($all_values);
// last key and value (we dont care about the pointer for the temp created arrays)
$last_key = end($all_keys);
$last_value = end($all_values);
/* you can use reset function after end function call
if you worry about the pointer */
What about this:
$server = $_SERVER;
echo array_shift(array_values($server));
echo array_shift(array_keys($server));
reversed:
$reversed = array_reverse($server);
echo array_shift(array_values($reversed));
echo array_shift(array_keys($reversed));
I think array_slice() will do the trick for you.
<?php
$a = array_slice($_SERVER, 0, 1);
$b = array_slice($_SERVER, -1, 1, true);
//print_r($_SERVER);
print_r($a);
print_r($b);
?>
OUTPUT
Array ( [TERM] => xterm )
Array ( [argc] => 1 )
DEMO: https://3v4l.org/GhoFm

PHP / json encode wrongly interprets as associative array

Edit1: The problem: I want to convert in php a associative array to a indexed one. So I can return it via json_encode as an array and not as an object. For this I try to fill the missing keys. Here the description:
Got a small problem, I need to transfer a json_encoded array as an array to js. At the moment it returns an Object. I´m working with Angular so I really need an Array. I try to explain it as much as possible.
$arrNew[0][5][0][0][1]["id"] = 1;
//$arrNew[0][0][0][0][1] = "";
//$arrNew[0][1][0][0][1] = "";
//$arrNew[0][2][0][0][1] = "";
//$arrNew[0][3][0][0][1] = "";
//$arrNew[0][4][0][0][1] = "";
$arrNew[0][5][0][0][1]["name"] = 'Test';
var_dump($arrNew);
So if I return it now It returns the second element as object cause of the missing index 0-4 and the 4th element cause of the missing index 0 (associative array -> object)
So if I uncomment the block it works like a charm. Now I have the problem its not every time the element 5 sometime 3, 4 or something else so I build a function which adds them automaticly:
$objSorted = cleanArray($arrNew);
function cleanArray($array){
end($array);
$max = key($array) + 1; //Get the final key as max!
for($i = 0; $i < $max; $i++) {
if(!isset($array[$i])) {
$array[$i] = '';
} else {
end($array[$i]);
$max2 = key($array[$i]) + 1;
for($i2 = 0; $i2 < $max2; $i2++) {
.... same code repeats here for every index
So if I vardump it it returns:
The problem:
On js side its still an object, what I also see is that the elements are not sorted. So I think somehow PHP sees it still as an associative array. Any clue why this happens ? The key is set with the index of the loop and has to be a integer value.
PS: I know reworking it in JS is possible but would have be done nearly on every request with a huge load of loops
If I understand your problem, you create a sparse multidimensional array of objects. Because the arrays have gaps in the keys, json_encode() produces objects on some levels but you need it to produce arrays for all but the most inner level.
The following function fills the missing keys (starting from 0 until the maximum value used as numeric key in an array) on all array levels. It then sorts each array by their keys to make sure json_encode() encodes it as array and not object.
The sorting is needed, otherwise json_encode() generates an object; this behaviour is explained in a note on the json_encode() documentation page:
When encoding an array, if the keys are not a continuous numeric sequence starting from 0, all keys are encoded as strings, and specified explicitly for each key-value pair.
// If $arr has numeric keys (not all keys are tested!) then returns
// an array whose keys are a continuous numeric sequence starting from 0.
// Operate recursively for array values of $arr
function fillKeys(array $arr)
{
// Fill the numeric keys of all values that are arrays
foreach ($arr as $key => $value) {
if (is_array($value)) {
$arr[$key] = fillKeys($value);
}
}
$max = max(array_keys($arr));
// Sloppy detection of numeric keys; it may fail you for mixed type keys!
if (is_int($max)) {
// Fill the missing keys; use NULL as value
$arr = $arr + array_fill(0, $max, NULL);
// Sort by keys to have a continuous sequence
ksort($arr);
}
return $arr;
}
// Some array to test
$arrNew[0][5][0][0][1]["id"] = 1;
$arrNew[0][3][0][2][1]["id"] = 2;
$arrNew[0][5][0][0][1]["name"] = 'Test';
echo("============= Before ==============\n");
echo(json_encode($arrNew)."\n");
$normal = fillKeys($arrNew);
echo("============= After ==============\n");
echo(json_encode($normal)."\n");
The output:
============= Before ==============
[{"5":[[{"1":{"id":1,"name":"Test"}}]],"3":[{"2":{"1":{"id":2}}}]}]
============= After ==============
[[null,null,null,[[null,null,[null,{"id":2}]]],null,[[[null,{"id":1,"name":"Test"}]]]]]
The line $arr = $arr + array_fill(0, $max, NULL); uses NULL as values for the missing keys. This is, I think, the best for the Javascript code that parses the array (you can use if (! arr[0]) to detect the dummy values).
You can use the empty string ('') instead of NULL to get a shorter JSON:
[["","","",[["","",["",{"id":2}]]],"",[[["",{"id":1,"name":"Test"}]]]]]
but it requires slightly longer code on the JS side to detect the dummy values (if (arr[0] != '')).

if two array has identical values in same format irrespective of key without using any loop

array1 = (a=>1, b=>2, c=>3, d=>1 )
array2 = (g=>1, d=>2, f=>3, e=>1 )
I cannot use === operator as keys are different. The above two arrays has same value format, want to display yes if they have, I can always run a loop but want to avoid that part.
You may be looking for array_values():
<?php
$array1 = ['a'=>1 ,'b'=>2, 'c'=>3, 'd'=> 1];
$array2 = ['g'=>1 ,'d'=>2, 'f'=>3, 'e'=> 1];
var_dump(array_values($array1)===array_values($array2)); // bool(true)
?>
You can temporary standardize the key first using array_values() function.
$tmp1 = array_values(array1);
$tmp2 = array_values(array2);
if($tmp1 === $tmp2) echo 'yes';

Check Array exists in Array of Arrays

I personally like that title. My question is about the simplest and yet most secured way to find out if an array is contained in another array of arrays.
Here's my sample code to explaine a little bit more clear:
$container = array();
$array1 = array('A','B','C');
$container[] = $array1;
$array2 = array();
$array2[2] = 'C';
$array2[1] = 'B';
$array2[0] = 'A'; //now, the array is physically the same as $array1
if (in_array($array2,$container)) {
echo "is inside";
}
If I have more complex array (no objects in it) which contains several keys which may get added in different order, but are physically the same, does in_array compare reliable, or do I have to check every key itself?
You car use the native function PHP array_walk_recursive with your custom callback.

str_replace() and strpos() for arrays?

I'm working with an array of data that I've changed the names of some array keys, but I want the data to stay the same basically... Basically I want to be able to keep the data that's in the array stored in the DB, but I want to update the array key names associated with it.
Previously the array would have looked like this: $var_opts['services'] = array('foo-1', 'foo-2', 'foo-3', 'foo-4');
Now the array keys are no longer prefixed with "foo", but rather with "bar" instead. So how can I update the array variable to get rid of the "foos" and replace with "bars" instead?
Like so: $var_opts['services'] = array('bar-1', 'bar-2', 'bar-3', 'bar-4');
I'm already using if(isset($var_opts['services']['foo-1'])) { unset($var_opts['services']['foo-1']); } to get rid of the foos... I just need to figure out how to replace each foo with a bar.
I thought I would use str_replace on the whole array, but to my dismay it only works on strings (go figure, heh) and not arrays.
The idea:
Get a list of all your array keys
Modify each one of them as you choose
Replace the existing keys with the modified ones
The code:
$keys = array_keys($arr);
$values = array_values($arr);
$new_keys = str_replace('foo', 'bar', $keys);
$arr = array_combine($new_keys, $values);
What this actually does is create a new array which has the same values as your original array, but in which the keys have been changed.
Edit: updated as per Kamil's comment below.
For the values you've provided
$var_opts['services'] = array('foo-1', 'foo-2', 'foo-3', 'foo-4');
var_dump($var_opts['services']);
foreach($var_opts['services'] as &$val) {
$val = str_replace('foo', 'bar', $val);
}
unset($val);
var_dump($var_opts['services']);
or if you want to change the actual keys
$var_opts['services'] = array('foo-1' => 1, 'foo-2' => 2, 'foo-3' => 3, 'foo-4' => 4);
var_dump($var_opts['services']);
foreach($var_opts['services'] as $i => $val) {
unset($var_opts['services'][$i]);
$i = str_replace('foo', 'bar', $i);
$var_opts['services'][$i] = $val;
}
var_dump($var_opts['services']);

Categories