When building a web application I needed to save referrer Google search queries to a file and later on echo them.
The thing I have tried so far is:
function write_to_file($q)
{$filename = 'sitemap.dat';
$fh = fopen($filename, "a");
if(flock($fh, LOCK_EX))
{fwrite($fh, $q);
flock($fh, LOCK_UN);}
fclose($fh);}
$ref = $_SERVER['HTTP_REFERER'];
if(strstr($ref, "http://")){
if(strstr($ref, "google.com")){
//echo $ref;
$regex ='/q=(.+?)&/';
preg_match($regex, $ref, $query);
$user_query = ''.$query[1].'';
write_to_file($user_query);
}}
Simplifying the above code first it creates a function to save text into file, then it looks for a refer, checks if it is not https then it check if it's google.com.
All sorted now it grabs the query part and writes it to the file. However I can't get it working because the page after the script is not displayed and nothing is saved in sitemap.dat.
Also, if I remove the file function it echos search%20query, which is I want.
Check this out.
function write_to_file($q=''){
if($q==='') return false;
$fh = fopen('sitemap.dat', "a");
if(flock($fh, LOCK_EX)){
fwrite($fh, $q."\n");
flock($fh, LOCK_UN);
}
fclose($fh);
echo 'done';
}
$ref = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : '';
if(strstr($ref, "http://www.google.co")){
preg_match('/q=(.+)&?/', $ref, $query);
if(count($query)>1){
write_to_file($query[1]);
}
}
Related
i've now written this short script.
It records a serial or token number, checks to see if its in a .dat file, and allows access if its present. Otherwise it denies access to the site.
It also removes the token from the file once it has been redeemed as it were.
However, when i add multiple tokes in the dat file, the code doesn work properly. It only works with a single entry. How would i make it work for multiple entries.
im thinking of maybe implementing some sort of array somewhere? or explode?
index.php
require_once "married.php";
session_start();
$url_request = (isset($_SERVER['HTTPS']) ? "https" : "http") .
"://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$ip = $_SERVER['REMOTE_ADDR'];
$token = substr($url_request,45);
$_SESSION["cookie"] = $token;
$tk = $_SESSION["cookie"];
$ips = array();
$page = file("urls.dat");
foreach($page as $line)
{
array_push($ips, $line);
}
if(in_array($tk, $ips))
{
//header("Location: mysite.co.uk");
echo "<title>My Site</title>Here is my site";
$file = fopen("ip_match.dat","a");
fwrite($file,$tk . " " . $ip . "\r\n");
fclose($file);
$oldMessage = $_SESSION["cookie"];
$deletedFormat = "";
$str=file_get_contents('urls.dat');
$str=str_replace("$oldMessage", "$deletedFormat",$str);
file_put_contents('urls.dat', $str);
exit;
} else {
echo ("<title>404 Not Found</title>
<h1>Not Found</h1>The requested URL was not found on this server.
<br>
<br>
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request. test");
exit;
}
urls.dat
1089yht
url: http://mmmmmmmmmmmmm.co.uk/url/index.php?key=1089yht
ps. Happy Holidays all!
Look at JSON. You could do something like this:
$tokens = ['foo', 'bar'];
file_put_contents('urls.json', json_encode($tokens));
// and then you can decode it back
// returns ['foo', 'bar']
$decodedTokens = json_decode(file_get_contents('urls.json'));
If you still want to use simple text file, you could save every record at new line and then load line by line.
$tokens = [];
while(! feof($file)) {
$line = fgets($file);
// or save to array
$tokens[] = $line;
}
fclose($file);
try
$str = preg_replace("/{$oldMessage}/", $deletedFormat, $str, 1);
Instead of
$str=str_replace("$oldMessage", "$deletedFormat",$str);
Because: str_replace replaces everything.
preg_replace lets you limit how many replacements.
As you can see in the code below, I'm trying to use flock to prevent other clients to acess the php (actually multiple users will acess this something like 10 times per second, each one), as I've found searching here... But this is not working. My data.txt is getting blank everytime doing this.
<?php
$fileName = $_GET["room"]."/data.txt";
function replaceLine($data){
if (stristr($data, $_GET["player"])){
return $_GET["player"]." ".$_GET["data"]."\n";
}
return $data;
}
$file = fopen($fileName,"r");
if (flock($file, LOCK_EX)){
//ftruncate($file, 0);
///--------------
$data = file($fileName);
$data = array_map("replaceLine", $data);
file_put_contents($fileName, implode('', $data));
echo fread($file, filesize($fileName)+1);
///--------------
fflush($file);
flock($file, LOCK_UN);
} else {
echo "wait";
}
fclose($file);
?>
This is the original code (that I was trying to modify to prevent making the file empty): (It works as I want, but have this file problem...)
<?php
$fileName = $_GET["room"]."/data.txt";
function replaceLine($data){
if (stristr($data, $_GET["player"])){
return $_GET["player"]." ".$_GET["data"]."\n";
}
return $data;
}
$data = file($fileName);
$data = array_map("replaceLine", $data);
file_put_contents($fileName, implode('', $data));
$file = fopen($fileName,"r");
echo fread($file, filesize($fileName)+1);
fclose($file);
?>
Sorry for asking this newbie question, but I have not idea how to fix this and I'm searching and trying different things for weeks! Thanks!
You are opening the file for read only and then you are attempting to write to that same file. Try setting the fopen parameter to read/write.
$file = fopen($fileName,"r+");
I would also use fwrite() instead of file_put_contents() since you already have the file pointer and opening it again will likely be denied by the lock.
I am having this strange issue and can't figure it out.
On some websites I have this script works perfect... same code, same server settings...
With php, there is a simple page view hit counter that stores locally in a txt file.
Then I echo out the value on the footer copyright area of my websites to give the client a quick statistic... its pretty cool how fast it grows.
Anyway.. i have a client corner grill ny . com (seo purposes I added spaces )
On that website.. its been working great for years.
Now another website and a bunch more.. for example... savianos . com
This breaks.. and the text value is blank.
This is the counter.php code
<?php
session_start();
$counter_name = "counter/hits.txt";
//Check if a text file exists. If not create one and initialize it to zero.
if (!file_exists($counter_name)) {
$f = fopen($counter_name, "w");
fwrite($f,"0");
fclose($f);
}
// Read the current value of our counter file
$f = fopen($counter_name,"r");
$counterVal = fread($f, filesize($counter_name));
fclose($f);
// Has visitor been counted in this session?
// If not, increase counter value by one
if(!isset($_SESSION['hasVisited'])){
$_SESSION['hasVisited']="yes";
$counterVal++;
$f = fopen($counter_name, "w");
fwrite($f, $counterVal);
fclose($f);
}
?>
Now, if I add a value in the txt file.. like 1040... and go to the website it starts to work... then after a week or so I check it .. its blank again.
Any ideas?
I am thinking that this may be happening because the website might get a TON of views during dinner time friday night.. and the simple script can't handle it so.. while its trying to write a added a number it just breaks and go to blank.. and never starts back up again.
The structure is this.
/counter/ folder has
counter.php and a hits.txt file
Every page of the website the very first thing is
<?php include ('counter/counter.php'); ?>
and in the footer of the website we have
<?php echo $counterVal; ?>
Your code looks perfect, but let's understand the situation. You have a file which can be accessed concurrently for many users, because page visit can be done by multiple users on same time. This does't seem right you have to lock the file manipulation for another user while someone is modifying it, right?. Please have a look
Visits counter without database with PHP
It is most likely because you have two concurrent scripts that tried to open the file at one and one of them fail. You have to use flock() when there are multiple instances of the script that could operate at the same time. Counter are some of the heaviest things if you going to use file reading and writing. I wrote this wrapper to easily implement file locking.
If you want to check out one of my counters that in operation try http://ozlu.org. That dynamic counter image was self-built. The fileReadAll will read the entire file in one shot. The file writer only has two modes, write or append. You can pass the fileWriter an array or a string and it will write it to the file. The function will not add any \n to format your text so you would have to add that. The default mode for the fileWriteAll is w if you do not set the third argument.
function fileWriteAll($file, $content, $mode = "w"){
$mode = $mode === "w" || $mode === "a"? $mode : "w";
$FILE = fopen($file, $mode);
while (!flock($FILE, LOCK_EX)) { usleep(1); }
if( is_array($content) ){
for ($i = 0; $i < count($content); $i++){
fwrite($FILE, $content[$i]);
}
} else {
fwrite($FILE, $content);
}
flock($FILE, LOCK_UN);
fclose($FILE);
}
function fileReadAll($file){
$FILE = fopen($file, 'r');
while (!flock($FILE, LOCK_SH)) { usleep(1); }
$content = fread($FILE, filesize($file));
flock($FILE, LOCK_UN);
fclose($FILE);
return $content;
}
Your modified code:
session_start();
$counterName = './views.txt';
if (!file_exists($counterName)) {
$file = fopen($counterName, 'w');
fwrite($file, '0');
fclose($file);
}
$file = fopen($counterName, 'r');
$value = fread($file, filesize($counterName));
fclose($file);
if (! isset($_SESSION['visited'])) {
$_SESSION['visited'] = 'yes';
$value++;
$file = fopen($counterName, 'w');
fwrite($file, $value);
fclose($file);
}
session_unset();
echo $value;
I'm making a unique visitors counter for my website and I went for many tutorials, until I found this easy code but the problem is that the program never adds new ips or counts new visits . The values of ip.txt and count.txt never change :(
Here is the whole code :
<?php
function hit_count() {
$ip_address = $_SERVER ['REMOTE_ADDR'];
$ip_file = file ('ip.txt');
foreach($ip_file as $ip) {
$ip_single = ($ip);
if ($ip_address==$ip_single){
$found = true;
break;
} else {
$found = false;
}
}
if ($found==true){
$filename = 'count.txt';
$handle = fopen ($filename, 'r');
$current = fread($handle, filesize($filename));
fclose($handle);
$current_inc = $current = 1;
$handle = fopen($filename, 'w');
fwrite($handle, $current_inc);
fclose($handle);
$handle = fopen('ip.txt', 'a');
fwrite($handle, $ip_address."\n");
fclose($handle);
}
}
?>
This code is full of mistakes. It will never work.
Mistake number #1:
$ip_file = file('ip.txt');
Each element on $ip_file ends with a newline symbol, so even if your IP is in the list it will never match $_SERVER ['REMOTE_ADDR']. file() must be run with the FILE_IGNORE_NEW_LINES flag.
Mistake number #2:
if ($found==true){
The counter will only increase and try to add the IP in the list if it was already found in the list. If the list is empty it will never do jack. Invert this logic!
Mistake number #3:
$current_inc = $current = 1;
It will never count beyond 1.
Besides that, you must make sure that the PHP script has permission to change those files. Usually the scripts don't have permission to edit the site files for security reasons.
All that said, your script should be changed to something more like this:
if (!in_array($_SERVER['REMOTE_ADDR'], file('ip.txt', FILE_IGNORE_NEW_LINES)))
{
file_put_contents('ip.txt', $_SERVER['REMOTE_ADDR'] . "\n", FILE_APPEND);
$count = file_get_contents('count.txt');
$count++;
file_put_contents('count.txt', $count);
}
Clean, simple, direct. But you still have to make sure the PHP script has permission to edit those files.
here's what I've got so far - i really need to ban any tags from being entered as it's like a guestbook, but this doesn't seem to work:
<?php
$txt = $_POST['txt'];
//the data
$data = "
$txt";
//my attempt to implement a filter
var_dump(filter_var($data,FILTER_SANITIZE_SPECIAL_CHARS));
//open the file and choose the mode
$fh = fopen("users.txt", "a");
fwrite($fh, $data);
//close the file
fclose($fh);
header('Location: http://www.google.com/');
?>
You need to assign the returned value of filter_var
$data = filter_var($data,FILTER_SANITIZE_SPECIAL_CHARS);
filter_var can return FALSE if the filter fails. So, to be complete, you really should do something like:
$filtered_data = filter_var($data,FILTER_SANITIZE_SPECIAL_CHARS);
if($filtered_data !== FALSE) {
//write $filtered_data
} else {
//handle error
}