Alin
Alin

Reputation: 1228

Store clicks inside .txt/.php file on the server

I know that most of you will say that saving clicks inside a .txt or .php file is slower than in a DB, and I agree, but I require this...

I already have a script that stores the clicks of a single form inside a .txt file. The thing is that I need to use that script for multiple forms and store the clicks in the same .txt (or .php) file and echo the number of clicks on each button. That's what I can't achieve.

If you have a solution for my issue and want to post an answer, please add some explanation so that I can understand why/how you did it so that I won't come asking the same questions all over again. Thanks

Here is what I have so far :

HMTL:

<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
    <input type="submit" value="click me!" name="clicks">
</form>
<div>Click Count: <?php echo getClickCount(); ?></div>

PHP:

if( isset($_POST['clicks']) ) { 
    incrementClickCount();
}

function getClickCount()
{
    return (int)file_get_contents("clickit.txt");
}

function incrementClickCount()
{
    $count = getClickCount() + 1;
    file_put_contents("clickit.txt", $count);
}

Update I am willing to use json for this (as I understand it can be done) but you will have to bear with me cause I never used json before and even if it's easy to read/write, first time is first time...

Upvotes: 0

Views: 471

Answers (2)

Ryan Vincent
Ryan Vincent

Reputation: 4513

Store 'click counts' from individual 'html forms' in a text file. It is tested.

Added an example of Counting Clicks using a form with Multiple Buttons.

It uses the text file to store a PHP array in JSON format

Working Website here

An overview:

/*
 *
 * We need to store the form 'click' counts in an array:
 * i.e.
 *   array( 'form1' =>  click count for Form1,
 *          'form2' =>  click count for form2
 *          ...
 *        );
 *
 * We need a 'key' to identify the 'current' form that we are counting the clicks of.
 *   I propose that it is based on the 'url' that caused the form to be actioned.
 *
 * The idea is to create an array of 'click counts' and 'serialize' it to and from a file.
 *
 * Performance may be an issue for large numbers of forms.   
 *  
 */

I created a class that 'looks after' the text file.

ClickCount.php:

<?php

/**
 * All the code to maintain the 'Form Click Counts' in a text file...
 *
 * The text file is really an 'array' that is keyed on a 'Text String'.
 *
 * The filename format will work on 'windows' and 'unix'.
 *
 * It is designed to work reliably rather than be 'cheap to run'.
 *
 * @author rfv
 */

class ClickCount {

    const CLICK_COUNT_FILE = 'FormClickCounts.txt';

    protected $clickCounts = array();


    public function __construct()
    {
        $this->loadFile();
    }


    /**
     * increment the click count for the formId
     *
     * @param string $textId - gets converted to a 'ButtonId'
     */
    public function incClickCount($textId)
    {
        $clickId = $this->TextIdlToClickId($textId);

        if (isset($this->clickCounts[$clickId])) {
            $this->clickCounts[$clickId]['click']++;
        }
        else {
            $this->clickCounts[$clickId]['textId'] = $textId;
            $this->clickCounts[$clickId]['click'] = 1;
        }

        $this->saveFile();
    }

    /**
     * Return the number of 'clicks' for a particular form.
     *
     * @param type $clickId
     * @return int clickCounts
     */
    public function getClickCount($textId)
    {
        $clickId = $this->TextIdlToClickId($textId);

        if (isset($this->clickCounts[$clickId])) {
            return $this->clickCounts[$clickId]['click'];
        }
        else {
            return 0;
        }
    }

    /**
     *
     * @return array the 'click counts' array
     */
    public function getAllClickCounts()
    {
        return $this->clickCounts;
    }

    /**
     * The file holds a PHP array stored in JSON format
     */
    public function loadFile()
    {
        $filePath = __DIR__ .'/'. self::CLICK_COUNT_FILE;
        if (!file_exists($filePath)) {
            touch($filePath);
            $this->saveFile();
        }

        $this->clickCounts = json_decode(file_get_contents($filePath), true);
    }

    /**
     * save a PHP array, in JSON format, in a file
     */
    public function saveFile()
    {
        $filePath = __DIR__ .'/'. self::CLICK_COUNT_FILE;
        file_put_contents($filePath, json_encode($this->clickCounts));
    }

