PHP array with duplicate fields but...
PHP array with duplicate fields but...
Author
Discussion

TonyRPH

Original Poster:

13,546 posts

198 months

Tuesday 15th February 2022
quotequote all
EDIT: I may have arrived at a partial solution (see next post).

I have a dynamically generated PHP array with duplicate fields.

I need to use most of the available data, so I don't think removing duplicate fields with array_unique is an option?

As can be seen from the array below, the song split occurs at the "file:" entry. So for each song, I need to use the data between the "file:" and "Id:" fields.

What is the best / easiest way to process this array? The fields containing "OK" and the empty field at the end are removed during processing.

This is a sample of the array, derived from two song entries (this is used by a web page I have developed to show songs playing from my server).


Array
(
[0] => OK MPD 0.23.5
[1] => file: Red_Hot_Chili_Peppers/Stadium_Arcadium/Disc_1/01_Dani_California.flac
[2] => Last-Modified: 2020-06-03T09:29:10Z
[3] => Format: 44100:16:2
[4] => Title: Dani California
[5] => Track: 1
[6] => Disc: 1
[7] => Date: 2006
[8] => Grouping: Alternatif et Indé
[9] => Genre: Pop Rock
[10] => AlbumArtist: Red Hot Chili Peppers
[11] => Artist: Red Hot Chili Peppers
[12] => Album: Stadium Arcadium Disc 1
[13] => Time: 282
[14] => duration: 282.224
[15] => Pos: 0
[16] => Id: 306

*** next song ***

[17] => file: Red_Hot_Chili_Peppers/Stadium_Arcadium/Disc_1/03_Charlie.flac
[18] => Last-Modified: 2020-06-03T09:29:10Z
[19] => Format: 44100:16:2
[20] => Title: Charlie
[21] => Track: 3
[22] => Disc: 1
[23] => Date: 2006
[24] => Grouping: Alternatif et Indé
[25] => Genre: Pop Rock
[26] => AlbumArtist: Red Hot Chili Peppers
[27] => Artist: Red Hot Chili Peppers
[28] => Album: Stadium Arcadium Disc 1
[29] => Time: 278
[30] => duration: 277.633
[31] => Pos: 1
[32] => Id: 307
[33] => OK
[34] =>
)


Edited by TonyRPH on Tuesday 15th February 10:04

TonyRPH

Original Poster:

13,546 posts

198 months

Tuesday 15th February 2022
quotequote all
Replying to my own post - I found the array_chunk function.

So I have now split the array into an array of arrays (is that right?) but I don't know how to address them.

My array name is $status - so usually for the first element I'll assign a variable thus: $element = $status['0'];

However I now have an array with arrays as elements (if that makes sense!) so how do I address it?

Array output after using the array_chunk function.


Array
(
[0] => Array
(
[0] => file: Red_Hot_Chili_Peppers/Stadium_Arcadium/Disc_1/10_Especially_In_Michigan.flac
[1] => Last-Modified: 2020-06-03T09:29:10Z
[2] => Format: 44100:16:2
[3] => Title: Especially In Michigan
[4] => Track: 10
[5] => Disc: 1
[6] => Date: 2006
[7] => Grouping: Alternatif et Indé
[8] => Genre: Pop Rock
[9] => AlbumArtist: Red Hot Chili Peppers
[10] => Artist: Red Hot Chili Peppers
[11] => Album: Stadium Arcadium Disc 1
[12] => Time: 241
[13] => duration: 240.936
[14] => Pos: 0
[15] => Id: 312
)

[1] => Array
(
[0] => file: Red_Hot_Chili_Peppers/Stadium_Arcadium/Disc_1/14_Hey.flac
[1] => Last-Modified: 2020-06-03T09:29:10Z
[2] => Format: 44100:16:2
[3] => Title: Hey
[4] => Track: 14
[5] => Disc: 1
[6] => Date: 2006
[7] => Grouping: Alternatif et Indé
[8] => Genre: Pop Rock
[9] => AlbumArtist: Red Hot Chili Peppers
[10] => Artist: Red Hot Chili Peppers
[11] => Album: Stadium Arcadium Disc 1
[12] => Time: 340
[13] => duration: 339.548
[14] => Pos: 1
[15] => Id: 313
)

[2] => Array
(
[0] => file: Red_Hot_Chili_Peppers/Stadium_Arcadium/Disc_1/11_Warlocks.flac
[1] => Last-Modified: 2020-06-03T09:29:10Z
[2] => Format: 44100:16:2
[3] => Title: Warlocks
[4] => Track: 11
[5] => Disc: 1
[6] => Date: 2006
[7] => Grouping: Alternatif et Indé
[8] => Genre: Pop Rock
[9] => AlbumArtist: Red Hot Chili Peppers
[10] => Artist: Red Hot Chili Peppers
[11] => Album: Stadium Arcadium Disc 1
[12] => Time: 206
[13] => duration: 205.710
[14] => Pos: 2
[15] => Id: 314
)

[3] => Array
(
[0] => OK
[1] =>
)

)


