Download Counter Language Table of Contents
 Japanese [日本語]  
 English [英語]  
 Korean [韓国語]  
 Simplified Chinese [简体中文]  
 Traditional Chinese [繁體中文]  
 Español [スペイン語]  
 Français [フランス語]  
 Português [ポルトガル語]  
  Arabic العربية [アラビア語]  
 Deutsch [ドイツ語]  
 Italiano [イタリア語]  
 Russian [ロシア語]  
 Turkish [トルコ語]  
 Hindi [ヒンディー語]  
 Vietnamese [ベトナム語]  
 Thai [タイ語]  
 Dutch [オランダ語]  
 Indonesian [インドネシア語]  
 Malay [マレー語]  
 Filipino [フィリピン語]  
 Swedish [スウェーデン語]  
 Norwegian [ノルウェー語]  
 Danish [デンマーク語]  
 Finnish [フィンランド語]  
 Polish [ポーランド語]  
 Czech [チェコ語]  
 Hungarian [ハンガリー語]  
 Greek [ギリシャ語]  
 Romanian [ルーマニア語]  

Download Counter
Download History Viewing Program
= Download and Install PHP Code =
Sample Download Counter

Introduction:

This is an introduction to a program that allows you to know the number of downloads when a web page user downloads and uses a program. It is possible to set up a download counter on the page, and site administrators can also easily check the download history on the browser.

[Sample Installed on Page]
Total Downloads: 1865 [Today: 23 Yesterday: 76]
[Sample Opened in Browser]

Note: If a page with a download link displays a message prompting file saving and is closed without initiating the download, it will still be counted as a download. This is because it counts the number of link clicks.

Download Instructions:

From this page, download the compressed "zip" file of the program and install it on your own site. The file is named "count.php", but you can change it.

You are free to use and modify the code, including changing the page design.

Please modify the code to add new functions or change the design to create a page that is easy to understand and use.

 PHP Program Download:
Installation Instructions:

Unzip the downloaded "count.php.zip" file, and a file named "count.php" will be created. Please create a directory such as "download_history" and save it there.

The "zip" file contains only one file, "count.php," and the "login screen" for the administrator is automatically generated.

Settings:

This is the main setting method. These main parts are also listed in the PHP file.

  1. Password Settings:
    1. A password must be set for the administrator page.
    2. The default password is "admin," but change it to any string of your choice.
    3. To enhance security, set a strong password.
  2. Setting Files to Download:
    1. Complete the settings for "$targetFiles = array()".
    2. This is the part such as "'1' => 'Your URL/file name.zip',".
  3. Directory for Saving Log Files:
    1. A directory named "log" is required on the remote server to store log files that record history.
    2. This program automatically creates a directory called "log" when you upload for the first time. However, if you get a message such as "No directory", please create and upload it separately.
  4. First-Time Upload History Display:
    1. When uploading for the first time, the "date" and the number "0" may be displayed in the history.
    2. This is because log files such as "count_1.log" containing the upload date are also generated in the automatically generated "log" directory.
    3. If this bothers you, download a file like "count_1.log" from the remote server, delete the data, and upload it.
    4. However, the "date" and "0" state may also be a history of when the counter was started. If there is a download on that day, it will be counted up.
  5. Administrator Viewing Page Display:
    1. When administrators view the page, you can choose whether to display the URL or only the file name.
    2. If multiple history tables are placed on one page, you can choose to keep them in the order set by "$targetFiles = array()" or sort them in the order of the date when new logs occurred.
  6. Page Design, CSS, etc.:
    1. Please adjust the page design, CSS, etc., as appropriate to make the page easy to read.
    2. At one time, CSS was written as an external file, but now it is written on the same page so that you can refer to the tags when changing CSS.
  7. Download Link Setup on the Page:
    1. Typically, the download <a> tag is written as follows:
      <a href="/download_history/sample.zip" download="File name when downloading.zip">[Arbitrary string]</a>
    2. In this program, write the download <a> tag as follows:
    3. [Example]Copy
      <a href="/download_history/count.php?download=1" download="File name when downloading.zip" target="_blank">[Arbitrary string]</a>
    4. Match the number in "download=1" to the number set in "$targetFiles = array()". This setting refers to the files to be downloaded.
    5. Please match the path to your page.
    6. Please upload the page with the download link after uploading the file with "$targetFiles = array()" (in this example, "count.php").
  8. Code for Displaying History in One Line:
    1. Create the following JavaScript and place it on the page you want to display:
    2. [Example]Copy
      <script type="text/javascript" src="/download_history/count.php?dsp_count=1&day_dsp=on"></script>
    3. Match the number in "dsp_count=1" to the number set in "$targetFiles = array()".
    4. If you delete "&day_dsp=on," only the "total number" will be displayed without the "today/yesterday" display.
    5. Total Downloads: 1865 [Today: 23 Yesterday: 76]
      Total Downloads: 1865
    6. Please match the path to your page.
