PHP Phar Stream Wrapper

Overview

Scrutinizer Code Quality Travis CI Build Status AppVeyor Build status

PHP Phar Stream Wrapper

Abstract & History

Based on Sam Thomas' findings concerning insecure deserialization in combination with obfuscation strategies allowing to hide Phar files inside valid image resources, the TYPO3 project decided back then to introduce a PharStreamWrapper to intercept invocations of the phar:// stream in PHP and only allow usage for defined locations in the file system.

Since the TYPO3 mission statement is inspiring people to share, we thought it would be helpful for others to release our PharStreamWrapper as standalone package to the PHP community.

The mentioned security issue was reported to TYPO3 on 10th June 2018 by Sam Thomas and has been addressed concerning the specific attack vector and for this generic PharStreamWrapper in TYPO3 versions 7.6.30 LTS, 8.7.17 LTS and 9.3.1 on 12th July 2018.

License

In general the TYPO3 core is released under the GNU General Public License version 2 or any later version (GPL-2.0-or-later). In order to avoid licensing issues and incompatibilities this PharStreamWrapper is licenced under the MIT License. In case you duplicate or modify source code, credits are not required but really appreciated.

Credits

Thanks to Alex Pott, Drupal for creating back-ports of all sources in order to provide compatibility with PHP v5.3.

Installation

The PharStreamWrapper is provided as composer package typo3/phar-stream-wrapper and has minimum requirements of PHP v5.3 (v2 branch) and PHP v7.0 (master branch).

Installation for PHP v7.0

composer require typo3/phar-stream-wrapper ^3.0

Installation for PHP v5.3

composer require typo3/phar-stream-wrapper ^2.0

Example

The following example is bundled within this package, the shown PharExtensionInterceptor denies all stream wrapper invocations files not having the .phar suffix. Interceptor logic has to be individual and adjusted to according requirements.

\TYPO3\PharStreamWrapper\Manager::initialize(
    (new \TYPO3\PharStreamWrapper\Behavior())
        ->withAssertion(new \TYPO3\PharStreamWrapper\Interceptor\PharExtensionInterceptor())
);

if (in_array('phar', stream_get_wrappers())) {
    stream_wrapper_unregister('phar');
    stream_wrapper_register('phar', \TYPO3\PharStreamWrapper\PharStreamWrapper::class);
}
  • PharStreamWrapper defined as class reference will be instantiated each time phar:// streams shall be processed.
  • Manager as singleton pattern being called by PharStreamWrapper instances in order to retrieve individual behavior and settings.
  • Behavior holds reference to interceptor(s) that shall assert correct/allowed invocation of a given $path for a given $command. Interceptors implement the interface Assertable. Interceptors can act individually on following commands or handle all of them in case not defined specifically:
    • COMMAND_DIR_OPENDIR
    • COMMAND_MKDIR
    • COMMAND_RENAME
    • COMMAND_RMDIR
    • COMMAND_STEAM_METADATA
    • COMMAND_STREAM_OPEN
    • COMMAND_UNLINK
    • COMMAND_URL_STAT

Interceptors

The following interceptor is shipped with the package and ready to use in order to block any Phar invocation of files not having a .phar suffix. Besides that individual interceptors are possible of course.

baseFileContainsPharExtension($path)) { return true; } throw new Exception( sprintf( 'Unexpected file extension in "%s"', $path ), 1535198703 ); } /** * @param string $path * @return bool */ private function baseFileContainsPharExtension(string $path): bool { $baseFile = Helper::determineBaseFile($path); if ($baseFile === null) { return false; } $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION); return strtolower($fileExtension) === 'phar'; } } ">
class PharExtensionInterceptor implements Assertable
{
    /**
     * Determines whether the base file name has a ".phar" suffix.
     *
     * @param string $path
     * @param string $command
     * @return bool
     * @throws Exception
     */
    public function assert(string $path, string $command): bool
    {
        if ($this->baseFileContainsPharExtension($path)) {
            return true;
        }
        throw new Exception(
            sprintf(
                'Unexpected file extension in "%s"',
                $path
            ),
            1535198703
        );
    }

