PHPackages                             mmdm/sim-file - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [File &amp; Storage](/categories/file-storage)
4. /
5. mmdm/sim-file

ActiveLibrary[File &amp; Storage](/categories/file-storage)

mmdm/sim-file
=============

A simple yet nice file management library

v0.2.5(5y ago)127MITPHPPHP &gt;=7.2

Since Sep 23Pushed 5y ago1 watchersCompare

[ Source](https://github.com/mmdm95/sim-file)[ Packagist](https://packagist.org/packages/mmdm/sim-file)[ RSS](/packages/mmdm-sim-file/feed)WikiDiscussions master Synced 1w ago

READMEChangelogDependenciesVersions (11)Used By (0)

Simplicity File System
======================

[](#simplicity-file-system)

A library for file management.

Install
-------

[](#install)

**composer**

```
composer require mmdm/sim-file
```

Or you can simply download zip file from github and extract it, then put file to your project library and use it like other libraries.

Just add line below to autoload files:

```
require_once 'path_to_library/autoloader.php';
```

and you are good to go.

How to use
----------

[](#how-to-use)

It has three parts to use:

- Download
- Upload
- FileSystem

### Download

[](#download)

#### Basic Usage

[](#basic-usage)

```
// create new Download instance
$download = new Download($path_to_your_file);
$download->download($your_new_name);

// or just use static function
$download = Download::makeDownloadFromPath($path_to_your_file);
$download->download($your_new_name);
```

#### Methods

[](#methods)

#### `download(?string $name = null): void`

[](#downloadstring-name--null-void)

The download main method. If *null* passed as `$name`, the original file name will use as downloadable file name.

#### `getPath(): ?string`

[](#getpath-string)

Get the path of file.

#### `setName(string $name)`

[](#setnamestring-name)

Set downloadable file name.

#### `getName(): string`

[](#getname-string)

Get name of downloadable file without extension.

#### `setExtension(string $extension)`

[](#setextensionstring-extension)

Set extension of downloadable file.

#### `getExtension(): ?string`

[](#getextension-string)

Get extension of downloadable file.

#### `getNameWithExtension(): string`

[](#getnamewithextension-string)

Get name of downloadable file with extension.

#### `setMimeType(string $mime_type)`

[](#setmimetypestring-mime_type)

Set mimetype of downloadable file.

#### `getMimeType(): string`

[](#getmimetype-string)

Get mimetype of downloadable file.

#### `getSize(): int`

[](#getsize-int)

Get size of downloadable file.

#### `getFormattedSize(): string`

[](#getformattedsize-string)

Get size of downloadable file in a human readable format like 2MB or 4KB etc.

#### `static makeDownloadFromPath(string $path): IDownload`

[](#static-makedownloadfrompathstring-path-idownload)

Make a download instance from a path with static calling.

---

### Upload

[](#upload)

To create a upload instance, you should pass a `FileUpload`instance to `Upload` constructor.

### `FileUpload`

[](#fileupload)

You should pass the key of `$_FILES` that have uploaded file.

#### Basic Usage

[](#basic-usage-1)

```
$fileUpload = new FileUpload($the_key_of_file_in_file_global_variable);
```

#### Methods

[](#methods-1)

#### `setValidations(array $validations)`

[](#setvalidationsarray-validations)

You can pass some validations to validate a file while upload method called.

Please refer to *Validations* section at the very bottom

**Note:** If unit is not specified, it'll be in bytes.

```
// new size validation instance
$sizeValidation = new SizeValidation('2MB', '1MB');
```

#### `getValidations(): array`

[](#getvalidations-array)

Get array of validations.

#### `getExtension(): string`

[](#getextension-string-1)

Get extension of uploaded file.

#### `getSize(): int`

[](#getsize-int-1)

Get size of uploaded file.

#### `getOriginalName(): string`

[](#getoriginalname-string)

Get original name of uploaded file without extension.

#### `getOriginalNameWithExtension(): string`

[](#getoriginalnamewithextension-string)

Get original name of uploaded file with extension.

#### `getErrors(): array`

[](#geterrors-array)

Get errors of uploaded file. Basically it is standard error of uploaded file error and can have other errors too.

**Note:** Validation errors are not included here.

#### `addError(string $error)`

[](#adderrorstring-error)

Add error to end of errors list.

#### `setError($key, string $error)`

[](#seterrorkey-string-error)

Set error as a specific error in errors list.

#### `hasError(): bool`

[](#haserror-bool)

Check if any error is set.

#### `errorMessagesTranslate(array $translate)`

[](#errormessagestranslatearray-translate)

Translate standard errors to your locally language.

#### Basic Usage

[](#basic-usage-2)

```
// create new Upload instance
$upload = new Upload();
$upload->upload($your_new_destination);
```

#### Methods

[](#methods-2)

#### `upload(string $destination, bool $overwrite = false): bool`

[](#uploadstring-destination-bool-overwrite--false-bool)

Do upload operation. Default behavior is to not overwrite existing file.

#### `setName(string $name)`

[](#setnamestring-name-1)

Set new name of uploaded file.

#### `getName(): string`

[](#getname-string-1)

Get new name of uploaded file without extension. Default name is original name unless it change.

#### `getNameWithExtension(): string`

[](#getnamewithextension-string-1)

Get new name of uploaded file with extension.

#### `getErrors(): array`

[](#geterrors-array-1)

Get errors during upload progress including validation errors.

#### `addError(string $error)`

[](#adderrorstring-error-1)

Add error end of errors list.

#### `setError(string $key, string $error)`

[](#seterrorstring-key-string-error)

Set error as a specific error in errors list.

#### `hasError(): bool`

[](#haserror-bool-1)

Check if any error is set.

---

### FileSystem

[](#filesystem)

You can use all methods in both normal instantiable way or use static methods of file system.

These methods works on both files and directories.

**Note:** Some of these methods that work only with directories, and have a little comment on method documentation that says:

> Works only on directories.

Normal instantiable way methods:
--------------------------------

[](#normal-instantiable-way-methods)

#### `exists(): bool`

[](#exists-bool)

Check if specified file is exists.

#### `isReadable(): bool`

[](#isreadable-bool)

Check if specified file is readable.

#### `isWritable(): bool`

[](#iswritable-bool)

Check if specified file is writable.

#### `isFile(): bool`

[](#isfile-bool)

Check if a path is file

#### `isDir(): bool`

[](#isdir-bool)

Check if a path is directory

#### `isEmpty(): bool`

[](#isempty-bool)

Check if a directory is empty or not.

**Note:** If you use file instead of directory, it'll use directory of that file to check.

#### `get($prefer = null): string`

[](#getprefer--null-string)

Get all contents of a file as string

#### `read($prefer = null): string`

[](#readprefer--null-string)

Alias of `get` method.

#### `put(string $data, ?int $mode = null)`

[](#putstring-data-int-mode--null)

Write some string data to a file and return number of bytes that were written to the file, or false on failure.

#### `write(string $data, ?int $mode = null)`

[](#writestring-data-int-mode--null)

Alias of `write` method.

#### `append(string $data)`

[](#appendstring-data)

Append some string data to a file and return number of bytes that were written to the file, or false on failure.

#### `prepend(string $data): bool`

[](#prependstring-data-bool)

Append some string data to beginning of a file.

#### `copy(string $new_destination, bool $overwrite = false): bool`

[](#copystring-new_destination-bool-overwrite--false-bool)

Copy a file to a new destination. Use *true* as `$overwrite`parameter if want to overwrite the existence file.

#### `move(string $new_destination, bool $overwrite = false): bool`

[](#movestring-new_destination-bool-overwrite--false-bool)

Move a file to a new destination. Use *true* as `$overwrite`parameter if want to overwrite the existence file.

#### `rename(string $new_name, bool $overwrite = false): bool`

[](#renamestring-new_name-bool-overwrite--false-bool)

Rename a file with new name. Use *true* as `$overwrite`parameter if want to overwrite the existence file.

#### `delete(): bool`

[](#delete-bool)

Do delete operation.

**Note:** It will delete folders recursively.

#### `deleteFilteredFiles(array $filters = []): bool`

[](#deletefilteredfilesarray-filters---bool)

Do delete operation on filtered files.

**Note:** Only delete files in first level of a directory (This means no recursion)

#### `deleteAllFilteredFiles(array $filters = []): bool`

[](#deleteallfilteredfilesarray-filters---bool)

Do delete operation on filtered files.

**Note:** It will delete folders recursively.

#### `chmod(string $mode): bool`

[](#chmodstring-mode-bool)

Change mode of a file.

#### `chown($user): bool`

[](#chownuser-bool)

Change owner/user of a file.

#### `chgrp($group): bool`

[](#chgrpgroup-bool)

Change group of a file.

#### `modificationTime()`

[](#modificationtime)

Get modification time of a file.

#### `touch(?int $time = null, ?int $atime = null): bool`

[](#touchint-time--null-int-atime--null-bool)

Change the touch time and access time of a file.

#### `getExtension($prefer = null): ?string`

[](#getextensionprefer--null-string)

Get extension of a file or returns `$prefer`.

#### `getMimeType($prefer = null): ?string`

[](#getmimetypeprefer--null-string)

Get mime type of a file or returns `$prefer`.

#### `getOwner()`

[](#getowner)

Get user name of a file or false.

#### `getOwnerID()`

[](#getownerid)

The user ID of the owner of the file, or false on failure.

#### `getGroup()`

[](#getgroup)

Get file's group.

#### `getGroupID()`

[](#getgroupid)

Get file's group id.

#### `getName(): string`

[](#getname-string-2)

Get file's name.

#### `getBasename(): string`

[](#getbasename-string)

Get file's basename.

#### `getInfo(int $options): array`

[](#getinfoint-options-array)

Returns file's information. Information can be one or many of following constants (meaning of constant is obvious):

- INFO\_FILENAME
- INFO\_BASENAME
- INFO\_DIRNAME
- INFO\_SIZE
- INFO\_EXT
- INFO\_MIME\_TYPE
- INFO\_IS\_READABLE
- INFO\_IS\_WRITABLE
- INFO\_OWNER
- INFO\_OWNER\_ID
- INFO\_GROUP
- INFO\_GROUP\_ID

#### `getSize(): int`

[](#getsize-int-2)

Get size of a file.

**Note:** Size of directories will be calculated recursively.

#### `mkdir($mode = self::MODE_DIR_PUBLIC, bool $recursive = true): bool`

[](#mkdirmode--selfmode_dir_public-bool-recursive--true-bool)

Make a directory with a specific mode. To make directory recursively, use *true* as `$recursive` parameter.

**Note:** This method is only for directories.

#### `getAllFiles(int $type = self::TYPE_FILE | self::TYPE_DIRECTORY): ?RecursiveIteratorIterator`

[](#getallfilesint-type--selftype_file--selftype_directory-recursiveiteratoriterator)

Will return a `RecursiveIteratorIterator` to iterate through all files or null on error.

**Note:** This method is only for directories.

**Note:** If you want a file's files, it'll use directory of that file as needed directory to get files from.

**Note:** Please see [this link](https://www.php.net/manual/en/class.recursiveiteratoriterator.php)for more information about `RecursiveIteratorIterator` methods.

An example of usage:

```
$files = $fileSystem->getAllFiles();
$files->rewind();
while ($files->valid()) {
  /**
  * @var SplFileInfo $file
  */
  $file = $files->current();

  // do whatever you need with that file

  $files->next();
}
```

#### `getAllFilesInDepth(int $depth = 0, int $type = self::TYPE_FILE | self::TYPE_DIRECTORY): array`

[](#getallfilesindepthint-depth--0-int-type--selftype_file--selftype_directory-array)

Will return an array of files of type `SplFileInfo` from depth of `$depth`.

**Note:** This method is only for directories.

**Note:** If you want a file's files, it'll use directory of that file as needed directory to get files from.

#### `getAllFilteredFilesInDepth(int $depth = 0, array $filters = []): array`

[](#getallfilteredfilesindepthint-depth--0-array-filters---array)

Will return an array of filtered files of type `SplFileInfo` from depth of `$depth`.

**Note:** This method is only for directories.

**Note:** If you want a file's files, it'll use directory of that file as needed directory to get files from.

Please refer to *Filters* section at the very bottom.

#### `getFiles(int $type = self::TYPE_FILE | self::TYPE_DIRECTORY): array`

[](#getfilesint-type--selftype_file--selftype_directory-array)

Get files of a specific directory as array of type `SplFileInfo`.

**Note:** This method is only for directories.

**Note:** If you want a file's files, it'll use directory of that file as needed directory to get files from.

#### `getFilteredFiles(array $filters = []): array`

[](#getfilteredfilesarray-filters---array)

Get filtered files of a specific directory as array of type `SplFileInfo`.

Please refer to *Filters* section at the very bottom.

**Note:** This method is only for directories.

**Note:** If you want a file's files, it'll use directory of that file as needed directory to get files from.

---

Static calling way methods:
---------------------------

[](#static-calling-way-methods)

Only difference of normal way and static way is, you should pass the file path you need to do the operation, to static methods.

#### `fileExists(string $filename): bool`

[](#fileexistsstring-filename-bool)

See `exists` in normal way.

#### `isFileReadable(string $filename): bool`

[](#isfilereadablestring-filename-bool)

See `isReadable` in normal way.

#### `isFileWritable(string $filename): bool`

[](#isfilewritablestring-filename-bool)

See `isWritable` in normal way.

#### `isItFile(string $filename): bool`

[](#isitfilestring-filename-bool)

See `isFile` in normal way.

#### `isItDir(string $filename): bool`

[](#isitdirstring-filename-bool)

See `isDir` in normal way.

#### `isDirEmpty(string $dir): bool`

[](#isdiremptystring-dir-bool)

See `isEmpty` in normal way.

#### `getFromFile(string $filename, $prefer = null): string`

[](#getfromfilestring-filename-prefer--null-string)

See `get` in normal way.

#### `readFromFile(string $filename, $prefer = null): string`

[](#readfromfilestring-filename-prefer--null-string)

See `read` in normal way.

#### `putToFile(string $filename, string $data, ?int $mode = null)`

[](#puttofilestring-filename-string-data-int-mode--null)

See `put` in normal way.

#### `writeToFile(string $filename, string $data, ?int $mode = null)`

[](#writetofilestring-filename-string-data-int-mode--null)

See `write` in normal way.

#### `appendToFile(string $filename, string $data)`

[](#appendtofilestring-filename-string-data)

See `append` in normal way.

#### `prependToFile(string $filename, string $data): bool`

[](#prependtofilestring-filename-string-data-bool)

See `prepend` in normal way.

#### `copyFile(string $source, string $new_destination, bool $overwrite = false): bool`

[](#copyfilestring-source-string-new_destination-bool-overwrite--false-bool)

See `copy` in normal way.

#### `moveFile(string $source, string $new_destination, bool $overwrite = false): bool`

[](#movefilestring-source-string-new_destination-bool-overwrite--false-bool)

See `move` in normal way.

#### `renameFile(string $old_name, string $new_name, bool $overwrite = false): bool`

[](#renamefilestring-old_name-string-new_name-bool-overwrite--false-bool)

See `rename` in normal way.

#### `deleteFile(string $filename): bool`

[](#deletefilestring-filename-bool)

See `delete` in normal way.

#### `deleteDirFilteredFiles(string $filename, array $filters = []): bool`

[](#deletedirfilteredfilesstring-filename-array-filters---bool)

See `deleteFilteredFiles` in normal way.

#### `deleteDirAllFilteredFiles(string $filename, array $filters = []): bool`

[](#deletedirallfilteredfilesstring-filename-array-filters---bool)

See `deleteAllFilteredFiles` in normal way.

#### `fileChmod(string $filename, string $mode): bool`

[](#filechmodstring-filename-string-mode-bool)

See `chmod` in normal way.

#### `fileChown(string $filename, $user): bool`

[](#filechownstring-filename-user-bool)

See `chown` in normal way.

#### `fileChgrp(string $filename, $group): bool`

[](#filechgrpstring-filename-group-bool)

See `chgrp` in normal way.

#### `fileModificationTime(string $filename)`

[](#filemodificationtimestring-filename)

See `modificationTime` in normal way.

#### `touchFile(string $filename, ?int $time = null, ?int $atime = null): bool`

[](#touchfilestring-filename-int-time--null-int-atime--null-bool)

See `touch` in normal way.

#### `getFileExtension(string $filename, $prefer = null): ?string`

[](#getfileextensionstring-filename-prefer--null-string)

See `getExtension` in normal way.

#### `getFileMimeType(string $filename, $prefer = null): ?string`

[](#getfilemimetypestring-filename-prefer--null-string)

See `getMimeType` in normal way.

#### `getFileOwner(string $filename)`

[](#getfileownerstring-filename)

See `getOwner` in normal way.

#### `getFileOwnerID(string $filename)`

[](#getfileowneridstring-filename)

See `getOwnerID` in normal way.

#### `getFileGroup(string $filename)`

[](#getfilegroupstring-filename)

See `getGroup` in normal way.

#### `getFileGroupID(string $filename)`

[](#getfilegroupidstring-filename)

See `getGroupID` in normal way.

#### `getFileName(string $filename): string`

[](#getfilenamestring-filename-string)

See `getName` in normal way.

#### `getFileBasename(string $filename): string`

[](#getfilebasenamestring-filename-string)

See `getBasename` in normal way.

#### `getFileInfo(string $filename, int $options): array`

[](#getfileinfostring-filename-int-options-array)

See `getInfo` in normal way.

#### `getFileSize(string $filename): int`

[](#getfilesizestring-filename-int)

See `getSize` in normal way.

#### `makeDir(string $dir, $mode = self::MODE_DIR_PUBLIC, bool $recursive = true): bool`

[](#makedirstring-dir-mode--selfmode_dir_public-bool-recursive--true-bool)

See `mkdir` in normal way.

#### `getDirAllFiles(string $dir, int $type = self::TYPE_FILE | self::TYPE_DIRECTORY): ?RecursiveIteratorIterator`

[](#getdirallfilesstring-dir-int-type--selftype_file--selftype_directory-recursiveiteratoriterator)

See `getAllFiles` in normal way.

#### `getDirAllFilesInDepth(string $dir, int $depth = 0, int $type = self::TYPE_FILE | self::TYPE_DIRECTORY): array`

[](#getdirallfilesindepthstring-dir-int-depth--0-int-type--selftype_file--selftype_directory-array)

See `getAllFilesInDepth` in normal way.

#### `getDirAllFilteredFilesInDepth(string $dir, int $depth = 0, array $filters = []): array`

[](#getdirallfilteredfilesindepthstring-dir-int-depth--0-array-filters---array)

See `getAllFilteredFilesInDepth` in normal way.

#### `getDirFiles(string $dir, int $type = self::TYPE_FILE | self::TYPE_DIRECTORY): array`

[](#getdirfilesstring-dir-int-type--selftype_file--selftype_directory-array)

See `getFiles` in normal way.

#### `getDirFilteredFiles(string $dir, array $filters = []): array`

[](#getdirfilteredfilesstring-dir-array-filters---array)

See `getFilteredFiles` in normal way.

How To
======

[](#how-to)

### How to add more validations

[](#how-to-add-more-validations)

To add your validation, you must extend from `AbstractValidator`from `Abstracts` directory and implement following method(s):

#### `validate(FileUpload $file): bool`

[](#validatefileupload-file-bool)

Main validation method that need a file of type `FileUpload`.

### How translate validations error(s)

[](#how-translate-validations-errors)

To translate validations error(s) you need to use `setMessage($key, $message)` method inside you class after extending `AbstractValidator` and set your locally message to specific error key.

Key of errors in each class are:

- ExtensionValidation

```
[
  'extension' => 'Specified extension is not allowed!'
]
```

- MimeTypeValidation

```
[
  'mimetype' => 'Specified mimetype is not allowed!',
]
```

- SizeValidation

```
[
  'gt_size' => 'File size is greater than allowed file size!',
  'lt_size' => 'File size is less than allowed file size!',
]
```

### How to add more filters

[](#how-to-add-more-filters)

To add your filter, you must implement `IFilter` interface from `Interfaces` directory and implement following method(s):

#### `filter(SplFileInfo $file): bool`

[](#filtersplfileinfo-file-bool)

Main filter method that need a file of type `SplFileInfo`.

Filters
=======

[](#filters)

Filter classes are:

- ExtensionFilter

```
// new extension filterer instance
// pass array of allowed extensions without dot
$extFilter = new ExtensionFilter(['png', 'jpg', 'jpeg']);
```

- MimeTypeFilter

```
// new mimetype filterer instance
// pass array of allowed mimetypes
$mimetypeFilter = new MimeTypeFilter(['image/png', 'image/jpg']);
```

- NameFilter

You should pass a regex according to name of file you need without extension to constructor.

```
// new name filterer instance
// files that name of them ends with 'es'
$nameFilter = new NameFilter('/es$/i');
```

- SizeFilter

You should pass max size as first parameter and min size as second parameter

Passed parameters can be in following format:

size of file with one of \['B', 'KB', 'MB', 'TB', 'PB'\]

**Note:** If unit is not specified, it'll be in bytes.

```
// new size filterer instance
$sizeFilter = new SizeFilter('2MB', '1MB');
```

- TypeFilter

There are two types: *file* and *directory* that can specify through constants below:

- IFileSystem::TYPE\_FILE
- IFileSystem::TYPE\_DIRECTORY

```
// new type filterer instance
$typeFilter = new TypeFilter(IFileSystem::TYPE_FILE | IFileSystem::TYPE_DIRECTORY);
```

- RegexFilter

You should pass a regex to filter a file and it'll apply on name and extension

```
// new regex filterer instance
$regexFilter = new RegexFilter('/es\.(png|jpe?g|gif)$/i');
```

Validation
==========

[](#validation)

Validations are as below for now:

- ExtensionValidation

```
// new extension validation instance
// pass array of allowed extensions without dot
$extValidation = new ExtensionValidation(['png', 'jpg', 'jpeg']);
```

- MimeTypeValidation

```
// new mimetype validation instance
// pass array of allowed mimetypes
$mimetypeValidation = new MimeTypeValidation(['image/png', 'image/jpg']);
```

- SizeValidation

You should pass max size as first parameter and min size as second parameter

Passed parameters can be in following format:

size of file with one of \['B', 'KB', 'MB', 'TB', 'PB'\]

License
=======

[](#license)

Under MIT license.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity9

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~23 days

Recently: every ~51 days

Total

10

Last Release

1850d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/d955ebaae3fe602e6ad26c16422f6ab25a61a436fd7f08425a5be5c73ef9025c?d=identicon)[mmdm95](/maintainers/mmdm95)

---

Top Contributors

[![mmdm95](https://avatars.githubusercontent.com/u/26489185?v=4)](https://github.com/mmdm95 "mmdm95 (38 commits)")

### Embed Badge

![Health badge](/badges/mmdm-sim-file/health.svg)

```
[![Health](https://phpackages.com/badges/mmdm-sim-file/health.svg)](https://phpackages.com/packages/mmdm-sim-file)
```

###  Alternatives

[knplabs/gaufrette

PHP library that provides a filesystem abstraction layer

2.5k39.8M123](/packages/knplabs-gaufrette)[google/cloud-storage

Cloud Storage Client for PHP

34390.8M125](/packages/google-cloud-storage)[illuminate/filesystem

The Illuminate Filesystem package.

15261.6M2.6k](/packages/illuminate-filesystem)[superbalist/flysystem-google-storage

Flysystem adapter for Google Cloud Storage

26320.6M30](/packages/superbalist-flysystem-google-storage)[creocoder/yii2-flysystem

The flysystem extension for the Yii framework

2931.7M62](/packages/creocoder-yii2-flysystem)[flowjs/flow-php-server

PHP library for handling chunk uploads. Works with flow.js html5 file uploads.

2451.6M15](/packages/flowjs-flow-php-server)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
