Luminova Framework

PHP Luminova: File Stream

Last updated: 2026-03-26 20:54:59

A lightweight wrapper for PHP file streams that provides safe, object-oriented access to reading, writing, and stream operations.

The File Stream class provides a simple and controlled way to work with file resources in PHP using a stream-based approach.

It wraps a native PHP stream resource and exposes common file operations (such as reading, writing, seeking, and metadata access) through a consistent object-oriented interface. Instead of calling low-level f* functions directly, you interact with the stream safely through the class.

Dynamic method calls are supported via __call(), allowing selected PHP stream functions (like fread, fwrite, and stream_get_contents) to be invoked directly on the instance. A built-in whitelist ensures only safe and expected functions can be executed.

This design helps reduce boilerplate, enforce safer usage, and keep file handling predictable, especially in larger applications.

For HTTP Message Stream see documentation.


Examples

Create Stream

Opens immediately:

$stream = new Stream('/var/data/report.csv', 'rb');
$data = $stream->read();
$stream->close();

Deferred open (attach context first):

$ctx = stream_context_create(['http' => ['method' => 'GET']]);

$stream = new Stream('http://example.com/file', 'rb', autoOpen: false);
$stream->setContext($ctx)->open();

From Resource

Wrap an existing handle. The stream will not close it.

$fp = fopen('/tmp/shared.log', 'a+b');
$stream = Stream::fromResource($fp);

$stream->lock(LOCK_EX);
$stream->write("entry\n");
$stream->unlock();

fclose($fp);

Reopen Stream

Switch mode without a new instance:

$stream = new Stream('/var/log/app.log', 'c+b');
$stream->close();

$stream->open('rb');
echo $stream->read();
$stream->close();

Inspection

State and Capability

Always check before I/O:

if (!$stream->isOpen()) {
    throw new RuntimeException('Stream is closed.');
}

if ($stream->isSeekable()) {
    $stream->seek(0, SEEK_END);
    $size = $stream->tell();
    $stream->rewind();
}

Permissions

Based on open mode:

if (!$stream->isReadable()) {
    throw new LogicException('Read not allowed.');
}

if (!$stream->isWritable()) {
    throw new LogicException('Write not allowed.');
}

Metadata

$size = $stream->size();

$type = $stream->metadata('stream_type');

Pointer

$pos = $stream->tell();

$stream->seek(-256, SEEK_END);
$tail = $stream->read(256);

Reading

$stream->lock(LOCK_SH);
$stream->rewind();
$content = $stream->read();
$stream->unlock();

Line-by-line:

$stream->rewind();
while (!$stream->eof()) {
    $line = $stream->readLine();
    if ($line === '') break;
}

Decoding

echo $stream->toString();

$arr = $stream->toArray();
$obj = $stream->toObject();

if ($stream->isJsonString()) {
    // valid JSON
}

Writing

Append safely:

$stream->lock(LOCK_EX);
$stream->seek(0, SEEK_END);
$stream->write("new entry\n");
$stream->flush();
$stream->unlock();

Write at offset:

$stream->writeAt('PATCHED', offset: 16);

Overwrite and Replace

$stream->overwrite(json_encode($config, JSON_PRETTY_PRINT));
$stream->replace('level=debug', 'level=info');

Truncate

$stream->lock(LOCK_EX);
try {
    $stream->truncate(0);
    $stream->write($data);
    $stream->flush();
} finally {
    $stream->unlock();
}

Locking

Blocking:

$stream->lock(LOCK_EX);
try {
    $stream->write($data);
    $stream->flush();
} finally {
    $stream->unlock();
}

Non-blocking:

$wouldBlock = 0;

try {
    $stream->lock(LOCK_SH | LOCK_NB, 1, 0, $wouldBlock);
} catch (RuntimeException $e) {
    if ($wouldBlock) {
        echo 'Locked by another process.';
    }
}

Try lock:

if (!$stream->tryLock(LOCK_EX)) {
    return;
}
$stream->write($data);
$stream->unlock();

