PHP transpiler - Write and deploy modern PHP 8 code, today.

Last update: Jun 11, 2022

Phabel phabel.io - PHP transpiler

Write and deploy modern PHP 8 code, today.

This is a transpiler that allows native usage of PHP 8+ features and especially syntax in projects and libraries, while allowing maintainers to publish a version targeting lower versions of php.

The transpiler seamlessly hooks into composer to transpile the package (and all dependencies down the current branch of the dependency tree!) on installation, on the user's machine, targeting the user's specific PHP version.

Created by Daniil Gentili

Usage

composer require --dev phabel/phabel

You can now publish your packagist package, and it will be automatically transpiled to any PHP version supported by phabel.

After git tagging a new release, just run:

vendor/bin/phabel publish

💡 Your PHP 7 users can now install your PHP 8 library 💡
💡 All your dependencies will also be transpiled to the correct PHP version. 💡

Supported PHP versions

Syntax/feature support:

Target:

  • 7.1+
  • 🐘 5.6, 7.0 in final testing stage.
  • 💡 5.4, 5.5 support coming soon!

No additional commands are required to add support for older versions: just composer update 😄

Async/await syntax

Phabel also supports async/await syntax, powered by Amp.
Parallelize your code, using native async/await syntax and the async Amp libraries for fully concurrent networking, I/O, database access in pure, native PHP!

Examples

File I/O

This example uses the amphp/file library:



// Write and read three files on your filesystem, in parallel
// Async/await syntax powered by phabel.io
// Concurrency powered by amphp.org

require 'vendor/autoload.php';

use Amp\Loop;
use function Amp\File\read;
use function Amp\File\write;

Loop::run(function () {
    // This is done in parallel!
    await [
        write('file1', 'contents1'),
        write('file2', 'contents2'),
        write('file3', 'contents3'),
    ];

    // This is also done in parallel!
    var_dump(await [
        read('file1'),
        read('file2'),
        read('file3'),
    ]);
});

You can publish this code as a Composer package and have it automatically transpile on installation, or even transpile it manually:

composer require amphp/file phabel/phabel
vendor/bin/phabel run input.php output.php
php output.php

GitHub