Edited by TonyRPH on Tuesday 15th February 10:13

droopsnoot

14,704 posts

272 months

Tuesday 15th February 2022
quotequote all
You could do something like

foreach ($status as $song) {
var_dump($song);
}

so each individual array would be in $song inside the loop. Otherwise, you'd access each one as $status[0][0], $status[0][1], and so on.

As you have control over how the array is built, wouldn't it be better to split each element on the colon while you're building it, then you could use $status[0]['file'] and so on?

Sorry, can't format it as code for some reason.



Edited by droopsnoot on Tuesday 15th February 10:16

akirk

5,778 posts

144 months

Tuesday 15th February 2022
quotequote all
you have a multi dimensional array - i.e. an array containing arrays...
you can address a field through the same pattern as an array:

echo $arrayName[0][1];

good starting point is here:
https://www.w3schools.com/PHP/php_arrays_multidime...

suggestion above ref. loops is a good idea - effectively a loop runs through the 'array of arrays' and then in each loop allows you to deal with the internal arrays as though they were stand-alone arrays...

TonyRPH

Original Poster:

13,546 posts

198 months

Tuesday 15th February 2022
quotequote all
Thanks everyone, you have set me on the right track!

Your collective help is much appreciated as always.


TonyRPH

Original Poster:

13,546 posts

198 months

Tuesday 15th February 2022
quotequote all
Well, it was all going swimmingly until I encountered an album that returns a different number of fields in the array, due to tagging differences.

