PHP - Edit a specific line in a txt file - php

I'm programming a visitcounter for my website...
The textfile should look like this:
index.php: 4 views
contact.php: 6
views etc.
Here is my code:
function set_cookie(){
setcookie("counter", "Don't delete this cookie!", time()+600);
}
function count_views(){
$page = basename($_SERVER['PHP_SELF']);
$file = fopen("counter.txt","r+");
$page_found = false;
if (!isset($_COOKIE['counter'])) {
while (!feof($file)) {
$currentline = fgets($file);
if(strpos($currentline, ":")){
$filecounter = explode(":", $currentline);
$pif = $filecounter[0]; $counterstand = $filecounter[1];
if ($pif == $page) {
$counterstand = intval($counterstand);
$counterstand++;
fseek($file, -1);
fwrite($file, $counterstand);
$page_found = true;
set_cookie();
}
}
}
if (!$page_found) { fwrite($file, $page . ": 1\n"); }
fclose($file);
}
}
And now my problem:
Everytime i visit the page he is not able to update the new value. so at the end it looks like this
home.php: 1
index.php: 1
2222
It looks like he takes the 1 from the correct line after the filename, and prints it at the end of the file...
how can I write the new value in the correct line?

this is another method to store your data in textfile which frequently changed.
function count_views(){
$page = basename($_SERVER['PHP_SELF']);
$filename = "counter.txt";
if (!isset($_COOKIE['counter']))
{
$fh = fopen($filename, 'r+');
$content = #fread($fh,filesize($filename));
$arr_content = json_decode($content, true);
if(isset($arr_content[$page]))
{
$arr_content[$page] = $arr_content[$page]+1;
}
else
{
$arr_content[$page] = 1;
}
$content = json_encode($arr_content);
#ftruncate($fh, filesize($filename));
#rewind($fh);
fwrite($fh, $content);
}
}
here we use a array which key is the page and the value is the counter.
and we store it in json_encode format in it.
whenever we want to update a particular page count. read the json written in file decode it in php array and update the count if page exists or assign 1 with new page if page index not exists in array.
then we again encode it in json and store it in textfile.

Related

PHP - How to write a line in text file if line already available in file then count the request

I want to write a PHP code which write a string line in text file if the line already available in text file then count the requests for example
text file contain:
red.apple:1
big.orange:1
green.banana:1
If some one request to add big.orange in file if its already available in file then count as big.orange:2 if not available then write new line big.orange:1
after execution code text file
red.apple:1
big.orange:2
green.banana:1
I've written the following code but not working.
<?PHP
$name = $_GET['fname']
$file = fopen('request.txt', "r+") or die("Unable to open file!");
if ($file) {
while (!feof($file)) {
$entry_array = explode(":",fgets($file));
if ($entry_array[0] == $name) {
$entry_array[1]==$entry_array[1]+1;
fwrite($file, $entry_array[1]);
}
}
fclose($file);
}
else{
fwrite($file, $name.":1"."\n");
fclose($file);
}
?>
Instead of creating your own format which you need to parse manually, you can simply use json.
Below is a suggestion about how it would work. It will add the requested fname value if it doesn't already exist and will also create the file if it doesn't already exists.
$name = $_GET['fname'] ?? null;
if (is_null($name)) {
// The fname query param is missing so we can't really continue
die('Got no name');
}
$file = 'request.json';
if (is_file($file)) {
// The file exists. Load it's content
$content = file_get_contents($file);
// Convert the contents (stringified json) to an array
$data = json_decode($content, true);
} else {
// The file does not extst. Create an empty array we can use
$data = [];
}
// Get the current value if it exists or start with 0
$currentValue = $data[$name] ?? 0;
// Set the new value
$data[$name] = $currentValue + 1;
// Convert the array to a stringified json object
$content = json_encode($data);
// Save the file
file_put_contents($file, $content);
If you still need to use this format (like, this is some exam test or legacy), try the function:
function touchFile($file, $string) {
if (!file_exists($file)) {
if (is_writable(dirname($file))) {
// create file (later)
$fileData = "";
} else {
throw new ErrorException("File '".$file."' doesn't exist and cannot be created");
}
} else $fileData = file_get_contents($file);
if (preg_match("#^".preg_quote($string).":(\d+)\n#m", $fileData, $args)) {
$fileData = str_replace($args[0], $string.":".(intval($args[1])+1)."\n", $fileData);
} else {
$fileData .= $string.":1\n";
}
if (file_put_contents($file, $fileData)) {
return true;
} else {
return false;
}
}

Page Hit Counter - Working but want to limit it to per IP Address

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.

php set lines in a text file to an array value

Im looking to do something like the following
$file = ('file.txt');
$fopen($file);
then read each line from the file individually and set it as a specific array
like so
read $file get $line1 set as $array[0]
read $file get $line2 set as $array[1]
read $file get $line3 set as $array[2]
I would like to use these arrays created from the lines on the text file IN PLAIN TEXT like this:
$urlout = file_get_contents("http://myurl.com/?=$line1");
echo $urlout;
$urlout2 = file_get_contents("http://myurl.com/?=$line2");
echo $urlout2;
$urlout3 = file_get_contents("http://myurl.com/?=$line3");
echo $urlout3;
So if the array were 123.22.11.22 the link would look like this:
$line1 = array[0] (123.22.11.22)
$urlout = file_get_contents("http://myurl.com/?=$line1");
echo $urlout;
and the result would be
Info for 123.22.11.22
more info
some more
Modified answer as per the change indicated by the user :
Reading 2 lines on each loop..
$lines = file("file.txt");
for($i=0 ; $i<count($lines); $i=($i+2) )
{
echo file_get_contents("http://myurl.com/?=".$lines[$i]);
echo file_get_contents("http://myurl.com/?=".$lines[($i + 1)]);
}
Imp Note : A URL can be used as a filename with file_get_contents() function, only if the fopen wrappers have been enabled.
$handle = fopen("file.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
echo file_get_contents("http://myurl.com/?=$line");
}
fclose($handle);
}
The answer was to insert a "\n" separator upon inserting into the text file, then removing it after the first result was called
$lines = file("geo.txt");
for($i=0 ; $i<count($lines); $i=($i+2) )
{
echo file_get_contents("https://test.com/api/GEO.php?info=".$lines[$i]);
$lolz = file_get_contents("https://test.com/api/GEO.php?info=".$lines[($i + 1)]);
$lolz = str_replace(" \n", '', $lolz);
echo "<br>".$lolz;
}