Utilities

Copy

$source->rewind();
$source->copy($dest, length: 4096);

Checksum

$hash = $stream->checksum('sha256');
$fast = $stream->checksum('xxh3', true);

Filtering

$stream->contains('hello');
$result = $stream->search('hello');

Class Definition

  • Class namespace: Luminova\Storage\Stream
  • This class implements: Stringable

Properties

resource

The underlying file resource handle, or null when closed.

protected ?resource $resource = null;

context

Optional stream context resource created via stream_context_create(), to be use when opening stream.

protected ?resource $context = null

isReadonly

Object-level read-only mode.

protected bool $isReadonly = false

isReadonlyImmutable

Immutable read-only mode.

protected bool $isReadonlyImmutable = false;

isOwnsHandler

Whether this instance owns (and is therefore responsible for closing) the handle.

protected bool $isOwnsHandler = true;

False when the handle was injected via Stream::fromResource().


allowedDynamicFunctions

Whitelist of allowed dynamic stream functions.

This controls which PHP functions can be called via __call() on the underlying stream resource.

protected ?array<int,string-callable> $allowedDynamicFunctions = [
    'fread', 'fwrite', 'fseek', 'ftell', 'fstat',
    'rewind', 'feof', 'fgetc', 'fgets', 'fflush',
    'ftruncate', 'stream_get_contents'
];

Usage:

  • null → use default allowed functions (safe defaults, e.g., fread, fwrite, etc.)
  • [] → deny all dynamic function calls.
  • [...] → explicitly allow only the listed functions.

allowedResourceType

Expected resource type (default: stream).

protected string $allowedResourceType = 'stream';

filename

The stream filename.

protected string $filename = '';

mode

The stream open file mode.

protected string $mode = 'c+b';

autoOpen

Auto open stream.

If set to true, stream will attempt to open once object is created.

protected bool $autoOpen = true;

Methods

constructor

Creates a new Stream instance and, optionally, opens the underlying file immediately.

Set $autoOpen to false and call setContext() before open() when a custom streamcontext is required, because the context is passed to fopen() at open time.

public __construct(string $filename, string $mode = 'c+b', bool $autoOpen = true): mixed

Parameters:

