Combining two foreach without errors - php

I have a simple html dom query which read information from a football fixtures source, and I am loading also a json source.
Here is my full code:
<?php
header('Content-Type: text/html; charset=utf-8');
ini_set("user_agent", "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17");
include_once('simple_html_dom.php');
ini_set('display_errors', true);
error_reporting(E_ALL);
$str = file_get_contents('general.json');
$json = json_decode($str,true);
$filename = "source.html";
$html = file_get_html($filename);
class matches {
var $day;
var $kickofftime;
var $result;
function matches ($day, $kickofftime, $result){
$this->day=$day;
$this->kickofftime=$kickofftime;
$this->result=$result;
return $this;
}
}
$i=0;
$day=$html->find('h1',0);
$day->plaintext;
$day=str_replace("<h1>TODAY FOOTBALL FIXTURES: ","", $day);
$day=str_replace("</h1>","", $day);
$matchday = str_replace(array('MONDAY ', 'TUESDAY ', 'WEDNESDAY ', 'THURSDAY ', 'FRIDAY ', 'SATURDAY ', 'SUNDAY '), '', $day);
$matchday=str_replace(" ","-", $matchday);
$matchday=date('Y-m-d', strtotime($matchday));
foreach($html->find('table.fixtures') as $matches)
{
foreach ($matches->find('tr[class=a1],tr[class=a2]') as $matchesTR) {
$kickofftime=$matchesTR->find('td[class=a11],td[class=a21]',0)->plaintext;
$kodate = date('Y-m-d H:i:s', strtotime("$matchday $kickofftime +1 hour"));
$result=$matchesTR->find('td');
echo $kodate;
echo $result[6]->plaintext.'<br>' ;
$i++;
}
}
//Here is the 2nd foreach with the data of JSON source:
foreach($json as $key => $value) {
$value = json_decode($value, true);
echo $value["country"] . ", " . $value["competition"] . " " . $value["club"] . "<br>";
}
// clean up memory
$html->clear();
unset($html);
?>
The current results from the simple html dom html source:
2014-12-23 20:00:00 2-1
2014-12-23 11:00:00 3-1
2014-12-26 08:00:00 1-1
The result from the JSON source:
America Copa America Boca Juniors
Europe Bundesliga Hannover
Asia JLeague Nagoya
I would like to combine these two results in one foreach and I would like to get this result:
2014-12-23 20:00:00 2-1 America Copa America Boca Juniors
2014-12-23 11:00:00 3-1 Europe Bundesliga Hannover
2014-12-26 08:00:00 1-1 Asia JLeague Nagoya
I hope one can help me because I tried a lot of variation but without result. Many thanks!

You can use array_map function of PHP.
Lets say your values are in arrays $a, $b:
$mapFunc = function($n, $m) {
return "$n $m";
};
$c = array_map($mapFunc, $a, $b);

Related

Add data to an array

