Laravel: Count integer value based on week of the month - php

I'm trying to count integer value from JSON: https://pomber.github.io/covid19/timeseries.json and got what I expected.
{
"date": [
"22 Jan",
"23 Jan",
"24 Jan",
"25 Jan",
....
],
"total_confirmed": [
555,
653,
941,
1434,
....
],
"total_deaths": [
17,
18,
26,
42,
....
],
"total_recovered": [
28,
30,
36,
39,
....
],
"max_value_of_total_confirmed": 272166
}
Here's my controller:
$client = new Client();$request = $client->get('https://pomber.github.io/covid19/timeseries.json');
$response = $request->getBody()->getContents();
$posts_dates = json_decode($response, true);
$confirmed_array = array();
$deaths_array = array();
$recovered_array = array();
if ( ! empty( $posts_dates ) ) {
foreach ( $posts_dates as $country => $data ) {
foreach ( $data as $dataKey => $dateData ) {
$date = new \DateTime( $dateData['date'] );
$day = $date->format( 'd M' );
if ( !isset($confirmed_array[$day]) ) {
$confirmed_array[$day] = 0;
}
$confirmed_array[$day] += $dateData['confirmed'];
}
foreach ( $data as $dataKey => $dateData ) {
$date = new \DateTime( $dateData['date'] );
$day = $date->format( 'd M' );
if ( !isset($deaths_array[$day]) ) {
$deaths_array[$day] = 0;
}
$deaths_array[$day] += $dateData['deaths'];
}
foreach ( $data as $dataKey => $dateData ) {
$date = new \DateTime( $dateData['date'] );
$day = $date->format( 'd M' );
if ( !isset($recovered_array[$day]) ) {
$recovered_array[$day] = 0;
}
$recovered_array[$day] += $dateData['recovered'];
}
}
}
$output = [
"date" => array_keys($confirmed_array),
"total_confirmed" => array_values($confirmed_array),
"total_deaths" => array_values($deaths_array),
"total_recovered" => array_values($recovered_array),
"max_value_of_total_confirmed" => max($confirmed_array)
];
return $output;
What I'm trying to get is grouping those data not by date, but by week of the month (W3 Jan, W4 Jan, W1 Feb, W2 Feb, etc). Any help would be appreciated :)
Thank you.