So now my array looks like this: (I'm using 16 as the chunk count - and the Bad Company album only returns 14 fields) sooooo......

Any ideas how to counter this?


Array
(
[0] => Array
(
[0] => file: Red_Hot_Chili_Peppers/Stadium_Arcadium/Disc_1/12_C_mon_Girl.flac
[1] => Last-Modified: 2020-06-03T09:29:10Z
[2] => Format: 44100:16:2
[3] => Title: C'mon Girl
[4] => Track: 12
[5] => Disc: 1
[6] => Date: 2006
[7] => Grouping: Alternatif et Indé
[8] => Genre: Pop Rock
[9] => AlbumArtist: Red Hot Chili Peppers
[10] => Artist: Red Hot Chili Peppers
[11] => Album: Stadium Arcadium Disc 1
[12] => Time: 229
[13] => duration: 228.989
[14] => Pos: 0
[15] => Id: 330
)

[1] => Array
(
[0] => file: Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/05_Burnin’_Sky.flac
[1] => Last-Modified: 2020-06-05T16:54:29Z
[2] => Format: 44100:16:2
[3] => Artist: Bad Company
[4] => Title: Burnin’ Sky
[5] => Date: 1999
[6] => Genre: Rock
[7] => Track: 5
[8] => Album: The ‘Original’ Bad Co. Anthology Disc 2
[9] => AlbumArtist: Bad Company
[10] => Time: 302
[11] => duration: 302.133
[12] => Pos: 1
[13] => Id: 331
[14] => file: Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/07_Too_Bad.flac
[15] => Last-Modified: 2020-06-05T16:54:29Z
)

[2] => Array
(
[0] => Format: 44100:16:2
[1] => Artist: Bad Company
[2] => Title: Too Bad
[3] => Date: 1999
[4] => Genre: Rock
[5] => Track: 7
[6] => Album: The ‘Original’ Bad Co. Anthology Disc 2
[7] => AlbumArtist: Bad Company
[8] => Time: 233
[9] => duration: 233.000
[10] => Pos: 2
[11] => Id: 332
[12] => file: Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/11_Oh_Atlanta.flac
[13] => Last-Modified: 2020-06-05T16:54:29Z
[14] => Format: 44100:16:2
[15] => Artist: Bad Company
)

[3] => Array
(
[0] => Title: Oh Atlanta
[1] => Date: 1999
[2] => Genre: Rock
[3] => Track: 11
[4] => Album: The ‘Original’ Bad Co. Anthology Disc 2
[5] => AlbumArtist: Bad Company
[6] => Time: 249
[7] => duration: 249.333
[8] => Pos: 3
[9] => Id: 333
[10] => file: Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/01_Honey_Child.flac
[11] => Last-Modified: 2020-06-05T16:54:29Z
[12] => Format: 44100:16:2
[13] => Artist: Bad Company
[14] => Title: Honey Child
[15] => Date: 1999
)

)

** playlist output after processing - now a bit messed up! **

Red Hot Chili Peppers - C'mon Girl<br />
302 - Bad Company<br />
2 - 1999<br />
Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/01_Honey_Child.flac - 11<br />

akirk

5,778 posts

144 months

Tuesday 15th February 2022
quotequote all
the above question was about how you get the data back out - this is an issue in how you put it in...
if a record doesn't have data for a specific field, then you need to add an empty entry to keep everything in the same place...

what structure is the original data in / where are you getting it from?

HappyMidget

6,794 posts

145 months

Tuesday 15th February 2022
quotequote all
Can you use something like https://pastebin.com/ to upload your code to, makes it a lot easier for suggestions on how to refactor your code.

TonyRPH

Original Poster:

13,546 posts

198 months

Tuesday 15th February 2022
quotequote all
akirk said:
the above question was about how you get the data back out - this is an issue in how you put it in...
if a record doesn't have data for a specific field, then you need to add an empty entry to keep everything in the same place...

what structure is the original data in / where are you getting it from?
I get the data via a network socket which connects to the MPD (Music Player Daemon) daemon. I have no control over what it returns.

For example, the raw data is this: (after sending the command 'playlistid')

The row data always begins with "file:" and ends with "Id" - however depending on what tags are in the song file - there will be a different number of rows returned, and the corresponding key=>field changes in the array. So I can't repeatedly use the same (array) key to retrieve the data.

output from playlistid said:
playlistid
file: Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/03_Silver,_Blue_and_Gold.flac
Last-Modified: 2020-06-05T16:54:29Z
Format: 44100:16:2
Artist: Bad Company
Title: Silver, Blue and Gold
Date: 1999
Genre: Rock
Track: 3
Album: The ‘Original’ Bad Co. Anthology Disc 2
AlbumArtist: Bad Company
Time: 305
duration: 304.506
Pos: 0
Id: 363
file: Bad_Company/The_Original_Bad_Co._Anthology/Disc_2/05_Burnin’_Sky.flac
Last-Modified: 2020-06-05T16:54:29Z
Format: 44100:16:2
Artist: Bad Company
Title: Burnin’ Sky
Date: 1999
Genre: Rock
Track: 5
Album: The ‘Original’ Bad Co. Anthology Disc 2
AlbumArtist: Bad Company
Time: 302
duration: 302.133
Pos: 1
Id: 364
OK
HappyMidget said:
Can you use something like https://pastebin.com/ to upload your code to, makes it a lot easier for suggestions on how to refactor your code.
Yes I have a pastebin account I can certainly do that. However the code I've tried for this is currently a mess - so I won't post it.

The array data is there though.

This paste shows how the array varies because of the varying number of rows returned. (I was using array_chunk($array,16) because originally I was getting 16 fields back - however as I say - it now varies according to song tags...

This paste illustrates the issue



Edited by TonyRPH on Tuesday 15th February 15:06

cwis

1,248 posts

209 months

Tuesday 15th February 2022
quotequote all
what function are the arrays returned from in php?

You could create an array template with named elements and then use explode() on the ':' in your current output to push the output into the template.

Explode would convert the string "file: A filename" into an array:

array([0]=> "file",[1]=>"A filename")

And you could easily reference the elements by name to populate your template.

Once you get another "file" you know to save the template (in a parent array perhaps using $array[] and start another one..

A better way would be to create "song" and "playlist" classes It'll be clearer why once you start doing stuff with the info you're currently collecting and storing...

akirk

5,778 posts

144 months

Tuesday 15th February 2022
quotequote all
okay - that makes more sense...
basically you can't (as you have discovered) just chunk into equal length arrays as the data is not equal lengths - therefore you can't assume that the 13th bit of data will always be the same...

In the absence of that, you need to assume that the data will be irregular, so instead of looking for data in chunks or slots you need to look for data that matches patterns... so to build your array you need to think (at a non-technical level) like this:

- slot 1 in the array, I want the title
- title section of text will always start: 'title:' and is then any content after that until we hit a line break / something else...
- now code, go looking for that pattern matching and bring back the content
- if content - add into section [0] of the array
- if no content - create section [0] of the array as empty

without structure you have to use pattern matching

TonyRPH

Original Poster:

13,546 posts

198 months

Tuesday 15th February 2022
quotequote all
akirk said:
okay - that makes more sense...
basically you can't (as you have discovered) just chunk into equal length arrays as the data is not equal lengths - therefore you can't assume that the 13th bit of data will always be the same...

In the absence of that, you need to assume that the data will be irregular, so instead of looking for data in chunks or slots you need to look for data that matches patterns... so to build your array you need to think (at a non-technical level) like this:

- slot 1 in the array, I want the title
- title section of text will always start: 'title:' and is then any content after that until we hit a line break / something else...
- now code, go looking for that pattern matching and bring back the content
- if content - add into section [0] of the array
- if no content - create section [0] of the array as empty

without structure you have to use pattern matching
And pattern matching was exactly what I ended up doing.

Here's the pastebin with the playlist generating code

It's probably awful code by professional standards, but thus far it seems to be working, although I'm sure there will be bugs....

Thanks for all the help.


akirk

5,778 posts

144 months

Tuesday 15th February 2022
quotequote all
looks fine! smile