https://github.com/phabelio/phabel
Comments
  • 1. Parse error

    When trying to transpile PHPStan's source, I get this error:

    Syntax error, unexpected ',' on line 390 while parsing /Users/ondrej/Development/phpstan/src/Command/FixerApplication.php!
    

    But of course the source code is valid PHP and there's nothing special on line 390.

    Reviewed by ondrejmirtes at 2021-09-08 08:58
  • 2. Shouldn't prefix transpiled libraries?

    This is a theoretical question, I haven't checked if an issue actually happens or not.

    I can see that transpiled libraries under vendor/phabel/transpiler71 still retain the same namespace: Nette\Utils\Strings is transpiled under Nette\Utils\Strings, not under PhabelVendor/Nette\Utils\Strings. Isn't that a problem?

    For instance, if two libraries use Nette\Utils\Strings, and of them is using Phabel and the other not, couldn't that create conflicts?

    Reviewed by leoloso at 2021-09-27 11:16
  • 3. Casting type breaks the logic

    I have this function:

    public static function findFirstSymbolPosition(
      string $haystack,
      string $needle,
      $skipFromChars = '',
      $skipUntilChars = ''
    ): int|false {
      // Edge case: If the string starts with the symbol, then the array count of splitting the elements will be 1
      if (substr($haystack, 0, strlen($needle)) == $needle) {
        return 0;
      }
      // Split on that searching element: If it appears within the string,
      // it will produce an array with exactly 2 elements (since using option "ONLY_FIRST_OCCURRENCE")
      // The length of the first element equals the position of that symbol
      $fieldQueryInterpreter = QueryParserFacade::getInstance();
      $options = [
        QueryParserOptions::ONLY_FIRST_OCCURRENCE => true,
      ];
      $symbolElems = $fieldQueryInterpreter->splitElements(
        $haystack,
        $needle,
        $skipFromChars,
        $skipUntilChars,
        QuerySyntax::SYMBOL_FIELDARGS_ARGVALUESTRING_OPENING,
        QuerySyntax::SYMBOL_FIELDARGS_ARGVALUESTRING_CLOSING,
        $options
      );
      if (count($symbolElems) == 2) {
        return strlen($symbolElems[0]);
      }
      // Edge case: If the string finishes with the symbol, then the array count of splitting the elements will be 1
      if (substr($haystack, -1 * strlen($needle)) == $needle) {
        return strlen($haystack) - strlen($needle);
      }
    
      return false;
    }
    

    It must return false if the string is not found, or an int with the first position where it is found.

    When transpiled to 7.1, it becomes this:

    public static function findFirstSymbolPosition(string $haystack, string $needle, $skipFromChars = '', $skipUntilChars = '')
    {
      // Edge case: If the string starts with the symbol, then the array count of splitting the elements will be 1
      if (\Phabel\Target\Php80\Polyfill::substr($haystack, 0, strlen($needle)) == $needle) {
        $phabelReturn = 0;
        if (!$phabelReturn instanceof false) {
          if (!\is_int($phabelReturn)) {
            if (!(\is_bool($phabelReturn) || \is_numeric($phabelReturn))) {
              throw new \TypeError(__METHOD__ . '(): Return value must be of type false|int, ' . \Phabel\Plugin\TypeHintReplacer::getDebugType($phabelReturn) . ' returned in ' . \Phabel\Plugin\TypeHintReplacer::trace());
            } else {
              $phabelReturn = (int) $phabelReturn;
            }
          }
        }
        return $phabelReturn;
      }
      // Split on that searching element: If it appears within the string,
      // it will produce an array with exactly 2 elements (since using option "ONLY_FIRST_OCCURRENCE")
      // The length of the first element equals the position of that symbol
      $fieldQueryInterpreter = QueryParserFacade::getInstance();
      $options = [QueryParserOptions::ONLY_FIRST_OCCURRENCE => true];
      $symbolElems = $fieldQueryInterpreter->splitElements($haystack, $needle, $skipFromChars, $skipUntilChars, QuerySyntax::SYMBOL_FIELDARGS_ARGVALUESTRING_OPENING, QuerySyntax::SYMBOL_FIELDARGS_ARGVALUESTRING_CLOSING, $options);
      if (count($symbolElems) == 2) {
        $phabelReturn = strlen($symbolElems[0]);
        if (!$phabelReturn instanceof false) {
          if (!\is_int($phabelReturn)) {
            if (!(\is_bool($phabelReturn) || \is_numeric($phabelReturn))) {
              throw new \TypeError(__METHOD__ . '(): Return value must be of type false|int, ' . \Phabel\Plugin\TypeHintReplacer::getDebugType($phabelReturn) . ' returned in ' . \Phabel\Plugin\TypeHintReplacer::trace());
            } else {
              $phabelReturn = (int) $phabelReturn;
            }
          }
        }
        return $phabelReturn;
      }
      // Edge case: If the string finishes with the symbol, then the array count of splitting the elements will be 1
      if (\Phabel\Target\Php80\Polyfill::substr($haystack, -1 * strlen($needle)) == $needle) {
        $phabelReturn = strlen($haystack) - strlen($needle);
        if (!$phabelReturn instanceof false) {
          if (!\is_int($phabelReturn)) {
            if (!(\is_bool($phabelReturn) || \is_numeric($phabelReturn))) {
              throw new \TypeError(__METHOD__ . '(): Return value must be of type false|int, ' . \Phabel\Plugin\TypeHintReplacer::getDebugType($phabelReturn) . ' returned in ' . \Phabel\Plugin\TypeHintReplacer::trace());
            } else {
              $phabelReturn = (int) $phabelReturn;
            }
          }
        }
        return $phabelReturn;
      }
      $phabelReturn = false;
      if (!$phabelReturn instanceof false) {
        if (!\is_int($phabelReturn)) {
          if (!(\is_bool($phabelReturn) || \is_numeric($phabelReturn))) {
            throw new \TypeError(__METHOD__ . '(): Return value must be of type false|int, ' . \Phabel\Plugin\TypeHintReplacer::getDebugType($phabelReturn) . ' returned in ' . \Phabel\Plugin\TypeHintReplacer::trace());
          } else {
            $phabelReturn = (int) $phabelReturn;
          }
        }
      }
      return $phabelReturn;
    }
    

    There is a problem: the false would always be converted to 0, breaking the application, in this part:

      $phabelReturn = false;
      if (!$phabelReturn instanceof false) {
        if (!\is_int($phabelReturn)) {
          if (!(\is_bool($phabelReturn) || \is_numeric($phabelReturn))) {
            throw new \TypeError(__METHOD__ . '(): Return value must be of type false|int, ' . \Phabel\Plugin\TypeHintReplacer::getDebugType($phabelReturn) . ' returned in ' . \Phabel\Plugin\TypeHintReplacer::trace());
          } else {
            $phabelReturn = (int) $phabelReturn;
          }
        }
      }
      return $phabelReturn;
    

    After commenting line $phabelReturn = (int) $phabelReturn; it started working.

    Indeed, several sections of my application were not working after transpiling to 7.. Then I commented all instances of these pieces of code:

    // $phabelReturn = (string) $phabelReturn;
    // $phabelReturn = (int) $phabelReturn;
    // $phabelReturn = (bool) $phabelReturn;
    

    Then it started working.

    Maybe the issue is returning false|int? Or maybe casting shouldn't be done? (Maybe there's no need for it?)

    Reviewed by leoloso at 2021-09-27 10:31
  • 4. str_starts_with only available in PHP8

    This library uses str_starts_with in four places, but it is only available on PHP 8, which I think defeats the purpose of this transpiler. Source: https://www.php.net/manual/en/function.str-starts-with.php. Composer/Transformer.php breaks my composer update on PHP 7.4.

    Reviewed by fmdelvalle at 2021-08-23 17:58
  • 5. Path to static assets are broken

    When transpiling, library vendor/foo/bar will be now accessible under vendor/phabel/transpiler71/foo/bar. This is a problem when this library has static assets, such as .js or .css files, which are referenced directly.

    For instance, my plugin accesses assets like this:

    $cssFile = $mainPluginURL . 'vendor/graphql-by-pop/graphql-clients-for-wp/build/static/css/main.css';
    

    After transpiling, this code must be fixed:

    $cssFile = $mainPluginURL . 'vendor/phabel/transpiler71/graphql-by-pop/graphql-clients-for-wp/build/static/css/main.css';
    

    Maybe this is related to #10, as to enable developers to add custom hooks to fix these issues.

    Reviewed by leoloso at 2021-09-27 10:21
  • 6. Symfony's function `import` has different signatures, it is not fixed when transpiling to 7.1

    Symfony has the same function import from class FileLoader with different signatures, and these are not harmonized when transpiling to PHP 7.1.

    In Symfony\Component\Config\Loader\FileLoader it has bool $ignoreErrors = false (source):

    public function import($resource, string $type = null, bool $ignoreErrors = false, string $sourceResource = null, $exclude = null)
    

    In its extending class Symfony\Component\DependencyInjection\Loader\FileLoader it has $ignoreErrors = false, so bool is missing (source):

    public function import($resource, string $type = null, $ignoreErrors = false, string $sourceResource = null, $exclude = null)
    

    When running this in PHP 7.1 it shows a warning (first lines of this screenshot):

    Screenshot 2021-09-27 at 15-39-38 WordPress › Error

    I guess that, when transpiling, the first function should have the bool typehint removed.

    Reviewed by leoloso at 2021-09-27 10:05
  • 7. Docs - Clarify what publish does

    Hi, I don't understand the magic behind the publish command. The README says:

    You can publish this code as a Composer package and have it automatically transpile on installation

    How is this achieved?

    Reviewed by ondrejmirtes at 2021-09-08 08:57
  • 8. Typed properties not removed

    Hello, I'm trying this project on PHPStan's source code. When running this command, I'd expect the sources in dist directory to not contain typed properties. Or is there any additional configuration to do if I'd like to support PHP 7.1? Thanks!

    vendor/bin/phabel run src/ dist
    
    *********
    * Phabel *
    *********
    
    PHP transpiler - Write and deploy modern PHP 8 code, today: https://phabel.io
    
    Transpilation in progress...  77% (709/914)
    Syntax error, unexpected ',' on line 390 while parsing /Users/ondrej/Development/phpstan/src/Command/FixerApplication.php!
    Transpilation in progress... 100% (914/914)
    Done!
    
    Reviewed by ondrejmirtes at 2021-09-08 08:56
  • 9. The package is not transpiled when not having "type: library" or not placed under vendor/

    I have a package with type wordpress-plugin, and then I configure it in composer.json to be installed not under vendor/, but under wordpress/wp-content/plugins/:

    {
      "extra": {
        "installer-paths": {
          "wordpress/wp-content/plugins/{$name}/": [
            "type:wordpress-plugin"
          ]
        }
      }
    }
    

    This library is not being transpiled.

    After changing to type: library (and being installed under vendor/) then it is transpiled.

    Reviewed by leoloso at 2021-09-27 09:51
  • 10. [ErrorException] Constant PHABEL_INCLUDED already defined

    I have [email protected] installed.

    after running composer require --dev phabel/phabel I got this error:

    [ErrorException] Constant PHABEL_INCLUDED already defined

    Reviewed by HosseinKeramati at 2021-09-07 09:04
  • 11. `use ($var)` missing from transpiled code

    I have this code:

    public function getMandatoryDirectivesForFields(ObjectTypeResolverInterface $objectTypeResolver): array
    {
      $interfaceTypeResolvers = $objectTypeResolver->getAllImplementedInterfaceTypeResolvers();
      foreach ($this->getFieldNames() as $fieldName) {
        // Calculate all the interfaces that define this fieldName
        $interfaceTypeResolversForField = array_values(array_filter(
          $interfaceTypeResolvers,
          fn (InterfaceTypeResolverInterface $interfaceTypeResolver) => in_array($fieldName, $interfaceTypeResolver->getFieldNamesToImplement()),
        ));
        // ...
      }
      // ...
    }
    

    Transpiling to 7.1, it became this:

    public function getMandatoryDirectivesForFields(ObjectTypeResolverInterface $objectTypeResolver) : array
    {
      $interfaceTypeResolvers = $objectTypeResolver->getAllImplementedInterfaceTypeResolvers();
      foreach ($this->getFieldNames() as $fieldName) {
        // Calculate all the interfaces that define this fieldName
        $interfaceTypeResolversForField = array_values(\Phabel\Target\Php74\Polyfill::array_filter($interfaceTypeResolvers, function (InterfaceTypeResolverInterface $interfaceTypeResolver) {
          return in_array($fieldName, $interfaceTypeResolver->getFieldNamesToImplement());
        }));
        // ...
      }
      // ...
    }
    

    So the use ($fieldName) code is missing in the anonymous function, throwing a warning:

    Notice: Undefined variable: fieldName in /app/wordpress/wp-content/plugins/phabel-graphql-api-for-wp/vendor/phabel/transpiler71/getpop/mandatory-directives-by-configuration/src/RelationalTypeResolverDecorators/ConfigurableMandatoryDirectivesForFieldsRelationalTypeResolverDecoratorTrait.php on line 34
    
    Reviewed by leoloso at 2021-09-27 11:09
  • 12. Fatal error: Uncaught TypeError: Argument 1 passed to PhabelVendor\PhpParser\Builder\Param::__construct()

    Fatal error in phabelio/phabel PHP 7.2.34 Windows 22000.376

    composer.json
    {
      "require": {
          "php": "^7.2",
          "mixplat/mixplat-php-client": "^1.0",
          "symfony/dotenv": "^5.3",
          "danog/madelineproto": "7.0.48.9998"
      },
      "config": {
          "allow-plugins": {
              "phabel/phabel": true
          }
      }
    }                       
    
    composer update -v
    Package operations: 47 installs, 0 updates, 0 removals                                                                                                                                         
    Installs: phabel-transpiler72.symfony/polyfill-php80:v1.23.1, phabel-transpiler72.symfony/polyfill-mbstring:v1.23.1, phabel-transpiler72.psr/log:1.1.4, phabel-transpiler72.psr/http-message:1.
    0.1, phabel-transpiler72.psr/http-factory:1.0.1, phabel-transpiler72.paragonie/random_compat:v9.99.100, phabel-transpiler72.paragonie/constant_time_encoding:v2.4.0, phabel-transpiler72.phpsec
    lib/phpseclib:3.0.12, phabel-transpiler72.league/uri-interfaces:2.3.0, phabel-transpiler72.league/uri:6.5.0, phabel-transpiler72.erusev/parsedown:1.7.4, phabel-transpiler72.danog/tg-file-deco
    der:0.1.8, phabel-transpiler72.danog/primemodule:1.0.7, phabel-transpiler72.danog/magicalserializer:1.0, phabel-transpiler72.amphp/amp:v2.6.1, phabel-transpiler72.danog/loop:0.1.1, phabel-tra
    nspiler72.amphp/parser:v1.0.0, phabel-transpiler72.amphp/byte-stream:v1.8.1, phabel-transpiler72.danog/ipc:0.1.15, phabel-transpiler72.daverandom/libdns:v2.0.2, phabel-transpiler72.danog/libd
    ns-json:0.1.1, phabel-transpiler72.amphp/sync:v1.4.2, phabel-transpiler72.league/uri-parser:1.4.1, phabel-transpiler72.kelunik/certificate:v1.1.2, phabel-transpiler72.amphp/process:v1.1.3, ph
    abel-transpiler72.amphp/windows-registry:v0.3.3, phabel-transpiler72.amphp/serialization:v1.0.0, phabel-transpiler72.amphp/cache:v1.5.0, phabel-transpiler72.amphp/dns:v1.2.3, phabel-transpile
    r72.amphp/socket:v1.2.0, phabel-transpiler72.amphp/hpack:v3.1.1, phabel-transpiler72.amphp/http:v1.6.3, phabel-transpiler72.amphp/http-client:v4.6.2, phabel-transpiler72.danog/dns-over-https:
    0.2.6, phabel-transpiler72.cash/lrucache:1.0.0, phabel-transpiler72.amphp/websocket:v1.0.2, phabel-transpiler72.amphp/websocket-client:v1.0.0, phabel-transpiler72.amphp/redis:v1.0.6, phabel-t
    ranspiler72.amphp/sql:v1.0.1, phabel-transpiler72.amphp/sql-common:v1.1.2, phabel-transpiler72.amphp/postgres:v1.4.3, phabel-transpiler72.amphp/mysql:v2.1.2, phabel-transpiler72.monolog/monol
    og:2.3.5, phabel-transpiler72.amphp/log:v1.1.0, phabel-transpiler72.amphp/http-client-cookies:v1.2.0, phabel-transpiler72.amphp/parallel:v1.4.1, phabel-transpiler72.amphp/file:v2.0.2         
    - Installing phabel-transpiler72.symfony/polyfill-php80 (v1.23.1): Extracting archive                                                                                                        
    - Installing phabel-transpiler72.symfony/polyfill-mbstring (v1.23.1): Extracting archive                                                                                                     
    - Installing phabel-transpiler72.psr/log (1.1.4): Extracting archive                                                                                                                         
    - Installing phabel-transpiler72.psr/http-message (1.0.1): Extracting archive                                                                                                                
    - Installing phabel-transpiler72.psr/http-factory (1.0.1): Extracting archive                                                                                                                
    - Installing phabel-transpiler72.paragonie/random_compat (v9.99.100): Extracting archive                                                                                                     
    - Installing phabel-transpiler72.paragonie/constant_time_encoding (v2.4.0): Extracting archive                                                                                               
    - Installing phabel-transpiler72.phpseclib/phpseclib (3.0.12): Extracting archive                                                                                                            
    - Installing phabel-transpiler72.league/uri-interfaces (2.3.0): Extracting archive                                                                                                           
    - Installing phabel-transpiler72.league/uri (6.5.0): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.erusev/parsedown (1.7.4): Extracting archive                                                                                                                
    - Installing phabel-transpiler72.danog/tg-file-decoder (0.1.8): Extracting archive                                                                                                           
    - Installing phabel-transpiler72.danog/primemodule (1.0.7): Extracting archive                                                                                                               
    - Installing phabel-transpiler72.danog/magicalserializer (1.0): Extracting archive                                                                                                           
    - Installing phabel-transpiler72.amphp/amp (v2.6.1): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.danog/loop (0.1.1): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.amphp/parser (v1.0.0): Extracting archive                                                                                                                   
    - Installing phabel-transpiler72.amphp/byte-stream (v1.8.1): Extracting archive                                                                                                              
    - Installing phabel-transpiler72.danog/ipc (0.1.15): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.daverandom/libdns (v2.0.2): Extracting archive                                                                                                              
    - Installing phabel-transpiler72.danog/libdns-json (0.1.1): Extracting archive                                                                                                               
    - Installing phabel-transpiler72.amphp/sync (v1.4.2): Extracting archive                                                                                                                     
    - Installing phabel-transpiler72.league/uri-parser (1.4.1): Extracting archive                                                                                                               
    - Installing phabel-transpiler72.kelunik/certificate (v1.1.2): Extracting archive                                                                                                            
    - Installing phabel-transpiler72.amphp/process (v1.1.3): Extracting archive                                                                                                                  
    - Installing phabel-transpiler72.amphp/windows-registry (v0.3.3): Extracting archive                                                                                                         
    - Installing phabel-transpiler72.amphp/serialization (v1.0.0): Extracting archive                                                                                                            
    - Installing phabel-transpiler72.amphp/cache (v1.5.0): Extracting archive                                                                                                                    
    - Installing phabel-transpiler72.amphp/dns (v1.2.3): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.amphp/socket (v1.2.0): Extracting archive                                                                                                                   
    - Installing phabel-transpiler72.amphp/hpack (v3.1.1): Extracting archive                                                                                                                    
    - Installing phabel-transpiler72.amphp/http (v1.6.3): Extracting archive                                                                                                                     
    - Installing phabel-transpiler72.amphp/http-client (v4.6.2): Extracting archive                                                                                                              
    - Installing phabel-transpiler72.danog/dns-over-https (0.2.6): Extracting archive                                                                                                            
    - Installing phabel-transpiler72.cash/lrucache (1.0.0): Extracting archive                                                                                                                   
    - Installing phabel-transpiler72.amphp/websocket (v1.0.2): Extracting archive                                                                                                                
    - Installing phabel-transpiler72.amphp/websocket-client (v1.0.0): Extracting archive                                                                                                         
    - Installing phabel-transpiler72.amphp/redis (v1.0.6): Extracting archive                                                                                                                    
    - Installing phabel-transpiler72.amphp/sql (v1.0.1): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.amphp/sql-common (v1.1.2): Extracting archive                                                                                                               
    - Installing phabel-transpiler72.amphp/postgres (v1.4.3): Extracting archive                                                                                                                 
    - Installing phabel-transpiler72.amphp/mysql (v2.1.2): Extracting archive                                                                                                                    
    - Installing phabel-transpiler72.monolog/monolog (2.3.5): Extracting archive                                                                                                                 
    - Installing phabel-transpiler72.amphp/log (v1.1.0): Extracting archive                                                                                                                      
    - Installing phabel-transpiler72.amphp/http-client-cookies (v1.2.0): Extracting archive                                                                                                      
    - Installing phabel-transpiler72.amphp/parallel (v1.4.1): Extracting archive                                                                                                                 
    - Installing phabel-transpiler72.amphp/file (v2.0.2): Extracting archive                                                                                                                     
    23 package suggestions were added by new dependencies, use `composer suggest` to see details.                                                                                                  
    Generating autoload files                                                                                                                                                                      
    31 packages you are using are looking for funding.                                                                                                                                             
    Use the `composer fund` command to find out more!                                                                                                                                              
    > post-update-cmd: Phabel\Composer\Plugin->onUpdate                                                                                                                                            
    Creating plugin graph...                                                                                                                                                                       
                                                                                                                                                                                                 
    *********                                                                                                                                                                                      
    * Phabel *                                                                                                                                                                                     
    *********                                                                                                                                                                                      
                                                                                                                                                                                                 
    PHP transpiler - Write and deploy modern PHP 8 code, today: https://phabel.io                                                                                                                  
                                                                                                                                                                                                 
    Transpilation in progress... 100% (3842/3842)                                                                                                                                                  
                                                                                                                                                                                                 
    Fatal error: Uncaught TypeError: Argument 1 passed to PhabelVendor\PhpParser\Builder\Param::__construct() must be of the type string, null given, called in D:\lib\vendor\phabel\phabel\src\Plugin\ClassStoragePlugin.php on line 310 and defined in D:\lib\vendor\phabel\phabel\vendor-bundle\phabel\php-pars
    er\lib\PhpParser\Builder\Param.php:24                                                                                                                                                          
    Stack trace:                                                                                                                                                                                   
    #0 D:\lib\vendor\phabel\phabel\src\Plugin\ClassStoragePlugin.php(310): PhabelVendor\PhpParser\Builder\Param->__construct(NULL)                         
    #1 D:\lib\vendor\phabel\phabel\src\Traverser.php(532): Phabel\Plugin\ClassStoragePlugin->finish()                                                      
    #2 D:\lib\vendor\phabel\phabel\src\Composer\Transformer.php(386): Phabel\Traverser->run(1)                                                             
    #3 D:\lib\vendor\phabel\phabel\src\Composer\Plugin.php(131): Phabel\Composer\Transformer->transform(Array, Array)                                      
    #4 D:\lib\vendor\phabel\phabel\vendor-bundle\phabel\php-parser\lib\PhpParser\Builder\Param.php on line 24                               
    
    Reviewed by vladdevops at 2021-12-24 09:39
  • 13. suggestion: use Semantic Versioning

    most of composer packages use Semantic Versioning, such as 1.2.3, not 1.2.3.4

    image

    docs: https://semver.org/ https://getcomposer.org/doc/articles/versions.md

    if need build number, use 1.2.3+80, not 1.2.3.80

    Build metadata MAY be denoted by appending a plus sign and a series of dot separated identifiers immediately following the patch or pre-release version. Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-]. Identifiers MUST NOT be empty. Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3—-117B344092BD.

    Reviewed by sinkcup at 2021-12-17 06:17
  • 14. Downgrade attributes?

    I'm using Symfony DependencyInjection, which uses attribute #[Required] to call a function when creating a service.

    When transpiling to PHP 7.1, #[Required] is still there.

    This is a problem, attributes should be removed from PHP 7, since it introduces a new syntax.

    But instead of removing it, could it be converted into something that doesn't break the application?

    For instance, for DependencyInjection, transforming it to phpdoc /** @required */ works.

    And for other cases? How to downgrade custom attributes?

    Reviewed by leoloso at 2021-09-27 10:15
  • 15. Can trigger own functionality when transpiling?

    I have a WordPress plugin, coded in 8.0, to be transpiled to 7.1. The required PHP version must be indicated in the plugin's main file header:

    <?php
    /*
    Requires PHP: 8.0
    */
    

    Is it possible to inject some custom functionality, so that when we trigger the transpiling, this header is converted into this?

    <?php
    /*
    Requires PHP: 7.1
    */
    
    Reviewed by leoloso at 2021-09-27 10:10
  • 16. Named arguments are not properly substituted

    Given a class:

    class Foo {
      public static function foo(string $a, string $b, string $c): self
      { ... }
    }
    

    When calling this in the original code:

    Foo::foo(a: 'hello', b: 'world', c: '!');
    

    It is transpiled to:

    Foo::foo(a: 'hello', b: 'world', c: '!');
    

    This also happens with non-static methods The rest of the transpilation seems to work correctly.

    Reviewed by ian-zunderdorp at 2021-09-22 10:30