I would recommend using collection. You can easily manage using the methods provided by Laravel.
Group By Day
$client = new Client();
$request = $client->get('https://pomber.github.io/covid19/timeseries.json');
$response = $request->getBody()->getContents();
$posts_dates = json_decode($response, true);
/****** Here we go ******/
$posts_dates = collect($posts_dates)
->flatten(1)
->groupBy('date')
->map(function ($item, $key) {
$item = collect($item);
$date = \Carbon\Carbon::parse($key);
$key = 'W' . $date->weekOfMonth . $date->format(' M');
return [
'date' => $key,
'total_confirmed' => $item->sum('confirmed'),
'total_deaths' => $item->sum('deaths'),
'total_recovered' => $item->sum('recovered'),
];
})
->groupBy(function ($item, $key) {
return collect($item)->keys()->all();
})
->map(function ($item, $key) {
return $item->map(function ($item) use ($key) {
return $item[$key];
});
});
$posts_dates->put('max_value_of_total_confirmed', $posts_dates['total_confirmed']->max());
dd($posts_dates->toArray());
Result
array:5 [
"date" => array:59 [
0 => "W4 Jan"
1 => "W4 Jan"
2 => "W4 Jan"
3 => "W4 Jan"
4 => "W4 Jan"
5 => "W4 Jan"
6 => "W4 Jan"
7 => "W5 Jan"
8 => "W5 Jan"
9 => "W5 Jan"
10 => "W1 Feb"
11 => "W1 Feb"
12 => "W1 Feb"
13 => "W1 Feb"
14 => "W1 Feb"
15 => "W1 Feb"
16 => "W1 Feb"
17 => "W2 Feb"
18 => "W2 Feb"
19 => "W2 Feb"
20 => "W2 Feb"
21 => "W2 Feb"
22 => "W2 Feb"
23 => "W2 Feb"
24 => "W3 Feb"
25 => "W3 Feb"
26 => "W3 Feb"
27 => "W3 Feb"
28 => "W3 Feb"
29 => "W3 Feb"
30 => "W3 Feb"
31 => "W4 Feb"
32 => "W4 Feb"
33 => "W4 Feb"
34 => "W4 Feb"
35 => "W4 Feb"
36 => "W4 Feb"
37 => "W4 Feb"
38 => "W5 Feb"
39 => "W1 Mar"
40 => "W1 Mar"
41 => "W1 Mar"
42 => "W1 Mar"
43 => "W1 Mar"
44 => "W1 Mar"
45 => "W1 Mar"
46 => "W2 Mar"
47 => "W2 Mar"
48 => "W2 Mar"
49 => "W2 Mar"
50 => "W2 Mar"
51 => "W2 Mar"
52 => "W2 Mar"
53 => "W3 Mar"
54 => "W3 Mar"
55 => "W3 Mar"
56 => "W3 Mar"
57 => "W3 Mar"
58 => "W3 Mar"
]
"total_confirmed" => array:59 [
0 => 555
1 => 653
2 => 941
3 => 1434
4 => 2118
5 => 2927
6 => 5578
7 => 6166
8 => 8234
9 => 9927
10 => 12038
11 => 16787
12 => 19881
13 => 23892
14 => 27635
15 => 30817
16 => 34391
17 => 37120
18 => 40150
19 => 42762
20 => 44802
21 => 45221
22 => 60368
23 => 66885
24 => 69030
25 => 71224
26 => 73258
27 => 75136
28 => 75639
29 => 76197
30 => 76823
31 => 78579
32 => 78965
33 => 79568
34 => 80413
35 => 81395
36 => 82754
37 => 84120
38 => 86011
39 => 88369
40 => 90306
41 => 92840
42 => 95120
43 => 97882
44 => 101784
45 => 105821
46 => 109795
47 => 113561
48 => 118592
49 => 125865
50 => 128343
51 => 145193
52 => 156094
53 => 167446
54 => 181527
55 => 197142
56 => 214910
57 => 242708
58 => 272166
]
"total_deaths" => array:59 [
0 => 17
1 => 18
2 => 26
3 => 42
4 => 56
5 => 82
6 => 131
7 => 133
8 => 171
9 => 213
10 => 259
11 => 362
12 => 426
13 => 492
14 => 564
15 => 634
16 => 719
17 => 806
18 => 906
19 => 1013
20 => 1113
21 => 1118
22 => 1371
23 => 1523
24 => 1666
25 => 1770
26 => 1868
27 => 2007
28 => 2122
29 => 2247
30 => 2251
31 => 2458
32 => 2469
33 => 2629
34 => 2708
35 => 2770
36 => 2814
37 => 2872
38 => 2941
39 => 2996
40 => 3085
41 => 3160
42 => 3254
43 => 3348
44 => 3460
45 => 3558
46 => 3802
47 => 3988
48 => 4262
49 => 4615
50 => 4720
51 => 5404
52 => 5819
53 => 6440
54 => 7126
55 => 7905
56 => 8733
57 => 9867
58 => 11299
]
"total_recovered" => array:59 [
0 => 28
1 => 30
2 => 36
3 => 39
4 => 52
5 => 61
6 => 107
7 => 126
8 => 143
9 => 222
10 => 284
11 => 472
12 => 623
13 => 852
14 => 1124
15 => 1487
16 => 2011
17 => 2616
18 => 3244
19 => 3946
20 => 4683
21 => 5150
22 => 6295
23 => 8058
24 => 9395
25 => 10865
26 => 12583
27 => 14352
28 => 16121
29 => 18177
30 => 18890
31 => 22886
32 => 23394
33 => 25227
34 => 27905
35 => 30384
36 => 33277
37 => 36711
38 => 39782
39 => 42716
40 => 45602
41 => 48228
42 => 51170
43 => 53796
44 => 55865
45 => 58358
46 => 60694
47 => 62494
48 => 64404
49 => 67003
50 => 68324
51 => 70251
52 => 72624
53 => 76034
54 => 78088
55 => 80840
56 => 83207
57 => 84854
58 => 87256
]
"max_value_of_total_confirmed" => 272166
]
Group By Week
$client = new Client();
$request = $client->get('https://pomber.github.io/covid19/timeseries.json');
$response = $request->getBody()->getContents();
$posts_dates = json_decode($response, true);
/****** Here we go ******/
$posts_dates = collect($posts_dates)
->flatten(1)
->map(function ($item) {
$date = \Carbon\Carbon::parse($item['date']);
$item['week'] = 'W' . $date->weekOfMonth . $date->format(' M');
return $item;
})
->groupBy('week')
->map(function ($item, $key) {
$item = collect($item);
return [
'date' => $key,
'total_confirmed' => $item->sum('confirmed'),
'total_deaths' => $item->sum('deaths'),
'total_recovered' => $item->sum('recovered'),
];
})
->groupBy(function ($item, $key) {
return collect($item)->keys()->all();
})
->map(function ($item, $key) {
return $item->map(function ($item) use ($key) {
return $item[$key];
});
});
$posts_dates->put('max_value_of_total_confirmed', $posts_dates['total_confirmed']->max());
dd($posts_dates->toArray());
Result
array:5 [
"date" => array:10 [
0 => "W4 Jan"
1 => "W5 Jan"
2 => "W1 Feb"
3 => "W2 Feb"
4 => "W3 Feb"
5 => "W4 Feb"
6 => "W5 Feb"
7 => "W1 Mar"
8 => "W2 Mar"
9 => "W3 Mar"
]
"total_confirmed" => array:10 [
0 => 14206
1 => 24327
2 => 165441
3 => 337308
4 => 517307
5 => 565794
6 => 86011
7 => 672122
8 => 897443
9 => 1275899
]
"total_deaths" => array:10 [
0 => 372
1 => 517
2 => 3456
3 => 7850
4 => 13931
5 => 18720
6 => 2941
7 => 22861
8 => 32610
9 => 51370
]
"total_recovered" => array:10 [
0 => 353
1 => 491
2 => 6853
3 => 33992
4 => 100383
5 => 199784
6 => 39782
7 => 355735
8 => 465794
9 => 490279
]
"max_value_of_total_confirmed" => 1275899
]