I have manage to get the information I need from a website. Now I want to insert the data into an array, so I can easily insert the information to the database.
Here's how the code looks like right now:
<?php
$page = file_get_contents("http://www.kalender.se/helgdagar");
$string = trim(preg_replace('/\s\s+/', '', $page));
$string = preg_replace("#<a.*?>(.*?)<\/a>#s", '|\1', $string);
preg_match_all("/<td>([\d-]{10})<\/td><td>(.*?)<\/td>/s", $string, $matches);
foreach($matches[0] AS $test) {
$splitted = explode('|', $test);
echo '<pre>'; print_r($splitted[0]); echo '</pre>';
}
?>
Which prints out the following with $splitted[0]:
2018-01-01
2018-01-06
2018-03-30
2018-04-01
2018-04-02
2018-05-01
2018-05-10
2018-05-20
2018-06-06
2018-06-23
2018-11-03
2018-12-25
2018-12-26
And with $splitted[1]:
Nyårsdagen
Trettondedag jul
Långfredagen
Påskdagen
Annandag påsk
Första maj
Kristi himmelfärdsdag
Pingstdagen
Sveriges nationaldag
Midsommar
Alla helgons dag
Juldagen
Annandag jul
I want this information to be grouped and also be in an array, like this:
Array(
'2018-01-01' => 'Nyårsdagen',
'2018-01-06' => 'Trettondedag jul',
... and so on
);
How can I accomplish this?
I didn't even know that array_combine() even existed until Jon Stirling mentioned it in his comment. Many thanks, Jon! :)
Here's the final result:
<?php
$page = file_get_contents("http://www.kalender.se/helgdagar");
$string = trim(preg_replace('/\s\s+/', '', $page));
$string = preg_replace("#<a.*?>(.*?)<\/a>#s", '\1', $string);
preg_match_all("/<td>([\d-]{10})<\/td><td>(.*?)<\/td>/s", $string, $matches);
$array_test_1 = Array();
foreach($matches[1] AS $test1) {
$array_test_1[] = $test1;
# echo '<pre>'; print_r($splitted[1]); echo '</pre>';
}
$array_test_2 = Array();
foreach($matches[2] AS $test2) {
$array_test_2[] = $test2;
# echo '<pre>'; print_r($splitted[1]); echo '</pre>';
}
$finishit = array_combine($array_test_1, $array_test_2);
echo '<pre>'; print_r($finishit); echo '</pre>';
?>

Complex parsing a text file in PHP

