src/ExceptionHandler.php
public static function writeLogLine($log_file, $input, $timestamp = null){

		if(is_null(self::$_error_folder)){

			return false;
		}

		// Prevent people from escaping the pre-defined folder
		$log_file = basename($log_file);

		$fp = @fopen(self::$_error_folder . $log_file, 'ab'); // NOSONAR

		if(!$fp){

			return false;
		}

		if(empty($timestamp)){

			$timestamp = time();
		}

		$line = [];
		$line[] = date(\DateTime::ISO8601, $timestamp);

		if($input instanceof \Throwable){

			$message = $input->getMessage();

			if(!($input instanceof BaseException)){

				/**
				 * Remove superfluous whitespace from the message (mostly to
				 * prevent the message from spanning multiple lines, making the
				 * log-file more difficult to analyse).
				 * SP\F\BaseException does this in its constructor; our old
				 * BaseException (and external exceptions) will not, so we do it
				 * here for them...
				 */

				$message = preg_replace('/\s+/', ' ', $message);
			}

			$line[] = BaseException::getShortName(get_class($input));
			$line[] = $message;
			$line[] = $input->getFile();
			$line[] = $input->getLine();

			$line_out = vsprintf('[%s] %s: %s in %s on line %d', $line);
		}
		elseif(is_string($input)){

			$line[] = $input;
			$line_out = vsprintf('[%s] %s', $line);
		}
		else{

			return false;
		}

		// Block until we acquire an exclusive lock

		if(flock($fp, LOCK_EX)){

			fwrite($fp, $line_out . PHP_EOL);

			flock($fp, LOCK_UN);
			fclose($fp);

			return true;
		}
		else{

			return false;
		}
	}
public static function writeLogLine($log_file, $input, $timestamp = null){

		if(is_null(self::$_error_folder)){

			return false;
		}

		// Prevent people from escaping the pre-defined folder
		$log_file = basename($log_file);

		$fp = @fopen(self::$_error_folder . $log_file, 'ab'); // NOSONAR

		if(!$fp){

			return false;
		}

		if(empty($timestamp)){

			$timestamp = time();
		}

		$line = [];
		$line[] = date(\DateTime::ISO8601, $timestamp);

		if($input instanceof \Throwable){

			$message = $input->getMessage();

			if(!($input instanceof BaseException)){

				/**
				 * Remove superfluous whitespace from the message (mostly to
				 * prevent the message from spanning multiple lines, making the
				 * log-file more difficult to analyse).
				 * SP\F\BaseException does this in its constructor; our old
				 * BaseException (and external exceptions) will not, so we do it
				 * here for them...
				 */

				$message = preg_replace('/\s+/', ' ', $message);
			}

			$line[] = BaseException::getShortName(get_class($input));
			$line[] = $message;
			$line[] = $input->getFile();
			$line[] = $input->getLine();

			$line_out = vsprintf('[%s] %s: %s in %s on line %d', $line);
		}
		elseif(is_string($input)){

			$line[] = $input;
			$line_out = vsprintf('[%s] %s', $line);
		}
		else{

			return false;
		}

		// Block until we acquire an exclusive lock

		if(flock($fp, LOCK_EX)){

			fwrite($fp, $line_out . PHP_EOL);

			flock($fp, LOCK_UN);
			fclose($fp);

			return true;
		}
		else{

			return false;
		}
	}
Write a line to a specified log-file in the error folder.

<p>While the output of {@link BaseException::generateExceptionLog()} is
useful for detailed troubleshooting, it is less than ideal when it
comes to providing summaries/overviews of exceptions that have occurred
over a certain period of time.</br>
So, instead of writing a full stack-trace and environment information
this method writes a single line to a log-file providing some basic
details of the {@link $input}.</p>

<p>This function will also accept a simple message string as input.
It will not contain any hints on file and location, but at least you can
log your message to a specific file in the error location.</p>

<p>The format of the log-file generated closely resembles that of PHP's
internal error log. The only difference is the timestamp format for
which I'm unable to find a constant matching the format used by PHP's
error log...</p>

Returns <em>true</em> on success, <em>false</em> on failure.</p>

@param string $log_file
@param string/Throwable $input
@param integer $timestamp
@return bool