Related

range(strtotime("00:00"), strtotime("23:59"), 30*60) does not work properly after upgrade laravel to 7. Is it php problem?

After upgrade Laravel 7 from 6 I have got an error.
Array used to have total 48 items but now 50 items.
Is it php error? or laravel error?
I tested on laravel 5 it gives total 48 items.
$times = [];
$range= range(strtotime("00:00"), strtotime("23:59"), 30*60);
foreach($range as $time){
$times[] = date("H:i",$time);
}
return $times;
array:50 [▼
0 => "00:00"
1 => "00:30"
2 => "01:00"
3 => "01:30"
4 => "02:00"
5 => "02:30"
6 => "02:00"
7 => "02:30"
8 => "03:00"
9 => "03:30"
10 => "04:00"
11 => "04:30"
12 => "05:00"
13 => "05:30"
14 => "06:00"
15 => "06:30"
16 => "07:00"
17 => "07:30"
18 => "08:00"
19 => "08:30"
20 => "09:00"
21 => "09:30"
22 => "10:00"
23 => "10:30"
24 => "11:00"
25 => "11:30"
26 => "12:00"
27 => "12:30"
28 => "13:00"
29 => "13:30"
30 => "14:00"
31 => "14:30"
32 => "15:00"
33 => "15:30"
34 => "16:00"
35 => "16:30"
36 => "17:00"
37 => "17:30"
38 => "18:00"
39 => "18:30"
40 => "19:00"
41 => "19:30"
42 => "20:00"
43 => "20:30"
44 => "21:00"
45 => "21:30"
46 => "22:00"
47 => "22:30"
48 => "23:00"
49 => "23:30"
]
6 => "02:00" and 7 => "02:30" are duplicated.
Any advice please?
Thanks
Found the reason why. It is because of day light saving. #JoffreySchmitz commented. Thanks.

Fill up emtpy array spots with prev value