    /**
     * 'normalise' a 'form action' to a string that can be used as an array key
     * @param type $textId
     * @return string
     */
    public function TextIdlToClickId($textId)
    {
        return bin2hex(crc32($textId));
    }
}

The 'index.php' file that runs this...

<?php // https://stackoverflow.com/questions/28912960/store-clicks-inside-txt-php-file-on-the-server

include __DIR__ .'/ClickCount.php';

/*
 * This is, to be generous, 'proof of concept' of:
 *
 *   1) Storing click counts for individual forms in a text file
 *   2) Easily processing the data later
 */

/*
 *
 * We need to store the form 'click' counts in an array:
 * i.e.
 *   array( 'form1' =>  click count for Form1,
 *          'form2' =>  click count for form2
 *          ...
 *        );
 *
 * o We need a 'key' to identify the 'current' form that we are counting the clicks of.
 *   I propose that it is based on the 'url' that caused the form to be actioned.
 *
 * The rest i will make up as i go along...
 */

?>
<!DOCTYPE html>
<head>
    <title>store-clicks-inside-txt-php-file-on-the-server</title>
</head>
<body>
    <h2>select form...</h2>

    <p><a href="/form1.php">Form 1</a></p>
    <p><a href="/form2.php">Form 2</a></p>

    <h2>Current Counts</h2>
    <pre>
    <?php $theCounts = new ClickCount(); ?>
    <?php print_r($theCounts->getAllClickCounts()); ?>
    </pre>
</body>

The two form files that 'clicks' are counted...

Form 1

<?php
include __DIR__ .'/ClickCount.php';

// change this for your system...
define ('HOME', '/index.php');

// this looks after the 'click counts' text file
$clickCounts = new ClickCount();

if (isset($_POST['cancel'])) {
    header("location: ". HOME);
    exit;
}

// increment the count for the current form
if (isset($_POST['clicks'])) {
    $clickCounts->incClickCount($_SERVER['PHP_SELF']);
}

?>
<h2>Form 1</h2>
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
    <input type="submit" value="click me!" name="clicks">
    <input type="submit" value="cancel" name="cancel">
</form>
<div>Click Count: <?php echo $clickCounts->getClickCount($_SERVER['PHP_SELF']); ?></div>

Form with Multiple Button:

<?php
include __DIR__ .'/ClickCount.php';

// change this for your system...
define ('HOME', '/clickcount/index.php');

// this looks after the 'click counts' text file
$clickCounts = new ClickCount();

if (isset($_POST['cancel'])) {
    header("location: ". HOME);
    exit;
}

// increment the count for the current form
if (isset($_POST['clicks'])) {
    $clickCounts->incClickCount($_POST['clicks']);
}

?>
<h2>Multiple Buttons on the Form - Count the Clicks</h2>
<form action="<?php $_SERVER['PHP_SELF']; ?>" method="post">
    <br /><label for="clicks1">1) Click Me</label><input type="submit" value="click me - 1!" id="clicks1" name="clicks">
    <br /><label for="clicks1">2) Click Me</label><input type="submit" value="click me - 2!" id="clicks2" name="clicks">
    <br /><label for="clicks1">3) Click Me</label><input type="submit" value="click me - 3!" id="clicks3" name="clicks">
    <br /><label for="clicks1">4) Click Me</label><input type="submit" value="click me - 4!" id="clicks4" name="clicks">
    <br /><br /><input type="submit" value="cancel" name="cancel">
</form>
<div>Click Counts:
       <?php foreach ($clickCounts->getAllClickCounts() as $counts): ?>
           <?php if (strpos($counts['url'], 'click me -') !== false): ?>
             <?php echo '<br />Counts for: ', $counts['url'], ' are: ', $counts['click']; ?>
           <?php endif ?>
       <?php endforeach ?>
</div>

Upvotes: 2

Umair Hamid
Umair Hamid

Reputation: 3557

Check this method (Not tested).

$my_file = 'clickit.txt';
//Read the file
$handle = file_get_contents($my_file);
//Add click
$data = $handle+1;
//Write the file
file_put_contents($my_file,$data);

Upvotes: 0

Related Questions