    /**
     * @param string $path
     * @return bool
     */
    private function baseFileContainsPharExtension(string $path): bool
    {
        $baseFile = Helper::determineBaseFile($path);
        if ($baseFile === null) {
            return false;
        }
        $fileExtension = pathinfo($baseFile, PATHINFO_EXTENSION);
        return strtolower($fileExtension) === 'phar';
    }
}

ConjunctionInterceptor

This interceptor combines multiple interceptors implementing Assertable. It succeeds when all nested interceptors succeed as well (logical AND).

\TYPO3\PharStreamWrapper\Manager::initialize(
    (new \TYPO3\PharStreamWrapper\Behavior())
        ->withAssertion(new ConjunctionInterceptor([
            new PharExtensionInterceptor(),
            new PharMetaDataInterceptor(),
        ]))
);

PharExtensionInterceptor

This (basic) interceptor just checks whether the invoked Phar archive has an according .phar file extension. Resolving symbolic links as well as Phar internal alias resolving are considered as well.

\TYPO3\PharStreamWrapper\Manager::initialize(
    (new \TYPO3\PharStreamWrapper\Behavior())
        ->withAssertion(new PharExtensionInterceptor())
);

PharMetaDataInterceptor

This interceptor is actually checking serialized Phar meta-data against PHP objects and would consider a Phar archive malicious in case not only scalar values are found. A custom low-level Phar\Reader is used in order to avoid using PHP's Phar object which would trigger the initial vulnerability.

\TYPO3\PharStreamWrapper\Manager::initialize(
    (new \TYPO3\PharStreamWrapper\Behavior())
        ->withAssertion(new PharMetaDataInterceptor())
);

Reader

  • Phar\Reader::__construct(string $fileName): Creates low-level reader for Phar archive
  • Phar\Reader::resolveContainer(): Phar\Container: Resolves model representing Phar archive
  • Phar\Container::getStub(): Phar\Stub: Resolves (plain PHP) stub section of Phar archive
  • Phar\Container::getManifest(): Phar\Manifest: Resolves parsed Phar archive manifest as documented at http://php.net/manual/en/phar.fileformat.manifestfile.php
  • Phar\Stub::getMappedAlias(): string: Resolves internal Phar archive alias defined in stub using Phar::mapPhar('alias.phar') - actually the plain PHP source is analyzed here
  • Phar\Manifest::getAlias(): string - Resolves internal Phar archive alias defined in manifest using Phar::setAlias('alias.phar')
  • Phar\Manifest::getMetaData(): string: Resolves serialized Phar archive meta-data
  • Phar\Manifest::deserializeMetaData(): mixed: Resolves deserialized Phar archive meta-data containing only scalar values - in case an object is determined, an according Phar\DeserializationException will be thrown
$reader = new Phar\Reader('example.phar');
var_dump($reader->resolveContainer()->getManifest()->deserializeMetaData());

Helper

  • Helper::determineBaseFile(string $path): string: Determines base file that can be accessed using the regular file system. For instance the following path phar:///home/user/bundle.phar/content.txt would be resolved to /home/user/bundle.phar.
  • Helper::resetOpCache(): Resets PHP's OPcache if enabled as work-around for issues in include() or require() calls and OPcache delivering wrong results. More details can be found in PHP's bug tracker, for instance like https://bugs.php.net/bug.php?id=66569

Security Contact

In case of finding additional security issues in the TYPO3 project or in this PharStreamWrapper package in particular, please get in touch with the TYPO3 Security Team.

