Group Array from .csv | PHP - php

I have this code and what i'm trying to do is , group the data coming from the .csv by Player , and then group by year and league , so for example , i will have faker -> 2021 -> lck->data ; ->2020->lck->data
and sometimes when a player has played more than one league in a year , faker->2021->lck->data | 2021->kespa->data
the problem is when i show the kills(image) , the year 2020 is adding the kills from 2021 plus kills from 2020.
and what i want is 2020 show the kills from that league and that year and the same with 2021.
The result im Getting :
Faker => 2021 => kills [1,2,3] ; 2020 => kills [1,2,3,6,9,12];
The expected result is :
Faker => 2021 => kills [1,2,3] ; 2020 => kills [6,9,12]
how can i achieve that ?
Thats the csv
gameid,datacompleteness,url,league,year,split,playoffs,date,game,patch,playerid,side,position,player,team,champion .....
thats my code;
<?php
$csvFileData = file('./datalck.csv');
$dataMatch = [];
foreach ($csvFileData as $lines) {
$data[] = str_getcsv($lines);
}
foreach ($dataMatch as $matchs) {
// So here i'm grouping the array by player
//[3] is the position for the league
//[4] is the position for year
//[13] is the position of player name ,
//[23] The position of kills
if ($matchs[13] != NULL and $matchs[13] != "") {
$group[$matchs[13]][] = [
'Player' => $matchs[13],
"kills" => $matchs[23],
'league' => $matchs[3],
'year' => $matchs[4],
];
}
}
foreach ($group as $players => $p) {
$kills = [];
foreach ($p as $op) {
$kills[] = $op['kills'];
$group2[$op['Player']][$op['year']][$op['league']] = [
"Player" => $op['Player'],
"kills" => $kills,
"league" => $op['league'],
"year" => $op['year'],
];
}
}
foreach ($group2 as $op2) {
echo '<pre>';
var_dump(($group2));
echo '</pre>';
}
?>

You are adding to $kills array, without taking care of the year.
So, when you parse the year 2021, the $kills array already contains the 2020 data.
You could create an empty array the first time (each new year), and then, fill it.
foreach ($group as $players => $p)
{
foreach ($p as $op)
{
// variables for readability
$plyr = $op['Player'];
$year = $op['year'];
$leag = $op['league'];
$kills = $op['kills'];
// create the initial state
if (!isset($group2[$plyr][$year][$leag]))
{
$group2[$plyr][$year][$leag] = [
"Player" => $plyr,
"league" => $leag,
"year" => $year,
"kills" => [], // empty array
];
}
// add value to array for the player/year/league :
$group2[$plyr][$year][$leag]['kills'][] = $kills;
}
}
See a working demo.

Related

Create CSV with dynamic grouped headers in PHP from array