About Extension Settings

When displaying multiple tables, the program's default setting is to sort by the latest update time. If you want to sort by the total download count, create a new file like "total_downloads.php" and replace the following part.

  1. Change in comments
    Replace the comments in the following section:
    // Choose whether to replace the original array with a new one sorted in the order of the new logs when displaying multiple tables on a page
  2. Copy the replacement comment
    // If displaying multiple tables on the page, choose whether to replace the original array and sort in the order of the total number of downloads.
  3. Code and comment changes
    Replace the code and comments in the following section. Please consider it as one block.
    // Get file paths and their last update dates (sort in descending order of the latest date)
    $filePathsAndDates = array();
    foreach ($filePath as $key => $path) {
        if (file_exists($path)) {
            $filePathsAndDates[$key] = filemtime($path);
        } else {
            // Output this error to the log and decide whether to continue or interrupt the process
            echo "Error: File does not exist - $path<br>";
        }
    }
    
    // Sort in descending order by the last update date (so that newer dates come first)
    arsort($filePathsAndDates);
    
    // Rebuild the array of sorted file paths
    $sortedFilePaths = array();
    foreach ($filePathsAndDates as $key => $date) {
        $sortedFilePaths[$key] = $filePath[$key];
    }
  4. Copy replacement code and comments
    // Array that stores the total number of downloads
    $totalDownloads = array();
    
    // Get the file path and its total number of downloads
    foreach ($filePath as $key => $path) {
         if (file_exists($path)) {
             $line = file($path);
             $total = 0;
    
             // Sum the number of downloads for each row
             foreach ($line as $val) {
                 $valArray = explode(',', $val);
                 $total += trim($valArray[1]);
             }
    
             // Store the total number of downloads in an array
             $totalDownloads[$key] = $total;
         } else {
             // Output this error to the log and decide whether to continue or abort the process
             echo "Error: File does not exist - $path";
         }
    }
    
    // Sort by total number of downloads in descending order
    arsort($totalDownloads);
    
    // Rebuild the sorted array of file paths
    $sortedFilePaths = array();
    foreach ($totalDownloads as $key => $total) {
         $sortedFilePaths[$key] = $filePath[$key];
    }
  5. File creation and setup
    1. When creating multiple pages, to prevent mistakes in setting items while adding content uniformly, create the following part of the code as an external file, and load it into the currently implemented part with a different code. Create an external file with a name like "config.php".
    // Configuration of files to download. If there are multiple files, add them as '2', '3', '4', etc. Also, '0' is valid.
    // Use "http:" or "https:" for the protocol.
    $targetFiles = array(
        '1' => 'YourURL/FileName.zip',
        '2' => 'YourURL/FileName.pdf',
        '3' => 'YourURL/FileName.pdf',
        '4' => 'YourURL/FileName.pdf',
    );
  6. Copy the sample of the part to be named "config.php"
    <!doctype html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>DownloadHistory</title>
    <meta name="robots" content="NOINDEX,NOFOLLOW">
    </head>
    <body>
    <?php
    // Make only this part an external file and load it into the page you use with "include __DIR__ . '/config.php';"
    // Configuration of files to download. If there are multiple files, add them as '2', '3', '4', etc. Also, '0' is valid.
    // Use "http:" or "https:" for the protocol.
    $targetFiles = array(
        '1' => 'YourURL/FileName.zip',
        '2' => 'YourURL/FileName.pdf',
        '3' => 'YourURL/FileName.pdf',
        '4' => 'YourURL/FileName.pdf',
    );
    ?>
    </body>
    </html>
    
  7. Code to load an external file and its placement
    1. Include the file created with a name like "config.php" at the following location with the code "include __DIR__ . '/config.php';".
    2. Comment out or delete the following section and replace it with the code "include __DIR__ . '/config.php';".
    //$targetFiles = array(
    //    '1' => 'YourURL/FileName.zip',
    //    '2' => 'YourURL/FileName.pdf',
    //    '3' => 'YourURL/FileName.pdf',
    //    '4' => 'YourURL/FileName.pdf',
    //);
  8. Copy the code to replace
    include __DIR__ . '/config.php';