A simple way to deploy your application to a remote location.

Deploy Plugin A simple way to deploy your application to a remote location. Currently in Active Development This plugin is incomplete. This plugin is

Apr 30, 2022
Open software engineering platform and fun adventure game

Phabricator is a collection of web applications which help software companies build better software. Phabricator includes applications for: reviewing

Jun 22, 2022
Deployer based deployment for WordPress with media and database synchronisation.

deployer-extended-wordpress What does it do? Should I use "deployer-extended-wordpress" or "deployer-extended-wordpress-composer"? Dependencies Instal

Jun 3, 2021
A deployment tool written in PHP with support for popular frameworks out of the box
A deployment tool written in PHP with support for popular frameworks out of the box

Deployer A deployment tool written in PHP with support for popular frameworks out of the box. See deployer.org for more information and documentation.

Jun 28, 2022
Elegant SSH tasks for PHP.

Laravel Envoy Introduction Laravel Envoy provides a clean, minimal syntax for defining common tasks you run on your remote servers. Using Blade style

Jul 2, 2022
The PHP Deployment Tool

Magallanes What's Magallanes? Magallanes is a deployment tool for made with PHP for PHP applications; it's quite simple to use and manage. For more in

Jun 18, 2022
A deployer library for PHP 5.3

Plum An object oriented deployer library Installation and configuration Plum does not provide and autoloader but follow the PSR-0 convention. $plum =