I am using PHP 7.3.5.
I have an array with emtpy spots, which I would like to fill up values from the previous spot:
For example:
0 => 'FriAug 1',
1 => '',
2 => '',
3 => '',
4 => '',
Should result in:
0 => '01.08.2019',
1 => '01.08.2019',
2 => '01.08.2019',
3 => '01.08.2019',
4 => '01.08.2019',
I tried the following:
<?php
$arr = array (
0 => 'FriAug 1',
1 => '',
2 => '',
3 => '',
4 => '',
5 => '',
6 => '',
7 => '',
8 => '',
9 => '',
10 => '',
11 => '',
12 => '',
13 => '',
14 => '',
15 => '',
16 => '',
17 => '',
18 => '',
19 => 'SatNov 2',
20 => 'SunNov 3',
21 => '',
22 => '',
23 => '',
24 => '',
25 => '',
26 => 'MonJan 4',
27 => '',
28 => '',
29 => '',
30 => '',
31 => '',
32 => '',
33 => '',
34 => '',
35 => '',
36 => '',
37 => '',
38 => '',
39 => '',
40 => '',
41 => '',
42 => '',
43 => '',
44 => '',
45 => 'TueDec 5',
46 => '',
47 => '',
48 => '',
49 => '',
50 => '',
51 => '',
52 => '',
53 => '',
54 => '',
55 => '',
56 => '',
57 => '',
58 => '',
59 => '',
60 => '',
61 => '',
62 => 'WedNov 6'
);
$resArr = array();
foreach ($arr as $key => $v) {
$prev = $key - 1;
if($arr[$key] === '') {
array_push($resArr, strtotime(preg_replace("^.{0,3}","", $arr[$prev])));
} else {
array_push($resArr, strtotime(preg_replace("^.{0,3}","", $arr[$key])));
}
}
print_r($resArr);
My final result should look like the following:
// Wanted Result:
0 => '01.08.2019',
1 => '01.08.2019',
2 => '01.08.2019',
3 => '01.08.2019',
4 => '01.08.2019',
5 => '01.08.2019',
6 => '01.08.2019',
7 => '01.08.2019',
8 => '01.08.2019',
9 => '01.08.2019',
10 => '01.08.2019',
11 => '01.08.2019',
12 => '01.08.2019',
13 => '01.08.2019',
14 => '01.08.2019',
15 => '01.08.2019',
16 => '01.08.2019',
17 => '01.08.2019',
18 => '01.08.2019',
19 => '02.11.2019',
20 => '03.11.2019',
21 => '03.11.2019',
22 => '03.11.2019',
23 => '03.11.2019',
24 => '03.11.2019',
25 => '03.11.2019',
26 => '04.11.2019',
27 => '04.11.2019',
28 => '04.11.2019',
29 => '04.11.2019',
30 => '04.11.2019',
31 => '04.11.2019',
32 => '04.11.2019',
33 => '04.11.2019',
34 => '04.11.2019',
35 => '04.11.2019',
36 => '04.11.2019',
37 => '04.11.2019',
38 => '04.11.2019',
39 => '04.11.2019',
40 => '04.11.2019',
41 => '04.11.2019',
42 => '04.11.2019',
43 => '04.11.2019',
44 => '04.11.2019',
45 => '05.12.2019',
46 => '05.12.2019',
47 => '05.12.2019',
48 => '05.12.2019',
49 => '05.12.2019',
50 => '05.12.2019',
51 => '05.12.2019',
52 => '05.12.2019',
53 => '05.12.2019',
54 => '05.12.2019',
55 => '05.12.2019',
56 => '05.12.2019',
57 => '05.12.2019',
58 => '05.12.2019',
59 => '05.12.2019',
60 => '05.12.2019',
61 => '05.12.2019',
62 => '06.11.2019'
);
However, I only get null/false values in my final output.
Any suggestions what I am doing wrong?
I appreciate your replies!
One of the problems is the use of the regex - your pattern isn't correct - but as it's just removing 3 chars of the front, it's easier to use substr() to remove them.
The second part is that you just look at the previous array position in the source array - which may also be blank. This version just stores the last value generated (in $prev) and keeps on using it when needed...
$resArr = array();
$prev = "";
foreach ($arr as $key => $v) {
if($arr[$key] === '') {
array_push($resArr, $prev);
} else {
$prev = date("d.m.Y",strtotime(substr($arr[$key], 3)));
array_push($resArr, $prev);
}
}
This could be simplified without losing too much clarity to...
$resArr = array();
$prev = "";
foreach ($arr as $key => $v) {
if($arr[$key] !== '') {
$prev = date("d.m.Y",strtotime(substr($arr[$key], 3)));
}
array_push($resArr, $prev);
}

Sort array using another array of values

I have the following array depicting points accumulated during the year. As a tie breaker on equal points, I have another value that I calculate that I want the result to be sorted on.
This is the sorted array, showing points during the year:
$results = [
1 => 220
0 => 209
4 => 127
14 => 89
3 => 84
7 => 78
2 => 71
13 => 61
16 => 56
8 => 48
12 => 45
10 => 42
11 => 42
6 => 39
5 => 35
9 => 32
15 => 22
17 => 22
18 => 22
19 => 1
Because indexes 10 and 11, and 15, 17 and 18 are equal, they need to be sorted by the lowest values in the following array:
// For 10 and 11
$anotherArray = [
11 => 101
10 => 119
]
// For 15, 17 and 18
$anotherArray = [
17 => 150
18 => 160
15 => 179
]
So the resulting array should look like this:
$finalArray = [
1 => 220
0 => 209
4 => 127
14 => 89
3 => 84
7 => 78
2 => 71
13 => 61
16 => 56
8 => 48
12 => 45
11 => 42
10 => 42
6 => 39
5 => 35
9 => 32
17 => 22
18 => 22
15 => 22
19 => 1
]
How would I achieve this?
EDIT: It's not the same as this question. The solution suggested is based on the values of an array and does not solve the issue where I need to insert values in another array in the correct order.
A 2-dimensional array is created with the values of the result array and the values of the 'anotherArrays'.
This array is sorted with uasort () and converted back into a one-dimensional array.
$results = [
1 => 220,0 => 209,4 => 127, 14 => 89, 3 => 84, 7 => 78,
2 => 71, 13 => 61, 16 => 56, 8 => 48, 12 => 45, 10 => 42, 11 => 42,
6 => 39, 5 => 35, 9 => 32, 15 => 22, 17 => 22, 18 => 22, 19 => 1
];
$anotherArray1 = [11 => 101, 10 => 119];
$anotherArray2 = [17 => 150, 18 => 160, 15 => 179];
$sekArr = array_replace($results,$anotherArray1,$anotherArray2);
$newArr = [];
foreach($results as $key => $value){
$newArr[$key] = ["v" => $value, 's' => $sekArr[$key]];
}
uasort($newArr, function($a,$b){
return $b['v'] <=> $a['v'] ?: $a['s'] <=> $b['s'];
});
$results = [];
foreach($newArr as $key => $arr){
$results[$key] = $arr['v'];
}
var_dump($results);
Try for yourself: https://3v4l.org/Si6ST

Symfony2 weird issue with for loop or me :)