* The "font-family" in the program should be adjusted to match your own site if necessary.
《 PHP Code to Create Download Counter 》
Save the file with a ".php" extension.

<?php
//***************************************************************************************************
// Download Counter and Download History Viewer PHP Program
// [Everyone's Knowledge A Little Useful Book]
// [みんなの知識 ちょっと便利帳]
// https://www.benricho.org/Tips/download_history/
// Released: January 22, 2024
//
// Overview:
// This program is a system for tracking the history of file downloads, equipped with user authentication functionality.
// It includes features such as input data sanitization, log file creation, and display of download statistics.
// You are free to use it, including modifying the code and changing the page design.
//
// Note:
// Before uploading the page containing the download links, make sure to configure the "$targetFiles = array()" section of this file,
// and upload this page before the page with the download links.
// Failure to do so may result in users being unable to download when attempting, as this page sets and references the files to be downloaded.
//
// Configuration and Notes:
// ① The password is set to "admin," but please change it to any desired string.
// ② The "log" directory for storing log files is automatically generated upon the first upload.
// However, if you encounter messages such as "directory not found," please upload it separately.
// ③ Upon the initial upload, the history display shows "date" and the number "0."
// This is because log files like "count_1.log" with the upload date are simultaneously generated in the automatically created "log" directory.
// If this is a concern, access the remote server, download files like "count_1.log," delete the data, and then upload.
// ④ When displaying multiple tables on a page in history display, you can choose whether to retain the array set in [$targetFiles = array] or display them in chronological order.
// ⑤ In the history display, you can choose whether to include the domain in 1) displaying the file or 2) showing only the file name.
//
// [Format of the Link on the Page with Download Links]
// [Example] <a href="/download_history/count.php?download=Registered Number" download="DownloadedFileName.zip" target="_blank">[Any String]</a>
// ① Adjust the number in "download=1" to the number set in "$targetFiles = array()".
// ② Adjust the path to match your page.
//
// [Code (JavaScript) for displaying history in one line on the page where the download link is placed]
// [Example] <script type="text/javascript" src="/download_history/count.php?dsp_count=1&day_dsp=on"></script>
// ① Adjust the number in "dsp_count=1" to the number set in "$targetFiles = array()".
// ② If you remove "&day_dsp=on," it will display only the "total" without "today" and "yesterday".
// ③ Adjust the path to match your page.
//***************************************************************************************************

// Configuration of files to download. If there are multiple files, add them as '2', '3', '4', etc. Also, '0' is valid.
// Use "http:" or "https:" for the protocol.
$targetFiles = array(
    '1' => 'YourURL/FileName.zip',
    '2' => 'YourURL/FileName.pdf',
    '3' => 'YourURL/FileName.pdf',
    '4' => 'YourURL/FileName.pdf',
);

