Current setting: In the same PHP document I have a PHP randomizer function and the HTML that calls that function -- a separate txt document with strings that are called by the php function:
Function
<?php
function rand_line($fileName, $maxLineLength = 4096) {
$handle = @fopen($fileName, "strings.txt");
if ($handle) {
$random_line = null;
$line = null;
$count = 0;
while (($line = fgets($handle, $maxLineLength)) !== false) {
$count++;
if(rand() % $count == 0) {
$random_line = $line;
}
}
if (!feof($handle)) {
echo "Error: unexpected fgets() fail\n";
fclose($handle);
return null;
} else {
fclose($handle);
}
return $random_line;
}
}
?>
I call the function in the HTML using:
<?php echo rand_line("strings.txt");?> <input type="button" value="Another String" onClick="window.location.reload()">
This tends to be slow when multiple users access the page and press the button to obtain a new status.
What I would like to achieve:
Improve the performance and make the whole thing not so heavy: maybe the randomizer is unnecessarily complicated and I could work with AJAX calls for example, but if possible keeping the string list inside the strings.txt file and separated from the PHP script and HTML.
Sorry if I don't know what I'm talking about... I'm not a proficient programmer. Just a guy that hacks stuff together once in a while :)
You really don't want to use window.location.reload();
That is terrible... You do not want to refresh a page...
location.reload() sends http request for a whole new page (whole HTML), and then not only that your browser needs to render whole HTML again, you have to transfer more duplicated data through a network, from point A to point B.
You should send HTTP request only for a data that you need (you don't need whole HTML again, you loaded it the 1st time you visited page).
Instead, use XMLHttpRequest
javascript library (AJAX) to request only for a portion of data (in your case => random line string)
HTML:
<!DOCTYPE html>
<html>
<head lang="en">
<script type="text/javascript">
function loadDoc(url, cfunc) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (xhttp.readyState == 4 && xhttp.status == 200) {
cfunc(xhttp);
}
};
xhttp.open("GET", url, true)
xhttp.send();
}
function randomLine(xhttp) {
alert(xhttp.responseText);
}
</script>
</head>
<body>
<input type="button" value="Get random line" onClick="loadDoc('http://localhost:8080/myScript.php', randomLine)">
</body>
</html>
PHP:
myScript.php
<?php
function rand_line($fileName, $maxLineLength = 4096)
{
...
}
echo rand_line("strings.txt");
?>
* EDIT #2 *
Fully-functioning script. Grabs initial strings via PHP, and stores in array for later JavaScript usage. Minimizes # of calls.
PHP to grab strings from file ; generates a default (random) string, as well as an array of strings for later use with button.
/**
* @input array $file
* @return array (mixed) [0] => string, [1] => array
*/
$randomStringFromFile = function($file) {
if (!$file) return false;
/**
* @return Removes carriage returns from the file
* and wraps $val with single-quotes so as
* to not break JavaScript
*/
$add_quotes = function(&$val) {
return str_replace("\n", "", "'$val'");
};
return [$file[rand(0, count($file)-1)], array_map($add_quotes, $file)];
};
$randomString = $randomStringFromFile( @file('strings.txt') ) ?: false;
JavaScript
<div id="string_container"><?php echo $randomString[0]; // defaults random string to page ?></div><br>
<button onclick="getString();">Another String</button>
<script>
var getString = function() {
var arr = [<?php echo implode(',', $randomString[1]); ?>],
setString = document.getElementById('string_container').innerHTML = arr[Math.floor(Math.random() * arr.length)];
};
</script>
Place the above in your page and you should be good to go.
EDIT (ORIGINAL)
We can remove PHP from the equation entirely using the following ( fastest method):
<div id="string_container"></div><br>
<button onclick="getString();">Another String</button>
<script>
var getString = function() {
var request = new XMLHttpRequest(),
file = 'strings.txt';
request.open('GET', file);
request.onload = function() {
if (request.status === 200) {
var arr = request.responseText.split("\n"), /** assuming line breaks in file are standard carriage returns (Unix); "\r" if Windows */
setString = document.getElementById('string_container').innerHTML = arr[Math.floor(Math.random() * arr.length-1)];
}
};
request.send();
};
</script>
ORIGINAL w/PHP
We can simplify the PHP even further, removing loops from the equation altogether.
$randomStringFromFile = function($file) {
if (!$file) return false;
return $file[rand(0, count($file)-1)];
};
echo $randomStringFromFile( @file('strings.txt') ) ?: 'No worky!';
Using file() will return the contents in an array, thus allowing you to simply select a key at random and return the value.
NOTE On average, $file[rand(0, count($file)-1)]
outperformed array_rand()
(Eg $file[array_rand($file)];
) when selecting a key at random. By negligible amounts, have you.. ~0.0002s
vs ~0.0005s
, respectively.
You can simplify your code
function rand_line($fileName, $maxLineLength = 4096) {
$f = file($fileName);
$length = $maxLineLength + 1;
do {
$line = $f[array_rand($f)];
$length = strlen($line);
} while ($length > $maxLineLength);
return $line;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.