I experience a weird issue with for loop I mean I have associative array with makes:
$makes = array(0 => '9FF',
1 => 'AC',
2 => 'AMG',
3 => 'Alfa Romeo',
4 => 'Alpina',
5 => 'Ariel',
6 => 'Ascari',
7 => 'Aston Martin',
8 => 'Audi',
9 => 'B Engineering',
10 => 'BAC',
11 => 'BMW',
12 => 'Beck',
13 => 'Bentley',
14 => 'Bertone',
15 => 'Bizzarrini',
16 => 'Brabus',
17 => 'Bristol',
18 => 'Brooke',
19 => 'Bugatti',
20 => 'Buick',
21 => 'Cadillac',
22 => 'Callaway',
23 => 'Caparo',
24 => 'Caterham',
25 => 'Chevrolet',
26 => 'Chrysler',
27 => 'Citroen',
28 => 'Cizeta Moroder',
29 => 'Connaught',
30 => 'Covini',
31 => 'Dauer',
32 => 'David Brown',
33 => 'Dax',
34 => 'De Lorean',
35 => 'De Tomaso',
36 => 'Dodge',
37 => 'Dome',
38 => 'ES Motorsports',
39 => 'Elfin',
40 => 'Ferrari',
41 => 'Fiat',
42 => 'Fioravanti',
43 => 'Fisker',
44 => 'Ford',
45 => 'GM',
46 => 'GTA',
47 => 'Gemballa',
48 => 'Ghia',
49 => 'Ginetta',
50 => 'Giugiaro',
51 => 'Grinnall',
52 => 'Gumpert',
53 => 'Hennessey',
54 => 'Heuliez',
55 => 'Honda',
56 => 'Invicta',
57 => 'Isdera',
58 => 'Iso',
59 => 'Ital Design',
60 => 'Jaguar',
61 => 'Jeep',
62 => 'Jensen',
63 => 'Joss',
64 => 'KTM',
65 => 'Keio University',
66 => 'Koenig',
67 => 'Koenigsegg',
68 => 'Lamborghini',
69 => 'Lancia',
70 => 'Land Rover',
71 => 'LeBlanc',
72 => 'Leading Edge',
73 => 'Lexus',
74 => 'Light Car Company',
75 => 'Lingenfelter',
76 => 'Lister',
77 => 'Lotec',
78 => 'Lotus',
79 => 'MB Roadcars',
80 => 'MG',
81 => 'Marcos',
82 => 'Maserati',
83 => 'Maybach',
84 => 'Mazda',
85 => 'McLaren',
86 => 'Melling',
87 => 'Mercedes',
88 => 'Mitsubishi',
89 => 'Monteverdi',
90 => 'Morgan',
91 => 'Mosler',
92 => 'Nissan',
93 => 'Noble',
94 => 'Oldsmobile',
95 => 'Pagani',
96 => 'Palmer',
97 => 'Panoz',
98 => 'Panther',
99 => 'Peugeot',
100 => 'Pininfarina',
101 => 'Plymouth',
102 => 'Pontiac',
103 => 'Porsche',
104 => 'Prodrive',
105 => 'Radical',
106 => 'Renault',
107 => 'Rimac',
108 => 'Rolls Royce',
109 => 'Roush',
110 => 'Ruf',
111 => 'SCG',
112 => 'SSC',
113 => 'Saab',
114 => 'Saleen',
115 => 'Sbarro',
116 => 'Schuppan',
117 => 'Sin',
118 => 'Spectre',
119 => 'Spyker',
120 => 'Stealth',
121 => 'Strathcarron',
122 => 'Studiotorino',
123 => 'Subaru',
124 => 'Superformance',
125 => 'TVR',
126 => 'Techart',
127 => 'Tesla',
128 => 'Tiger',
129 => 'Toroidion',
130 => 'Toyota',
131 => 'Tramontana',
132 => 'Trident',
133 => 'UVA',
134 => 'Ultima',
135 => 'Vauxhall',
136 => 'Vector',
137 => 'Vemac',
138 => 'Venturi',
139 => 'Veritas',
140 => 'Volkswagen',
141 => 'Volvo',
142 => 'Westfield',
143 => 'Wiesmann',
144 => 'Wolfrace',
145 => 'Yamaha',
146 => 'Zagato',
147 => 'Zenvo');
and some other code:
$pics = '';
$logos = "http://www.supercarworld.com/images/logos/";
$gif = ".gif";
for ($x = 0; $x < count($makes); $x++) {
$pics = array($logos.$makes[$x].$gif);
print_r($pics[$x]);
$car = new Car();
$car->setName('http://www.supercarworld.com/images/fullpics/595.jpg');
// em entity manager
$em = $this->getDoctrine()->getManager();
$em->persist($car);
$em->flush();
$car = $this->getDoctrine()
->getRepository('GrupaProjektBundle:Car')
->findOneBy(array('id' => $car->getId(), 'name' => $car->getName()));
return $this->render('GrupaProjektBundle:Sc:supercars.html.twig', array('car' => $car,
'pics' => $pics[$x],
));
}
and when I want to get [$x] the behaviour is weird it displays only zero element i.e 9FF but when I get [0] or [1] from $makes it works
Why?
I want to make it to iterate am I missing some incrementation?
$pics is not an array, or the way you are assigning it, it is an array with exactly one element & will get overwritten in each iteration of your for loop.
Did you mean to do that, or did you want
$pics = array();
Then in your for loop:
$pics[$x] = $logos.$makes[$x].$gif;
I'm guessing here as it's not immediately clear what you're trying to achieve. But I can certainly say you're overwriting $pics on each iteration of your for loop.