// Set character encoding for HTML output
header("Content-Type: text/html; charset=utf-8");

// Character encoding on the page displaying the download history
$encodingType = 'UTF-8';

// Define user authentication information and other settings
$userid = 'admin';   // User ID (replace 'admin' with any string)
$password = 'admin'; // Password (replace 'admin' with any string)
$hashedPassword = password_hash($password, PASSWORD_DEFAULT); // Use password_hash() to generate a hash value
$dataLogDir = 'log/'; // The 'log' directory is automatically generated by this program. If not created, upload a directory named 'log' separately

// Choose whether to include the domain when displaying the file name or not
$includeDomain = 1;  // 1: Display including the domain name, 0: Display only the file name

// Choose whether to replace the original array with a new one sorted in the order of the new logs when displaying multiple tables on a page
$sortTables = 1;  // 1: Sort, 0: Do not sort

$dir = 'log'; // Directory to store log files and download history

// Get the domain of your site
$domain = $_SERVER['HTTP_HOST'];

// Session management: Prevent session hijacking and use session_set_cookie_params()
session_set_cookie_params(0, '/', $domain, true, true); // Set HttpOnly and Secure flags
session_start();
if (!isset($_SESSION['auth'])) {
    $_SESSION['auth'] = FALSE;
}

// Password hashing: Use password_needs_rehash()
if (password_needs_rehash($hashedPassword, PASSWORD_DEFAULT)) {
    $newHashedPassword = password_hash($password, PASSWORD_DEFAULT);
    // Save the new hash value in a database, etc.
}

// Create the directory if it doesn't exist
if (!is_dir($dir)) {
    if (mkdir($dir, 0755, true)) {
    } else {
        // Display if directory creation fails
        echo 'Please create the "' . $dataLogDir . '" directory and upload it separately.';
    }
}

// Check if the log directory is writable
if (!is_writable($dataLogDir)) {
    die('The "' . $dataLogDir . '" directory either does not exist or does not have write permissions. Please create the directory and set the permissions properly (e.g., 755).');
}

// Get the base date and yesterday's date
$baseDay = date("Y/m/d");
$yesterday = date("Y/m/d", strtotime("-1 day"));

// Function to get the day of the week from a date
function getDayOfWeek($date)
{
    $dayOfWeek = date('w', strtotime($date));
    $weekDays = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
    return $weekDays[$dayOfWeek];
}

// Set the file path for each target file and create a log file if it doesn't exist
foreach ($targetFiles as $key => $val) {
    $filePath[$key] = $dataLogDir . "count_" . $key . ".log";

    // Create the log file if it doesn't exist
    if (!file_exists($filePath[$key])) {
        createLogFile($filePath[$key]);
    }
}

// Get file paths and their last update dates (sorted in descending order of date)
$filePathsAndDates = array();
foreach ($filePath as $key => $path) {
    if (file_exists($path)) {
        $filePathsAndDates[$key] = filemtime($path);
    } else {
        // Output this error to the log and decide whether to continue or abort processing
        echo "Error: File does not exist - $path<br>";
    }
}

// Descending sort by the last update date (newest date comes first)
arsort($filePathsAndDates);

// Rebuild the array of sorted file paths
$sortedFilePaths = array();
foreach ($filePathsAndDates as $key => $date) {
    $sortedFilePaths[$key] = $filePath[$key];
}

// Conditionally choose whether to use the sorted paths for sorting
$filePath = ($sortTables) ? $sortedFilePaths : $filePath;

