fd = \fopen($file_path, 'a'); if ($this->fd === false) { throw new \RuntimeException("Unable to open log file at $file_path"); } $this->name = $name; $this->level = $level; // In some cases PHP does not run the destructor. \register_shutdown_function([$this, 'close']); } public function __destruct() { $this->close(); } public function log(int $level, string $message): void { if ($level <= $this->level) { $lv = $this->levelToString($level); $line = "{$this->name} $lv: $message\n"; \flock($this->fd, LOCK_EX); \fwrite($this->fd, $line); \flock($this->fd, LOCK_UN); } } public function close() { \flock($this->fd, LOCK_UN); \fclose($this->fd); } }