In describing and ID3v2 header and the frames within, https://id3.org/id3v2.3.0#ID3v2_frame_overview states:
The frame ID is followed by a size descriptor, making a total header size of ten bytes in every frame.
Yet when I use a hex editor to look through the frames of an ID3 tag, the frame seems to be 12 bytes. I have looked at numerous songs and they seem to have the tag, followed by a 4 byte size descriptor and then 4 additional bytes (the description says this should be two flag bytes).
I admit to being a little of of my depth here but I'm trying to write ID3v2 tags using PHP and I'm a bit stumped.
You haven't read 3.3.1. Frame header flags:
Which means the following in addition to 3.3. ID3v2 frame overview:
If looking bit wise at those 2 bytes "Flags" of the 10 bytes frame header then you have to expect additional bytes as per set flag:
So your observation might be correct. If you link to the first 4096 bytes of such a file then I can tell you if they're still correct as per the standard although they "look" like having 12 bytes per header.