// Return JavaScript code to the client (dynamically displaying download counts)
if (isset($_GET['dsp_count'])) {
    header("Content-type: application/x-javascript");

    // Set the header as a JavaScript file
    if (!preg_match("/^[0-9]+$/", $_GET['dsp_count'])) {
        echo "document.write(\"Parameter must be a half-width number\")";
        exit();
    }

    $dspCountNo = $_GET['dsp_count'];
    if (!file_exists($filePath[$dspCountNo])) {
        createLogFile($filePath[$dspCountNo]);
    }

    $line = file($filePath[$dspCountNo]);
    $total = 0;
    $todayCount = 0;
    $yesterdayCount = 0;

    foreach ($line as $val) {
        $valArray = explode(',', $val);
        $total += trim($valArray[1]);
        if (strpos($valArray[0], $baseDay) !== false) {
            $todayCount = trim($valArray[1]);
        }
        if (strpos($valArray[0], $yesterday) !== false) {
            $yesterdayCount = trim($valArray[1]);
        }
    }

    // If the date display option is ON, display including the date
    if (isset($_GET['day_dsp']) && $_GET['day_dsp'] == 'on') {
        $countDsp = <<<EOF
document.write('<div class="counter_inpage">Total downloads: <strong>{$total}</strong>[<span class="count_today">Today : <strong>{$todayCount}</strong></span>  <span class="count_yesterday">Yesterday : <strong>{$yesterdayCount}</strong></span>]</div>')
EOF;
    } else {
        // If the date display option is OFF, display only the total download count
        $countDsp = <<<EOF
document.write('<p class="counter_inpage">Total downloads: {$total}</p>')
EOF;
    }

    // If the character encoding is not UTF-8, convert
    if ($encodingType != 'UTF-8') $countDsp = mb_convert_encoding($countDsp, "$encodingType", 'UTF-8');
    echo $countDsp;

    exit();
}