So I am trying to parse a TXT file which has the following format. Each entry is on a single line.
SAMPLE.TXT
2016-02-24 13:54:23 Local0.Info 172.16.120.4 1 1456311263.500015263 ASD_MX600 urls src=172.16.41.15:62490 dst=144.76.76.148:80 mac=00:1B:0D:63:84:00 user=CN=Smith\John,OU=S-HS,OU=SAcc,DC=abc,DC=org,DC=ab agent='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 seb/2.0 SEBKEY' request: GET http://something.com/theme/image.php/clean/page/1455532301/icon
2016-02-24 13:54:23 Local0.Info 172.16.120.4 1 1456311263.500097075 ASD_MX600 urls src=172.16.41.15:62485 dst=144.76.76.148:80 mac=00:1B:0D:63:84:00 user=CN=Smith\John,OU=S-HS,OU=SAcc,DC=abc,DC=org,DC=ab agent='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 seb/2.0 SEBKEY' request: GET http://somethingelse.com/theme/image.php/clean/core/1455532301/f/pdf-24
I need to do the following:
1. Parse the entire file into an array. //DONE
2. Pick up everything after 1 145... (which will end up in [3] of the array) and parse it further so that I have the following breakdowns.
- urls
- src=172.16.41.15:62490
- dst=144.76.76.148:80
- mac=00:1B:0D:63:84:00
- user=CN=Smith\John,OU=S-HS,OU=SAcc,DC=abc,DC=org,DC=ab
- agent='Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 seb/2.0 SEBKEY'
- request: GET
- http://something.com/theme/image.php/clean/page/1455532301/icon
I am having a hard time getting the syntax right for the 2nd parse within the main loop. I get the entire giant section from index 3 [3] and I think I am also using the explode() right to chop it off based on ' ' but then I am lost. How do i get hold of the data as shown above? My code progress so far:
<?php
$txt_file = file_get_contents('C:\sample.txt');
$rows = explode("\n", $txt_file);
array_shift($rows);
foreach($rows as $row => $data)
{
//get row data
$row_data = explode(' ', $data); //chop each row first based on bigger space
//--------------------------
$info[$row]['timestamp'] = $row_data[0];
// $info[$row]['localinfo'] = $row_data[1];
$info[$row]['ip'] = $row_data[2];
$info[$row]['other'] = $row_data[3]; //This is where LONGEST string exists
//--------------------------
$row_data1 = explode(' ', $row_data[3]); //chop index item based on smaller space
$rowd_data2[$row_data1]['urlsflows'] = $row_data1[3];
//display data
// echo 'Row ' . $row . ' TIMESTAMP: ' . $info[$row]['timestamp'] . '<br />';
// echo 'Row ' . $row . ' LOCALINFO: ' . $info[$row]['localinfo'] . '<br />';
// echo 'Row ' . $row . ' IP: ' . $info[$row]['ip'] . '<br />';
//--The line below is where I am lost. Kindly help.
echo $rowd_data2[$row_data1]['urlsflows'];
} //end of for loop
?>
This code works for the input file:
<?php
$rows = explode("\n", file_get_contents('SAMPLE.TXT'));
$result = array();
foreach ($rows as $row) {
if (trim($row) == "") {
continue;
}
$timeMatches = array();
$reTime = "/([0-9-]* [0-9:]*) /";
preg_match($reTime, $row, $timeMatches);
$re = "/src=(.*) dst=(.*) mac=(.*) user=(.*) agent=(.*) request: (.*) (.*)/";
$matches = array();
preg_match($re, $row, $matches);
$result[] = array('time' => $timeMatches[1], 'src' => $matches[1]
, 'dst' => $matches[2], 'mac' => $matches[3]
, 'user' => $matches[4], 'agent' => $matches[5]
, 'method' => $matches[6], 'url' => $matches[7]);
}
var_dump($result);
The output of the var_dump($result) is:
array(2) {
[0]=>
array(8) {
["time"]=>
string(20) "2016-02-24 13:54:23"
["src"]=>
string(18) "172.16.41.15:62490"
["dst"]=>
string(16) "144.76.76.148:80"
["mac"]=>
string(17) "00:1B:0D:63:84:00"
["user"]=>
string(49) "CN=Smith\John,OU=S-HS,OU=SAcc,DC=abc,DC=org,DC=ab"
["agent"]=>
string(76) "'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 seb/2.0 SEBKEY'"
["method"]=>
string(3) "GET"
["url"]=>
string(63) "http://something.com/theme/image.php/clean/page/1455532301/icon"
}
[1]=>
array(8) {
["time"]=>
string(20) "2016-02-24 13:54:23"
["src"]=>
string(18) "172.16.41.15:62485"
["dst"]=>
string(16) "144.76.76.148:80"
["mac"]=>
string(17) "00:1B:0D:63:84:00"
["user"]=>
string(49) "CN=Smith\John,OU=S-HS,OU=SAcc,DC=abc,DC=org,DC=ab"
["agent"]=>
string(76) "'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 seb/2.0 SEBKEY'"
["method"]=>
string(3) "GET"
["url"]=>
string(71) "http://somethingelse.com/theme/image.php/clean/core/1455532301/f/pdf-24"
}
}
I think this should work:
$txt_file = file_get_contents('C:\sample.txt');
$rows = explode("\n", $txt_file);
array_shift($rows);
$info = [];
foreach($rows as $row => $data)
{
//get row data
$row_data = explode(' ', $data); //chop each row first based on bigger space
//--------------------------
$info[$row] = [];
list($info[$row]['timestamp'], $info[$row]['ip'],$info[$row]['other'] ) = explode(" ", $row_data[0]);
// $info[$row]['localinfo'] = $row_data[1];
//--------------------------
$row_data1 = explode(' ', $row_data[1]); //chop index item based on smaller space
$rowd_data2[$row_data1]['urlsflows'] = $row_data1[3];
//display data
// echo 'Row ' . $row . ' TIMESTAMP: ' . $info[$row]['timestamp'] . '<br />';
// echo 'Row ' . $row . ' LOCALINFO: ' . $info[$row]['localinfo'] . '<br />';
// echo 'Row ' . $row . ' IP: ' . $info[$row]['ip'] . '<br />';
//--The line below is where I am lost. Kindly help.
echo $rowd_data2[$row_data1]['urlsflows'];
} //end of for loop
?>
<?php
$myfile = fopen("C:\sample.txt", "r") or die("Unable to open file!");
// Output one line until end-of-file
while(!feof($myfile)) {
echo $line = fgets($myfile) . "<br>";// you can do the explode and assignment here.
//example
$row_data = explode(' ', $line);
//don't worry about spaces, it will trim by PHP `trim` function, that will erase all the spaces
}
fclose($myfile);
?>