Could someone please assist in achieving that follow tasks please?
How to create a CSV export from a multidimensional array, but to have dynamic grouped column headings
Array (
[0] => Array ( [months] => 06/2020 [hours] => 202 [skill] => 5 )
[1] => Array ( [months] => 06/2020 [hours] => 563.5 [skill] => 6 )
[2] => Array ( [months] => 07/2020 [hours] => 140.5 [skill] => 6 )
[3] => Array ( [months] => 07/2020 [hours] => 522.5 [skill] => 5 )
)
So the output on the CSV would be like
+----------------------------+------------+--------+
| | Skill 6 |Skill 5 |
+----------------------------+------------+--------+
| 06/2020 | 563.5 | 202 |
+----------------------------+------------+--------+
| 07/2020 | 140.5 | 522.5 |
+----------------------------+------------+--------+
Added CSV output I have so far
Current CSV Element of the code
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename=result_file.csv");
header("Pragma: no-cache");
header("Expires: 0");
// Building $data_array from DB
foreach ($data_array as $subarray) {
$tempKey = $subarray['skill'].$subarray['months'];
$subarray['hours'] = str_replace(',', '', $subarray['hours']);
if (isset($result[$tempKey])) {
$result[$tempKey]['hours'] += $subarray['hours'];
} else {
$result[$tempKey] = $subarray;
}
}
// CSV Output
outputCSV($result);
function outputCSV($result) {
$output = fopen("php://output", "w");
foreach ($result as $row) {
fputcsv($output, $row);
}
fclose($output);
}
any help would be greatly appreciated, TIA
Question edited
Pretty sure if I thought about this for a bit I could improve it but it seems like it gets the right answer
$in = [
[ 'months' => '06/2020', 'hours' => 202, 'skill' => 5 ],
[ 'months' => '06/2020', 'hours' => 563.5, 'skill' => 6 ],
[ 'months' => '07/2020', 'hours' => 140.5, 'skill' => 6 ],
[ 'months' => '07/2020', 'hours' => 522.5, 'skill' => 5 ]
];
$firstTitle = 'Month';
$months = [];
$skills = [$firstTitle=>1];
// make an array keyed on the date
foreach ( $in as $t) {
$months[$t['months']]['skill'.$t['skill']] = $t['hours'];
$skills['skill'.$t['skill']] = 1;
}
// sort skills into assending order
ksort($skills);
// open a file
$xl = fopen('excelfile.csv', 'w');
// echo title line from the skills array
fputcsv($xl, array_keys($skills));
// build csv line with skills in the correct order
foreach ($months as $date => $m){
// build array in correct sorted order
$t = [];
$t[] = $date;
foreach ($skills as $skill => $x) {
if ( $skill != $firstTitle) $t[] = $m[$skill];
}
fputcsv($xl,$t);
}
RESULT
Month,skill5,skill6
06/2020,202,563.5
07/2020,522.5,140.5
You're basically just aggregating the skill values by month and then outputting those aggregated values. This is not difficult, but you've got to be clear about what you're doing. One common reason I see new players get confused is that they're trying to use the most compact code possible, which makes it hard to keep track of what's happening. Be verbose, name things clearly, and comment your code relentlessly. You'll have a much easier time seeing why something isn't working, and your code will be much more maintainable. Write your code like someone else is going to be maintaining it. That someone else may be you in five years.
<?php
$dataArray = [
['months' => '06/2020', 'hours' => '202', 'skill' => '5'],
['months' => '06/2020', 'hours' => '563.5', 'skill' => '6'],
['months' => '06/2020', 'hours' => '303.7', 'skill' => '6'],
['months' => '08/2020', 'hours' => '123.5', 'skill' => '8'],
['months' => '07/2020', 'hours' => '140.5', 'skill' => '6'],
['months' => '07/2020', 'hours' => '522.5', 'skill' => '5'],
['months' => '08/2020', 'hours' => '123.5', 'skill' => '6']
];
/*
* Break out your formatting into functions so that it's re-usable and doesn't clutter up your logic
*/
function formatHours($hourString)
{
$hourString = str_replace(',', '', $hourString);
return floatval($hourString);
}
function buildSkillKey($skillValue)
{
return 'Skill '.$skillValue;
}
// Set up buffers for our skills and month values
$skills = [];
$buffer = [];
foreach($dataArray as $currRow)
{
//Format the hour value
$currHours = formatHours($currRow['hours']);
//Create key for the skill.
$skillKey = buildSkillKey($currRow['skill']);
/*
* Add the skill to the skill buffer. Using the value as the key is an easy way to both prevent duplicates
* without having to implement any logic, and have automatic alpha sorting
*/
$skills[$skillKey] = $skillKey;
// Set up an array for the month value if we don't have one already
if(!array_key_exists($currRow['months'], $buffer))
{
$buffer[$currRow['months']] = [];
}
/*
* If you don't have multiple month/skill entries that you need to aggregate, remove this condition
* and simply set the value in the buffer rather than adding with +=
*/
if(!array_key_exists($skillKey, $buffer[$currRow['months']]))
{
$buffer[$currRow['months']][$skillKey] = 0;
}
$buffer[$currRow['months']][$skillKey] += $currHours;
}
// Define a string for the months column header
$monthColumnTitle = '';
// Create the header row by combining the month header and the skills buffer
$header = array_merge([$monthColumnTitle], $skills);
// Open an output handle and send the header
$outputHandle = fopen("skills.csv", "w");
fputcsv($outputHandle, $header);
// Spin through the buffer
foreach($buffer as $currMonth=>$currSkillValues)
{
// Initialize an output array with the month in the first position
$currOutput = [$currMonth];
// Iterate through the skill buffer
foreach($skills as $currSkillLabel)
{
/*
* If we have a value for this skill, add it to the output row, otherwise insert an empty string.
*
* If you prefer to send zeros rather than empty strings, you can just set the field value to
* $currSkillValues[$currSkillLabel], since we initialized all skills with zeroes when building
* the value buffer.
*/
$currFieldValue = (!empty($currSkillValues[$currSkillLabel])) ? $currSkillValues[$currSkillLabel]:'';
$currOutput[] = $currFieldValue;
}
// Send the row
fputcsv($outputHandle, $currOutput);
}