Feb 5, 2022
PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant.

P H I N G Thank you for using PHING! PHing Is Not GNU make; it's a PHP project build system or build tool based on Apache Ant. You can do anything wit

Jun 22, 2022
An awesome starter template to create your Salla Apps today! 🚀
An awesome starter template to create your Salla Apps today! 🚀

Salla Apps Starter Kit An awesome starter template to create your Salla Apps today! Explore our blogs » Report Bug · Request Feature . </Salla Develop

Jun 12, 2022
Quickly deploy a seedbox with self-hosted services and a web portal using Docker and docker-compose.
Quickly deploy a seedbox with self-hosted services and a web portal using Docker and docker-compose.

Seedbox Quickly deploy and configure a seedbox with self-hosted services and a web portal using Docker and a single docker-compose.yml file. Screensho

Jun 6, 2022
Deploy your PHP with PHP. Inspired by Capistrano and Vlad.

Pomander A light-weight flexible deployment tool for deploying web applications. This project was inspired by Capistrano and Vlad the Deployer, as wel

Jun 4, 2022
Deploy and execute non-PHP AWS Lambda functions from your Laravel application.

Sidecar for Laravel Deploy and execute non-PHP AWS Lambda functions from your Laravel application. Read the full docs at hammerstone.dev/sidecar/docs.