Q: How can I combine these two foreach?

I have a simple html dom query which read informations from a football fixtures source, and I loading also a json source.
Here is my full code:
<?php
header('Content-Type: text/html; charset=utf-8');
ini_set("user_agent", "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17");
include_once('simple_html_dom.php');
ini_set('display_errors', true);
error_reporting(E_ALL);
$str = file_get_contents('general.json');
$json = json_decode($str,true);
$filename = "source.html";
$html = file_get_html($filename);
class matches {
var $day;
var $kickofftime;
var $title;
function matches ($day, $kickofftime, $tip){
$this->day=$day;
$this->kickofftime=$kickofftime;
$this->title=$title;
return $this;
}
}
$i=0;
$day=$html->find('h1',0);
$day->plaintext;
$day=str_replace("<h1>TODAY FOOTBALL FIXTURES: ","", $day);
$day=str_replace("</h1>","", $day);
$matchday = str_replace(array('MONDAY ', 'TUESDAY ', 'WEDNESDAY ', 'THURSDAY ', 'FRIDAY ', 'SATURDAY ', 'SUNDAY '), '', $day);
$matchday=str_replace(" ","-", $matchday);
$matchday=date('Y-m-d', strtotime($matchday));
foreach($html->find('table.fixtures') as $matches)
{
foreach ($matches->find('tr[class=a1],tr[class=a2]') as $matchesTR) {
$kickofftime=$matchesTR->find('td[class=a11],td[class=a21]',0)->plaintext;
$kodate = date('Y-m-d H:i:s', strtotime("$matchday $kickofftime +1 hour"));
$result=$matchesTR->find('td');
echo $kodate;
echo $result[6]->plaintext.'<br>' ;
$i++;
}
}
//Here is the 2nd foreach with the data of JSON source:
foreach($json as $key => $value) {
$value = json_decode($value, true);
echo $value["country"] . ", " . $value["competition"] . " " . $value["club"] . "<br>";
}
// clean up memory
$html->clear();
unset($html);
?>
The current results from the simple html dom html source:
2014-12-23 20:00:00 2-1
2014-12-23 11:00:00 3-1
2014-12-26 08:00:00 1-1
The result from the JSON source:
America Copa America Boca Juniors
Europe Bundesliga Hannover
Asia JLeague Nagoya
I would like to combine these two results in one foreach and I would like to get this result:
2014-12-23 20:00:00 2-1 America Copa America Boca Juniors
2014-12-23 11:00:00 3-1 Europe Bundesliga Hannover
2014-12-26 08:00:00 1-1 Asia JLeague Nagoya
I hope that there is some expert who can help for me because I tried a lot of variation but without result. Many thanks!
$j=0;
$jsonDecodedArray=$json;
foreach($html->find('table.fixtures') as $matches)
{
foreach ($matches->find('tr[class=a1],tr[class=a2]') as $matchesTR) {
$kickofftime=$matchesTR->find('td[class=a11],td[class=a21]',0)->plaintext;
$kodate = date('Y-m-d H:i:s', strtotime("$matchday $kickofftime +1 hour"));
$result=$matchesTR->find('td');
echo $kodate;
echo $result[6]->plaintext." ";
echo $jsonDecodedArray[$j]["country"] . ", " . $jsonDecodedArray[$j]["competition"] . " " . $jsonDecodedArray[$j]["club"] . "<br>"; ;
$i++;
$j++;
}
}

Q: How can I combine these two foreach loop