compare two differnt arrays and output with zero at different record in PHP

I have two different arrays like below,
month array
0 :November
1 :October
2 :September
3 :August
4 :July
5 :June
data array
0 {
profit :4045
month :June
}
1 {
profit :1161
month :August
}
2 {
profit :730
month :October
}
3 {
profit :1700
month :November
}
I need to compare these two arrays and make new array with profit as 0. Finally I want to get below array.
0 {
profit :4045
month :June
}
1 {
profit :0
month :July
}
2 {
profit :730
month :August
}
3 {
profit :0
month :September
}
4 {
profit :1700
month :October
}
5 {
profit :1700
month :November
}
I have tried below code, But it's not working
foreach ($month as $key => $value) {
if (array_key_exists($key, $data->month) {
$month[$key] = $data[$key];
} else {
$month[$key] = 0;
}
}
Ho can i make this array using month and data array?
foreach loops should do it
$month = array('November', 'October', 'September', 'August', 'July', 'June');
$data = array(
array('profit' => 4045, 'month' => 'June'),
array('profit' => 1161, 'month' => 'August'),
array('profit' => 730, 'month' => 'October'),
array('profit' => 1700, 'month' => 'November')
);
// output and temp arrays
$output = [];
$temp = [];
// Loop thru each data and set month as key, profit as value
foreach ($data as $value) {
$temp[$value['month']] = $value['profit'];
}
// Reverse month array
$month = array_reverse($month, true);
// Loop thru each month, check if month exist on temp, if not profit stays 0
foreach ($month as $value) {
$profit = 0;
if (array_key_exists($value, $temp)) {
$profit = $temp[$value];
}
$output[] = array('profit' => $profit, 'month' => $value);
}
// Output
echo '<pre>';
print_r($output);

PHP find all combinations to a sum in inner array

I'm writing a PHP script for available rooms in a hotel. I want every combination for a group (i.e. 4 person). This is my array.
$room_array = array(
array(
"title" => "1 person room",
"room_for" => 1,
"price" => 79
),
array(
"title" => "2 person room with other",
"room_for" => 1,
"price" => 69
),
array(
"title" => "2 person room alone",
"room_for" => 1,
"price" => 89
),
array(
"title" => "2 person",
"room_for" => 2,
"price" => 69
),
array(
"title" => "3 person",
"room_for" => 3,
"price" => 69
)
);
Possible outcome:
4x 1 person room
4x 2 person room with other
3x 1 person room + 1x 2 person room with other
2x 2 person room
1x 3 person room + 1x 1 person room
etc. etc.
This calls for a recursive function. But every example I looked at doesn't work with counting in the inner array. The closest i found was this question:
Finding potential combinations of numbers for a sum (given a number set to select from)
But i didn't get de solution to work..
UPDATE:
Hi, thanks for all the answers. Really helped me in finding the best practice. In the meantime, the assignment has changed a little so I can't answer my own original question. My problem is solved. Thanks again for the help!
My answer below will get you partway there.
Resources
I borrowed some code logic from this answer.
To quote the answer (in case of future removal), please view below.
You can try
echo "<pre>";
$sum = 12 ; //SUM
$array = array(6,1,3,11,2,5,12);
$list = array();
# Extract All Unique Conbinations
extractList($array, $list);
#Filter By SUM = $sum $list =
array_filter($list,function($var) use ($sum) { return(array_sum($var) == $sum);});
#Return Output
var_dump($list);
Output
array
0 => array
1 => string '1' (length=1)
2 => string '2' (length=1)
3 => string '3' (length=1)
4 => string '6' (length=1)
1 => array
1 => string '1' (length=1)
2 => string '5' (length=1)
3 => string '6' (length=1)
2 => array
1 => string '1' (length=1)
2 => string '11' (length=2)
3 => array
1 => string '12' (length=2)
Functions Used
function extractList($array, &$list, $temp = array()) {
if(count($temp) > 0 && ! in_array($temp, $list))
$list[] = $temp;
for($i = 0; $i < sizeof($array); $i ++) {
$copy = $array;
$elem = array_splice($copy, $i, 1);
if (sizeof($copy) > 0) {
$add = array_merge($temp, array($elem[0]));
sort($add);
extractList($copy, $list, $add);
} else {
$add = array_merge($temp, array($elem[0]));
sort($add);
if (! in_array($temp, $list)) {
$list[] = $add;
}
}
}
}
My answer
The code below uses the code referenced above. I changed the return functionality of the array_filter function to map it to your needs.
The only thing left for you to do is change the function so that it can catch multiple of the same type of room. At the moment, the code below will only output 1 of each type of room (as per the code referenced above). An easy way to get around this would be to multiply the array values you send to the function by the number of guests you are searching for rooms, but up to the amount of rooms available. So: if you are looking to book for 4 guests and you have no single rooms remaining and only 1 double room, your best match result would have to be a 2 person room and a 3 person room. I've added some brief functionality to add this (it's commented out), although I have not tested it. It will likely take a while to process that as well so if you're looking for a quicker method, you're gonna have to use a better algorithm as already mentioned in previous comments/answers or solve P vs NP
The code below also gives you the option to toggle a value of $exact. This value, if set to true, will return only matches exactly equal to the number of guests, and if set to false will return all matches that equal to at least the number of guests.
<?php
class Booking {
private $minGuests = 1;
protected $guests = 1;
protected $rooms = [];
public function getRoomCombinations(bool $exact = true) {
$guests = $this->guests;
$list = [];
$rooms = $this->rooms;
/*for($i = 0; $i < $guests-1; $i++) {
$rooms = array_merge($rooms, $this->rooms);
}
asort($rooms);*/
$this->extractList($rooms, $list);
$result = array_filter($list, function($var) use ($guests, $exact) {
if($exact)
return(array_sum(array_map(function($item) { return $item['room_for'];}, $var)) == $guests);
else
return(array_sum(array_map(function($item) { return $item['room_for'];}, $var)) >= $guests && count($var) <= $guests);
});
array_multisort(array_map('count', $result), SORT_ASC, $result);
return $result;
}
private function extractList(array $array, array &$list, array $temp = []) {
if (count($temp) > 0 && !in_array($temp, $list))
$list[] = $temp;
for($i = 0; $i < sizeof($array); $i++) {
$copy = $array;
$elem = array_splice($copy, $i, 1);
if (sizeof($copy) > 0) {
$add = array_merge($temp, array($elem[0]));
sort($add);
$this->extractList($copy, $list, $add);
} else {
$add = array_merge($temp, array($elem[0]));
sort($add);
if (!in_array($temp, $list)) {
$list[] = $add;
}
}
}
}
public function setGuests(int $guests) {
$this->guests = ($guests >= $this->minGuests ? $guests : $this->minGuests);
return $this;
}
public function setHotelRooms(array $rooms) {
$this->rooms = $rooms;
return $this;
}
}
$booking = (new Booking())
->setGuests(4)
->setHotelRooms([
[
"title" => "1 person room",
"room_for" => 1,
"price" => 79
],
[
"title" => "2 person room with other",
"room_for" => 1,
"price" => 69
],
[
"title" => "2 person room alone",
"room_for" => 1,
"price" => 89
],
[
"title" => "2 person",
"room_for" => 2,
"price" => 69
],
[
"title" => "3 person",
"room_for" => 3,
"price" => 69
]
]);
echo '<pre>' . var_export($booking->getRoomCombinations(true), true) . '</pre>';
?>
If you need all the combinations then you can use an backtracking iterative algorithm (depth path).
In summary:
Type of tree: binary tree because all the levels can contain a solution when the number of persons contabilized = objetive
Binary tree
Algorithm functions
You need to increment the cont every time that a level is generated with the number of persons of the level and decrement when you change your track (exploring brothers or back)
solution: array[0..levels-1] values {0 (node not selected) ,1 (node selected)}
solution[0] = 1 -> You choose that "1 person room" belongs to the solution
solutions: list/array of objects and every object contains array of titles of rooms
function Backtracking ()
level:= 1
solution:= s_initial
end:= false
repeat
generate(level, solution)
IF solution(level, solution) then
save_solution
else if test(level, solution) then
level:= level+ 1
else
while NOT MoreBrothers(level, solution)
go_back(level, s)
until level==0
2.1. Generate: generate next node
2.2. Solution: test if it's a solution
2.3. Critery: if we must continue by this track or bound
2.4. MoreBrothers: if there are nodes without check at this level
2.5. Backtrack: all the nodes at this level were explored
2.6. Save solution: add to the solutions array your object that contains strings
$room_array = array(
array(
"title" => "1 person room",
"room_for" => 1,
"price" => 79
),
array(
"title" => "2 person room with other",
"room_for" => 1,
"price" => 69
),
array(
"title" => "2 person room alone",
"room_for" => 1,
"price" => 89
),
array(
"title" => "2 person",
"room_for" => 2,
"price" => 69
),
array(
"title" => "3 person",
"room_for" => 3,
"price" => 69
)
);
// Gets rooms based on a given number of guests
function get_possible_rooms($num_guests) {
global $room_array;
$possible_rooms = [];
foreach ($room_array as $room) {
if ($num_guests <= $room['room_for']) {
$possible_rooms[] = $room['title'];
}
}
return $possible_rooms;
}
// Gets the available room capacities
function get_room_capacities() {
global $room_array;
$capacities = [];
foreach ($room_array as $room) {
$capacities[] = $room['room_for'];
}
return array_unique($capacities);
}
// Gets the different combinations of groups of guests based on the room capacities
function get_guest_assignments($remaining_guests, $parent_id = '', $num_guests, &$result) {
$room_capacities = get_room_capacities();
for ($i = 1; $i <= $remaining_guests; ++$i) {
if (in_array($i, $room_capacities)) {
$parent_guests = (isset($result[$parent_id])) ? $result[$parent_id] : 0;
$result[$parent_id . $i] = $parent_guests + $i;
for ($j = 1; $j <= $remaining_guests - $i; ++$j) {
// Recursively get the results for children
get_guest_assignments($j, $parent_id . $i, $num_guests, $result);
}
}
}
if ($remaining_guests === 1 && $parent_id !== '') {
// If it reaches the end and it does not fulfill the required number of guests,
// mark it for removal later
if ($result[$parent_id] < $num_guests) {
$result[$parent_id] = null;
}
}
// This is the last recursion
if ($result[$parent_id . '1'] === $num_guests) {
// Remove duplicates.
// To do this, we need to re-sort the keys (e.g. 21 becomes 12) and call array_unique()
// I admit this is a bit sloppy implementation.
$combinations = [];
foreach ($result as $key => $value) {
if ($value !== null) {
$nums = str_split($key);
sort($nums);
$combinations[] = implode('', $nums);
}
}
$result = array_unique($combinations);
}
}
// Gets the rooms for each group of guest
function get_room_assignments($guest_str) {
$rooms = [];
for ($i = 0; $i < strlen($guest_str); ++$i) {
$num_guests = intval(substr($guest_str, $i, 1));
$rooms[] = get_possible_rooms($num_guests);
}
return $rooms;
}
//----------
// RUN
//----------
$guests = 4;
$result = [];
get_guest_assignments($guests, null, $guests, $result);
foreach ($result as $guest_combi) {
$assignments = get_room_assignments($guest_combi);
// Printing output
echo 'Guest Combination ' . $guest_combi . "\n";
echo json_encode($assignments, JSON_PRETTY_PRINT);
echo "\n\n";
}
The output will look something like this:
...
Guest Combination 13
[
[
"1 person room",
"2 person room with other",
"2 person room alone",
"2 person",
"3 person"
],
[
"3 person"
]
]
...
"Guest combination 13" means the 4 guests will be split into groups of 1 and 3 persons.
Output is an array of possible rooms for each group. So in the example, the group of 1 can book 1 person room, 2 person room with other, ... 3 person room. And the group of 3 can book 3 person room.
—
Other notes:
I know we hate global but doing this just for brevity. Feel free to modify.
There's a shorter way to code this, but this implementation makes it easier to debug since guest combinations are used as keys.