Jun 27, 2022
Build and deploy Non-Fungible Algorand Tokens with Laravel & IPFS
Build and deploy Non-Fungible Algorand Tokens with Laravel & IPFS

Introduction Laravel is a web application framework with an expressive, elegant syntax designed to make developing web apps easier and faster through

Jun 24, 2022
WPCloudDeploy is a WordPress plugin that allows you to easily deploy servers at major cloud-server providers and then install apps
WPCloudDeploy is a WordPress plugin that allows you to easily deploy servers at major cloud-server providers and then install apps

WPCloudDeploy is a WordPress plugin that allows you to easily deploy servers at major cloud-server providers and then install apps

Jun 21, 2022
A simple way to deploy your application to a remote location.

Deploy Plugin A simple way to deploy your application to a remote location. Currently in Active Development This plugin is incomplete. This plugin is

Apr 30, 2022
Deploy WordPress websites with ease.

WordPress Deployer Deploy WordPress websites with ease. This package is basically a Deployer "recipe" for WordPress websites. Installation composer re

Dec 23, 2021
Personal Knowledge Management. Use branch "minimal change" to deploy as laravel package.

Knowfox Knowfox is my Personal Knowledge Management system. Having been an keen Evernote user since 2012, I finally got around to taking my precious n

May 31, 2022
Learn how to deploy Laravel 7 project in GCP from scratch

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Nov 21, 2021
Decorate Your Models and Write Clean/Reusable Code with Presenters.

Laravel Presenter A clean way to present your model attributes without putting them in the wrong file. Installation You can install the package via co

Jun 6, 2022