Php key is undefined, but there is key - php

I am making my own array from another one, using email field as key value. If there is more results with same email I am amking array_push to existing key.
I am getting always data in my array (with email) and here is the example
Input data
Example data
$saved_data = [
0 => ['custom_product_email' => 'test#test.com',...],
1 => ['custom_product_email' => 'test#test.com',...],
2 => ['custom_product_email' => 'bla#test.com',...],
3 => ['custom_product_email' => 'bla#test.com',...],
...
];
Code
$data = [];
foreach ($saved_data as $products) {
$curVal = $data[$products->custom_product_email];
if (!isset($curVal)) {
$data[$products->custom_product_email] = [];
}
array_push($data[$products->custom_product_email], $products);
}
Error
I am getting error Undefined index: test#test.com and if I debug my array, there is key with value of 'test#test.com', so key is defined (!)
so var $curVal key is undefined
Result
So the goal of foreach is to filter all objects in array with same email, here is the example:
$data = [
'test#test.com' => [
0 => {data},
1 => {data},
...
],
'bla#test.com' => [
0 => {data},
1 => {data},
...
],
];

this line $curVal = $data[$products->custom_product_email]; is useless and is the one provoking the error: you just initialized $data as an empty array, logically the index is undefined.
You should test directly if (!isset($data[$products->custom_product_email])) {
Then explanation: there is a fundamental difference between retreiving the value of an array's index which is undefined and the same code in an isset. The latter evaluating the existence of a variable, you can put inside something that doesn't exist (like an undefined array index access). But you can't store it in a variable before the test.

Did you not see the error message?
Parse error: syntax error, unexpected '{' in ..... from this code
$saved_data = [
0 => {'custom_product_email' => 'test#test.com',...},
1 => {'custom_product_email' => 'test#test.com',...},
2 => {'custom_product_email' => 'bla#test.com',...},
3 => {'custom_product_email' => 'bla#test.com',...},
...
];
Change the {} to [] to correctly generate the array.
$saved_data = [
0 => ['custom_product_email' => 'test#test.com',...],
1 => ['custom_product_email' => 'test#test.com',...],
2 => ['custom_product_email' => 'bla#test.com',...],
3 => ['custom_product_email' => 'bla#test.com',...],
...
];
Your next issue is in this code
$data = [];
foreach ($saved_data as $products) {
$curVal = $data[$products->custom_product_email];
// ^^^^^
$data is an empty array that you initialised 2 lines above, so it does not contain any keys or data!

Check, if $data[$products->custom_product_email] is already set in $data array
Try This code
$data = [];
foreach ($saved_data as $products) {
$curVal = isset($data[$products->custom_product_email]) ? $data[$products->custom_product_email] : null;
if (!isset($curVal)) {
$data[$products->custom_product_email] = [];
}
array_push($data[$products->custom_product_email], $products);
}

Related

Merge multiple multidimensional arrays by value

Problem
I have the following array, consisting of N different services, where each entry consists of an identifier and a unique (user)name.
$input = [
'service_1' => [
'1234' => 'John_Doe_1',
'4567' => 'Jane Doe X',
'7891' => 'J.Doe1',
],
'service_2' => [
'100001' => 'Jane Doe X',
'100002' => 'John_Doe_1',
'100003' => 'J.Doe1',
],
'service_N' => [
'07faed21-2920-4d7d-a263-88deba9c422c' => 'John_Doe_1',
'1160178c-dfbf-4091-b4c0-a8ec55c22800' => 'J.Doe1',
],
];
Now I'm looking for a way to format it in a way that I get the identifiers across each (user)name for the different services:
$output = [
'John_Doe_1' => [
'service_1' => '1234',
'service_2' => '100002',
'service_N' => '07faed21-2920-4d7d-a263-88deba9c422c',
],
'Jane Doe X' => [
'service_1' => '4567',
'service_2' => '100001',
'service_N' => null, // either value should be null or key should not exist
],
'J.Doe1' => [
'service_1' => '7891',
'service_2' => '100003',
'service_N' => '1160178c-dfbf-4091-b4c0-a8ec55c22800',
],
];
I'm looking for a flexible way (with N services) to do this but I can't come up with a good solution.
The code below should do the trick. This is how it works.
Loops over the keys of the outer array to get the keys for the output array.
Loops over the key value pair within every inner array.
Creates an empty array in the output array with the username as key if it does not exist.
Adds the 'ID' of the server under the name that we created earlier under the key it's currently looping through.
This should also still work within a reasonable time if your array input gets really big (e.g. 10000 elements).
$output = [];
// Loop over service_1, service_2, service_N etc.
foreach(array_keys($input) as $service_name)
{
// Loop over the inner key value pair (e.g. 10001 => John Doe X)
foreach($input[$service_name] as $service_id => $username)
{
// Create a key with the name if it does not exist in the output.
if(!isset($output[$username]))
{
$output[$username] = [];
}
// Add the key value pair to the correct output name.
$output[$username][$service_name] = $service_id;
}
}
That code will produce the following output.
Array
(
[John_Doe_1] => Array
(
[service_1] => 1234
[service_2] => 100002
[service_N] => 07faed21-2920-4d7d-a263-88deba9c422c
)
[Jane Doe X] => Array
(
[service_1] => 4567
[service_2] => 100001
)
[J.Doe1] => Array
(
[service_1] => 7891
[service_2] => 100003
[service_N] => 1160178c-dfbf-4091-b4c0-a8ec55c22800
)
)
I've been on a functional programming kick recently and figured I'd dive into PHP to see what I could come up with. Here's a nested array_walk method that seems to do the trick!
$output = Array();
array_walk($input, function($item, $key) use (&$output) {
array_walk($item, function($item, $key, $parent_key) use (&$output) {
$output[$parent_key][$item] = $key;
}, $key);
});
var_dump($output);

Loop events, grab data from specific keys, add to new array - PHP [duplicate]

This question already has answers here:
"Notice: Undefined variable", "Notice: Undefined index", "Warning: Undefined array key", and "Notice: Undefined offset" using PHP
(29 answers)
Closed 3 years ago.
I am trying to loop through these array items and grab data from just the url items, adding all that collected data to a new array.
Steps I am trying to achieve:
1. Loop through the $event['lineups'] (4 items).
2. Loop through the data inside the event (6 items each)
3. Grab the following from each:
facebook_page_url, instagram_page_url, official_website_url
array (size=4)
0 =>
array (size=6)
'id' => string '22007301-f49f-442d-b93f-4c7ce5cbc8de' (length=36)
'name' => string 'MC Bassman' (length=10)
'facebook_page_url' => string 'https://www.facebook.com/bassmansdc/' (length=36)
'instagram_page_url' => string 'https://www.instagram.com/mcbassman_sdc/' (length=40)
'official_website_url' => string '' (length=0)
'position' => int 1
1 =>
array (size=6)
'id' => string 'f4c41b6f-33a1-4da0-b7fa-ffdfbd84724d' (length=36)
'name' => string 'Indika' (length=6)
'facebook_page_url' => string 'https://www.facebook.com/INDIKAMCR/' (length=35)
'instagram_page_url' => string 'https://www.instagram.com/indikamcr/' (length=36)
'official_website_url' => null
'position' => int 2
My attempt and code:
Set which keys we need to grab data from:
$default_keys = [
'facebook_page_url',
'instagram_page_url',
'official_website_url',
];
Create a new array to add data to:
$performer_urls = [];
Loop through each $event['lineups'] item in array: array (size=4)
foreach( $event['lineups'] as $lineups ) {
Loop through each value in array: array (size=6)
foreach( $lineups as $lineup ) {
Check if data exists, if so, update the $performer_urls array with a key and data.
if ( isset( $lineup[ $key ] ) && ! empty( $lineup[ $key ] ) ) {
$performer_urls[$key] = $event['lineups'][ $key ];
}
Full code so far:
$default_keys = [
'facebook_page_url',
'instagram_page_url',
'official_website_url',
];
$performer_urls = [];
foreach( $event['lineups'] as $lineups ) {
foreach( $lineups as $lineup ) {
// Example: $contact_details['address_line_1']
if ( isset( $lineup[ $key ] ) && ! empty( $lineup[ $key ] ) ) {
// Update array (example): $address['address_line_1'] = $contact_details['address_line_1']
$performer_urls[$key] = $event['lineups'][ $key ];
}
}
}
var_dump($performer_urls);
Notice: Undefined variable: key in
The errors I am getting now are referring to the undefined $key variable being used but hopefully you can see what I am trying to achieve here and almost there?
I believe I came out with a solution, I got your idea but I'm afraid you have some issues in your code.
I've just refactored them, and the most important, I didn't get it how exactly are you going to populate your new $performer_urls array without overwriting keys, that's why I chose to incremental keys just using [ ] syntax.
First things first, yes PHP is right complaining about your $key undefined variable :-) example:
Then I refactored the wrong parts (as I got it), here it comes the full code:
<?php
$event['lineups'] = [
[
'id' => '22007301-f49f-442d-b93f-4c7ce5cbc8de',
'name' => 'MC Bassman',
'facebook_page_url' => 'https://www.facebook.com/bassmansdc/',
'instagram_page_url' => 'https://www.instagram.com/mcbassman_sdc/',
'official_website_url' => '',
'position' => 1,
],
[
'id' => 'f4c41b6f-33a1-4da0-b7fa-ffdfbd84724d',
'name' => 'Indika',
'facebook_page_url' => 'https://www.facebook.com/INDIKAMCR/',
'instagram_page_url' => 'https://www.instagram.com/indikamcr/',
'official_website_url' => null,
'position' => 2,
],
];
$default_keys = [
'facebook_page_url',
'instagram_page_url',
'official_website_url',
];
$performer_urls = [];
foreach ($event['lineups'] as $lineups) {
foreach ($lineups as $key => $value) {
if (in_array($key, $default_keys) && !empty($value)) {
$performer_urls[] = $value;
}
}
}
var_dump($performer_urls);
I've got this:
array(4) {
[0] =>
string(36) "https://www.facebook.com/bassmansdc/"
[1] =>
string(40) "https://www.instagram.com/mcbassman_sdc/"
[2] =>
string(35) "https://www.facebook.com/INDIKAMCR/"
[3] =>
string(36) "https://www.instagram.com/indikamcr/"
}

how to turn this function to be recursive with multiple dimensional array?

Hello I am think about how to build this array with a recursive function with a lot of layer.
So the data would like that.
id belongs_to
1a NULL
2a NULL
3a 1a
4a NULL
5a 2a
And non-recursive function like:
foreach ($first_layer as $first_layer_obj) {
$array[$first_layer_obj->id] = [];
$second_layer = /* SELECT id FROM client WHERE belongs_to $first_layer_obj->id */;
foreach ($second_layer as $second_layer_obj) {
$array[$first_layer_obj->id][$second_layer_obj->id] = [];
$third_layer = /* SELECT id FROM client WHERE belongs_to $second_layer_obj->id */;
foreach ($third_layer as $third_layer_obj->id) {
$array[$first_layer_obj->id][$second_layer_obj->id][$third_layer_obj->id] = [];
}
}
I am expecting the output is:
array(3) {
["1a"]=>
array(1){
["3a"]=>[]
}
["2a"]=>
array(1){
["5a"]=>[]
}
["4a"]=>[]
}
Certainly the first piece of advice that I have is, you should avoid performing recursive/iterated calls to your database. You should make a single call to extract all of the desired rows in a single result set and let php do the hard part.
I've decided to try a non-recursive approach. To permit this, the result set must be prepared so that "grander" children are listed first. Now, I realize that it is entirely possible that your sample data doesn't actually represent your project values and sorting cannot be used to prepare the result set adequately -- you'll have to let me know (and perhaps update your question with more accurate sample data).
[see inline comments for what's happening in my script]
*If you aren't using php7+, then my null coalescing operator ($row1['children'] ?? []) will cause issues. You can use: (isset($row1['children']) ? $row1['children'] : []
Code: (Demo)
// use ORDER BY belongs_to DESC, id ASC ... or usort() to prepare result set
$resultset = [
['id' => '6a', 'belongs_to' => '5a'],
['id' => '5a', 'belongs_to' => '3a'],
['id' => '8a', 'belongs_to' => '3a'],
['id' => '3a', 'belongs_to' => '1a'],
['id' => '1a', 'belongs_to' => null],
['id' => '2a', 'belongs_to' => null],
['id' => '4a', 'belongs_to' => null],
['id' => '7a', 'belongs_to' => null]
];
foreach ($resultset as $index1 => &$row1) { // make input array modifiable by reference (not working with a copy)
if ($row1['belongs_to']) { // original belongs_to value is not null (not a top-level parent)
foreach ($resultset as $index2 => $row2) { // search for targeted parent
if ($row2['id'] == $row1['belongs_to']) { // parent found
$resultset[$index2]['children'][] = [$row1['id'] => $row1['children'] ?? []]; // store original row as child
unset($resultset[$index1]); // remove original row (no reason to iterate it again in outer loop)
break; // halt inner loop (no reason to iterate further)
}
}
} else { // original belongs_to value is null (top-level parent)
$output[$row1['id']] = $row1['children'] ?? []; // store children to top
}
}
var_export($output);
Output:
array (
'1a' =>
array (
0 =>
array (
'3a' =>
array (
0 =>
array (
'5a' =>
array (
0 =>
array (
'6a' =>
array (
),
),
),
),
1 =>
array (
'8a' =>
array (
),
),
),
),
),
'2a' =>
array (
),
'4a' =>
array (
),
'7a' =>
array (
),
)

PHP: create subarray based on similar value types

Hello to the community: in the following array, I'd like to gather all the hobbies of the same user under that user's name into a subarray I'd call hobbies.
My current solution is to compare whether the email value is the same for both arrays, and if so, then push the hobby into its own array.
The problem is that the loops seems right but does not produce the results I expect it and I can't see where lies the problem. I thank you all for your time.
for($x = 0; $x <= count($majorArray); $x++) {
if($majorArray[$x]['email'] == $majorArray[$x+1]['email'])
array_push($hobbies, $majorArray[$x]['hobby']);
}
The array:
Array
(
[1] => Array
(
[fname] => Eli
[lname] => Solo
[hobby] => plants
[id] => 1
[email] => elis#elis.com
)
[2] => Array
(
[fname] => Eli
[lname] => Solo
[hobby] => hiking
[id] => 1
[email] => elis#elis.com
)
The problem with your code is that you compare the email of the current contents with the email of the next.
This check does not check if the user is already present, it just checks the next user in the array. This will only work if the next user is also the current, not if there is something in between.
Also, this code will eventually give you an undefined index error, as it will try to fetch the data under the next key in the last iteration.
Also it's not clear where $hobbies is from, according to you explanation, you want to create a hobbies array, and append all data there.
You can try the following (untested):
<?php
$majorArray = [
[
'fname' => 'Eli',
'lname' => 'Solo',
'hobby' => 'plants',
'id' => 1,
'email' => 'elis#elis.com',
],
[
'fname' => 'Eli',
'lname' => 'Solo',
'hobby' => 'hiking',
'id' => 1,
'email' => 'elis#elis.com',
],
];
$output = [];
foreach ($majorArray as $userData) {
// check if email already exists as key, you can also just use id for this
if (!array_key_exists($userData['email'], $output)) {
$newUserData = [
'fname' => $userData['fname'],
'lname' => $userData['lname'],
'id' => $userData['id'],
'email' => $userData['email'],
'hobbies' => [], // create the hobbies array
];
// add the newly created user data array to the output with email as key
$output[$userData['email']] = $newUserData;
}
// append the hobby to the hobbies array
$output[$userData['email']]['hobbies'][] = $userData['hobby'];
}
// array_values will reset the array keys if you need to
print_r(array_values($output));
Simply write a new array and use the ID as key
$betterArray = array();
foreach($majorArray as $data){
$betterArray[$data['id']]['fname'] = $data['fname'];
$betterArray[$data['id']]['lname'] = $data['lname'];
$betterArray[$data['id']]['email'] = $data['email'];
$betterArray[$data['id']]['hobbies'][] = $data['hobby'];
}
notice the [] in the last line in the loop to add a new element to the subarray each time it loops trough

Retrieve single value from this php array

I have this php array $result2 that looks like this.
[
(int) 0 => object(stdClass) {
id => (int) 1
username => 'asd'
password => '123'
fullname => 'asd'
email_addr => 'asd#gmail.com'
}
]
From $result2, I want to have a $json_result that looks like this;
[{"email_addr":"asd#gmail.com"}]
I tried
$emailAddress[] = ['email_addr' => $result2['email_addr'] ];
echo json_encode($emailAddress);
However, the error I get is this;
Notice (8): Undefined index: email_addr
[APP/Controller\DeptUsersController.php, line 126]
The output is like this which is wrong;
[{"email_addr":null}]
What is the correct way?
Read carefully (int) 0 => object(stdClass) It's an object, and this object is an element with index 0 of an array. So:
$emailAddress[] = ['email_addr' => $result2[0]->email_addr ];
it's object you can't show value if using $result2['email_addr'] you should using this $result2->email_addr method
You have an object of type stdClass so you can't access directly to the field email_addr. Try this code:
$mObject = new stdClass();
$mObject = $result2[0];
$emailAddress[] = ['email_addr' => $mObject->email_addr ];
echo json_encode($emailAddress);
This should fix your error
Try this:
$emailAddress[] = ['email_addr' => $result2[0]->email_addr ];
You can use array_intersect_key :
$wanted = ["email_addr"=>""];
$data = [
"id" => 1,
"username" => 'asd',
"password" => '123',
"fullname" => 'asd',
"email_addr" => 'asd#gmail.com',
];
$result = array_intersect_key($wanted, $data);
var_dump($result);
It useful when you need one or more key to find. It more saving time

Categories