PHP - Count number of times string appears in file - php

I've got a file (leaderboard.txt) that looks like this:
funkystudios
funkystudios
funkystudios
gilletteracer74
axehairgel
Ferby123
dirdam
TheWu13
Expert_Assassin
TheWu13
ocanosoup
I want to be able to read this file, and print out the number of times each person appears in the file. (Also place in order of # of times in file)
funkystudios: 3
TheWu13: 2
gilletteracer74: 1
axehairgel: 1
(and so on)
I've tried various ways but It all came down to an issue when I would try to order them correctly... I'm guessing there is a pretty easy way to do this. (I'm new to PHP...)
EDIT:
I have gotten to this point:
foreach(array_count_values(file('leaderboard.txt')) as $person => $count)
echo "{$person} : {$count}<br />\r\n";
It doesn't order by the $count, but simply who comes up first in the file.

$counted = array_count_values(file('leaderboard.txt'));
arsort($counted);
foreach($counted as $person => $count)
echo "{$person} : {$count}<br />\r\n";

Related

How to parse URL when using the pager plugin with AJAX

I am trying to use the tablesorter pager plugin with AJAX but run into som problemes (or limitations) when trying to handle the AJAX request in my php backend.
If eg. the table is set up with a default sorting of
sortList: [ [0,1], [1,0] ]
I will get a URL like this on my AJAX request:
page=0&size=50&filter=fcol[6]=batteri&sort=col[0]=1&col[1]=0
In my php back end I do a
$cur_sort = $_GET['sort']
and get
col[0]=1
So the last part is missing - I guess since it contains a & char.
How do I get the entire sort string?
That said how is the string col[0]=1&col[1]=0 best parsed? I need to extract the info that col 0 is to be sorter DESC and col 1 ASC.
You can try this;
parse_str($_SERVER['QUERY_STRING'],$data);
It will parse the url to an array;
Also; you should use empty [] instead of [1] and [0]
See more here: parse_str()
Example:
$str = "page=0&size=50&filter=fcol[6]=batteri&sort=col[0]=1&col[1]=0";
parse_str($str, $output);
echo $output['page']; // echo 0
And to answer your question; it is correct; is echoing col[0]=1 because you are dividing with & see here:
&sort=col[0]=1 & col[1]=0;
An advice; use more names, instead.
You could use
&sort[]=1&sort[]=0;
UPDATE:
To access the last one; you should do, simply;
$_GET['col'][1];
If you want to access, the last number in
$_GET['sort'];
You can do this;
$explode = explode('=',$_GET['sort']);
$end = end($explode);
echo $end; //it will outout 1
If you print your entire query_String, it will print this;
Array
(
[page] => 0
[size] => 50
[filter] => fcol[6]=batteri
[sort] => col[0]=1
[col] => Array
(
[1] => 0
)
)
I'm not sure how the ajaxUrl option is being used, but the output shared in the question doesn't look right.
I really have no idea how the string in the question is showing this format:
&sort=col[0]=1&col[1]=0 (where did sort= come from?)
&filter=fcol[6]=batteri (where did filter= come from?)
If you look at how you can manipulate the ajaxUrl option, you will see this example:
ajaxUrl: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
So say you have the following settings:
page = 2
size = 10
sortList is set to [[0,1],[3,0]] (1st column descending sort, 4th column ascending sort)
filters is set as ['','','fred']
The resulting url passed to the server will look like this:
http://mydatabase.com?page=2&size=10&col[0]=1&col[3]=0&fcol[2]=fred
The col part of the {sortList:col} placeholder sets the sorted column name passed to the URL & the fcol part of {filterList:fcol} placeholder sets the filter for the set column. So those are not fixed names.
If the above method for using the ajaxUrl string doesn't suit your needs, you can leave those settings out of the ajaxUrl and instead use the customAjaxUrl option to modify the URL as desired. Here is a simple example (I know this is not a conventional method):
ajaxUrl: "http://mydatabase.com?page={page}&size={size}",
// modify the url after all processing has been applied
customAjaxUrl: function(table, url) {
var config = table.config,
// convert [[0,1],[3,0]] into "0-1-3-0"
sort = [].concat.apply( [], config.sortList ).join('-'),
// convert [ '', '', 'fred' ] into "--fred"
filter = config.lastSearch.join('-');
// send the server the current page
return url += '&sort=' + sort + '&filter=' + filter
}
With the same settings, the resulting URL will now look like this:
http://mydatabase.com?page=2&size=10&sort=0-1-3-0&filter=--fred
This is my own best solution so far, but it's not really elegant:
if (preg_match_all("/[^f]col\[\d+]=\d+/", $_SERVER['QUERY_STRING'], $matches)) {
foreach($matches[0] AS $sortinfo) {
if (preg_match_all("/\d+/", $sortinfo, $matches)) {
if(count($matches[0]) == 2) {
echo "Col: ".$matches[0][0]."<br/>";
echo "Order: ".$matches[0][1]."<br/>";
}
}
}
}
It gives me the info I need
Col: 0
Order: 1
Col: 1
Order: 0
But is clumbsy. Is there a better way?

PHP code to replace certain values in array, code generator

I am trying to write PHP code as a hobby project to basically create a "possible" code generator. The scenario is that we have a list of 25 valid characters that can be used.
Imagine that you have a 25 character code but you have accidentally scratched off the first two characters or three characters at any location in the code. Now we need to find all the possible combinations to try out. I have put all the valid characters into the array below that can be used in the code.
$valid=array("B","C","D","F","G","H","J","K","M","P","Q","R","T","V","W","X","Y","Z",
"2","3","4","6","7","8","9");
$arraylength=count($valid);
The still available or seen characters are input into a text box and in the place where the character is unreadable is left blank and the variable values are fetched.
$char1= $_POST['code1'];
$char2= $_POST['code2'];
$char3= $_POST['code3'];
$char4= $_POST['code4'];
$char5= $_POST['code5'];
$char6= $_POST['code6'];
$char7= $_POST['code7'];
$char8= $_POST['code8'];
$char9= $_POST['code9'];
$char10= $_POST['code10'];
$char11= $_POST['code11'];
$char12= $_POST['code12'];
$char13= $_POST['code13'];
$char14= $_POST['code14'];
$char15= $_POST['code15'];
$char16= $_POST['code16'];
$char17= $_POST['code17'];
$char18= $_POST['code18'];
$char19= $_POST['code19'];
$char20= $_POST['code20'];
$char21= $_POST['code21'];
$char22= $_POST['code22'];
$char23= $_POST['code23'];
$char24= $_POST['code24'];
$char25= $_POST['code25'];
And put into an array...
$jada = array($char1, $char2, $char3, $char4, $char5, $char6, $char7, $char8, $char9, $char10, $char11, $char12, $char13, $char14, $char15
, $char16, $char17, $char18, $char19, $char20, $char21, $char22, $char23, $char24, $char25);
I have been stumped for a while now, the fiddling I have done at the moment is that if a variable is empty then do something (as a test echo or print the possible combinations)
if(!isset($char1) || trim($char1) == ""){
for($x=0;$x<$arraylength;$x++) {
echo $valid[$x];
echo "<br>";
} }
else{
echo ($char1);
}
Can you guys help out?
Saw this still in an open status after many years of hiatus, I figured that I may as well share some information.
In the end I figured it out, you can grab the source here and test it in your own server: https://github.com/Masterkriz/XBOX_Pre-paid_code_fixer

Why is this PHP foreach loop only executing once?

Trying to debug some issues with WordPress' notorious pseudo-cron. Thought about putting this on WordPressAnswers but I think this is less about WP and more a basic PHP question on a foreach that seems to never get past its first run. (Yes, definitely looked at a bunch of similar questions, but no love there, sorry.)
Here's the code, with 3 checkpoints where I added output for testing. I'm including the entire code of everything in the loop, just to be thorough, though most of it's probably beside the point. Checkpoints 2 and 3 never display for me, and checkpoint 1 only shows up once (i.e. on first iteration of loop). Not shown is where I'm outputting $crons, and count($crons) for good measure, to confirm that, yes, it absolutely has multiple elements.
foreach ( $crons as $timestamp => $cronhooks ) {
echo("<br>loop for timestamp " . $timestamp); // checkpoint 1
if ( $timestamp > $gmt_time ) {
break;
}
foreach ( $cronhooks as $hook => $keys ) {
echo("<br>loop for hook " . $hook); // checkpoint 2
foreach ( $keys as $k => $v ) {
$schedule = $v['schedule'];
if ( $schedule != false ) {
$new_args = array($timestamp, $schedule, $hook, $v['args']);
call_user_func_array('wp_reschedule_event', $new_args);
}
wp_unschedule_event( $timestamp, $hook, $v['args'] );
do_action_ref_array( $hook, $v['args'] );
// If the hook ran too long and another cron process stole the lock, quit.
if ( _get_cron_lock() != $doing_wp_cron ) {
echo("quitting!"); // checkpoint 3
return;
}
}
}
}
All the output I'm getting from this, despite my 5 elements, is:
loop for timestamp 1382968401
I'll be grateful for extra eyes on whatever I'm missing. I'm 95% sure this is WP core code, except my checkpoints, although for various reasons it's not out of the question that another programmer was mucking about in here in an end-run around our version control system. A whole other problem, obviously!
Assuming $gmt_time is current UTC time, then the timestamp 1382968401 will be greater (as of this writing):
$d = new DateTime('#'.'1382968401', new DateTimeZone('UTC'));
echo $d->format('Y-m-d H:i:s'); // output 2013-10-28 13:53:21
Which would explain why your loop breaks on the first iteration.
Well, foreach can't be wrong.
The only way your loop could do only one iteration is that it breaks. And that could only mean that the first $timestamp is greater than $gmt_time.
(There's also the return possibility near the bottom, but you already said you receive one line of text, so it couldn't have gone that way...)
I'm guessing that you want to just skip the iteration if the scheduled task is in the future. To do that, just change break with continue.

Getting currency conversion data from Yahooapis now that iGoogle is gone

Up until yesterday I had a perfectly working budget organizer site/app working with iGoogle.
Through PHP, using the following little line
file_get_contents('http://www.google.com/ig/calculator?hl=en&q=1usd=?eur');
and similar I was able to get all I needed.
As of today, this is no longer working. When I looked into the issue, what has happened is that Google has retired iGoogle. Bummer!
Anyway, I was looking around elsewhere but I can't find anything that fits my needs. I would REALLY love to just fix it and get it running again by just switching this one line of code (i.e. changing the Google address with the address of some other currency API available) but it seems like none does.
The API from rate-exchange.appspot.com seems like it could be a iGoogle analog but, alas, it never works. I keep getting an "Over Quota" message.
(Here comes an initial question: anybody out there know of a simple, reliable, iGoogle-sort API?)
So I guess the natural thing would be to the Yahoo YQL feature (at least I suppose it is as reliable).
Yahoo's queries look like this:
http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("USDEUR", "USDJPY", "USDBGN")&env=store://datatables.org/alltableswithkeys
What I really can't figure out is how to parse this data. It outputs an XML.
What I used to have is this:
function exchange($inputAmount,$inputCurrency,$outputCurrency) {
$exchange = file_get_contents('http://www.google.com/ig/calculator?hl=en&q='.$inputAmount.$inputCurrency.'=?'.$outputCurrency);
$exchange = explode('"', $exchange);
$exchange = explode('.', $exchange['3']);
$exchange[0] = str_replace(" ", "",preg_replace('/\D/', '', $exchange[0]));
if(isset($exchange[1])){
$exchange[1] = str_replace(" ", "",preg_replace('/\D/', '', $exchange[1]));
$exchange = $exchange[0].".".$exchange[1];
} else{
$exchange = $exchange[0];
}
return $exchange;
}
So the user was able to get the exchange rate from an input currency such as "USD" and an output currency such as "EUR" on a specific amount of money. As I said, this was working swimmingly up until yesterday night.
Any ideas?
Never mind! Solved it!
For anyone interested, here's what I did to get my code to work (with the least chnges possible) with the Yahoo YQL:
// ** GET EXCHANGE INFO FROM YAHOO YQL ** //
$url = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("USDEUR", "EURUSD")&env=store://datatables.org/alltableswithkeys'; //<-- Get the YQL info from Yahoo (here I'm only interested in converting from USD to EUR and vice-versa; you should add all conversion pairs you need).
$xml = simplexml_load_file($url) or die("Exchange feed not loading!"); //<-- Load the XML file into PHP variable.
$exchange = array(); //<-- Build an array to hold the data we need.
for($i=0; $i<2; $i++): //<-- For loop to get data specific to each exchange pair (you should change 2 to the actual amount of pairs you're querying for).
$name = (string)$xml->results->rate[$i]->Name; //<-- Get the name of the pair and turn it into a string (this looks like this: "USD to EUR").
$rate = (string)$xml->results->rate[$i]->Rate; //<-- Do the same for the actual rate resulting from the conversion.
$exchange[$name] = $rate; //<-- Put the data pairs into the array.
endfor; //<-- End for loop. :)
// ** WORK WITH EXCHANGE INFO ** //
$toeur = array( //<-- Create new array specific for conversion to one of the units needed.
'usd' => $exchange['USD to EUR'], //<-- Create an array key for each unit used. In this case, in order to get the conversion of USD to EUR I ask for it from my $exchange array with the pair Name.
'eur' => 1); //<-- The way I coded the app, I found it more practical to also create a conversion for the unit into itself and simply use a 1, which translates into "do not convert"
$tousd = array(
'eur' => $exchange['EUR to USD'],
'usd' => 1);
This is basically all you need to get all the exchange info you want. After that, you use it all something like this:
amount*$toxxx['coin'];
So, say I wanted to know how many Euro is 100 USD right now:
100*$toeur['usd'];
Piece of cake!
Still a very useful solution by QuestionerNo27. Since early 2015, however, Yahoo YQL apparently slightly changed the XML output of their api. 'Name' now no longer translates into a string like 'USD to EUR', but to 'USD/EUR' and should in the code above be referenced this way:
$toeur = array(
'usd' => $exchange['USD/EUR']
instead of
$toeur = array(
'usd' => $exchange['USD to EUR']
and in a similar fashion for other currency conversions.
I created a routine to convert the currency based on #QuestionerNo27 http://jamhubsoftware.com/geoip/currencyconvertor.php?fromcur=USD&tocur=EUR&amount=1 you can consume this
<?php
$fromcur = $_GET['fromcur'];
$tocur = $_GET['tocur'];
$amt = $_GET['amount'];
// ** GET EXCHANGE INFO FROM YAHOO YQL ** //
$url = 'http://query.yahooapis.com/v1/public/yql?q=select * from yahoo.finance.xchange where pair in ("'.$fromcur.$tocur.'")&env=store://datatables.org/alltableswithkeys'; //<-- Get the YQL info from Yahoo (here I'm only interested in converting from USD to EUR and vice-versa; you should add all conversion pairs you need).
$xml = simplexml_load_file($url) or die("Exchange feed not loading!"); //<-- Load the XML file into PHP variable.
$exchange = array(); //<-- Build an array to hold the data we need.
for($i=0; $i<2; $i++): //<-- For loop to get data specific to each exchange pair (you should change 2 to the actual amount of pairs you're querying for).
$name = (string)$xml->results->rate[$i]->Name; //<-- Get the name of the pair and turn it into a string (this looks like this: "USD to EUR").
$rate = (string)$xml->results->rate[$i]->Rate; //<-- Do the same for the actual rate resulting from the conversion.
$exchange[$name] = $rate; //<-- Put the data pairs into the array.
endfor; //<-- End for loop. :)
// ** WORK WITH EXCHANGE INFO ** //
$conv = $fromcur . '/' . $tocur;
$toeur = array( //<-- Create new array specific for conversion to one of the units needed.
$tocur => $amt*$exchange[$conv], //<-- Create an array key for each unit used. In this case, in order to get the conversion of USD to EUR I ask for it from my $exchange array with the pair Name.
$fromcur => $amt,
"ex_amt" =>$amt*$exchange[$conv]); //<-- The way I coded the app, I found it more practical to also create a conversion for the unit into itself and simply use a 1, which translates into "do not convert"
echo json_encode($toeur);
?>

PHP Script on timer, can't get file to cache

I've been stuck on this for a couple of days now, and I'm really having trouble getting this script to function correctly.
I have a very basic starting script, which outputs a random page of text/html/php every time the page refreshes.
<?php
$pages = array(1 => 'text1-1.php', 2 => 'text1-2.php', 3 => 'text1-3.php', 4 => 'text1- 4.php');
$key = array_rand ( $pages );
include($pages[$key]) ;
?>
My goal is to have a script that only changes the output every 1 or 2 days (or what ever time is specify), so no matter how many times you refresh the page, the output won't change until the timer expires.
I have tried the following pieced together from tips people have given me, but no matter what I try the script always outputs something different, every time the page is refreshed.
I think the problem is the file isn't caching, but I don't understand why.
If there are any other problems you can see, I would be grateful for some pointers. :)
Thank you for any help you can offer. :)
<?php
$pages = array(1 => 'text1-1.php', 2 => 'text1-2.php', 3 => 'text1-3.php', 4 => 'text1- 4.php');
$cachefile = "cache/timer.xml";
$time = $key = null;
$time_expire = 24*60*60;
if(is_file($cachefile)) {
list($time, $key) = explode(' ', file_get_contents($cachefile));
}
if(!$time || time() - $time > $time_expire) {
$key = rand(0,count($pages)-1);
file_put_contents($cachefile, time().' '.$key);
}
include($pages[$key]) ;
?>
How about this method to generate your random number:
srand(floor(time()/60/60/24/2));
$key = rand(0,count($pages)-1);
It fixes the seed for two days (technically for 48 hours, not necessarily matching two full days) so the first call to rand() always returns the first number based on that seed.
Have you checked to make sure the file is actually created? Does the directory "cache" exist? Can you web server process write to it? Note that file_put_contents will issue a WARNING only if it cannot create the file; no error will be produced and the script will appear to run without a problem if you have your server set to not show warnings.
I absolutely agree the file is not being written; your code works fine for me.
Without cache/:
Warning: file_put_contents(cache/timer.xml): failed to open stream: No such file or directory in ...
With cache/ and write permissions:
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
$ php test.php
text1-1.php
Replace
if(!$time || time() - $time > $time_expire) {
With
if (! $time || (time () - $time) > $time_expire) {
Also
mt_rand is better than rand you might want to change that too
Edit 1
Since your array is not starting form 0 you should also
replace
$key = rand(0,count($pages)-1);
With
$key = mt_rand( 1, count ( $pages ));
Or
make your array
$pages = array (
0 => 'text1-1.php',
1 => 'text1-2.php',
2 => 'text1-3.php',
3 => 'text1-4.php'
);
Tested your script now .. it works perfectly fine ... let me know if you need anything else
Thanks
:)

Categories