PHP实现日志(txt/log)文件写入查找删除


PHP实现txt文件内容的读取,查询,删除操作

【规则】

- 内存表最多保存 **5 条记录**

- 当插入第 6 条记录时,**自动触发** `flush()`

- flush 之后,将数据追加到一个名为 `data.log` 的 **固定文件**

- 文件格式:每行一条记录,格式为 `key:value:timestamp`

- `get()` 方法应当:

  - 先检查内存中的数据

  - 如果内存中未找到,则从文件中读取

<?php

declare(strict_types=1);

namespace PHP\Demo;

class index
{
    /** @var array<string, array{value:string, timestamp:int, deletedAt:int|null}> */
    private $memory = [];
    private $fileName = 'data.log';

    public function __construct()
    {
    }

    public function put(string $key, string $value): void {
        $count = count($this->memory);
        if($count >= 2){
            $this->flush();
        }
        $this->memory[$key] = [
            'value' => $value,
            'timestamp' => time(),
            'deletedAt' => null,
        ];
    }

    public function flush(): void {
        foreach ($this->memory as $key => $record) {
            file_put_contents($this->fileName, "$key:{$record['value']}:{$record['timestamp']}:\n", FILE_APPEND);
        }
        $this->memory = [];
    }

    public function get(string $key) {
        // 首先检查内存中的数据
        if (isset($this->memory[$key])) {
            // 检查是否已被删除
            if ($this->memory[$key]['deletedAt'] !== null) {
                return null; // 已删除的数据返回null
            }
            return $this->memory[$key]['value'];
        }

        $fileName = $this->fileName;
        // 如果文件不存在,返回null
        if (!file_exists($fileName)) {
            return null;
        }

        // 从最新记录开始查找(反向遍历)
        $datas = file($this->fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        for ($line = count($datas)-1;$line >= 0; $line--){
            [$name, $value, $timestamp,$del] = explode(':', $datas[$line], 4); // 限制为3部分以防值中包含冒号
            if($name == $key && !$del){
                return $value;
            }
        }
        return null;
    }
    function del($key)
    {
        $delLine = 0;
        $datas = file($this->fileName, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
        for ($line = count($datas)-1;$line >= 0; $line--){
            [$name, $value, $timestamp, $del] = explode(':', $datas[$line], 4); // 限制为3部分以防值中包含冒号
            if($name == $key && !$del){
                $delLine = $line+1;
                $datas[$line] .= time();
                break;
            }
        }
        file_put_contents($this->fileName, implode("\n", $datas)."\n");
        return $delLine;
    }
}


上一篇

评论

登录后可发表评论