Grouping with hyphenate not working with i18N for weekdays

I am working on a snippet for displaying opening hours and it works fine in english language and when I change the keys of array to another language it doesn't hyphenate the letters instead it does separation by comma.
What am I doing Wrong?
Below is the PHP code with 2 arrays with 1 commented which is in english and which works fine. Another is an italian langugage weekdays
<?php
/*
// english weekdays
$openHours = array(
'Mon' => '9am-7pm',
'Tue' => '9am-7pm',
'Wed' => '9am-7pm',
'Thu' => '9am-10pm',
'Fri' => 'closed',
'Sat' => '9am-10pm',
'Sun' => '9am-10pm'
);
*/
// italian weekdays
$openHours = array(
'lunedì' => '9am-7pm',
'martedì' => '9am-7pm',
'mercoledì' => '9am-7pm',
'giovedì' => '9am-10pm',
'venerdì' => 'closed',
'sabato' => '9am-10pm',
'domenica' => '9am-10pm'
);
$new_array = array();
foreach($openHours as $key => $value)
{
if(in_array($value,$new_array))
{
$key_new = array_search($value, $new_array);//to get the key of element
unset($new_array[$key_new]); //remove the element
$key_new = $key_new.','.$key; //updating the key
$new_array[$key_new] = $value; //inserting new element to the key
}
else
{
$new_array[$key] = $value;
}
}
foreach ($new_array as $days=>$time){
$daylist = explode(',',$days);
if ($time!='closed'){
if (count($daylist)>2){
$limit = count($daylist)-1;
$first = $daylist[0];
$last = $daylist[$limit];
//loop will go here.
if (date('D', strtotime('+'.$limit.' days', strtotime($first)))==$last){
echo $first.'-'.$last.' '.$time.'<br>';
} else {
$sep = '';
foreach ($daylist as $sepdays){
echo $sep.$sepdays;
$sep = ',';
}
echo ' '.$time.'<br>';
}
} else {
echo $days.' '.$time.'<br>';
}
} else {
$daylist = explode(',',$days);
foreach ($daylist as $sepdays){
echo $sepdays.' '.$time.'<br>';
}
}
}
?>
RESULT
Current Result what am getting with italian language.
lunedì,martedì,mercoledì 9am-7pm
venerdì closed
giovedì,sabato,domenica 9am-10pm
Expected RESULT
This is what I'm expecting.
lunedì-mercoledì 9am-7pm
venerdì closed
giovedì,sabato,domenica 9am-10pm
You are using your array's keys within date and strtotime functions to do your comparisons, both functions works for English. If you need to do it on other languages you should use setlocale and strftime, it will be a lot more complicated process. My suggestions:
Use numeric representation of the days of the week (0-6) and on display, replace the number with the value for the desired language.
Use multidimensional arrays including the numeric day of the week and the opening hours.