I have a simple html dom query which read informations from a football fixtures source, and I loading also a json source.
Here is my full code:
<?php
header('Content-Type: text/html; charset=utf-8');
ini_set("user_agent", "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.60 Safari/537.17");
include_once('simple_html_dom.php');
ini_set('display_errors', true);
error_reporting(E_ALL);
$str = file_get_contents('general.json');
$json = json_decode($str,true);
$filename = "source.html";
$html = file_get_html($filename);
class matches {
var $day;
var $kickofftime;
var $result;
function matches ($day, $kickofftime, $tip){
$this->day=$day;
$this->kickofftime=$kickofftime;
$this->result=$result;
return $this;
}
}
$i=0;
$day=$html->find('h1',0);
$day->plaintext;
$day=str_replace("<h1>TODAY FOOTBALL FIXTURES: ","", $day);
$day=str_replace("</h1>","", $day);
$matchday = str_replace(array('MONDAY ', 'TUESDAY ', 'WEDNESDAY ', 'THURSDAY ', 'FRIDAY ', 'SATURDAY ', 'SUNDAY '), '', $day);
$matchday=str_replace(" ","-", $matchday);
$matchday=date('Y-m-d', strtotime($matchday));
foreach($html->find('table.fixtures') as $matches)
{
foreach ($matches->find('tr[class=a1],tr[class=a2]') as $matchesTR) {
$kickofftime=$matchesTR->find('td[class=a11],td[class=a21]',0)->plaintext;
$kodate = date('Y-m-d H:i:s', strtotime("$matchday $kickofftime +1 hour"));
$result=$matchesTR->find('td');
echo $kodate;
echo $result[6]->plaintext.'<br>' ;
$i++;
}
}
//Here is the 2nd foreach with the data of JSON source:
foreach($json as $key => $value) {
$value = json_decode($value, true);
echo $value["country"] . ", " . $value["competition"] . " " . $value["club"] . "<br>";
}
// clean up memory
$html->clear();
unset($html);
?>
The current results from the simple html dom html source:
2014-12-23 20:00:00 2-1
2014-12-23 11:00:00 3-1
2014-12-26 08:00:00 1-1
The result from the JSON source:
America Copa America Boca Juniors
Europe Bundesliga Hannover
Asia JLeague Nagoya
I would like to combine these two results in one foreach and I would like to get this result:
2014-12-23 20:00:00 2-1 America Copa America Boca Juniors
2014-12-23 11:00:00 3-1 Europe Bundesliga Hannover
2014-12-26 08:00:00 1-1 Asia JLeague Nagoya
I hope that there is some expert who can help for me because I tried a lot of variation but without result. I got some advice (with code) from experts, but there was everytime errors. With my code there is no error, but I need other solution because I would like to put all variables to one foreach. Many thanks, I hope that somebody could help me with code, because I am not on high level at php. Thanks again!
I would like to put the two foreach into one foreach, but I don't want to create a new array because I not need.
Assuming you will always have the same amount of items in each and that they match 1 to 1, 2 to 2, you can do this:
$htmlDates = array();
$jsonLeag = array();
foreach($html->find('table.fixtures') as $matches) {
foreach($matches->find('tr[class=a1],tr[class=a2]') as $matchesTR) {
$kickofftime=$matchesTR->find('td[class=a11],td[class=a21]',0)->plaintext;
$kodate = date('Y-m-d H:i:s', strtotime("$matchday $kickofftime +1 hour"));
$result=$matchesTR->find('td');
//echo $kodate;
//echo $result[6]->plaintext.'<br>' ;
$htmlDates[] = $kodates;
}
}
//Here is the 2nd foreach with the data of JSON source:
foreach($json as $key => $value) {
$value = json_decode($value, true);
//echo $value["country"] . ", " . $value["competition"] . " " . $value["club"] . "<br>";
$jsonLeag[] = $value["country"] . ", " . $value["competition"] . " " . $value["club"];
}
if(count($htmlDates) < count($jsonLeag)){
for($i=0;$i<count($htmlData);$i++){
echo $htmlData[$i] . " " . $jsonLeag[$i] . "<br />\r\n";
}
} else {
for($i=0;$i<count($jsonLeag);$i++){
echo $htmlData[$i] . " " . $jsonLeag[$i] . "<br />\r\n";
}
}
Since you have the nested list first and nothing ties the two data sets together, there is no simple way to run one loop and get the data from both. It's easier to push the data you want into an array for each set, and then walk both arrays with one counter. The caveat here is that if one has an extra element, you will get missing results or errors.
Save keys of json arrays and use the next in each loop.
$json_keys = array_keys($json);
$i_key = 0;
foreach($html->find('table.fixtures') as $matches)
{
foreach ($matches->find('tr[class=a1],tr[class=a2]') as $matchesTR) {
$kickofftime=$matchesTR->find('td[class=a11],td[class=a21]',0)->plaintext;
$kodate = date('Y-m-d H:i:s', strtotime("$matchday $kickofftime +1 hour"));
$result=$matchesTR->find('td');
echo $kodate;
echo $result[6]->plaintext.
$value = json_decode($json[$json_keys[$i_key++]], true);
echo $value["country"] . ", " . $value["competition"] . " " . $value["club"] . "<br>";
$i++;
}
}
// clean up memory
$html->clear();
unset($html);
There are many other variants - use array_shift(), next()... I've written the first come in mind