Comments
  • Support CLI tools that use phars without a .phar extension

    Support CLI tools that use phars without a .phar extension

    Some CLI tools are shipped as phar files and the install instructions tell users to rename the cli_command.phar to cli_command.

    In this instance the interceptor can produce false positives because it is handling a phar file without a phar extension. But the very first caller is a phar file so I think it is safe to assume this is intentional.

    opened by alexpott 17
  • If fileinfo ext is not available use a fallback method to determine mimetype of a compressed phar file

    If fileinfo ext is not available use a fallback method to determine mimetype of a compressed phar file

    The latest version forces both Drupal and Typo3 to be dependent on PHP's fileinfo extension. Previously this was only suggested for the Typo3 CMS (see https://github.com/TYPO3/TYPO3.CMS/blob/master/composer.json) and is not part of Drupal's requirements - see https://www.drupal.org/project/drupal/issues/3053552.

    opened by alexpott 10
  • Performance down between 0469d9f and b7a21f0

    Performance down between 0469d9f and b7a21f0

    When we upgraded to Drupal 8.6.13 due to the recent security issue we also had several dependencies update, one of them being this library due to Core's version requirement being set to "^2.0.1". So instead of using 2.0.1 as bundled with Core we ended up with the pre-release 2.1.0 and the time it took to run simple Drush commands like status skyrocketed.

    With v2.1.0 (b7a21f0) installed we get these numbers:

    time drupal status
    ...
    real    0m29.862s
    user    0m19.492s
    sys     0m10.350s
    

    With v2.0.1 (0469d9f) we get these numers:

    time drupal status
    ...
    real    0m2.422s
    user    0m1.695s
    sys     0m0.705s
    

    The diff looks fairly small, but does seem to introduce brumann/polyfill-unserialize, could that be what's making it take a lot longer?

    bug 
    opened by TwoD 9
  • Breaking included AWS Phar

    Breaking included AWS Phar

    Hi. Joomla 3.9.4 updated/included this package. Currently I'm using aws.phar to use for S3, but since last update, I'm getting this error:

    Uncaught TYPO3\PharStreamWrapper\Exception: Unexpected file extension in "phar://aws-3.67.5.phar/aws-autoloader.php"

    This error is related to this package, not in Joomla or my own code. Maybe a bug?

    bug 
    opened by neoacevedo 8
  • Including dependencies packed with clue/phar-composer results in exception

    Including dependencies packed with clue/phar-composer results in exception

    In a non-composer TYPO3 project I follow @helhum‘s suggestions here https://insight.helhum.io/post/148112375750/how-to-use-php-libraries-in-legacy-extensions to require third party dependencies. After an update to a TYPO3 version including phar-stream-wrapper I‘m facing this exception:

    #1530103999: Method stream_select() cannot be used
    

    thrown in the line that does actually require the autoload.php file inside the phar, equally to

    @include 'phar://' . ExtensionManagementUtility::extPath('ext-key') . 'Libraries/symfony-process.phar/vendor/autoload.php';
    

    Expected behaviour: Register classes inside phar and load classes from there as needed.

    PHP is 5.6.24 and target TYPO3 version is 6.2.40

    opened by cumuru 8
  • Use appveyor to test on windows

    Use appveyor to test on windows

    As there are windows only issues see #36 how about adding a .appveyor integration for Windows testing?

    This is nearly there. It includes #36 because it needs the public static Helper method...

    opened by alexpott 7
  • Does not handle fgets returning an error gracefully

    Does not handle fgets returning an error gracefully

    If fgets returns false due to an error, this package will crash as it passes a bool to strpos:

    TypeError: strpos() expects parameter 1 to be string, bool given in strpos() (line 109 of /var/www/html/jwtest-com/vendor/typo3/phar-stream-wrapper/src/Phar/Reader.php).
    

    I'm still not certain how we got an error from fgets. We were trying to launch the phpstan.phar:

    TYPO3\PharStreamWrapper\Phar\Reader->extractData('/var/www/html/jwtest-com/vendor/phpstan/phpstan/phpstan.phar') (Line: 53)
    

    Relevant issue on Drupal.org. This gets triggered with:

        if (!class_exists('PHPStan\ExtensionInstaller\GeneratedConfig')) {
    

    That causes the PHPStan\PharAutoloader to execute:

    PHPStan\PharAutoloader::loadClass('PHPStan\ExtensionInstaller\GeneratedConfig')
    spl_autoload_call('PHPStan\ExtensionInstaller\GeneratedConfig')
    class_exists('PHPStan\ExtensionInstaller\GeneratedConfig') (Line: 589)
    

    And we end up broken. I don't know how many lines it takes to get an error, but it's before feof returns true.

    bug 
    opened by mglaman 6
  • Ensure PHP 7.4 compatibility

    Ensure PHP 7.4 compatibility

    PR #48 started to add compatibility for PHP 7.4 (snapshot), however there are a couple of tests that still fail for 7.4, see https://travis-ci.org/TYPO3/phar-stream-wrapper/builds/570805048

    This might be related to current beta state - anyway it's worth taking a closer look...

    testing 
    opened by ohader 6
  • [TASK] Silence PHP opcache warnings

    [TASK] Silence PHP opcache warnings

    There are some environments where opcache.restrict_api(https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.restrict-api) is enabled for security/stability reasons. Using them produce PHP warnings

    qente:tmp alex$ php -dopcache.restrict_api=1 -r 'require "vendor/typo3/phar-stream-wrapper/src/Helper.php";\TYPO3\PharStreamWrapper\Helper::resetOpCache();'
    
    PHP Warning:  Zend OPcache API is restricted by "restrict_api" configuration directive in /tmp/vendor/typo3/phar-stream-wrapper/src/Helper.php on line 34
    
    Warning: Zend OPcache API is restricted by "restrict_api" configuration directive in /tmp/vendor/typo3/phar-stream-wrapper/src/Helper.php on line 34
    
    opened by xknown 5
  • Breaks typo3 8.7.25 on symlinked webroot

    Breaks typo3 8.7.25 on symlinked webroot

    On a typo3 8.7.25 installation that has a symlinked webroot, the following errors occur:

    Warning: Uncaught TYPO3\PharStreamWrapper\Exception: Executing phar:///data/sites/web/depontnl/www/typo3conf/ext/emogrifier/Resources/Private/Php/Emogrifier.phar/vendor/autoload.php is denied in /data/sites/web/depontnl/subsites/typo3_src-8.7.25/typo3/sysext/core/Classes/IO/PharStreamWrapperInterceptor.php:39 Stack trace: #0 /data/sites/web/depontnl/subsites/typo3_src-8.7.25/vendor/typo3/phar-stream-wrapper/src/Behavior.php(72): TYPO3\CMS\Core\IO\PharStreamWrapperInterceptor->assert('phar:///data/si...', 'stream_open') #1 /data/sites/web/depontnl/subsites/typo3_src-8.7.25/vendor/typo3/phar-stream-wrapper/src/Manager.php(110): TYPO3\PharStreamWrapper\Behavior->assert('phar:///data/si...', 'stream_open') #2 /data/sites/web/depontnl/subsites/typo3_src-8.7.25/vendor/typo3/phar-stream-wrapper/src/PharStreamWrapper.php(421): TYPO3\PharStreamWrapper\Manager->assert('phar:///data/si...', 'stream_open') #3 /data/sites/web/depontnl/subsites/typo3_src-8.7.25/vendor/typo3/phar-stream-wrapper/src/PharStreamWrapper.php(256): TYPO3\ in /data/sites/web/depontnl/subsites/typo3_src-8.7.25/typo3/sysext/core/Classes/IO/PharStreamWrapperInterceptor.php on line 39

    Fatal error: TYPO3\CMS\Core\Utility\GeneralUtility::requireOnce(): Failed opening required 'phar:///data/sites/web/depontnl/www/typo3conf/ext/emogrifier/Resources/Private/Php/Emogrifier.phar/vendor/autoload.php' (include_path='.') in /data/sites/web/depontnl/subsites/typo3_src-8.7.25/typo3/sysext/core/Classes/Utility/GeneralUtility.php on line 4249

    Reverting to 8.7.24 resolves it. The same setup, but then a non-symlinked webroot on staging, generates no errors on 8.7.25, so it seems related to the symlink.

    opened by abvdveen 5
  • Check meta-data deserialization capabilities in PHP 8

    Check meta-data deserialization capabilities in PHP 8

    • https://github.com/php/php-src/commit/0c238ede019f6ffbe7c996ec1695a747f4bca966
    • https://github.com/php/php-src/pull/5855

    Also, change the signature from getMetadata() to getMetadata(array $unserialize_options = []). Start throwing earlier if setMetadata() is called and serialization threw.

    Scope for this package, craft a bunch of exploits for PHP 8 and see whether it works. In case it does, this package probably could "hand over" Phar handling to native PHP 8 then...

    opened by ohader 3
  • Deprecate unused constant in PharInvocationResolver

    Deprecate unused constant in PharInvocationResolver

    Constant ASSERT_INTERNAL_INVOCATION is not used anymore since https://github.com/TYPO3/phar-stream-wrapper/commit/eb6607fb147f607e0e0cca1d7e3896814f7c5616#diff-0dd07cb25bec3476d9fc1d8a3db389b3L59

    Asserting internal alias invocation just did not work out in a simple example like this

    require('/path/bundle.phar');
    // which internally does e.g. include('phar://bndl/vendor/autoload.php')
    // given that Phar stub loads `autoload.php` using an internal alias
    $object = new BundledClass();
    
    housekeeping 
    opened by ohader 0
Releases(v3.1.7)
  • v3.1.7(Sep 20, 2021)

  • v2.2.2(Sep 21, 2021)

  • v2.2.1(Nov 11, 2020)

    Albeit the v2 branch of typo3/phar-stream-wrapper is dedicated to PHP5, it seems to be used with PHP7 as well.

    PHP versions 7.4.12, 7.3.24 introduced a different behavior for stream_wrapper_restore() and would throw a PHP notice which is mitigated with this phar stream wrapper release.

    • see #66
    • see php/php-src#6183
    • see php/php-src@5ed0602
    Source code(tar.gz)
    Source code(zip)
  • v3.1.6(Nov 7, 2020)

    PHP versions 8.0-RC1, 7.4.12, 7.3.24 introduced a different behavior for stream_wrapper_restore() and would throw a PHP notice which is mitigated with this phar stream wrapper release. Besides that, test cases are now executed via symfony/phpunit-bridge instead of phpunit/phpunit.

    • see #66
    • see #65
    • see https://github.com/php/php-src/pull/6183
    • see https://github.com/php/php-src/commit/5ed0602ec622274bf5672304ae414e5ecb2e5167
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Jul 27, 2020)

    Nested serialized structures have not been handled correctly in https://github.com/dbrumann/polyfill-unserialize, which has been fixed in version 2.0.0. It's still possible to use version ^1.0 of the polyfill explicitly in projects - otherwise new ^2.0 will be used.

    • https://github.com/dbrumann/polyfill-unserialize/releases/tag/v2.0.0
    • https://github.com/dbrumann/polyfill-unserialize/issues/10
    Source code(tar.gz)
    Source code(zip)
  • v3.1.3(Oct 18, 2019)

  • v2.1.3(Oct 18, 2019)

    Resolved Issues

    • #49: Ensure PHP 7.4 compatibility

    Notice

    Branch v2 is not considered to be dramatically changed in order to be compatible with future PHP versions anymore. Albeit this branch now should be working for PHP 5.3, 5.4, 5.5, 5.6, 7.0, 7.1, 7.2, 7.3 and 7.4 we'd like to encourage projects to switch to the master branch and v3.1.3 or any later version - which is considered to be adjusted for future PHP versions as well.

    tl;dr: No guarantee v2 branch will be maintained for upcoming PHP 7.4.x and PHP 8 versions

    Source code(tar.gz)
    Source code(zip)
  • v3.1.2(May 14, 2019)

    Resolved Issues

    • #34: Normalize resolved Windows path to Unix-style
    • #42: Avoid analysing non-phar files on alias resolving
    • #40: Add Windows tests using AppVeyor
    • #33: Add alternative mime-type resolving (without ext-fileinfo)
    Source code(tar.gz)
    Source code(zip)
  • v2.1.2(May 14, 2019)

    Resolved Issues

    • #34: Normalize resolved Windows path to Unix-style
    • #42: Avoid analysing non-phar files on alias resolving
    • #40: Add Windows tests using AppVeyor
    • #33: Add alternative mime-type resolving (without ext-fileinfo)
    Source code(tar.gz)
    Source code(zip)
  • v3.1.1(May 6, 2019)

    Releases v3.1.1 and v.2.1.1 aim to overcome drawbacks in Phar's alias resolving from Phar stub as well as solving performance aspects.

    Resolved Issues

    • alias resolving & handling #21, #24
    • performance #23
    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(May 6, 2019)

    Releases v3.1.1 and v.2.1.1 aim to overcome drawbacks in Phar's alias resolving from Phar stub as well as solving performance aspects.

    Resolved Issues

    • alias resolving & handling #21, #24
    • performance #23
    Source code(tar.gz)
    Source code(zip)
  • v3.1.0(Mar 4, 2019)

    Description

    Releases v3.1.0 and v.2.1.0 aim to overcome drawbacks in Phar's alias resolving (either by Phar archives using Phar::setAlias() in meta-data or Phar::mapPhar() in stub code).

    Merged pull-requests

    • Phar alias resolving (v3: #10, #12, v2: #14, #15)
    • Phar alias handling and (v3: #16, #17, v2: #20)

    Migration

    In case custom Assertable interceptors have been used, path resolving has to be adjusted in order to make use of alias resolving features.

    before - example in v3.0.1

    $baseFile = Helper::determineBaseFile($path);
    

    after - example in v3.1.0

    $invocation = Manager::instance()->resolve($path);
    $baseName = $invocation->getBaseName(); // previously called $baseFile
    

    Open Issues

    There have been reports about flaws using stream_select() and according stream_cast() in PharStreamWrapper. Since it was not possible to reproduce the behavior in an isolated scenario and specific platform requiresments were not clear, these aspects have not been covered by these releses - see #8 and #19 for details.

    Features

    • added low-level Phar\Reader for stub & meta-data (incl. alias) and their model representations
    • added Resolver\PharInvocationResolver in order to resolve/handle alias names
    • added Interceptor\ConjunctionInterceptor for combining multiple interceptors
    • added Interceptor\PharMetaDataInterceptor for actually testing against insecure deserialization in meta-data of Phar archives
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Mar 4, 2019)

    Description

    Releases v3.1.0 and v.2.1.0 aim to overcome drawbacks in Phar's alias resolving (either by Phar archives using Phar::setAlias() in meta-data or Phar::mapPhar() in stub code).

    Merged pull-requests

    • Phar alias resolving (v3: #10, #12, v2: #14, #15)
    • Phar alias handling and (v3: #16, #17, v2: #20)

    Migration

    In case custom Assertable interceptors have been used, path resolving has to be adjusted in order to make use of alias resolving features.

    before - example in v3.0.1

    $baseFile = Helper::determineBaseFile($path);
    

    after - example in v3.1.0

    $invocation = Manager::instance()->resolve($path);
    $baseName = $invocation->getBaseName(); // previously called $baseFile
    

    Open Issues

    There have been reports about flaws using stream_select() and according stream_cast() in PharStreamWrapper. Since it was not possible to reproduce the behavior in an isolated scenario and specific platform requiresments were not clear, these aspects have not been covered by these releses - see #8 and #19 for details.

    Features

    • added low-level Phar\Reader for stub & meta-data (incl. alias) and their model representations
    • added Resolver\PharInvocationResolver in order to resolve/handle alias names
    • added Interceptor\ConjunctionInterceptor for combining multiple interceptors
    • added Interceptor\PharMetaDataInterceptor for actually testing against insecure deserialization in meta-data of Phar archives
    Source code(tar.gz)
    Source code(zip)
  • v3.0.1(Oct 18, 2018)

  • v2.0.1(Oct 18, 2018)

  • v3.0.0(Sep 7, 2018)

    Basically no functional differences to v1.0.1 release. Since PHP 5.3 compatibility has been merged into this repository, the new v2 branch will be used for PHP 5.3 related sources and master still requires PHP 7.0. That's why v1.0.1 is re-released now as v3.0.0.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Sep 7, 2018)

  • v1.1.0(Sep 7, 2018)

  • v1.0.1(Aug 30, 2018)

    • a93126f [TASK] Allow Manager::destroy() even if not being initialized
    • ce3af19 [TASK] Fix spelling issues
    • ffb7c2c [TASK] Adjust export-ignore filename
    • 56b4c73 [TASK] Exclude test files from being exported
    • 9ae4768 [TASK] Add copyright headers to PHPdoc
    Source code(tar.gz)
    Source code(zip)
Owner
TYPO3 GitHub Department
https://github.com/typo3-documentation https://github.com/FriendsOfTYPO3
TYPO3 GitHub Department
A stream wrapper for Flysystem V2.

Flysystem Stream Wrapper This package provides a stream wrapper for Flysystem V2. Flysystem V1 If you're looking for Flysystem 1.x support, check out

Martin Mandl 9 Oct 21, 2022
An object oriented PHP driver for FFMpeg binary

php-ffmpeg An Object-Oriented library to convert video/audio files with FFmpeg / AVConv. Check another amazing repo: PHP FFMpeg extras, you will find

null 4.4k Jan 2, 2023
CSV data manipulation made easy in PHP

CSV Csv is a simple library to ease CSV parsing, writing and filtering in PHP. The goal of the library is to be powerful while remaining lightweight,

The League of Extraordinary Packages 3k Jan 4, 2023
PHP library that provides a filesystem abstraction layer − will be a feast for your files!

Gaufrette Gaufrette provides a filesystem abstraction layer. Why use Gaufrette? Imagine you have to manage a lot of medias in a PHP project. Lets see

KNP Labs 2.4k Jan 7, 2023
PHP-based anti-virus anti-trojan anti-malware solution.

What is phpMussel? An ideal solution for shared hosting environments, where it's often not possible to utilise or install conventional anti-virus prot

null 384 Dec 13, 2022
An object oriented PHP driver for FFMpeg binary

php-ffmpeg An Object-Oriented library to convert video/audio files with FFmpeg / AVConv. Check another amazing repo: PHP FFMpeg extras, you will find

null 4.4k Jan 2, 2023
PHP runtime & extensions header files for PhpStorm

phpstorm-stubs STUBS are normal, syntactically correct PHP files that contain function & class signatures, constant definitions, etc. for all built-in

JetBrains 1.2k Dec 25, 2022
A PHP library to deal with all those media services around, parsing their URLs and displaying their audios/videos.

MediaEmbed A utility library that generates HTML embed tags for audio or video located on a given URL. It also parses and validates given media URLs.

Mark Sch. 165 Nov 10, 2022
Watch changes in the file system using PHP

Watch changes in the file system using PHP This package allows you to react to all kinds of changes in the file system. Here's how you can run code wh

Spatie 170 Dec 25, 2022
File manager module for the Lumen PHP framework.

Lumen File Manager File manager module for the Lumen PHP framework. Please note that this module is still under active development. NOTE: Branch 5.1 i

Digia 40 Aug 20, 2022
This small PHP package assists in the loading and parsing of VTT files.

VTT Transcriptions This small PHP package assists in the loading and parsing of VTT files. Usage use Laracasts\Transcriptions\Transcription; $transcr

Laracasts 52 Nov 28, 2022
一个轻量级的 PHP 文件编辑器

AdminX 一个轻量级的 PHP 文件编辑器 安装 只需要前往 Release 页面下载最新版本的 adminx.php 放在你的主机文件里即可 若需要实时更新的 Develop Version 可以前往源代码找到 adminx.php 即可 配置 所有可配置的选项均在 adminx.php 的前

喵丶可爱 6 Aug 19, 2022
A full PHP implementation of Minecraft's Named Binary Tag (NBT) format.

php-nbt A full PHP implementation of Minecraft's Named Binary Tag (NBT) format. In contrast to other implementations, this library provides full suppo

Aternos 8 Oct 7, 2022
A php sharex uploader with discord embed function/twitter card support

Sharex Uploader Simple Sharex Uploader with Discord embed function Download replace your data and upload to your sevrer

Clynt 4 Jan 9, 2022
Upload File Library For PHP ( Simple & Easy User )

Upload File Library For Backend/ServerSide PHP ( Simple & Easy For Use ), Support Multiple Upload

Lamhot Simamora 1 Oct 12, 2021
Gotipath Storage is a file storage library for PHP. It provides one interface to interact with FTP/SFTP.

Gotipath Storage is a file storage library for PHP. It provides one interface to interact with FTP/SFTP. When you use this package, you're protected from vendor lock-in, That mean you can connect to any FTP/SFTP storage. Also it's comes with base URL option to connect Gotipath CDN.

Gotipath 2 Nov 3, 2021
PHPProject is a library written in pure PHP that provides a set of classes to write to different project management file formats

PHPProject PHPProject is a library written in pure PHP that provides a set of classes to write to different project management file formats, i.e. Micr

PHPOffice 192 Dec 17, 2022
ORM-based file upload package for php.

#Stapler Note: If you've previously been using this package, then you've been using it with Laravel. This package is no longer directly coupled to the

Code Sleeve 541 Dec 30, 2022