Read data from a text file, edit it and save it in PHP

I want to write a script which reads data from a text file, lets me edit it and then allows me to save the contents to a text file.
I think I can load the file content in a text field to edit the file, though better suggestions are welcome . I want to load 10 lines at a time, edit them and then append them to a single output file
As of now I am just able to read data from the file.
<html>
<body>
<?php
$file = fopen("t.txt", "r");
$i = 0;
while (!feof($file)) {
$line_of_text = fgets($file);
$members = explode('\n', $line_of_text);
var_dump($members);
}
fclose($file);
?>
</body>
</html>
To read in 10 lines at a time, you do the following
$output = '';
$has_content = true;
while ($has_content) {
for ($i = 0; $i < 10; $i++) {
$line = fgets($file);
if (is_null($line)) {
$has_content = false;
break;
}
$processed_line = ...
$output .= $processed_line;
}
}
After closing the readable filehandle, you can write it back to the original file
$fh = fopen("t.txt", "w");
fwrite($fh, $output);
fclose($fh);
You can read entire file a single string using file_get_contents. Also, take a look on related question Read Data From Text File PHP.

File manupulation search and replace csv php

I need a script that is finding and then replacing a sertain line in a CSV like file.
The file looks like this:
18:110327,98414,127500,114185,121701,89379,89385,89382,92223,89388,89366,89362,89372,89369
21:82297,79292,89359,89382,83486,99100
98:110327,98414,127500,114185,121701
24:82297,79292,89359,89382,83486,99100
Now i need to change the line 21.
This is wat i got so far.
The first 2 to 4 digits folowed by : ar a catergory number. Every number after this(followed by a ,) is a id of a page.
I acces te id's i want (i.e. 82297 and so on) from database.
//test 2
$sQry = "SELECT * FROM artikelen WHERE adviesprijs <>''";
$rQuery = mysql_query ($sQry);
if ( $rQuery === false )
{
echo mysql_error ();
exit ;
}
$aResult = array ();
while ( $r = mysql_fetch_assoc ($rQuery) )
{
$aResult[] = $r['artikelid'];
}
$replace_val_dirty = join(",",$aResult);
$replace_val= "21:".$replace_val_dirty;
// file location
$file='../../data/articles/index.lst';
// read the file index.lst
$file1 = file_get_contents($file);
//strip eerde artikel id van index.lst
$file3='../../data/articles/index_grp21.lst';
$file3_contents = file_get_contents($file3);
$file2 = str_replace($file3_contents, $replace_val, $file1);
if (file_exists($file)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
if (file_exists($file3)) {
echo "The file $filename exists";
} else {
echo "The file $filename does not exist";
}
// replace the data
$file_val = $file2;
// write the file
file_put_contents($file, $file_val);
//write index_grp98.lst
file_put_contents($file3, $replace_val);
mail('info#', 'Aanbieding catergorie geupdate', 'Aanbieding catergorie geupdate');
Can anyone point me in the right direction to do this?
Any help would be appreciated.
You need to open the original file and go through each line. When you find the line to be changed, change that line.
As you can not edit the file while you do that, you write a temporary file while doing this, so you copy over line-by-line and in case the line needs a change, you change that line.
When you're done with the whole file, you copy over the temporary file to the original file.
Example Code:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
This part is just setting up the basics: The category, the IDs of the articles and then building the related strings.
Now opening the file to change the line in:
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
The file is locked so that no other process can edit the file while it gets changed. Next to that file, the temporary file is needed, too:
$temp = new SplTempFileObject(4096);
After setting up the two files, let's go over each line in $file and compare if it needs to be replaced:
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
Now the $temporary file contains already the changed line. Take note that I used UNIX type of EOF (End Of Line) character (\n), depending on your concrete file-type this may vary.
So now, the temporary file needs to be copied over to the original file. Let's rewind the file, truncate it and then write all lines again:
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
And finally you need to lift the lock:
$file->flock(LOCK_UN);
And that's it, in $file, the line has been replaced.
Example at once:
$path = 'file';
$category = 21;
$articles = [111182297, 79292, 89359, 89382, 83486, 99100];
$prefix = $category . ':';
$prefixLen = strlen($prefix);
$newLine = $prefix . implode(',', $articles);
$file = new SplFileObject($path, 'r+');
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
$file->flock(LOCK_EX);
$temp = new SplTempFileObject(4096);
foreach ($file as $line) {
$isCategoryLine = substr($line, 0, $prefixLen) === $prefix;
if ($isCategoryLine) {
$line = $newLine;
}
$temp->fwrite($line."\n");
}
$file->seek(0);
$file->ftruncate(0);
foreach ($temp as $line) {
$file->fwrite($line);
}
$file->flock(LOCK_UN);
Should work with PHP 5.2 and above, I use PHP 5.4 array syntax, you can replace [111182297, ...] with array(111182297, ...) in case you're using PHP 5.2 / 5.3.

Categories