// Processing when a file download is requested
if (isset($_GET['download'])) {
    $fileId = $_GET['download'];

    // Exit if the file ID is not a number or if the file ID does not exist
    if (!preg_match("/^[0-9]+$/", $fileId) || !isset($filePath[$fileId])) {
        exit('Incorrect numeric parameter');
    }

    // Open the file and lock it
    $fp = fopen($filePath[$fileId], "rb+");
    if (!$fp) {
        exit('Failed to open the file');
    }

    flock($fp, LOCK_EX);

    // Read the log file and store it in an array
    $line = array();
    while (($data = fgets($fp)) !== false) {
        $line[] = $data;
    }

    // Truncate the file and add a new date line at the beginning
    ftruncate($fp, 0);
    rewind($fp);

    // Add a new date line at the beginning if it doesn't exist
    if (strpos($line[0], $baseDay) === false) {
        $writeLine = $baseDay . ',1' . "\n";
        fwrite($fp, $writeLine);
    }

    // Process each line in the file
    foreach ($line as $val) {
        // Increment the download count for the current date
        if (strpos($val, $baseDay) !== false) {
            $valArray = explode(',', $val);
            $valArray[1] = rtrim($valArray[1], "\n") + 1;
            $val = $valArray[0] . ',' . $valArray[1] . "\n";
        }
        fwrite($fp, $val);
    }

    // Flush the buffer and release the lock
    fflush($fp);
    flock($fp, LOCK_UN);

    // Close the file
    fclose($fp);

    // Clear the output buffer
    ob_end_clean();

    // Perform the file download
    header("Location: {$targetFiles[$fileId]}");
    exit();
} else {
    // Start the session, destroy the session if logout is requested
    session_start();
    if (isset($_GET['logout'])) {
        $_SESSION = array();
        session_destroy();
    }

    $loginError = '';

    if (!isset($_SESSION['auth'])) {
        $_SESSION['auth'] = FALSE;
    }

    // Use the password hash function to generate a hash value
    // Login processing
    if (isset($_POST['userid']) && isset($_POST['password'])) {
        // Compare hash values for authentication
        if ($_POST['userid'] === $userid && password_verify($_POST['password'], $hashedPassword)) {
            $oldSid = session_id();
            session_regenerate_id(TRUE);

            if (version_compare(PHP_VERSION, '5.1.0', '<')) {
                $path = session_save_path() != '' ? session_save_path() : '/tmp';
                $oldSessionFile = $path . '/sess_' . $oldSid;

                if (file_exists($oldSessionFile)) {
                    unlink($oldSessionFile);
                }
            }

            $_SESSION['auth'] = TRUE;
        } else {
            // Processing for authentication failure
            $_SESSION['auth'] = FALSE;
            $loginError = '<div style="text-align: center; color: crimson;">Incorrect user ID or password.</div>';
        }
    }

  // If authentication is not successful, display the login screen
    if ($_SESSION['auth'] !== TRUE) {
        ?>
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="utf-8">
            <meta name="robots" content="NOINDEX,NOFOLLOW">
            <title>Download History Login Screen</title>
            <!-- Login screen styles (modifiable as needed)-->
            <style>
                body {
                    font-family: Arial, sans-serif;
                    background-color: #f4f4f4;
                    margin: 0px;
                    padding: 0px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    height: 100vh;
                }
                form {
                    background-color: #fff;
                    padding: 20px;
                    border-radius: 8px;
                    box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
                }
                label {
                    display: block;
                    margin-bottom: 8px;
                }
                input {
                    font-size: 18px; 
                    width: 100%;
                    padding: 8px;
                    margin-bottom: 16px;
                    box-sizing: border-box;
                }
                button {
                    font-size: 16px;
                    background-color: #4caf50;
                    color: #fff;
                    padding: 10px;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                }
                .logintitle {
                    text-align: center;
                    font-size: 18px;
                    font-weight: bold;
                }
                .logininfo {
                    text-align: center;
                }
                .passwordshow {
                    font-size: 14px;
                    font-weight: bold;
                    color: darkgray;
                    text-align: center;
                }
                .center-container {
                    display: inline-block;
                    margin: 0 5px 0 0;
                }
            </style>
        </head>
        <body>
            <div id="login_form">
                <form action="<?php echo $fileName; ?>?mode=download" method="post">
                    <p class="logintitle">【View Download History】</p>
                    <?php if (isset($loginError)): ?>
                        <!-- Display an error message if the $loginError variable is set -->
                        <p style="color: crimson;"><?php echo $loginError; ?></p>
                    <?php endif; ?>
                    <label for="userid">User ID:</label>
                    <input type="text" id="userid" name="userid" required>
                    <label for="password">Password:</label>
                    <input type="password" id="password" name="password" required>
                    <?php
                        // Assuming $showPassword is a PHP variable determining whether to initially show the password
                        echo '<label class="passwordshow" for="showPassword">[Show Password]<div class="center-container"><input type="checkbox" id="showPassword" onchange="togglePasswordVisibility()" ' . ($showPassword ? 'checked' : '') . '></div></label>';
                    ?>
                    <button type="submit" name="login_submit">Login</button>
                </form>   
            </div>

<!-- Control the visibility of the password -->
<script>
  function togglePasswordVisibility() {
    var passwordInput = document.getElementById('password');
    var showPasswordCheckbox = document.getElementById('showPassword');

    if (showPasswordCheckbox.checked) {
      // If checked, the password will be displayed
      passwordInput.type = 'text';
    } else {
      // Uncheck to hide password
      passwordInput.type = 'password';
    }
  }
</script>
</body>
</html><?php
exit();
} else {
  // If logged in, display the download history page
  ?>
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="robots" content="NOINDEX,NOFOLLOW">
    <title>Download History</title>
    <!-- Download history viewing style (modifiable as needed) -->
    <style>
                 body {
                     font-family: 'Hiragino Kaku Gothic ProN', 'Hiragino Kaku Gothic ProN W3', Meiryo, Osaka, 'MS PGothic', arial, helvetica, sans-serif;
                 }
                 .log_title {
                     font-size: 16px;
                     font-weight: bold;
                     color: brown;
                     margin: 0px 0px 15px 10px;
                 }
                 .get_url {
                     font-size: 13px;
                     font-weight: bold;
                     padding: 8px 0;
                     color: brown;
                     background-color: lightgoldenrodyellow;
                 }
                 .log_table{
                     float:left;
                     width: 300px;
                     border: #CCC 1px solid;
                     border-radius: 5px;
                     margin: 0px 0px 5px 10px;
                     padding: 0px 5px 5px 5px;
                     word-break: break-all;
                 }
                 table {
                     width: 100%;
                     border-collapse: collapse;
                 }
                 td,
                 th {
                     padding: 5px 10px;
                     border: 1px solid #999;
                     text-align: right;
                     font-size: 90%;
                 }
                 th {
                     background: lavenderblush;
                     text-align: center;
                     font-weight: normal;
                 }
                 .tableheader {
                     background: lavender;
                     text-align: center;
                     font-weight: bold;
                     white-space: nowrap;
                 }
                 .total{
                     float:left;
                     margin: -25px 0px 0px 10px;
                 }
                 .counter_inpage{
                     margin: 15px 0px 8px 0px;
                 }
                 .bold{
                     font-weight: bold;
                 }
             </style>
  </head>
  <body>
    <div class="log_title">【Download History】 【<a href="?logout=true">Logout</a>】</div> 
    <?php foreach($filePath as $key => $val){ ?>                      
      <div class="log_table">         
        <div class="get_url"><?php echo $includeDomain ? $targetFiles[$key] : basename($targetFiles[$key]); ?></div>
        <table align="center">
          <tr>
            <th class="tableheader">Date</th>
            <th class="tableheader">Downloads</th>
          </tr>
          <?php	  
            $totalDownload = 0;

            // Read only if the file exists
            if (file_exists($val)) {
              $line = file($val);
              foreach ($line as $lineVal) {
                $lineArray = explode(',', $lineVal);

                // Check if $lineArray[1] is a numeric value
                $numericValue = filter_var($lineArray[1], FILTER_VALIDATE_FLOAT);
                if ($numericValue !== false) {
                  $totalDownload += $numericValue;
                  ?>
                  <tr>
                    <th nowrap><?php echo $lineArray[0] . ' (' . getDayOfWeek($lineArray[0]) . ')'; ?></th>
                    <td class="bold" nowrap><?php echo $lineArray[1]; ?></td>
                  </tr>
                  <?php
                }
              }
            }
          ?>
          <tr>
            <th colspan="2" class="bold">Total Downloads: <?php echo $totalDownload;?></th>
          </tr>
        </table>
      </div>              
    <?php
                }
              }
            }
          ?>
</body>
</html><?php
// Function to sanitize all elements in an array
function sanitize($arr)
{
  // If it's an array, apply sanitization recursively
  if (is_array($arr)) {
    return array_map('sanitize', $arr);
  }
  // Remove NULL characters from within strings
  return str_replace("\0", "", $arr);
}

// Create a new log file if it doesn't exist
function createLogFile($filePath)
{
  $baseDay = date("Y/m/d");
  $fp = fopen($filePath, "a+b");

  if ($fp) {
    flock($fp, LOCK_EX);
    ftruncate($fp, 0);
    rewind($fp);
    fwrite($fp, "$baseDay,0");
    fflush($fp);
    flock($fp, LOCK_UN);
    fclose($fp);

    // Set file permissions
    chmod($filePath, 0666);
  } else {
  }
}
Save the file with a ".php" extension.
This concludes the introduction of the PHP code for the "Download Counter/Download History Viewing Program." We hope you find it useful.

There may be errors in the wording as it is a translation from the Japanese version. We apologize for the inconvenience, but if there is an error in the wording in the code, please correct or adjust it yourself.

Your feedback on using this code is appreciated. Please note that I cannot respond to questions.

おすすめサイト・関連サイト…

Last updated : 2024/06/29