Sorting a google calendar feed (parsing with DOM)

I'm embedding dates from google calendar into a website, and it's all working, with the exception of sorting. For some reason, it sorts into reverse-chronological order, when I'd really just like it to be normal chronological (first event first).
this is the output:
August 11th: Intern depart
August 6th: Last Day of Summer Camp
July 7th: Ignore this
July 6th: This is another example event
July 5th: example
June 28th: Summer Camp Starts
June 24th: Summer Pool Party
June 21st: Intern arrival date
June 15th: Assistant Director Arrival Date
June 14th: Director's training begins
May 26th: Brainstorm day for directors
I'm really still just learning a lot of this stuff- thanks for the help in advance!
<?php
$confirmed = 'http://schemas.google.com/g/2005#event.confirmed';
$three_months_in_seconds = 60 * 60 * 24 * 28 * 3;
$three_months_ago = date("Y-m-d\Th:i:sP", time() - 172800);
$three_months_from_today = date("Y-m-d\Th:i:sP", time() + $three_months_in_seconds);
$feed = "http://www.google.com/calendar/feeds/qp6o02ka3iaoem2kr8odga6j7s%40group.calendar.google.com/" .
"public/full?orderby=starttime&singleevents=true&" .
"start-min=" . $three_months_ago . "&" .
"start-max=" . $three_months_from_today;
$doc = new DOMDocument();
$doc->load( $feed );
$entries = $doc->getElementsByTagName( "entry" );
foreach ( $entries as $entry ) {
$status = $entry->getElementsByTagName( "eventStatus" );
$eventStatus = $status->item(0)->getAttributeNode("value")->value;
if ($eventStatus == $confirmed) {
$titles = $entry->getElementsByTagName( "title" );
$title = $titles->item(0)->nodeValue;
$times = $entry->getElementsByTagName( "when" );
$startTime = $times->item(0)->getAttributeNode("startTime")->value;
$when = date( "F jS", strtotime( $startTime ) );
$whentime = date( "g:ia", strtotime ( $startTime ) );
$places = $entry->getElementsByTagName( "where" );
$where = $places->item(0)->getAttributeNode("valueString")->value;
$links = $entry->getElementsByTagName( "link" );
$link = $links->item(0)->nodeValue;
print $when;
if ($whentime == "12:00am"){
;
}
else{
echo " at ";
print $whentime;
}
echo ": ";
echo "<b>";
print $title . "\n";
echo "</b>";
echo " ";
if(empty($where)){;}else{
echo "<br />";
print $where . "\n";
}
print $link;
print "<br />";
}
}
?>
Add &sortorder=descending to your feed URL. You can find documentation for this in the FAQ

Categories