如果使用了外部文本文件,如何从中删除值 PHP

How to remove a value from an external text file if it is used PHP

我只是想知道是否可以从随机选择的外部 .txt 文件中删除值。

// Opens file with key values
$randomkeys = file('keys.txt');

// Takes keys from file and puts it into an array
$random_keys = array_rand($randomkeys, 2);

// Outputs the random key chosen
echo "Your code is: ";
echo $randomkeys[$random_keys[0]];

这是我目前正在使用的代码,它通过读取包含所有键的文件来工作,然后将其放入一个数组中,该数组稍后会显示给使用该网站的用户。

我想补充的是,当用户查看网站时,显示给他们的密钥将从列表中删除,这样其他人就无法获得相同的密钥。

您可以使用 file_get_contents 提取文件中的数据,使用 str_replace 删除该行,使用 file_put_contents 将数据放回原处。正如这个答案中所建议的那样:

How to delete a line from the file with php?

虽然这可能不是最有效的方法,但根据您的应用程序,您最终可能会大量读取和写入磁盘。理想情况下,您会使用像 MySQL 或 SQLite 这样的数据库。

编辑 2016 年 9 月 25 日

下面是一个可能适合您的数据库的简单实现。自 PHP 5.3 起,默认启用 SQLite3。此方法在您需要时生成新代码,而不是预先生成列表。当然,如果您愿意,也可以使用此方法预先生成一个列表。

PHP 文档: http://php.net/manual/en/book.sqlite3.php

您只需要了解几个概念即可:

  • SQLite3::open [创建或打开数据库文件]
  • SQLite3::query [选择]
  • SQLite3::querySingle [选择]
  • SQLite3::exec [用于插入、创建、删除、更新]

注意:我生成 "Code" 的方法不是加密安全的。如果安全是一个大问题,请参阅:PHP: How to generate a random, unique, alphanumeric string?

Setup.php

运行这个文件一次创建你的数据库,你可以删除它

<?php
class MyDB extends SQLite3
{
    function __construct()
    {
        $this->open('mysqlitedb.db');
    }
}

$db = new MyDB();

$db->exec('CREATE TABLE codes (code_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,code varchar(50) NOT NULL)');

$db->close();

CodeManager.php

在您要生成或删除代码的任何位置包含此文件

<?php

class CodeManager extends SQLite3
{
    function __construct()
    {
        // You can change this to the file location of the code list.
        $this->open('mysqlitedb.db');
    }

    function getRandomCode()
    {
        do {
            // If users have a unique identifier, you can use it instead of rand()
            // This should guarrantee a unique value that doesn't have to be checked first.
            // You can also replace md5(...) with any method you prefer to generate the code
            $code = md5(uniqid(rand(), true));

            $code_check = $this->querySingle('SELECT code FROM codes WHERE code="'.$code.'"');

        } while(!is_null($code_check)); // Need this loop as long as we are using rand()

        // Try to add the code to the list of used codes
        if($this->exec('INSERT INTO codes (code) VALUES ("'.$code.'")'))
            return $code;

        return false;
    }

    function deleteCode($to_delete)
    {
        // Try to delete the record
        if($this->exec('DELETE FROM codes WHERE code="'.$to_delete.'"'))
                return true;

        // If we couldn't delete the record
        return false;
    }

    function getAllCodes()
    {
        $all_codes = array();
        $results = $this->query("SELECT * FROM codes");

        while ($row = $results->fetchArray()) {
                $all_codes[] = $row['code'];
        }

        return $all_codes;
    }
}

App.php

如何使用示例CodeManager.php

<?php

include('CodeManager.php');

$cm = new CodeManager();

// Get a single new code
$new_code = $cm->getRandomCode();
echo $new_code."\r\n";

// Get a list of all codes generated so far
$all = $cm->getAllCodes();

// Display them one by one
foreach($all as $single){
    echo $single . "\r\n";
}

?>

最好的解决方案是使用 RDBMS。

但是如果您坚持使用 .txt 文件来解决:

unset($randomkeys[$random_keys[0]]);
array_values($randomkeys);
file_put_contents('keys.txt', implode("\n", $randomkeys));

但请记住,在异步访问的情况下,它可以保留使用过的密钥(因为并行写入)——因此最好使用 DB。

或者只是有另一个文件:used_keys.txt 并将使用过的密钥附加到底部。

所以解决方案:

$keys = file('keys.txt'); // reads keys file
$used_keys = file('used_keys.txt'); // reads used keys file
$keys = array_values(array_diff($keys, $used_keys)); // returns array of unused keys
$key = $keys[mt_rand(0, sizeof($keys)-1)]; // picks random key

// outputs random key
echo "Your code is: ";
echo $key;

// appends used random key to the end of used keys file
file_put_contents('used_keys.txt', $key, FILE_APPEND);