I am looking for a way to read multiple (over 50) plain text websites and parse only certain information into a html table, or as a csv file.When I say "plain text" I mean that while it is a web address, it does not have any html associated with it.This would be an example of the source. I am pretty new to this, and was looking for help in seeing how this could be done.
update-token:179999210
vessel-name:Name Here
vessel-length:57.30
vessel-beam:14.63
vessel-draft:3.35
vessel-airdraft:0.00
time:20140104T040648.259Z
position:25.04876667 -75.57001667 GPS
river-mile:sd 178.71
rate-of-turn:0.0
course-over-ground:58.5
speed-over-ground:0.0
ais-367000000 {
pos:45.943912 -87.384763 DGPS
cog:249.8
sog:0.0
name:name here
call:1113391
imo:8856857
type:31
dim:10 20 4 5
draft:3.8
destination:
}
ais-367000000 {
pos:25.949652 -86.384535 DGPS
cog:105.6
sog:0.0
name:CHRISTINE
call:5452438
type:52
status:0
dim:1 2 3 4
draft:3.0
destination:IMTT ST.ROSE
eta:06:00
}
Thanks for any suggestions you guys might have.
I may be completely missing the point here - but here is how you could take the contents (assuming you had them as a string) and put them into a php key/value array. I "hard-coded" the string you had, and changed one value (the key ais-3670000 seemed to repeat, and that makes the second object overwrite the first).
This is a very basic parser that assumes a format like you described above. I give the output below the code:
<?php
echo "<html>";
$s="update-token:179999210
vessel-name:Name Here
vessel-length:57.30
vessel-beam:14.63
vessel-draft:3.35
vessel-airdraft:0.00
time:20140104T040648.259Z
position:25.04876667 -75.57001667 GPS
river-mile:sd 178.71
rate-of-turn:0.0
course-over-ground:58.5
speed-over-ground:0.0
ais-367000000 {
pos:45.943912 -87.384763 DGPS
cog:249.8
sog:0.0
name:name here
call:1113391
imo:8856857
type:31
dim:10 20 4 5
draft:3.8
destination:
}
ais-367000001 {
pos:25.949652 -86.384535 DGPS
cog:105.6
sog:0.0
name:CHRISTINE
call:5452438
type:52
status:0
dim:1 2 3 4
draft:3.0
destination:IMTT ST.ROSE
eta:06:00
}";
$lines = explode("\n", $s);
$output = Array();
$thisElement = & $output;
foreach($lines as $line) {
$elements = explode(":", $line);
if (count($elements) > 1) {
$thisElement[trim($elements[0])] = $elements[1];
}
if(strstr($line, "{")) {
$elements = explode("{", $line);
$key = trim($elements[0]);
$output[$key] = Array();
$thisElement = & $output[$key];
}
if(strstr($line, "}")) {
$thisElement = & $output;
}
}
echo '<pre>';
print_r($output);
echo '</pre>';
echo '</html>';
?>
Output of the above (can be seen working at http://www.floris.us/SO/ships.php):
Array
(
[update-token] => 179999210
[vessel-name] => Name Here
[vessel-length] => 57.30
[vessel-beam] => 14.63
[vessel-draft] => 3.35
[vessel-airdraft] => 0.00
[time] => 20140104T040648.259Z
[position] => 25.04876667 -75.57001667 GPS
[river-mile] => sd 178.71
[rate-of-turn] => 0.0
[course-over-ground] => 58.5
[speed-over-ground] => 0.0
[ais-367000000] => Array
(
[pos] => 45.943912 -87.384763 DGPS
[cog] => 249.8
[sog] => 0.0
[name] => name here
[call] => 1113391
[imo] => 8856857
[type] => 31
[dim] => 10 20 4 5
[draft] => 3.8
[destination] =>
)
[ais-367000001] => Array
(
[pos] => 25.949652 -86.384535 DGPS
[cog] => 105.6
[sog] => 0.0
[name] => CHRISTINE
[call] => 5452438
[type] => 52
[status] => 0
[dim] => 1 2 3 4
[draft] => 3.0
[destination] => IMTT ST.ROSE
[eta] => 06
)
)
A better approach would be to turn the string into "properly formed JSON", then use json_decode. That might look like the following:
<?php
echo "<html>";
$s="update-token:179999210
vessel-name:Name Here
vessel-length:57.30
vessel-beam:14.63
vessel-draft:3.35
vessel-airdraft:0.00
time:20140104T040648.259Z
position:25.04876667 -75.57001667 GPS
river-mile:sd 178.71
rate-of-turn:0.0
course-over-ground:58.5
speed-over-ground:0.0
ais-367000000 {
pos:45.943912 -87.384763 DGPS
cog:249.8
sog:0.0
name:name here
call:1113391
imo:8856857
type:31
dim:10 20 4 5
draft:3.8
destination:
}
ais-367000001 {
pos:25.949652 -86.384535 DGPS
cog:105.6
sog:0.0
name:CHRISTINE
call:5452438
type:52
status:0
dim:1 2 3 4
draft:3.0
destination:IMTT ST.ROSE
eta:06:00
}";
echo '<pre>';
print_r(parseString($s));
echo '</pre>';
function parseString($s) {
$lines = explode("\n", $s);
$jstring = "{ ";
$comma = "";
foreach($lines as $line) {
$elements = explode(":", $line);
if (count($elements) > 1) {
$jstring = $jstring . $comma . '"' . trim($elements[0]) . '" : "' . $elements[1] .'"';
$comma = ",";
}
if(strstr($line, "{")) {
$elements = explode("{", $line);
$key = trim($elements[0]);
$jstring = $jstring . $comma . '"' . $key .'" : {';
$comma = "";
}
if(strstr($line, "}")) {
$jstring = $jstring . '} ';
$comma = ",";
}
}
$jstring = $jstring ."}";
return json_decode($jstring);
}
echo '</html>';
?>
Demo at http://www.floris.us/SO/ships2.php ; note that I use the variable $comma to make sure that commas are either included, or not included, at various points in the string.
Output of this code looks similar to what we had before:
stdClass Object
(
[update-token] => 179999210
[vessel-name] => Name Here
[vessel-length] => 57.30
[vessel-beam] => 14.63
[vessel-draft] => 3.35
[vessel-airdraft] => 0.00
[time] => 20140104T040648.259Z
[position] => 25.04876667 -75.57001667 GPS
[river-mile] => sd 178.71
[rate-of-turn] => 0.0
[course-over-ground] => 58.5
[speed-over-ground] => 0.0
[ais-367000000] => stdClass Object
(
[pos] => 45.943912 -87.384763 DGPS
[cog] => 249.8
[sog] => 0.0
[name] => name here
[call] => 1113391
[imo] => 8856857
[type] => 31
[dim] => 10 20 4 5
[draft] => 3.8
[destination] =>
)
[ais-367000001] => stdClass Object
(
[pos] => 25.949652 -86.384535 DGPS
[cog] => 105.6
[sog] => 0.0
[name] => CHRISTINE
[call] => 5452438
[type] => 52
[status] => 0
[dim] => 1 2 3 4
[draft] => 3.0
[destination] => IMTT ST.ROSE
[eta] => 06
)
)
But maybe your question is "how do I get the text into php in the first place". In that case, you might look at something like this:
<?php
$urlstring = file_get_contents('/path/to/urlFile.csv');
$urls = explode("\n", $urlstring); // one url per line
$responses = Array();
// loop over the urls, and get the information
// then parse it into the $responses array
$i = 0;
foreach($urls as $url) {
$responses[$i] = parseString(file_get_contents($url));
$i = $i + 1;
}
function parseString($s) {
$lines = explode("\n", $s);
$jstring = "{ ";
$comma = "";
foreach($lines as $line) {
$elements = explode(":", $line);
if (count($elements) > 1) {
$jstring = $jstring . $comma . '"' . trim($elements[0]) . '" : "' . $elements[1] .'"';
$comma = ",";
}
if(strstr($line, "{")) {
$elements = explode("{", $line);
$key = trim($elements[0]);
$jstring = $jstring . $comma . '"' . $key .'" : {';
$comma = "";
}
if(strstr($line, "}")) {
$jstring = $jstring . '} ';
$comma = ",";
}
}
$jstring = $jstring ."}";
return json_decode($jstring);
}
?>
I include the same parsing function as before; it's possible to make it much better, or leave it out altogether. Hard to know from your question.
Questions welcome.
UPDATE
Based on comments I have added a function that will perform the curl on the file resource; let me know if this works for you. I have created a file http://www.floris.us/SO/ships.txt that is an exact copy of the file you showed above, and a http://www.floris.us/SO/ships3.php that contains the following source code - you can run it and see that it works (note - in this version I don't read anything from a .csv file - you already know how to do that. This is just taking the array, and using it to obtain a text file, then converting it to a data structure you can use - display, whatever):
<?php
$urls = Array();
$urls[0] = "http://www.floris.us/SO/ships.txt";
$responses = Array();
// loop over the urls, and get the information
// then parse it into the $responses array
$i = 0;
foreach($urls as $url) {
// $responses[$i] = parseString(file_get_contents($url));
$responses[$i] = parseString(myCurl($url));
$i = $i + 1;
}
echo '<html><body><pre>';
print_r($responses);
echo '</pre></body></html>';
function parseString($s) {
$lines = explode("\n", $s);
$jstring = "{ ";
$comma = "";
foreach($lines as $line) {
$elements = explode(":", $line);
if (count($elements) > 1) {
$jstring = $jstring . $comma . '"' . trim($elements[0]) . '" : "' . $elements[1] .'"';
$comma = ",";
}
if(strstr($line, "{")) {
$elements = explode("{", $line);
$key = trim($elements[0]);
$jstring = $jstring . $comma . '"' . $key .'" : {';
$comma = "";
}
if(strstr($line, "}")) {
$jstring = $jstring . '} ';
$comma = ",";
}
}
$jstring = $jstring ."}";
return json_decode($jstring);
}
function myCurl($f) {
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $f);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// $output contains the output string
$output = curl_exec($ch);
// close curl resource to free up system resources
curl_close($ch);
return $output;
}
?>
Note - because two entries have the same "tag", the second one overwrites the first when using the original source data. If that is a problem let me know. Also if you have ideas on how you actually want to display the data, try to mock up something and I can help you get it right.
On the topic of time-outs
There are several possible timeout mechanisms that can be causing you problems; depending on which it is, one of the following solutions may help you:
If the browser doesn't get any response from the server, it will eventually time out. This is almost certainly not your problem right now; but it might become your issue if you fix the other problems
php scripts typically have a built in "maximum time to run" before they decide you sent them into an infinite loop. If you know you will be making lots of requests, and these requests will take a lot of time, you may want to set the time-out higher. See http://www.php.net/manual/en/function.set-time-limit.php for details on how to do this. I would recommend setting the limit to a "reasonable" value inside the curl loop - so the counter gets reset for every new request.
Your attempt to connect to the server may take too long (this is the most likely problem as you said). You can set the value (time you expect to wait to make the connection) to something "vaguely reasonable" like 10 seconds; this means you won't wait forever for the servers that are offline. Use
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
for a 10 second wait. See Setting Curl's Timeout in PHP
Finally you will want to handle the errors gracefully - if the connection did not succeed, you don't want to process the response. Putting all this together gets you something like this:
$i = 0;
foreach($urls as $url) {
$temp = myCurl($url);
if (strlen($temp) == 0) {
echo 'no response from '.$url.'<br>';
}
else {
$responses[$i] = parseString(myCurl($url));
$i = $i + 1;
}
}
echo '<html><body><pre>';
print_r($responses);
echo '</pre></body></html>';
function myCurl($f) {
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $f);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // try for 10 seconds to get a connection
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // try for 30 seconds to complete the transaction
// $output contains the output string
$output = curl_exec($ch);
// see if any error was set:
$curl_errno = curl_errno($ch);
// close curl resource to free up system resources
curl_close($ch);
// make response depending on whether there was an error
if($curl_errno > 0) {
return '';
}
else {
return $output;
}
}
Last update? I have updated the code one more time. It now
Reads a list of URLs from a file (one URL per line - fully formed)
Tries to fetch the contents from each file in turn, handling time-outs and echoing progress to the screen
Creates tables with the some of the information from the files (including a reformatted time stamp)
To make this work, I had the following files:
www.floris.us/SO/ships.csv containing three lines with
http://www.floris.us/SO/ships.txt
http://floris.dnsalias.com/noSuchFile.html
http://www.floris.us/SO/ships2.txt
Files ships.txt and ships2.txt at the same location (almost identical copies but for name of ship) - these are like your plain text files.
File ships3.php in the same location. This contains the following source code, that performs the various steps described earlier, and attempts to string it all together:
<?php
$urlstring = file_get_contents('http://www.floris.us/SO/ships.csv');
$urls = explode("\n", $urlstring); // one url per line
$responses = Array();
// loop over the urls, and get the information
// then parse it into the $responses array
$i = 0;
foreach($urls as $url) {
$temp = myCurl($url);
if(strlen($temp) > 0) {
$responses[$i] = parseString($temp);
$i = $i + 1;
}
else {
echo "URL ".$url." did not repond<br>";
}
}
// produce the actual output table:
echo '<html><body>';
writeTable($responses);
echo '</pre></body></html>';
// ------------ support functions -------------
function parseString($s) {
$lines = explode("\n", $s);
$jstring = "{ ";
$comma = "";
foreach($lines as $line) {
$elements = explode(":", $line);
if (count($elements) > 1) {
$jstring = $jstring . $comma . '"' . trim($elements[0]) . '" : "' . $elements[1] .'"';
$comma = ",";
}
if(strstr($line, "{")) {
$elements = explode("{", $line);
$key = trim($elements[0]);
$jstring = $jstring . $comma . '"' . $key .'" : {';
$comma = "";
}
if(strstr($line, "}")) {
$jstring = $jstring . '} ';
$comma = ",";
}
}
$jstring = $jstring ."}";
return json_decode($jstring, true);
}
function myCurl($f) {
// create curl resource
$ch = curl_init();
// set url
curl_setopt($ch, CURLOPT_URL, $f);
//return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // try for 10 seconds to get a connection
curl_setopt($ch, CURLOPT_TIMEOUT, 30); // try for 30 seconds to complete the transaction
// $output contains the output string
$output = curl_exec($ch);
// see if any error was set:
$curl_errno = curl_errno($ch);
$curl_error = curl_error($ch);
// close curl resource to free up system resources
curl_close($ch);
// make response depending on whether there was an error
if($curl_errno > 0) {
echo 'Curl reported error '.$curl_error.'<br>';
return '';
}
else {
echo 'Successfully fetched '.$f.'<br>';
return $output;
}
}
function writeTable($r) {
echo 'The following ships reported: <br>';
echo '<table border=1>';
foreach($r as $value) {
if (strlen($value["vessel-name"]) > 0) {
echo '<tr><table border=1><tr>';
echo '<td>Vessel Name</td><td>'.$value["vessel-name"].'</td></tr>';
echo '<tr><td>Time:</td><td>'.dateFormat($value["time"]).'</td></tr>';
echo '<tr><td>Position:</td><td>'.$value["position"].'</td></tr>';
echo '</table></tr>';
}
echo '</table>';
}
}
function dateFormat($d) {
// with input yyyymmddhhmm
// return dd/mm/yy hh:mm
$date = substr($d, 6, 2) ."/". substr($d, 4, 2) ."/". substr($d, 2, 2) ." ". substr($d, 9, 2) . ":" . substr($d, 11, 2);
return $date;
}
?>
Output of this is:
You can obviously make this prettier, and include other fields etc. I think this should get you a long way there, though. You might consider (if you can) having a script run in the background to create these tables every 30 minutes or so, and saving the resulting html tables to a local file on your server; then, when people want to see the result, they would not have to wait for the (slow) responses of the different remote servers, but get an "almost instant" result.
But that's somewhat far removed from the original question. If you are able to implement all this in a workable fashion, and then want to come back and ask a follow-up question (if you're still stuck / not happy with the outcome), that is probably the way to go. I think we've pretty much beaten this one to death now.
First combine the websites into a csv or hard coded array, then file_get_contents() / file_put_contents() on each. Essentially:
$file = dataFile.csv
foreach($arrayOfSites as $site){
$data = file_get_contents($site);
file_put_contents($file, $data . "\n", FILE_APPEND);
}
Edit: Sorry was trying to do this fast. here is the full
Related
I have the following code that fetches arrays from a cURL.
$codici_hotel_arr = array();
foreach($data_destin['results'] as $key=>$val) {
$codici_hotel_arr[] = '"' . $val['hotel_code'] . '"';
$codici_price_arr[] = '"' . $val['products'][0]['price'] . '"';
}
$codici_definitivi = implode(', ', $codici_hotel_arr);
$codici_prezzi = implode(', ', $codici_price_arr);
The code returns these values:
**$codici_definitivi:**
"1074d0", "19f726", "1072ba", "183444", "1071bf", "112438", "1b326e", "15d8ab", "19d885", "193e61", "10aab2", "107155", "110669", "189b95", "16d78f", "18dd7d"
**$codici_prezzi**
"160.16", "234.32", "256.88", "325.42", "342.22", "353.30", "365.78", "372.84", "395.72", "478.75", "503.36", "543.39", "584.61", "584.61", "597.70", "601.63".
I would need to get a $codici_prezzi for each $codici_definitivi.
As a response of a string cURL, both codes are as follows:
1074d0 -> 160.16;
19f726 -> 234.32;
1072ba -> 256.88;
etc...
It's possible?
Thank you
If I don't misunderstood your requirement then this should work. Remove extra imploding and try to array_combine() the two corresponding arrays.
// Your initial code, after removing imploding
$codici_hotel_arr = $codici_price_arr = [];
foreach($data_destin['results'] as $key=>$val) {
$codici_hotel_arr[] = '"' . $val['hotel_code'] . '"';
$codici_price_arr[] = '"' . $val['products'][0]['price'] . '"';
}
// I assume your array structure will be after looping curl response
$codici_hotel_arr = ["1074d0", "19f726", "1072ba", "183444", "1071bf", "112438", "1b326e", "15d8ab", "19d885", "193e61", "10aab2", "107155", "110669", "189b95", "16d78f", "18dd7d"];
$codici_price_arr = ["160.16", "234.32", "256.88", "325.42", "342.22", "353.30", "365.78", "372.84", "395.72", "478.75", "503.36", "543.39", "584.61", "584.61", "597.70", "601.63"];
$result = array_combine($codici_hotel_arr,$codici_price_arr);
print '<pre>';
print_r($result);
print '</pre>';
Result:
Array (
[1074d0] => 160.16
[19f726] => 234.32
[1072ba] => 256.88
[183444] => 325.42
[1071bf] => 342.22
[112438] => 353.30
[1b326e] => 365.78
[15d8ab] => 372.84
[19d885] => 395.72
[193e61] => 478.75
[10aab2] => 503.36
[107155] => 543.39
[110669] => 584.61
[189b95] => 584.61
[16d78f] => 597.70
[18dd7d] => 601.63
)
Edit: Because I don't understand your expected result that's why I post it also.If you want it on string format then try like this,
function print_string($v, $k) {
echo "$k->$v\n";
}
array_walk($result, "print_string");
Supposing that the indices of the arrays are aligned, I would do this:
<?php
for($i = 0; $i < count($codici_definitivi); $i++) {
echo $codici_definitivi[0] . ' -> ' . $codici_prezzi[0];
// or set up any other mapping you need, e.g. key => value in another array
}
?>
Edit: you should place this mapping before the implode statements, otherwise you overwrite the original arrays with strings.
$new_codici_prezzi = array();
if(count($codici_definitivi) === count($codici_prezzi)){
for($i = 0; $i < count($codici_definitivi); $i++){
$new_codici_prezzi[$codici_definitivi[$i]] = $codici_prezzi[$i];
}
}
//After that, $new_codici_prezzi is your new array.
Hello I'm trying to get all the values from $_POST request and to log it.
This my code:
<?php
$file = 'error_log.log';
$info = date("Y-m-d H:i:s")." - ".print_r($_POST, true)."\n";
foreach ($_POST as $key => $value) {
foreach($value as $k => $v) {
$info .= $k."\n";
$info .= $v."\n";
}
}
$current = file_get_contents($file);
$current .= $info;
file_put_contents($file, $current);
?>
But my problem is that all I get is "Array".
Like this:
2014-01-01 17:32:50 - Array
(
)
2014-01-01 17:34:13 - Array
(
)
2014-01-01 17:47:39 - Array
(
)
2014-01-01 17:47:40 - Array
(
)
The array comes from print_r($_POST, true);. $_POST is always an array and if array is empty that is the correct output you except. So basicly this means you don't send anything to as POST maybe you are using get ?
What you could do is check if anything is posted at all.
if (count($_POST) > 0) {
$info .= print_r($_POST, true);
}
If you are redirecting user to this page in case of error, the POST values won't be redirected with the user. And if this is an error catching page, maybe you should get save $_SERVER['REQUEST_URI'] along the data, so you know in which page the error happend.
Also as I said in my comment you could optimize your file writing with this.
file_put_contents($file, $info, FILE_APPEND | LOCK_EX);
It locks the file, so other scripts can't write to it at a same time, and appends the info to the end of the file. So you could replace these lines with just one command.
$current = file_get_contents($file);
$current .= $info;
file_put_contents($file, $current);
The whole script
<?php
$file = 'error_log.log';
$info = date("Y-m-d H:i:s") . " - " . $_SERVER['REQUEST_URI'] . "\n";
$info .= "POST: " . ((count($_POST))?print_r($_POST,true):"EMPTY\n");
$info .= "GET : " . ((count($_GET))?print_r($_GET,true):"EMPTY\n") . "\n";
file_put_contents($file, $info, FILE_APPEND | LOCK_EX);
Output example
2014-01-01 17:33:25 - /stack/error.php
POST: EMPTY
GET : EMPTY
2014-01-01 17:34:11 - /stack/error.php?ads=bsd&error=true
POST: EMPTY
GET : Array
(
[ads] => bsd
[error] => true
)
You've made it more complex than it is. Instead of:
foreach ($_POST as $key => $value) {
foreach($value as $k => $v)
{
$info .= $k."\n";
$info .= $v."\n";
}
}
It's just
foreach ($_POST as $key => $value) {
$info .= $key."\n";
$info .= $value."\n";
}
I am trying to make use of files(.txt) to print logs. Inside the file, it logs an array value which looks like this:
Array
(
[NAME] => John Peters
[AGE] => 24
[COUNTRY] => United States
[EMAIL] => test#test.com
)
So now, I am trying to read the file contents and covert it onto an actual array so that I would be able to reference the value using the array key in a php file, something like:
echo 'Name : ' .$person['NAME'];
echo 'Age: ' .$person['AGE'];
echo 'Country: ' .$person['COUNTRY'];
echo 'Email: ' .$person['EMAIL'];
Is there a predefined php function to do it? Or how will I be able to accomplish what I want. I have tried to use the fread() and fgets() function but it doesn't really accomplish what I want or I might be missing something.
I wrote a quick script for you,
I assumed that in your (files).txt can contain many entries of print_r results e.g.
Array
(
[NAME] => John Peters
[AGE] => 24
[COUNTRY] => United States
[EMAIL] => test#test.com
)
Array
(
[NAME] => John Peters
[AGE] => 24
[COUNTRY] => United States
[EMAIL] => test#test.com
)
This script assumes that your inputs test.txt only contains array that has 1 level (so, it won't work with nested array)
$c = file_get_contents('test.txt');
# Matches all strings that has 'Array(...)' pattern
preg_match_all('#Array[^\)]+\)#', $c, $matches);
$items = array();
foreach($matches[0] as $match) {
# Extracts KEY => VAL patterns from matched text
if (preg_match_all('#\[([^\]]+)\].*?>(.*)#', $match, $array)) {
$items[] = array_combine($array[1], $array[2]);
}
}
# test your results
print_r($items);
you can read it using file_get_contents
Eg:
<?php
$homepage = file_get_contents('abc.txt');
echo $homepage;
?>
Hope it will help :)
I guess #Rezigned and I had the same idea... Here's what I came up with:
<?php
$file = file_get_contents('log.txt');
$file = preg_match_all('/(\s+\[[a-zA-Z0-9]+\]\s+=>\s+.+)\n/', $file, $lines);
$key = array();
$val = array();
foreach ($lines[0] as $line) {
$keys_vals = preg_split('/(\s+=>\s+)/', $line);
$key[] .= preg_replace('/[\[|\]]/', '', $keys_vals[0]);
$val[] .= $keys_vals[1];
}
$line_count = count($lines[0]);
for ($i = 0; $i < $line_count; $i++) {
print $key[$i] . ': ' . $val[$i];
}
There is a function shared by Matt in PHP manual called print_r_reverse, I think it's what you want. The following code is copied from PHP manual print_r function comments section directly.
<?php
function print_r_reverse($in) {
$lines = explode("\n", trim($in));
if (trim($lines[0]) != 'Array') {
// bottomed out to something that isn't an array
return $in;
} else {
// this is an array, lets parse it
if (preg_match("/(\s{5,})\(/", $lines[1], $match)) {
// this is a tested array/recursive call to this function
// take a set of spaces off the beginning
$spaces = $match[1];
$spaces_length = strlen($spaces);
$lines_total = count($lines);
for ($i = 0; $i < $lines_total; $i++) {
if (substr($lines[$i], 0, $spaces_length) == $spaces) {
$lines[$i] = substr($lines[$i], $spaces_length);
}
}
}
array_shift($lines); // Array
array_shift($lines); // (
array_pop($lines); // )
$in = implode("\n", $lines);
// make sure we only match stuff with 4 preceding spaces (stuff for this array and not a nested one)
preg_match_all("/^\s{4}\[(.+?)\] \=\> /m", $in, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
$pos = array();
$previous_key = '';
$in_length = strlen($in);
// store the following in $pos:
// array with key = key of the parsed array's item
// value = array(start position in $in, $end position in $in)
foreach ($matches as $match) {
$key = $match[1][0];
$start = $match[0][1] + strlen($match[0][0]);
$pos[$key] = array($start, $in_length);
if ($previous_key != '') $pos[$previous_key][1] = $match[0][1] - 1;
$previous_key = $key;
}
$ret = array();
foreach ($pos as $key => $where) {
// recursively see if the parsed out value is an array too
$ret[$key] = print_r_reverse(substr($in, $where[0], $where[1] - $where[0]));
}
return $ret;
}
}
So I'm attempting to remove specific parameters from the URL query string that are predefined in an array. Here's what I have so far:
<?php
// Construct the current page URL
$host = $_SERVER['HTTP_HOST'];
$script = $_SERVER['SCRIPT_NAME'];
$params = $_SERVER['QUERY_STRING'];
$currentUrl = 'http://' . $host . $script . '?' . $params;
// Store all URL parameters into an array (HOST, PATH, QUERY, etc)
$url_params = array();
$url_params = parse_url($currentUrl);
// Create an array to store just the query string, breaking them apart
$params_array = explode('&', $url_params['query']);
// Array holding URL parameters that we want to remove
$params_to_remove = array("param1", "param2", "param3", "param4", "param5");
$location = 0;
// Loop through and remove parameters found in PARAMS_TO_REMOVE array
for($x = 0; $x < count($params_to_remove); $x++) {
if(in_array($params_to_remove[$x], $params_array)) {
$location = array_search($params_to_remove[$x], $params_array);
unset($params_array[$location]);
}
}
// Print array after unwanted parameters were removed
print_r($params_array);
echo '<br /><br />';
// Construct a new array holding only the parameters that we want
$clean_params_array = array();
for($z = 0; $z < count($params_array); $z++) {
if($params_array[$z] != '') array_push($clean_params_array, $params_array[$z]);
}
// Print clean array
print_r($clean_params_array);
echo '<br />';
// Construct the new URL
// If there are paramters remaining in URL reconstruct them
if(count($clean_params_array) > 0) {
$final_url = 'http://www.example.com' . $url_params['path'] . '?';
for($y = 0; $y < count($clean_params_array); $y++) {
$final_url .= $clean_params_array[$y] . '&';
}
// Trim off the final ampersand
$final_url = substr($final_url, 0, -1);
}
// No parameters in final URL
else $final_url = 'http://www.example.com' . $url_params['path'];
// Print final URL
echo '<br />' . $final_url;
?>
Here's the output:
Using http://www.example.com/test.php?apple&banana&orange¶m1&strawberry¶m2&pineapple
Array ( [0] => apple [1] => banana [2] => orange [4] => strawberry [6] => pineapple )
Array ( [0] => apple [1] => banana [2] => orange [3] => strawberry )
http://www.example.com/test.php?apple&banana&orange&strawberry
As you can see I'm losing the last parameter. I also feel as if I'm being too verbose...where am I going wrong?
$new_url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?".implode("&",array_diff(explode("&",$_SERVER['QUERY_STRING']),Array("param1","param2","param3","param4","param5")));
One-liner ;)
Although you'd probably be better off taking that Array(...) out of there and defining it as a variable beforehand, so it's easier to read.
<?php
/**
* generateURL()
*
* Sprava URL adresy
*
* #author stenley <stenley#webdev.sk>
* #version 1.4
*/
function generateURL() {
$GET = $_GET;
$QUERY_STRING = '';
$SCRIPT_NAME = substr(strrchr($_SERVER["SCRIPT_NAME"],"/"),1);
$num_args = func_num_args();
if($num_args>0 && $num_args%2==0) {
$args = func_get_args();
foreach($args as $index => $paramName) {
$paramName = trim($paramName);
if($index%2==0 && !empty($paramName)) {
$paramValue = trim($args[$index+1]);
if(array_key_exists($paramName, $GET) && empty($paramValue)) {
unset($GET[$paramName]);
} elseif(!empty($paramValue)) {
$GET[$paramName] = $paramValue;
}
}
}
}
foreach($GET as $param => $value) {
$QUERY_STRING .= $param."=".$value."&";
}
return $SCRIPT_NAME.((empty($QUERY_STRING)) ? '' : "?".substr($QUERY_STRING,0,-5));
}
?>
here is great function for managing URL address. usage is easy. here are some examples in Slovak language. but I think you will understand code samples. or I will translate it for you
sorry for my english
Part of the answer is in this line:
Array ( [0] => apple [1] => banana [2] => orange [4] => strawberry [6] => pineapple )
Note that $params_array[5] does not exist. Yet you try to read $params_array[5] when $z==5
(In your while loop you go through values $z = 0; => $z < 6; (count($params_array))
You can use Kolink's solution, or use a foreach loop to go through all the values:
foreach($params_array as $param) {
if($param != '') array_push($clean_params_array, $param);
}
code;
$all_tags = array();
while ($row = mysql_fetch_assoc($result)) {
$all_tags = array_merge($all_tags, explode(' ', $row['title']));
}
$all_tags = array_count_values($all_tags);
echo "<pre>";
arsort($all_tags);
foreach ($all_tags as $key => $val) {
echo "$key = $val\n";
}
output;
fuups! = 7
401 = 5
Authorization = 5
Required = 5
, = 3
izle = 3
Error = 2
Server = 2
Internal = 2
500 = 2
Full = 1
MegaSinema.net = 1
Sinema = 1
Bad = 1
Request = 1
Film = 1
400 = 1
all i wanna do is merge 'keys' with same integer 'value'. example;
401 = 5
Authorization = 5
Required = 5
to
401 Authorization Required = 5
i don't know how could i do it. i tried a bunch of ways but i never let it work. thank you.
I misunderstood you in the beginning.
I think you could just save the objects in an array and implode them if needed.
$out = array();
foreach($array as $key=>$value)
if(array_key_exists($value, $out))
$out[$value][] = $key;
else
$out[$value] = array($key);
// Then you could do
echo implode(" ", $out[5]); // Should output "401 Authorization Required"
Working example at http://codepad.org/MgLKXA75
Another option is to directly append it and trim the "extra" space at the end.
$out = array();
foreach($array as $key=>$value)
if(array_key_exists($value, $out))
$out[$value] .= $key . ' ';
else
$out[$value] = $key . ' ';
// Then you could do
echo trim($out[5]); // Should output "401 Authorization Required"
Try this
<?php
$data = array('fuups!' => '7','401' => '5','Authorization' => '5','Required' => '5',',' => '3','izle' => '3','Error' => '2','Server' => '2','Internal' => '2','500' => '2','Full' => '1','MegaSinema.net' => '1','Sinema' => '1','Bad' => '1','Request' => '1','Film' => '1','400' => '1');
$rows = array();
$values = array_values($data);
asort($values);
$highestVal = $values[0];
for ($i = 0; $i <= $highestVal; $i++) {
foreach ($data as $key => $value) {
if ($i == $value) {
$rows[$i] = $rows[$i] . " {$key}";
}
}
}
?>
Working Example XD http://codepad.org/x9uHs1sp
EDIT----
To echo all keys, just replace var_dump($rows) with:
foreach ($rows as $key) {
echo "{$key}<br />";
}
I'm not familiar with PHP, but I think you can try to create a hash table to handle this.
For example, if you insert above 3 items into the hash table and use '5' as the key, the first item can be inserted correctly, and the other two should throw exceptions. You can catch the exception since it's excepted and append the values to the value of the first item. So the item in you hash table should be like:
key: 5
value: 401 Authorization Required
But you should make sure about the orders in the value.
Just my 2 cents, good luck!
Update:
If throwing exception is not acceptable, you can look-up a key in the hash table first, if the key doesn't exist then insert the key and value, if it already exists then append the value to existing item value.