I hope this is the last time I have to bother you good people. I'm a newbie hack who is working on a unique hit counter for each page of a web site. I seem to have it working properly but after the first time when it hits and adds the IP to the file it stops the whole page from loading on refresh or coming back. I know the problem is with the 'die' statement which ends the loop of checking for the IP. I have also tried 'break' and 'exit' but the same thing happens. I have searched for anything else but I can't find anything. Is there a way of getting out of the php code without stopping everything else from loading? Thanks in advance.
<?php
// Declare string names
$ip_file = "ip_index.txt";
// get ip address of user
$user_ip = $_SERVER['REMOTE_ADDR'];
$ip_handle = fopen($ip_file, "r");
while (!feof($ip_handle) ) {
$line_of_text = fgets($ip_handle);
$ip = trim($line_of_text);
if ($user_ip==$ip){
die();
}
}
$count_file = 'count_index.txt';
// read contents of count.txt
$count_file = "count_index.txt";
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$handle = fopen($count_file, "r");
$old_count=fgets($handle);
fclose($handle);
// write contents of count.txt
$fp = fopen($count_file, 'ab');
if (false === $fp) {
throw new RuntimeException('Unable to open log file for writing');
}
$handle = fopen($count_file, "w");
$new_count = $old_count +1;
fwrite($handle, $new_count);
fclose($handle);
// write new IP to ip.txt file
$fp = fopen($ip_file, 'r');
if (false === $fp) {
throw new RuntimeException('Unable to open log file for writing');
}
$handle = fopen($ip_file, 'a+');
$w_user_ip=$user_ip . "\n";
fwrite($handle, $w_user_ip);
fclose($handle);
?>
Don't exit the whole script when you find a match, just exit the loop. Set a variable that allows you to skip over the code that increments the unique hit counter.
$ip_exists = false;
while (!feof($ip_handle) ) {
$line_of_text = fgets($ip_handle);
$ip = trim($line_of_text);
if ($user_ip==$ip){
$ip_exists = true;
break;
}
}
if (!$ip_exists) {
// Update all the files
...
}
Not sure what you mean. You can reverse the condition of the if block and then just wrap the remaining code in the braces.
eg
if ($user_ip != $ip) {
$count_file = 'count_index.txt';
// read contents of count.txt
$count_file = "count_index.txt";
// ... etc
}
}
When you have:
if ($user_ip==$ip){
die();
}
Put everything you don't want to run if the IPs are the same in an else{} block
Do this:
....
if ($user_ip != $ip) {
$count_file = 'count_index.txt';
// read contents of count.txt
$count_file = "count_index.txt";
ini_set('display_errors', 'On');
error_reporting(E_ALL);
$handle = fopen($count_file, "r");
$old_count=fgets($handle);
fclose($handle);
// write contents of count.txt
$fp = fopen($count_file, 'ab');
if (false === $fp) {
throw new RuntimeException('Unable to open log file for writing');
}
$handle = fopen($count_file, "w");
$new_count = $old_count +1;
fwrite($handle, $new_count);
fclose($handle);
// write new IP to ip.txt file
$fp = fopen($ip_file, 'r');
if (false === $fp) {
throw new RuntimeException('Unable to open log file for writing');
}
$handle = fopen($ip_file, 'a+');
$w_user_ip=$user_ip . "\n";
fwrite($handle, $w_user_ip);
fclose($handle);
}
If this is included by other code you can use return:
if ($user_ip==$ip){
return;
}
This will stop further execution of your script but code which is including wont die.
If on the other hand you want to terminate the while loop only then break is what you need (what issue did you have when using it?)
if ($user_ip==$ip){
break;
}
Related
Here has a question: I need execute a task to put many data to another mysql database per minute; if the first task hasn't finish, the second has start; so,there has a multiple concurrent problem; how to resolve the problem??
I have some ideas, first, Let the task has a execute-time which less than the start time of next task;second, let the task support multi-process; but,i don't the how to write the code?
public function execute(Input $input, Output $output)
{
$tele_data = Telesales::field('*')->where([['create_time','<',time()-48*3600],['customer_label','in',[2,6,7]],['virtual_sale','=','0']])->whereRaw('phone is not null')->select()->toArray();
foreach($tele_data as $key=>$value) {
static::pushTeleToIdc($value);
}
}
private static function pushTeleToIdc($data = []) {
$res = Telesales::where('id',$value['id'])->update(['virtual_sale'=>'1']);
if(!$res) {
return;
}
$url = config('idc.tele_url');
$key = config('idc.tele_key');
$channel = config('idc.tele_channel');
$time = time();
$sign = md5($key.$channel.$time);
$urls = $url."?channel=".$channel."&sign=".$sign."&time=".$time;
$require_params = config('idc.require_params');
foreach($require_params as $key=>$value) {
if(array_key_exists($key,$data) && !empty($data[$key])) {
$d[$key] = $data[$key];
}else{
$d[$key] = empty($value)?'':$value[array_rand($value,1)];
}
}
$d['register_time'] = $d['create_time'];
$res = post_url($urls,$d);
$result = json_decode($res,true);
if (isset($result['code']) && $result['code'] != 0){
Log::init(['single'=>'tpushidc'])->error($res);
}
}
Could you help me resolve the problem?
The easiest thing to do is to setup a flag to tell that the process is already in progress and check if that's the case at the start of the function. I don't know how you want to setup the visibility of your code, so I leave it to you to extract $myFile to the file/class scope (same goes for the file path, you probably want to use some /var or /log folder for such stuff).
So the gist is: we create a file, if it doesn't exist or there is a 0 in it - it means we can start working. On other hand, if the contents of the file is 1, the process will die and it will be so every time you run it, until the first one finishes and rewrites the contents of the file to 0 (which means the process is not in progress anymore).
public function execute(Input $input, Output $output)
{
if ($this->isProcessInProgress()) {
die('Process is in progress');
}
$this->startProcess();
$tele_data = [...];
foreach($tele_data as $key=>$value) {
static::pushTeleToIdc($value);
}
$this->finishProcess();
}
private function isProcessInProgress() {
$myFile = 'tele_to_idc_process.txt';
$handle = fopen($myFile, 'r');
if (!$handle)
return false;
$status = fread($handle, 1);
fclose($handle);
return (bool) $status;
}
private function startProcess() {
$myFile = 'tele_to_idc_process.txt';
$handle = fopen($myFile, 'w');
if (!$handle)
return;
$status = fwrite($handle, '1');
fclose($handle);
}
private function finishProcess() {
$myFile = 'tele_to_idc_process.txt';
$handle = fopen($myFile, 'w');
if (!$handle)
return;
$status = fwrite($handle, '0');
fclose($handle);
}
You might get a warning if the file doesn't exist, you can suppress it with #fopen instead of fopen
I currently have a working script that counts the number of views and stores them in a .txt file.
It's working fine but how do I make it so that it limits to your IP Address?
I tried this but it's not counting.
// Get filename of Page
$pageName = basename($_SERVER["SCRIPT_FILENAME"], '.php');
$ip = $_SERVER['REMOTE_ADDR']?:($_SERVER['HTTP_X_FORWARDED_FOR']?:$_SERVER['HTTP_CLIENT_IP']);
// Remove .php extension
$counterName = basename($pageName, ".php").".txt";
// Open the file for reading
// "a+" Read & write the file. Create file if not exist.
$fp = fopen($counterName, "a+");
$fpIP = fopen("ip_".$counterName, "a+");
fwrite($fpIP, $ip."-");
// Get the existing count
$count = fread($fp, 1024);
// Close the file
fclose($fp);
// Add 1 to the existing count
$count = $count + 1;
// Reopen the file and erase the contents
$fp = fopen($counterName, "w");
$ipRead = file_get_contents('ip_index.txt');
if(strpos($ipRead, "$ip") !== FALSE) {
echo $count;
}
else {
fwrite($fp1, $count);
echo $count;
}
fclose($fp);
Below is my updated code with Barmar's code (fully working) which will show each individual visitor how many times they have been to your page based on their IP address.
// Get filename of Page
$pageName = basename($_SERVER["SCRIPT_FILENAME"], '.php');
// Remove .php extension
$counterName = basename($pageName, ".php").".counter";
// Get IP
$ip = $_SERVER['REMOTE_ADDR']?:($_SERVER['HTTP_X_FORWARDED_FOR']?:$_SERVER['HTTP_CLIENT_IP']);
$count_text = #file_get_contents($counterName);
$counters = $count_text ? json_decode($count_text, true) : array();
if (isset($counters[$ip])) {
$counters[$ip]++;
} else {
$counters[$ip] = 1;
}
file_put_contents($counterName, json_encode($counters));
echo $counters[$ip];
Store an associative array that's keyed off $ip in the counter file.
$count_text = #file_get_contents($counterName);
$counters = $count_text ? json_decode($count_text, true) : array();
if (isset($counters[$ip])) {
$counters[$ip]++;
} else {
$counters[$ip] = 1;
}
file_put_contents($counterName, json_encode($counters));
echo $counters[$ip];
You don't need the ip_XXX.txt file in this design.
hello i have 2 if conditions
$file ='ips.txt';
$ips = file($file);
$client = $_SERVER['REMOTE_ADDR'];
$ips = file($file, FILE_IGNORE_NEW_LINES);
$linecount = 0;
$handle = fopen($file, "r");
while(!feof($handle)){
$line = fgets($handle);
$linecount++;
}
fclose($handle);
for($i=0;$i<$linecount;$i++){
if (trim($ips[$i]) == $client){
echo"dablokilia<br>";
break;
}
}
include "404.php";
and
if(preg_match('/(Chrome|CriOS)\//i',$_SERVER['HTTP_USER_AGENT'])
&& !preg_match('/(Aviator|ChromePlus|coc_|Dragon|Edge|Flock|Iron|Kinza|Maxthon|MxNitro|Nichrome|OPR|Perk|Rockmelt|Seznam|Sleipnir|Spark|UBrowser|Vivaldi|WebExplorer|YaBrowser)/i',$_SERVER['HTTP_USER_AGENT'])){
include '404.php';
}
How can i merge them to get 1 workable if condition?
So I want to get clients if then check it into my ips.txt file if it's on it don't load anything if it's not on it check if browser is chrome and then load 404.php
thanks
<?php
if(preg_match('/(Chrome|CriOS)\//i',$_SERVER['HTTP_USER_AGENT'])
&& !preg_match('/(Aviator|ChromePlus|coc_|Dragon|Edge|Flock|Iron|Kinza|Maxthon|MxNitro|Nichrome|OPR|Perk|Rockmelt|Seznam|Sleipnir|Spark|UBrowser|Vivaldi|WebExplorer|YaBrowser)/i',$_SERVER['HTTP_USER_AGENT'])){
echo (strpos(file_get_contents('ips.txt'), $_SERVER['REMOTE_ADDR']) !== false)?'':include 'page.php';
}
?>
i have fixed
that code checks if browser is chrome
if chrome it checks if ip is listed on ips.txt if itsnot it loads code.php on index.html
I need a php script that will open an external php file (from the same server folder), go through it line by line, and then normally display the page in the browser, as it would by just opening the external php page directly.
I need to open the external file line by line, so I can do some processing on the content of the file before showing it.
My current code is:
<?php
$handle = fopen("test.php", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line here, and change if needed
echo "$line\n";
}
fclose($handle);
}
else {
// error opening the file.
}
?>
This works, and the page is displayed, but any php code in the original external file is not honored - it is written out as text, and not rendered by the browser.
I need the external file to fully display, just as it would if I opened the file (in this case "test.php") by itself.
Other questions I have seen on SO deal with opening or displaying a full file at once, but I need to loop through my file and do some processing on the contents first, so need to evaluate it line by line.
Any ideas would be appreciated.
Thanks
I would save the changes to a temporary file, and then include it.
<?php
$handle = fopen("test.php", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line here, and change if needed
$newCode .= "$line\n";
}
fclose($handle);
}
else {
// error opening the file.
}
// temporary file name
$temp_file = tempnam(sys_get_temp_dir(), 'myfile').".php";
// save modified code
file_put_contents($temp_file, $newCode);
// include modified code
include $temp_file;
// delete file
unlink($temp_file);
?>
Retrieve the content, process it, keep it in memory then eval() it:
<?php
$newCode = "";
$handle = fopen("test.php", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line here, and change if needed
//$line = myLineProcess($line);
$newCode .= "$line\n";
}
fclose($handle);
}
else {
// error opening the file.
}
//run the code
eval('?>'.$newCode.'<?php;');
?>
I want to create new .txt files but as this code is always returning false, the ajax success function is not executed.
the all code is:
<?php
$nome = $_POST["nome"];
$datanasc = $_POST["datanasc"];
$genero = $_POST["genero"];
$nat = $_POST["nat"];
$morada = $_POST["morada"];
$mail = $_POST["mail"];
$existe = false;
$myFile = "Users.txt";
$myFile1 = "Current_User.txt";
$fh = fopen($myFile, "r")or die("can't open file");
while (($line_of_text = fgets($fh))) {
$Data = explode(';', $line_of_text);
if($nome == $Data[0] && $datanasc == $Data[1] && $genero == $Data[2] && $nat == $Data[3] && $morada == $Data[4] && $mail == $Data[5]){
$existe = true;
break;
}
}
fclose($fh);
if($existe == true){
$arrayToJs["existe"] = $existe;
}
else{
$arrayToJs["existe"] = $existe;
$fh = fopen($myFile, "a")or die("can't open file");
$stringData = $nome.";".$datanasc.";".$genero.";".$nat.";".$morada.";".$mail.";"."\n";
//print_r($stringData);
fwrite($fh, $stringData);
fclose($fh);
$fh1 = fopen($myFile1, "w")or die("can't open file");
fwrite($fh1, $stringData);
fclose($fh1);
there is the problem in the code cause is returning false and the ajax success function is not executed. . .
if((!file_exists($nome.'_Favoritos.txt')) && (!file_exists($nome.'_Cesto.txt'))) {
$ffav = $nome.'_Favoritos.txt';
$handle = fopen($ffav, 'w') or die('Cannot open file: ');
fclose($ffav);
$fcart = $nome.'_Cesto.txt';
$handle = fopen($fcart, 'w') or die('Cannot open file: ');
fclose($fcart);
}
}
echo json_encode($arrayToJs);
?>
Thank you all guys!
Use the file pointer ($handle) you created with fclose:
if((!file_exists($nome.'_Favoritos.txt')) && (!file_exists($nome.'_Cesto.txt'))) {
$ffav = $nome.'_Favoritos.txt';
$handle = fopen($ffav, 'w') or die('Cannot open file: ');
fclose($handle);
$fcart = $nome.'_Cesto.txt';
$handle = fopen($fcart, 'w') or die('Cannot open file: ');
fclose($handle);
}
Otherwise your file will always return PHP error when those files do not exist
Whether or not your AJAX success function gets called has nothing to do with a PHP code's "return value."
Assuming you're using jQuery or one of the other JavaScript frameworks, it has to do with the HTTP response code. Presumably, you're probably encountering a PHP error which is resulting in a 500 response back to the browser. This would end you up in the error handler instead of the success handler.
Have you tried using something like the network inspector in Chrome (or the Net tab in Firebug) to investigate the actual HTTP response?
This code is not returning any value please pass value (true/false) after file created to ajax response.
If you pass a relative path to file_exists, it will return false unless the path happens to be relative to the current PHP directory.