php mp3 string error

i have a mp3 class to read mp3s for my site. (i cannot install the module since its a shared hosting). i upload the mp3 and then the system read it using my class and insert into my mysql the file name and location, and the basic tag (artist, song name, album). the mysql insert is ok but i have problem with the strings i am inserting.
here's my code: http://pastebin.com/fXsm0c3T
<?php
class Id3 {
private $tags = array(
'TALB' => 'album', 'TCON' => 'genre', 'TENC' => 'encoder',
'TIT2' => 'title', 'TPE1' => 'artist', 'TPE2' => 'ensemble', 'TYER' => 'year', 'TCOM' => 'composer',
'TCOP' => 'copyright', 'TRCK' => 'track', 'WXXX' => 'url',
'COMM' => 'comment'
);
private $genre = array(
0 => 'Blues', 1 => 'Classic Rock', 2 => 'Country', 3 => 'Dance', 4 => 'Disco', 5 => 'Funk', 6 => 'Grunge', 7 => 'Hip-Hop', 8 => 'Jazz', 9 => 'Metal', 10 => 'New Age', 11 => 'Oldies', 12 => 'Other',
13 => 'Pop', 14 => 'R&B', 15 => 'Rap', 16 => 'Reggae', 17 => 'Rock', 18 => 'Techno', 19 => 'Industrial', 20 => 'Alternative', 21 => 'Ska', 22 => 'Death Metal', 23 => 'Pranks', 24 => 'Soundtrack', 25 => 'Euro-Techno', 26 => 'Ambient', 27 => 'Trip-Hop', 28 => 'Vocal',
29 => 'Jazz+Funk', 30 => 'Fusion', 31 => 'Trance', 32 => 'Classical', 33 => 'Instrumental', 34 => 'Acid', 35 => 'House',
36 => 'Game', 37 => 'Sound Clip', 38 => 'Gospel', 39 => 'Noise', 40 => 'Alternative Rock', 41 => 'Bass', 42 => 'Soul', 43 => 'Punk', 44 => 'Space', 45 => 'Meditative', 46 => 'Instrumental Pop', 47 => 'Instrumental Rock', 48 => 'Ethnic',
49 => 'Gothic', 50 => 'Darkwave', 51 => 'Techno-Industrial', 52 => 'Electronic', 53 => 'Pop-Folk', 54 => 'Eurodance', 55 => 'Dream', 56 => 'Southern Rock', 57 => 'Comedy', 58 => 'Cult', 59 => 'Gangsta', 60 => 'Top 40', 61 => 'Christian Rap', 62 => 'Pop/Funk', 63 => 'Jungle', 64 => 'Native US', 65 => 'Cabaret', 66 => 'New Wave', 67 => 'Psychadelic', 68 => 'Rave', 69 => 'Showtunes', 70 => 'Trailer', 71 => 'Lo-Fi', 72 => 'Tribal', 73 => 'Acid Punk', 74 => 'Acid Jazz', 75 => 'Polka', 76 => 'Retro', 77 => 'Musical', 78 => 'Rock & Roll', 79 => 'Hard Rock', 80 => 'Folk', 81 => 'Folk-Rock', 82 => 'National Folk', 83 => 'Swing', 84 => 'Fast Fusion', 85 => 'Bebob', 86 => 'Latin',
87 => 'Revival', 88 => 'Celtic', 89 => 'Bluegrass', 90 => 'Avantgarde', 91 => 'Gothic Rock', 92 => 'Progressive Rock', 93 => 'Psychedelic Rock', 94 => 'Symphonic Rock', 95 => 'Slow Rock', 96 => 'Big Band', 97 => 'Chorus', 98 => 'Easy Listening', 99 => 'Acoustic',
100 => 'Humour', 101 => 'Speech', 102 => 'Chanson', 103 => 'Opera', 104 => 'Chamber Music', 105 => 'Sonata', 106 => 'Symphony', 107 => 'Booty Bass', 108 => 'Primus', 109 => 'Porn Groove', 110 => 'Satire', 111 => 'Slow Jam', 112 => 'Club',
113 => 'Tango', 114 => 'Samba', 115 => 'Folklore', 116 => 'Ballad', 117 => 'Power Ballad', 118 => 'Rhytmic Soul', 119 => 'Freestyle', 120 => 'Duet', 121 => 'Punk Rock', 122 => 'Drum Solo', 123 => 'Acapella', 124 => 'Euro-House',
125 => 'Dance Hall', 126 => 'Goa', 127 => 'Drum & Bass', 128 => 'Club-House', 129 => 'Hardcore', 130 => 'Terror', 131 => 'Indie', 132 => 'BritPop', 133 => 'Negerpunk', 134 => 'Polsk Punk', 135 => 'Beat', 136 => 'Christian Gangsta Rap', 137 => 'Heavy Metal', 138 => 'Black Metal', 139 => 'Crossover', 140 => 'Contemporary Christian', 141 => 'Christian Rock', 142 => 'Merengue', 143 => 'Salsa', 144 => 'Trash Metal', 145 => 'Anime', 146 => 'Jpop', 147 => 'Synthpop'
);
public function __construct() {
$this->info = '';
}
private function getId3() {
$handle = fopen($this->file, 'r');
$head = fread($handle,10);
$head = unpack("a3signature/c1version_major/c1version_minor/c1flags/Nsize", $head);
$result = array();
for ($i = 0; $i<5; $i++){
$tag = trim(fread($handle, 6));
if (!isset($this->tags[$tag])) continue;
$size = fread($handle, 2);
$size = unpack('n', $size); $size = $size[1]+2;
$value = fread($handle, $size);
$this->info[$this->tags[$tag]] = $value;
} fclose($handle);
}
public function load($file) {
$this->file = $file; $this->getId3(); }
}
$id3 = new Id3();
$id3->load('mp3.mp3');
print_R($id3->info);
now, when i read the value i get this:
Array
(
[genre] => ��Rock
[title] => ��Walk
[artist] => ��Foo Fighters
[album] => ��Wasting Light
)
what is wrong with my code?
based on your code, the $value needs to be trim or converted to UTF (I prefer converting to UTF).
I added function that will check which UTF is the mp3 and parse it correctly:
$value = $this->filter($value, $tag); // convert to UTF or else that is why you have weird chars
Here's a readable code.
<?php
class Id3 {
private $tags = array(
'TALB' => 'album',
'TCON' => 'genre',
'TENC' => 'encoder',
'TIT2' => 'title',
'TPE1' => 'artist',
'TPE2' => 'ensemble',
'TYER' => 'year',
'TCOM' => 'composer',
'TCOP' => 'copyright',
'TRCK' => 'track',
'WXXX' => 'url',
'COMM' => 'comment'
);
private $genre = array(
0 => 'Blues',
1 => 'Classic Rock',
2 => 'Country',
3 => 'Dance',
4 => 'Disco',
5 => 'Funk',
6 => 'Grunge',
7 => 'Hip-Hop',
8 => 'Jazz',
9 => 'Metal',
10 => 'New Age',
11 => 'Oldies',
12 => 'Other',
13 => 'Pop',
14 => 'R&B',
15 => 'Rap',
16 => 'Reggae',
17 => 'Rock',
18 => 'Techno',
19 => 'Industrial',
20 => 'Alternative',
21 => 'Ska',
22 => 'Death Metal',
23 => 'Pranks',
24 => 'Soundtrack',
25 => 'Euro-Techno',
26 => 'Ambient',
27 => 'Trip-Hop',
28 => 'Vocal',
29 => 'Jazz+Funk',
30 => 'Fusion',
31 => 'Trance',
32 => 'Classical',
33 => 'Instrumental',
34 => 'Acid',
35 => 'House',
36 => 'Game',
37 => 'Sound Clip',
38 => 'Gospel',
39 => 'Noise',
40 => 'Alternative Rock',
41 => 'Bass',
42 => 'Soul',
43 => 'Punk',
44 => 'Space',
45 => 'Meditative',
46 => 'Instrumental Pop',
47 => 'Instrumental Rock',
48 => 'Ethnic',
49 => 'Gothic',
50 => 'Darkwave',
51 => 'Techno-Industrial',
52 => 'Electronic',
53 => 'Pop-Folk',
54 => 'Eurodance',
55 => 'Dream',
56 => 'Southern Rock',
57 => 'Comedy',
58 => 'Cult',
59 => 'Gangsta',
60 => 'Top 40',
61 => 'Christian Rap',
62 => 'Pop/Funk',
63 => 'Jungle',
64 => 'Native US',
65 => 'Cabaret',
66 => 'New Wave',
67 => 'Psychadelic',
68 => 'Rave',
69 => 'Showtunes',
70 => 'Trailer',
71 => 'Lo-Fi',
72 => 'Tribal',
73 => 'Acid Punk',
74 => 'Acid Jazz',
75 => 'Polka',
76 => 'Retro',
77 => 'Musical',
78 => 'Rock & Roll',
79 => 'Hard Rock',
80 => 'Folk',
81 => 'Folk-Rock',
82 => 'National Folk',
83 => 'Swing',
84 => 'Fast Fusion',
85 => 'Bebob',
86 => 'Latin',
87 => 'Revival',
88 => 'Celtic',
89 => 'Bluegrass',
90 => 'Avantgarde',
91 => 'Gothic Rock',
92 => 'Progressive Rock',
93 => 'Psychedelic Rock',
94 => 'Symphonic Rock',
95 => 'Slow Rock',
96 => 'Big Band',
97 => 'Chorus',
98 => 'Easy Listening',
99 => 'Acoustic',
100 => 'Humour',
101 => 'Speech',
102 => 'Chanson',
103 => 'Opera',
104 => 'Chamber Music',
105 => 'Sonata',
106 => 'Symphony',
107 => 'Booty Bass',
108 => 'Primus',
109 => 'Porn Groove',
110 => 'Satire',
111 => 'Slow Jam',
112 => 'Club',
113 => 'Tango',
114 => 'Samba',
115 => 'Folklore',
116 => 'Ballad',
117 => 'Power Ballad',
118 => 'Rhytmic Soul',
119 => 'Freestyle',
120 => 'Duet',
121 => 'Punk Rock',
122 => 'Drum Solo',
123 => 'Acapella',
124 => 'Euro-House',
125 => 'Dance Hall',
126 => 'Goa',
127 => 'Drum & Bass',
128 => 'Club-House',
129 => 'Hardcore',
130 => 'Terror',
131 => 'Indie',
132 => 'BritPop',
133 => 'Negerpunk',
134 => 'Polsk Punk',
135 => 'Beat',
136 => 'Christian Gangsta Rap',
137 => 'Heavy Metal',
138 => 'Black Metal',
139 => 'Crossover',
140 => 'Contemporary Christian',
141 => 'Christian Rock',
142 => 'Merengue',
143 => 'Salsa',
144 => 'Trash Metal',
145 => 'Anime',
146 => 'Jpop',
147 => 'Synthpop'
);
private $file;
private $info;
public function __construct() {
$this->info = array(
'genre' => 'unknow',
'title' => 'unknow',
'artist' => 'unknow',
'album' => 'unknow',
);
}
private function filter($tag, $type) {
if ($type == 'COMM') {
$tag = substr($tag, 0, 3) . substr($tag, 10);
}
if(ord($tag[2]) == 0) {
return iconv('UTF-8', 'ISO-8859-1', substr($tag, 3));
}
elseif(ord($tag[2]) == 1) {
return iconv('UTF-16LE', 'UTF-8', substr($tag, 5));
}
elseif(ord($tag[2]) == 2) {
return iconv('UTF-16BE', 'UTF-8', substr($tag, 5));
}
elseif(ord($tag[2]) == 3) {
return substr($tag, 3);
}
return false;
}
private function getId3() {
$handle = fopen($this->file, 'rb');
$head = fread($handle, 10);
$head = unpack("a3signature/c1version_major/c1version_minor/c1flags/Nsize", $head);
if (!$head['signature'] == 'ID3') {
fclose($handle);
return false;
}
$result = array();
for ($i = 0; $i < 22; $i++) { //22 most popular tags, you had 5 therefore only the first five.
$tag = rtrim(fread($handle, 6));
if (!isset($this->tags[$tag])) {
continue;
}
$size = fread($handle, 2);
$size = unpack('n', $size);
$size = $size[1]+2;
$value = fread($handle, $size);
$value = $this->filter($value, $tag); // convert to UTF or else that is why you have weird chars
$this->info[$this->tags[$tag]] = $value;
}
fclose($handle);
}
public function load($file) {
$this->file = $file;
$this->getId3();
}
public function getInfo() {
return $this->info;
}
}
$id3 = new Id3();
$id3->load('mp3.mp3');
print_R($id3->getInfo());
To get more information about tags, read this wiki article: http://en.wikipedia.org/wiki/ID3

Categories