* @copyright 2019-2021 Vynatu Cyberlabs, Inc. * @license https://opensource.org/licenses/MIT MIT License */ namespace App\Services; class JsonModelStreamWriter { const ARR_OPEN = "["; const ARR_CLOSE = "]"; const OBJ_OPEN = "{"; const OBJ_CLOSE = "}"; const COLON = ":"; const COMMA = ","; /** * The open file resource. * * @var resource */ private $resource; /** * Whether the resource was closed. Prevents redundant is_resource() calls. * * @var bool */ private $is_closed; private $wrote_at_least_once = false; public function __construct(string $filename) { $this->resource = fopen($filename, 'w+'); fwrite($this->resource, self::ARR_OPEN); $this->is_closed = false; } /** * Write an array to the disk without buffering. * * @param array $array The key => value array to stream-write to the disk */ public function writeArray(array $array) { if ($this->is_closed) { return; } $temp_string = ""; if ($this->wrote_at_least_once) { $temp_string .= self::COMMA; } $temp_string .= self::OBJ_OPEN; $wrote_first_key = false; foreach ($array as $key => $value) { $json_key = json_encode((string)$key); // JSON Keys can only be strings. $json_value = $this->getValidJsonValue($value); if ($json_value === null) { continue; } if ($wrote_first_key) { $temp_string .= self::COMMA; } $temp_string .= $json_key . self::COLON . $json_value; $wrote_first_key = true; } if ($wrote_first_key) { $temp_string .= self::OBJ_CLOSE; fwrite($this->resource, $temp_string); $this->wrote_at_least_once = true; } } public function close() { fwrite($this->resource, self::ARR_CLOSE); fclose($this->resource); $this->is_closed = true; } private function getValidJsonValue($value) { if (is_object($value) || is_array($value)) { return null; } return json_encode($value); } }