PHP Search multidimensional array and return key - super super large varying array

Hi there I'm currently using an API built to scrape prices out of an MMO and display them in an array.
At the moment this is my code:
<?php
ini_set('max_execution_time', 0);
$data = json_decode(file_get_contents("http://www.gw2spidy.com/api/v0.9/json/all-items/all"), true);
foreach($data as $item) {
echo '<pre>';
print_r($data);
echo '</pre>';
}
?>
This returns a MASSIVE array. I saved the html file and it's around 35 megabytes.
It has every single price of every single item etc...
Okay so basically what I need is to search for an item such as 'Dusk' or by it's itemID '29185'.
The prices and array keys change every hour so I've been trying to figure out a dynamic way of extracting this data every time but I'm stumped...
The arrays are structured like:
Array
(
[count] => 19959
[results] => Array
(
[15875] => Array
(
[data_id] => 29185
[name] => Dusk
[rarity] => 5
[restriction_level] => 80
[img] => https://dfach8bufmqqv.cloudfront.net/gw2/img/content/fabc9042.png
[type_id] => 18
[sub_type_id] => 6
[price_last_changed] => 2012-12-03 08:30:49 UTC
[max_offer_unit_price] => 3180000
[min_sale_unit_price] => 3890000
[offer_availability] => 5574
[sale_availability] => 6
[gw2db_external_id] => 63505
[sale_price_change_last_hour] => 0
[offer_price_change_last_hour] => 0
)
If anyone can point me in the right direction that would be awesome! I have searched for days and days but can't figure it out... I bet you it's really simple too :(
First of all, it would be good to know if there is a way to retrieve from the GW2 API server only the UPDATED items since your last "fetch all". This would mean that you would only need to retrieve this entire array once, and then update the few records that are updated each time.
You can split the array using something like array_chunk http://php.net/manual/en/function.array-chunk.php
Use these split arrays to generate batch insert statements for a database such as MySQL.
Use a simple SELECT query to retrieve the statements.
If you want to do it without DB you'll just have to search for the item using a for-loop...
for($i = 0; $i < $array['count']; $i++)
{
if ($array['results'][$i]['name'] == 'Dusk')
// you found the item
}
Try this.
Here you have used to create a new array and access it.
ini_set('max_execution_time', 0);
$data = json_decode(file_get_contents("http://www.gw2spidy.com/api/v0.9/json/all-items/all"), true);
$new_arrry = array();
$i = 0;
foreach($data as $item) {
$new_arry[$i] = $item['name'];
$new_arry[$i] = $item['data_id'];
$i++;
}
Try a recursive array search. Here is an example using a recursive function posted on the php.net page for array_search. Note the function doesn't actually use the array_search php function, but provides a similar functionality which supports multi-dimensional arrays.
First the function:
function search($array, $key, $value)
{
$results = array();
if (is_array($array))
{
if (isset($array[$key]) && $array[$key] == $value)
$results[] = $array;
foreach ($array as $subarray)
$results = array_merge($results, search($subarray, $key, $value));
}
return $results;
}
Now use the function:
$data = json_decode(file_get_contents("http://www.gw2spidy.com/api/v0.9/json/all-items/all"), true);
$results = $data['results'];
$foundItems = search($results, 'name', 'Dusk');
print_r($foundItems);
This should give you an array of all the items in the results that match the name. Similarly a search on id would be:
$foundItems = search($results, 'data_id', '12345');
Preferred Solution
Use a Database like MySQL to store all the request and only update the database if the JSON as been modified Why ?
$url = "http://www.gw2spidy.com/api/v0.9/json/all-items/all";
var_dump(get_headers($url));
Output
array (size=13)
0 => string 'HTTP/1.1 200 OK' (length=15)
1 => string 'Server: cloudflare-nginx' (length=24)
2 => string 'Date: Mon, 03 Dec 2012 11:52:41 GMT' (length=35) <--- See Date
3 => string 'Content-Type: application/json' (length=30)
4 => string 'Content-Length: 8621869' (length=23)
5 => string 'Connection: close' (length=17)
6 => string 'cache-control: no-cache' (length=23)
7 => string 'X-Varnish-TTL: 300.000' (length=22)
8 => string 'Accept-Ranges: bytes' (length=20)
9 => string 'Age: 135' (length=8)
10 => string 'X-Varnish-Cache: HIT' (length=20)
11 => string 'Set-Cookie: __cfduid=d249da7538d37614f7bc206fd407142eb1354535561; expires=Mon, 23-Dec-2019 23:50:00 GMT; path=/; domain=.gw2spidy.com' (length=133)
12 => string 'CF-RAY: 286a7d677b004f85' (length=24)
As your can see it was last modified Date: Mon, 03 Dec 2012 11:52:41 GMT it does not make sense for you to pull all this information en every request
$url = "http://www.gw2spidy.com/api/v0.9/json/all-items/all";
$info = get_headers($url,true);
$lastDate = new DateTime();
$lastDate->setDate(2012, 12, 03);
$dateModified = DateTime::createFromFormat("D, d M Y g:i:s \G\M\T", $info['Date']);
if($dateModified > $lastDate)
{
//Parse Jason
//Update Database etc
}
// Select * from result where name = 'WHAT YOU WANT'
*Educational Purpose *
$filter = new \ProductIterator("http://www.gw2spidy.com/api/v0.9/json/all-items/all");
$filter->find("name", "dusk"); //<---- What you want to find
echo "<pre>";
foreach ( $filter as $value ) {
var_dump($value);
}
Output (2 results Found)
Dusky Dye - 20428
Dusk Dye - 20564
Dusk - 29185
Total Time
1.4957299232483 <------------------ Total Time
See Live Demo
Class Used
class ProductIterator extends FilterIterator {
private $key;
private $value;
public function __construct($url) {
$data = json_decode(file_get_contents($url), true);
parent::__construct(new ArrayIterator($data['results']));
unset($data);
}
public function find($key, $value) {
$this->key = $key;
$this->value = $value;
}
public function accept() {
$user = $this->getInnerIterator()->current();
if (isset($user[$this->key])) {
return stripos($user[$this->key], $this->value) !== false;
}
return false;
}
}

Categories