ParameterTypeDescription
$filenamestringThe filename or stream URI (e.g. php://temp, compress.zlib://file.gz).
$modestringThe fopen-compatible mode string (default: c+b).
$autoOpenboolWhen true (default) the file is opened in the constructor.
Pass false to defer opening until open() is called explicitly.

Throws:


from

Create a stream instance from a resource, filename, or raw string content.

This method detects the type of the given source and delegates creation:

  • resource → wraps the existing stream
  • string (filename) → opens a file stream using the given mode
  • string (non-file) → creates an in-memory stream from content
public static from(mixed $source, string $mode = 'wb+', bool $readonly = false): static

Parameters:

ParameterTypeDescription
$sourcemixedStream resource, file path, or raw string content.
$modestringFile open mode (used only when source is a file path).
$readonlyboolWeather to mark stream as read-only object (default: false).

Return Value:

static - Return new instance of stream class.

Throws:


fromResource

Wraps an already-open stream resource in a Stream instance without taking ownership.

The returned instance will never call fclose() on the resource; lifetimemanagement stays with the caller.

public static fromResource(resource $resource, string $filename = '', bool $readonly = false): self

Parameters:

ParameterTypeDescription
$resourceresourceA valid, open stream resource.
$filenamestringOptional filename to associate with the resource
(used for error messages only; does not affect I/O).
$readonlyboolWeather to mark stream as read-only object (default: false).

Return Value:

self - A new Stream instance wrapping the supplied resource.

Throws:


fromString

Create a read-write Stream from a plain string.

The string is written into a php://temp stream opened with the given mode, the pointer is rewound to position 0, and the stream is returned ready for both reading and writing.

public static fromString(string $content, string $mode = 'wb+', bool $readonly = false): static

Parameters:

ParameterTypeDescription
$contentstringThe raw string content to seed the stream with.
$modestringThe fopen() mode used to open the stream (default: 'wb+').
$readonlyboolWeather to mark stream as read-only object (default: false).

Return Value:

static - A new Stream instance containing the given content.

Throws:


setBlocking

Set whether the stream operates in blocking mode.

public setBlocking(bool $blocking): bool

Parameters:

ParameterTypeDescription
$blockingboolTrue for blocking, false for non-blocking.

Return Value:

bool - True on success, false on failure.

Throws:


setReadOnly

Mark the stream as read-only or writable.

When set to read-only, all write operations (write, truncate, etc.) will be blocked at the API level.

If $immutable is true, the stream becomes permanently read-only and cannot be changed back to writable.

public setReadOnly(bool $readonly, bool $immutable = false): self

Parameters:

ParameterTypeDescription
$readonlyboolTrue to make the stream read-only.
$immutableboolTrue to enforce permanent read-only mode.

Return Value:

self - Return instance of stream class.


setTimeout

Set the read/write timeout for the stream.

public setTimeout(int $seconds, int $microseconds = 0): bool

Parameters:

ParameterTypeDescription
$secondsintTimeout seconds.
$microsecondsintTimeout microseconds.

Return Value:

bool - True on success, false on failure.

Throws:


setContext

Attaches a stream context to be used the next time open() is called.

Must be called before open() (or before construction when $autoOpen is true).Setting the context after the stream is already open has no effect on the current handle.

public setContext(resource $context): self

Parameters:

ParameterTypeDescription
$contextresourceA context resource created by stream_context_create().

Return Value:

self - Return instance of stream class.

Throws:


setResource

Set the underlying stream resource for the wrapper.

This replaces the current stream resource with a new one.

The provided resource must be a valid PHP stream (get_resource_type() === 'stream').If a previous resource exists, it will be closed first.

public setResource(mixed $resource, string $filename = ''): self

Parameters:

ParameterTypeDescription
$resourcemixedA valid PHP stream resource to wrap.
$filenamestringOptional filename for the stream.

Return Value:

self - Returns the current instance for chaining.

Throws:

Note:After setting, the wrapper does not “own” the resource,meaning it will not close it automatically unless explicitly told.


setAllowedResourceType

Set the allowed stream resource type for this instance.

This defines the expected resource type for any stream assigned to this wrapper. Only valid PHP stream types are accepted.

public setAllowedResourceType(string $expected): self

Parameters:

ParameterTypeDescription
$expectedstringThe expected resource type (e.g., stream).

Return Value:

self - Returns instance stream class.

Throws:


getType

Returns the PHP resource type string of the underlying handle, or null if closed.

For a normal file or pipe this returns stream.

public getType(): ?string

Return Value:

string|null - Resource type string, or null when the handle is closed.

Use isOpen() to check whether the stream is usable.


getId

Get the internal resource identifier.

Returns the unique ID assigned by PHP to the underlying stream resource,or null if the stream is not initialized.

public getId(): ?int

Return Value:

int|null - Resource ID or null if no resource is available.


getResource

Returns the underlying stream resource.

public getResource(): ?resource

Return Value:

resource|null - Returns the stream resource, or null if closed.


isOpen

Returns true when the underlying file handle is open and valid.

public isOpen(): bool

Return Value:

bool - Return true if stream is open, otherwise false.


isType

Check if the stream resource matches a specific type.

Compares the actual type of the underlying stream resource with thegiven type string.

public isType(string $type): bool

Parameters:

ParameterTypeDescription
$typestringThe expected resource type (e.g., stream, file).

Return Value:

bool - Return true if the resource type matches, false otherwise.


isReadOnly

Check whether the stream is read-only.

Returns true if the stream is marked as read-only, meaning write operations(such as write, truncate, or overwrite) are not allowed.

public isReadOnly(): bool

Return Value:

bool - True if the stream is read-only, false otherwise.


isSeekable

Returns true when the stream supports random-access seeking.

Non-seekable streams (network sockets, pipes, php://stdin) return false.Calling seek() on a non-seekable stream returns -1 without throwing.

public isSeekable(): bool

Return Value:

bool - true if the stream is seekable, false if it is not orif the stream has been detached.


isReadable

Returns true when the stream mode allows reading.

Detection is based on the mode string: any mode containing r or + isconsidered readable.

Modes like: w, a, x, and c (without +) arewrite-only and return false.

public isReadable(): bool

Return Value:

bool - true if the stream is readable, false otherwise.


isWritable

Returns true when the stream mode allows writing.

Any mode other than plain r (without +) is considered writable. Thisincludes r+, w, w+, a, a+, x, x+, c, c+, and theirbinary (b) variants.

public isWritable(): bool

Return Value:

bool - true if the stream is writable, false otherwise.


isLocked

Returns true when another process (or a non-cooperative thread) currentlyholds an exclusive lock on the stream file.

The check uses a non-blocking LOCK_EX attempt. If the lock is successfullyacquired it is immediately released and false is returned (not locked byothers). If the attempt fails, another holder exists and true is returned.

Note: flock() is per-process on Linux. If this process already holds thelock, the probe will succeed (re-entrant), so isLocked() will return falseeven though the file is locked it only detects external locks.

public isLocked(): bool

Return Value:

bool - True if an external lock is detected, false otherwise.


isJsonString

Check whether the entire stream content is valid JSON.

If the stream is seekable, rewinds to the beginning before validating.Returns false for empty streams, unreadable resources, or invalid JSON.

public isJsonString(int $depth = 512): bool

Parameters:

ParameterTypeDescription
$depthintMaximum nesting depth of the structure being decoded (default: 512).

Return Value:

bool - Return true if the stream contains valid JSON, false otherwise.


isFile

Determine whether a string represents an existing filesystem path.

protected isFile(string $input, bool $throw): bool

Parameters:

ParameterTypeDescription
$inputstringThe filename to evaluate.
$throwboolWeather to throw exception if failed.

Return Value:

bool - Return true if the input resolves to an existing file =, otherwise false.

Throws:\Luminova\Exceptions\RuntimeException - If failed and $throw is true.


isUrl

Check if fopen target is a valid URL.

Checks for scheme: (http, https, ftp or stream_get_wrappers).And also consider if allow_url_fopen is disabled or not.

protected isUrl(string $path, bool $throw): bool

Parameters:

ParameterTypeDescription
$pathstring
$throwboolWeather to throw exception if failed.

Return Value:

bool - True if valid URL, false otherwise.

Throws:\Luminova\Exceptions\RuntimeException - If failed and $throw is true.


isFopenLike

Loosely detect if a string could be a valid fopen target.

Matches:

  • Local paths (absolute or relative)
  • Filenames with extensions
  • URLs (http, https, ftp)
protected isFopenLike(string $target): bool

Parameters:

ParameterTypeDescription
$targetstringThe target fopen filename.

Return Value:

bool - Return true if valid, otherwise false.


open

Opens (or re-opens) the stream using the configured path and mode.

If the stream is already open, close() is called first to preventhandle leaks before the new handle is created.

public open(?string $mode = null): bool

Parameters:

ParameterTypeDescription
$modestring|nullThe fopen() mode override. When null the mode passed
to the constructor (default c+b) is used.

Return Value:

bool - Returns true on success (the handle is a valid stream resource).

Throws:


close

Closes the stream and releases the file handle.

Only closes the handle when this instance owns it (i.e. not injected viafromResource()). After close(), all I/O methods will throw a RuntimeExceptionuntil open() is called again.

public close(): void

detach

Detach the underlying PHP resource from this stream object.

Once detached the stream is in an unusable state (equivalent to a closed stream), but the caller receives the raw resource and takes full responsibility for closing it.

public detach(): ?resource

Return Value:

resource|null - The detached resource, or null if the stream has already been detached or closed.


metadata

Retrieves stream metadata, optionally filtered to a single key.

Common keys:

  • seekable, mode, uri, eof
  • wrapper_type, stream_type
  • timed_out, blocked, unread_bytes
public metadata(?string $key = null): mixed

Parameters:

ParameterTypeDescription
$keystring|nullMetadata key to retrieve. Pass null to get the full array.

Return Value:

  • array - Return full metadata array when $key is null, empty array if handle is closed.
  • scalar - Return value for a specific key or null if the key does not exist or the handle is closed;

stat

Returns low-level file statistics for the open stream.

Possible Keys:

'dev', 'ino', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'size', 'atime','mtime', 'ctime', 'blksize', 'blocks'.

public stat(): array<string,int>

Return Value:

array<string,int> - Associative fstat array, or empty array on failure.


size

Calculate the byte size of the stream contents.

public size(): int

Return Value:

int - Return the file size in bytes, or -1 if unavailable.


seek

Moves the file pointer to the given byte offset.

Returns 0 on success, -1 on failure or when the stream is not seekable(matching fseek() semantics).

public seek(int $offset, int $whence = SEEK_SET): void

Parameters:

ParameterTypeDescription
$offsetintByte position to seek to.
Use negative values with SEEK_END to seek from the end of the file.
$whenceintOne of the SEEK_* constants (default: SEEK_SET).
- SEEK_SET — absolute position from the start.
- SEEK_CUR — offset relative to the current position.
- SEEK_END — offset relative to the end of the stream.

Throws:


tell

Returns the current byte offset of the file pointer.

public tell(): int

Return Value:

int - Current position in bytes.

Throws:


rewind

Rewinds the file pointer to the beginning of the stream (offset 0).

public rewind(): void

Throws:


eof

Returns true when the file pointer is at the end of the stream.

public eof(): bool

Return Value:

bool - Return true if EOF or no resource, otherwise false.


lock

Acquire an advisory file lock with optional retry support.

This method attempts to acquire a shared (read) or exclusive (write) lockon the underlying stream resource using flock().

By default, the call blocks until the lock is acquired.

When LOCK_NB is included in $flags, the call becomes non-blocking and will fail immediatelyif the lock cannot be obtained.

Retry logic applies only to blocking mode. When enabled, the method willretry acquiring the lock up to the specified number of attempts, with anoptional delay between attempts.

public lock(
    int $flags,
    int $retries = 1,
    int $delay = 0,
    ?int &$wouldBlock = null
): bool

Parameters:

ParameterTypeDescription
$flagsintThe lock options:
- LOCK_SH: Shared/read lock
- LOCK_EX: Exclusive/write lock
- LOCK_NB: Optional; enables non-blocking mode
$retriesintNumber of retry attempts in blocking mode (default: 1).
$delayintDelay in microseconds between retries (default: 0).
&$wouldBlockint|nullSet by flock() in non-blocking mode if the lock would block.

Return Value:

bool - True if the lock was acquired, false otherwise

Throws:

See Also:

  • tryLock() - For a dedicated non-throwable lock method.

unlock

Releases any advisory lock held on the stream.

Equivalent to flock($handle, LOCK_UN). Safe to call when no lock is held.

public unlock(): bool

Return Value:

bool - Return true on success, false on failure.


read

Reads from the stream.

When $length is -1 (the default) the entire remaining content from thecurrent pointer position to EOF is returned using stream_get_contents().When $length is positive, exactly $length bytes are read using fread().

public read(int $length = -1): string

Parameters:

ParameterTypeDescription
$lengthintNumber of bytes to read, or -1 to read until EOF.

Return Value:

string - The data read from the stream.

Throws:


readLine

Reads one line from the stream (up to and including the newline character).

Returns an empty string at EOF. When $length is provided,reading stops after $length - 1 bytes even if no newline was encountered,matching fgets() semantics.

public readLine(?int $length = null): string

Parameters:

ParameterTypeDescription
$lengthint|nullMaximum number of bytes to read (including the newline).
Pass null to use PHP's internal default buffer.

Return Value:

string - The line read, including the trailing newline if present, or an empty string at EOF.

Throws:


write

Writes data to the stream at the current (or specified) byte offset.

When $offset is non-zero the pointer is first moved to that position viaseek() before writing.

public write(string $data): int

Parameters:

ParameterTypeDescription
$datastringThe data to write.

Return Value:

int - Number of bytes written.

Throws:

Note:

The seek() is a no-op on non-seekable streams and $offset is silently ignored in that case. The method does NOT acquire a lock, callers should lock/unlock around write operations as needed.


writeAt

Writes data to the stream at the current (or specified) byte offset.

When $offset is non-zero the pointer is first moved to that position via seek() before writing.

public writeAt(string $data, int $offset): int

Parameters:

ParameterTypeDescription
$datastringThe data to write.
$offsetintByte offset to seek to before writing. 0 (default) writes
at the current pointer position without seeking.

Return Value:

int - Number of bytes written.

Throws:


overwrite

Overwrites the entire stream content with $data.

This method acquires an exclusive lock, rewinds, truncates to zero, writes $data,flushes, and releases the lock, all internally.

This is the safe, idiomatic way to replace a file's contents in one call.

public overwrite(string $data): int

Parameters:

ParameterTypeDescription
$datastringThe new content to write.

Return Value:

int - Number of bytes written.

Throws:


replace

Performs a search and replace on the entire stream content.

Reads the file under a shared lock, applies str_replace(), and writes theresult back via overwrite() (which acquires an exclusive lock internally).

public replace(array|string $search, array|string $replace): int

Parameters:

ParameterTypeDescription
$searcharray|stringThe value(s) to search for.
$replacearray|stringThe replacement value(s).

Return Value:

int - Number of bytes written after replacement.

Throws:


contains

Check if the stream contains the given string.

public contains(string $needle, bool $rewind = true): bool

Parameters:

ParameterTypeDescription
$needlestringThe string to search for.
$rewindboolWhether to rewind before searching (default: true).

Return Value:

bool - True if found, false otherwise.


Search for occurrences of a string in the stream.

public search(string $needle, bool $rewind = true, bool $firstOnly = false): array

Parameters:

ParameterTypeDescription
$needlestringThe string to search for.
$rewindboolWhether to rewind before searching.
$firstOnlyboolStop after the first occurrence match is found.

Return Value:

array<int,array{line: int, position: int}> - Returns an array of matches with line number and byte position:

[
    ['line' => 1, 'position' => 15],
    ['line' => 3, 'position' => 42],
]

truncate

Truncates the stream to the given size.

If $size is smaller than the file's current size, the extra data is discarded. If $size is larger, the file is extended with null bytes.

The file pointer is NOT moved after truncation, call rewind() or seek() as required.

public truncate(int $size = 0): bool

Parameters:

ParameterTypeDescription
$sizeintTarget size in bytes. Defaults to 0 (empty the file).

Return Value:

bool - True on success, false on failure.

Throws:


flush

Flushes the output buffers of the stream to the underlying storage device.

Should be called after a sequence of write() calls and before unlock()to ensure data is durably persisted before releasing the lock.

public flush(): bool

Return Value:

bool - True on success, false on failure.

Throws:


copy

Copies data from this stream into another stream.

Starts copying from the current pointer of the source. Use rewind()to start from the beginning. The destination pointer ends at the end of written data.

public copy(self $destination, int $length = -1, int $offset = 0): int

Parameters:

ParameterTypeDescription
$destinationselfTarget stream to copy into.
$lengthintMaximum bytes to copy. Default -1 copies until EOF.
$offsetintByte offset in the source stream. Default 0 uses current position.

Return Value:

int - Number of bytes copied.

Throws:


buffer

Read the entire stream content, always starting from the beginning.

If the stream is seekable the pointer is rewound to position 0 beforereading, so previously consumed content is included in the result.For non-seekable streams only the remaining (unread) bytes are returned.

public buffer(): string

Return Value:

string - The complete stream content (or remaining content for non-seekable streams).

Throws:


checksum

Generate a hash checksum of the entire stream content.

The stream pointer will be rewound before reading if the stream is seekable.For non-seekable streams, hashing is performed from the current position.

public checksum(string $algo = 'xxh3', bool $binary = false): string

Parameters:

ParameterTypeDescription
$algostringHash algorithm (e.g. xxh3, sha256, md5).
$binaryboolWhether to return raw binary output.

Return Value:

string - Return generated hash string.

Throws:


tryLock

Attempt to acquire a non-blocking advisory file lock.

This is a fail-fast wrapper around lock() that always operatesin non-blocking mode. It will attempt to acquire the lock once and returnimmediately.

Unlike lock(), this method does not throw an exception on failure.Instead, it returns false if the lock cannot be obtained.

public tryLock(
    int $flags,
    int $retries = 1,
    int $delay = 0,
    ?int &$wouldBlock = null
): bool

Parameters:

ParameterTypeDescription
$flagsintLock type: LOCK_SH (shared/read) or LOCK_EX (exclusive/write).
OCK_NB is automatically applied and does not need to be passed.
$retriesintIgnored in non-blocking mode (default: 1)
$delayintIgnored in non-blocking mode (default: 0)
&$wouldBlockint|nullSet to 1 if the lock could not be acquired because it would block.

Return Value:

bool - True if the lock was acquired, false otherwise.

Throws:


toString

Returns the full stream contents as a string, rewinding first.

This method rewinds before reading so callers alwaysget the complete content regardless of the current pointer position.

public toString(): string

Return Value:

string - Stream contents, or empty string on failure (safe for exception-free contexts).

Same as __toString()


toObject

Decode the stream content into a JSON object (stdClass).

Returns null if the buffer is empty, invalid JSON, or not an object at the root.

public toObject(int $depth = 512, int $flags = JSON_BIGINT_AS_STRING): ?object

Parameters:

ParameterTypeDescription
$depthintMaximum nesting depth of the structure being decoded (default: 512).
$flagsintOptional decoding flags (default: JSON_BIGINT_AS_STRING).

Return Value:

object|null - Decoded object, or null on failure.


toArray

Decode the stream content into a JSON associative array.

Returns an empty array for empty streams. Returns the raw content wrappedin an array if JSON validation fails.

public toArray(int $depth = 512, int $flags = JSON_BIGINT_AS_STRING): array

Parameters:

ParameterTypeDescription
$depthintMaximum nesting depth of the structure being decoded (default: 512).
$flagsintOptional decoding flags (default: JSON_BIGINT_AS_STRING).

Return Value:

array - Decoded array, or array with raw content on invalid JSON.


assertResource

Ensure the stream resource is valid.

protected assertResource(): void

Throws:

Use isOpen() when you need a non-throwing check.


assertResourceType

Ensure the resource type matches the expected type.

protected assertResourceType(): void

Throws:

Use isType() when you need a non-throwing check.


assertReadable

Ensure the stream is readable.

protected assertReadable(?string $prefix = null): void

Throws an exception if the underlying resource cannot be read.

Parameters:

ParameterTypeDescription
$prefixstring|nullOptional message prefix for context.

Throws:

Use isReadable() when you need a non-throwing check.


assertWritable

Ensure the stream is writable.

This checks both the internal read-only flag and the underlyingresource capability.

protected assertWritable(?string $prefix = null): void

Parameters:

ParameterTypeDescription
$prefixstring|nullOptional message prefix for context.

Throws:

Use isWritable() or isReadOnly() when you need a non-throwing check.


assertNewResource

Validate that the given resource is a valid PHP stream.

This static helper ensures that the provided resource is a PHP stream(i.e., get_resource_type() === 'stream'). It is intended for usebefore assigning or wrapping a new stream resource.

protected static assertNewResource(mixed $resource, string $expected = 'stream'): void

Parameters:

ParameterTypeDescription
$resourcemixedThe resource to validate.
$expectedstringThe expected resource type (default: 'stream').

Throws:


assertFopenTarget

Validate that the given is a valid fopen() target.

Validate:URL, File or registered stream wrapper.

protected assertFopenTarget(string $filename): void

Parameters:

ParameterTypeDescription
$filenamestringThe filename to validate.

Throws:\Luminova\Exceptions\RuntimeException - If not a valid target fopen.


newStatic

Override to create and return new stream instance.

This method is called internally by parent class Luminova\Storage\Stream, when new object need to be created.static::newStatic() is called, instead of new static(...).

This should be based on sub class __construct() signature that align with parent constructor signature.

protected static newStatic(string $filename, string $mode = 'c+b', bool $autoOpen = true): static

Parameters:

ParameterTypeDescription
$filenamestringThe filename to open stream.
$modestringFile open mode (used only when source is a file path).
$autoOpenboolWhen true the file is opened immediately.

Return Value:

static - Return new instance of stream class.

Example:s

Override newStatic() when your subclass modifies the constructor or needs to control how new instances are created.

use Luminova\Storage\Stream;

class CustomStream extends Stream
{
    protected string $prefix;

    public function __construct(
        string $filename,
        string $mode = 'c+b',
        string $prefix = ''
    ) {
       // parent::__construct($filename, $mode, false);
        $this->prefix = $prefix;
    }

    /**
     * Create a new instance of the current stream class.
     */
    protected static function newStatic(
        string $filename,
        string $mode = 'c+b',
        bool $autoOpen = true
    ): static 
    {
        // Ensure constructor signature is respected
        $instance = new static($filename, $mode, false, '[LOG]');
        if($autoOpen){
            $instance->open();
        }

        return $instance;
    }
}

Internal Usage

This method is typically used internally when duplicating or creating a new stream instance:

$stream = CustomStream::fromString('Hello world!', 'c+b');

// Internally creates a new instance of the same class
$newStream = CustomStream::newStatic($this->filename, $this->mode, $this->autoOpen);

__call

Dynamically calls a callable function on the underlying stream resource.

The function must be callable and expects the stream resource as its first argument.Any additional arguments are passed as subsequent parameters.

Default Allowed Functions:

  • fread, fwrite, stream_get_contents
  • fseek, ftell, rewind
  • fgetc, fgets, feof
  • fstat, fflush, ftruncate

To controller or disabled dynamic f-functions see Allowed Dynamic Functions Property.

public __call(string $fn, array<int,mixed> $arguments): mixed

Parameters:

ParameterTypeDescription
$fnstringName of the callable function (e.g., stream_get_contents).
$argumentsarrayAdditional arguments to pass to the function.

Return Value:

mixed - The result of the function call.

Throws:


Example:

Read entire stream.

$stream = new Stream('file.txt');

// Calls: stream_get_contents($resource)
$content = $stream->stream_get_contents();

echo $content;

// Read fixed number of bytes.
$data = $stream->fread(100);

// Move pointer and read
$stream->fseek(10);
$data = $stream->fread(20);

// Get stream metadata
$info = $stream->fstat();

print_r($info);

// Write to stream
$stream->fwrite("Hello");
$stream->fflush();

Custom allowed functions

// Allow only read operations
$stream->allowedDynamicFunctions = ['fread', 'stream_get_contents'];

// Allowed
$content = $stream->stream_get_contents();

// Not allowed (throws RuntimeException)
$stream->fwrite("Blocked");

Disable all dynamic calls

// Deny all
$stream->allowedDynamicFunctions = [];

// Any dynamic call will fail
$stream->fread(10); // RuntimeException

Important Notes

  • The method automatically injects the stream resource as the first argument
  • Only functions that accept a resource as the first parameter are valid
  • Invalid or disallowed calls will throw a Luminova\Exceptions\RuntimeException
  • This feature is powerful, but don’t treat it like a free-for-all, keep the whitelist tight