GithubHelp home page GithubHelp logo

laravel / serializable-closure Goto Github PK

View Code? Open in Web Editor NEW
466.0 13.0 28.0 205 KB

Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.

License: MIT License

PHP 100.00%
php serialize closure

serializable-closure's Introduction

Serializable Closure

Build Status Total Downloads Latest Stable Version License

Introduction

This project is a fork of the excellent opis/closure: 3.x package. At Laravel, we decided to fork this package as the upcoming version 4.x is a complete rewrite on top of the FFI extension. As Laravel is a web framework, and FFI is not enabled by default in web requests, this fork allows us to keep using the 3.x series while adding support for new PHP versions.

Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.

Official Documentation

Installation

Requires PHP 7.4+

First, install Laravel Serializable Closure via the Composer package manager:

composer require laravel/serializable-closure

Usage

You may serialize a closure this way:

use Laravel\SerializableClosure\SerializableClosure;

$closure = fn () => 'james';

// Recommended
SerializableClosure::setSecretKey('secret');

$serialized = serialize(new SerializableClosure($closure));
$closure = unserialize($serialized)->getClosure();

echo $closure(); // james;

Caveats

  • Anonymous classes cannot be created within closures.
  • Attributes cannot be used within closures.
  • Serializing closures on REPL environments like Laravel Tinker is not supported.
  • Serializing closures that reference objects with readonly properties is not supported.

Contributing

Thank you for considering contributing to Serializable Closure! The contribution guide can be found in the Laravel documentation.

Code of Conduct

In order to ensure that the Laravel community is welcoming to all, please review and abide by the Code of Conduct.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

License

Serializable Closure is open-sourced software licensed under the MIT license.

serializable-closure's People

Contributors

azjezz avatar driesvints avatar grahamcampbell avatar keithbrink avatar ksassnowski avatar morloderex avatar nunomaduro avatar olivernybroe avatar stefanzweifel avatar stylecibot avatar taylorotwell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

serializable-closure's Issues

Call to a member function `bindTo()` on `null`

  • Serializable Closure Version: 1.2.2
  • Laravel Version: 9.40.1
  • PHP Version: 8.1.12
  • Database Driver & Version: postgres 14

Description:

I was working on implementing batched jobs using Bus::batch when I noticed that chaining any completion callbacks will throw an error

Call to a member function bindTo() on null

image

Note
Extracting the closure from ->then to a protected function then calling it works ๐Ÿคทโ€โ™‚๏ธ
like ->then($this->notifyOwner())

I tried it with Tinker, and I got the same results, so I tried to simplify the work and tested the example stated in the readme file here using both Tinkerwell and tinker with the same results.

Psy Shell v0.11.9 (PHP 8.1.12 โ€” cli) by Justin Hileman
> use Laravel\SerializableClosure\SerializableClosure;
> $closure = fn () => 'james';
= Closure() {#5091 โ€ฆ2}

> SerializableClosure::setSecretKey('secret');
= null

> $serialized = serialize(new SerializableClosure($closure));

   WARNING  file_get_contents(eval()'d code): Failed to open stream: No such file or directory in vendor/laravel/serializable-closure/src/Support/ReflectionClosure.php on line 829.

= "O:47:"Laravel\SerializableClosure\SerializableClosure":1:{s:12:"serializable";O:46:"Laravel\SerializableClosure\Serializers\Signed":2:{s:12:"serializable";s:174:"O:46:"Laravel\SerializableClosure\Serializers\Native":5:{s:3:"use";a:0:{}s:8:"function";s:0:"";s:5:"scope";N;s:4:"this";N;s:4:"self";s:32:"00000000000013e30000000000000000";}";s:4:"hash";s:44:"A3kjjoOaJHAtn4QzC61Wx//EuVlbAb8Q6PmTlStglb8=";}}"

> $closure = unserialize($serialized)->getClosure();

   ERROR  Call to a member function bindTo() on null in vendor/laravel/serializable-closure/src/Serializers/Native.php on line 194.

image

Steps To Reproduce:

Open tinker and try the usage example listed here

Class not found when type-hint is defined for closure created from method

  • Serializable Closure Version: v1.1.0
  • Laravel Version: not laravel scope
  • PHP Version: 8.0.15

Description:

I created closure from object method and tried to serialize it, however once unserialized it fails because of type hint used for this method.

Steps To Reproduce:

Minimal code example is below:

Entry point script:

<?php

use Laravel\SerializableClosure\SerializableClosure;
use Rela589n\PhpDecorationIssue\SerializableClosure\SerializableClosureIssue;

require 'vendor/autoload.php';

$object = new SerializableClosureIssue();

/** @var SerializableClosure $original */
$original = unserialize(
    serialize(
        new SerializableClosure(Closure::fromCallable([$object, 'reproduceIssue']))
    )
);

var_dump($original->getClosure()());

Class with method which will be used as closure:

<?php

declare(strict_types=1);

namespace Rela589n\PhpDecorationIssue\SerializableClosure;

use JetBrains\PhpStorm\Immutable;

#[Immutable]
final class SerializableClosureIssue
{
    public function reproduceIssue(): Issue
    {
        return new Issue();
    }
}

Class for type-hinting in method:

<?php

declare(strict_types=1);

namespace Rela589n\PhpDecorationIssue\SerializableClosure;

use JetBrains\PhpStorm\Immutable;

#[Immutable]
final class Issue
{

}

The foregoing code gives next issue:

PHP Fatal error:  Uncaught Error: Class "Issue" not found in laravel-serializable-closure://function (): \Issue
    {
        return new \Issue();
    }:4
Stack trace:
#0 /home/rela589n/projects/php-decoration-issue/serializable-closure.php(17): Rela589n\PhpDecorationIssue\SerializableClosure\SerializableClosureIssue::{closure}()
#1 {main}
  thrown in laravel-serializable-closure://function (): \Issue
    {
        return new \Issue();
    } on line 4

Thanks

Thank you for this amazing package, it really complements missing PHP feature.

Using php's 8.1 first class callable method leaves an xdebug in limbo

When a closure is passed via a first class callable method xdebug doesn't know where it is.

<?php
namespace Foo;
include_once '/path/to/laravel/vendor/autoload.php';

use Laravel\SerializableClosure\SerializableClosure;

class Bar {
    public function __construct(public int $x = 0) {

    }

    public function foo(int $a) {
        $y = $a + $this->x;
        xdebug_break();
    }
}

$bar = new Bar();
$closure = new SerializableClosure($bar->foo(...));
$x = serialize($closure);
echo $x;
$z = unserialize($x);
$z->getClosure()(2);

image

When a closure is passed via a first class callable method, maybe serialize the given class, then call the method on the deserialized class?
Currently we need to use string references instead of these first class callable features we have now available.

Using php's 8.1 first class callable method leaves an xdebug in limbo

Serializable Closure Version

1.3.3

PHP Version

8.1.19

Description

When a closure is passed via a first class callable method xdebug doesn't know where it is.

image

When a closure is passed via a first class callable method, maybe serialize the given class, then call the method on the deserialized class?
Currently we need to use string references instead of these first class callable features we have now available.

Steps To Reproduce

<?php
namespace Foo;
include_once '/path/to/laravel/vendor/autoload.php';

use Laravel\SerializableClosure\SerializableClosure;

class Bar {
    public function __construct(public int $x = 0) {

    }

    public function foo(int $a) {
        $y = $a + $this->x;
        xdebug_break();
    }
}

$bar = new Bar();
$closure = new SerializableClosure($bar->foo(...));
$x = serialize($closure);
echo $x;
$z = unserialize($x);
$z->getClosure()(2);

Memory leak in anonymous function

  • Serializable Closure Version: 1.1.1
  • Laravel Version: -
  • PHP Version: 7.4.3
  • Database Driver & Version: -

Description:

Memory leak in anonymous function when using SerializableClosure

Steps To Reproduce:

use Laravel\SerializableClosure\SerializableClosure;

$baseMemory = memory_get_usage();

for ($i = 0; $i < PHP_INT_MAX; $i++) {
    $s = serialize(new SerializableClosure(fn() => 'james'));
    $u = unserialize($s);

    echo sprintf('%8d: ', $i), memory_get_usage() - $baseMemory, PHP_EOL;
    unset($s, $u);
}

It also occurs with the opis/closure package.
Link to a repository with the tests: https://github.com/r4y7s/laravel-serializable-closure-memory-leak

serialization crashes on typed properties

  • Serializable Closure Version: 1.2.0
  • Laravel Version: 9.17.0
  • PHP Version: 8.1.7
  • Database Driver & Version:

Description:

When a class is using a typed property that accepts closures, the code crashes, as you can't assign Native object where a Closure should be.

Steps To Reproduce:

class test {

    protected Closure $closure;

    public function __construct(Closure $closure)
    {
        $this->closure = $closure;
    }
}

$test = new test(function(){});

serialize(new SerializableClosure(
    function() use ($test){

    }
));

PHP 7.3 is not supported.

  • Serializable Closure Version: Latest
  • Laravel Version: 8.75
  • PHP Version: 7.3
  • Database Driver & Version: MySQL

Description:

I was trying to deploy my laravel app with jetstream installed, the only supported PHP version for the serve is 7.3. After deploying, this error shows.

Laravel\SerializableClosure\Exceptions\PhpVersionNotSupportedException PHP 7.3 is not supported.

Laravel\SerializableClosure\SerializableClosure::getClosure
vendor/laravel/serializable-closure/src/SerializableClosure.php:59
    if (\PHP_VERSION_ID < 70400) {

            throw new PhpVersionNotSupportedException();

        }

 

        return call_user_func_array($this->serializable, func_get_args());

    }

 

    /**

     * Gets the closure.

     *

     * @return \Closure

     */

    public function getClosure()

    {

        if (\PHP_VERSION_ID < 70400) {

            throw new PhpVersionNotSupportedException();

        }

Is there any workaround?

Laravel\SerializableClosure\Exceptions\InvalidSignatureException

  • Serializable Closure Version: 1.2.2
  • Laravel Version: 9.45.1
  • PHP Version: 8.1.13
  • Database Driver & Version: 10.5.18-MariaDB - MariaDB Server | libmysql - mysqlnd 7.4.33
  • Laravel queue driver: database

Description:

Whenever I dispatch a job, the job instantly gets into failed-jobs table and the exception message is:

Laravel\SerializableClosure\Exceptions\InvalidSignatureException: Your serialized closure might have been modified or it's unsafe to be unserialized. in /home/amralab/shein-automation.amralab.com/vendor/laravel/serializable-closure/src/Serializers/Signed.php:83
Stack trace:
#0 [internal function]: Laravel\SerializableClosure\Serializers\Signed->__unserialize(Array)
#1 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(97): unserialize('O:16:"App\\Jobs\\...')
#2 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php(60): Illuminate\Queue\CallQueuedHandler->getCommand(Array)
#3 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php(98): Illuminate\Queue\CallQueuedHandler->call(Object(Illuminate\Queue\Jobs\DatabaseJob), Array)
#4 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(425): Illuminate\Queue\Jobs\Job->fire()
#5 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(375): Illuminate\Queue\Worker->process('database', Object(Illuminate\Queue\Jobs\DatabaseJob), Object(Illuminate\Queue\WorkerOptions))
#6 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/Worker.php(173): Illuminate\Queue\Worker->runJob(Object(Illuminate\Queue\Jobs\DatabaseJob), 'database', Object(Illuminate\Queue\WorkerOptions))
#7 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(147): Illuminate\Queue\Worker->daemon('database', 'default', Object(Illuminate\Queue\WorkerOptions))
#8 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php(130): Illuminate\Queue\Console\WorkCommand->runWorker('database', 'default')
#9 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Illuminate\Queue\Console\WorkCommand->handle()
#10 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Container/Util.php(41): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
#11 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(93): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#12 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(37): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#13 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Container/Container.php(651): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#14 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Console/Command.php(182): Illuminate\Container\Container->call(Array)
#15 /home/amralab/shein-automation.amralab.com/vendor/symfony/console/Command/Command.php(312): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#16 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Console/Command.php(152): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#17 /home/amralab/shein-automation.amralab.com/vendor/symfony/console/Application.php(1022): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#18 /home/amralab/shein-automation.amralab.com/vendor/symfony/console/Application.php(314): Symfony\Component\Console\Application->doRunCommand(Object(Illuminate\Queue\Console\WorkCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#19 /home/amralab/shein-automation.amralab.com/vendor/symfony/console/Application.php(168): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#20 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Console/Application.php(102): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#21 /home/amralab/shein-automation.amralab.com/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(155): Illuminate\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#22 /home/amralab/shein-automation.amralab.com/artisan(37): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#23 {main}

Note: It was all OK and working, so far I remember I just added an eloquent update event listener

 protected static function boot()
    {
        parent::boot();
        /**
         * Write code on Method
         *
         * @return void
         */
        static::updated(queueable(function ($order) {
            send_update($order);
        }));
    }

and after adding that, the jobs doesn't work.

Edit: I have also edited a file inside vendor folder (laraveldaily/laravel-invoices)

Point to be noted: All the functionalities except laravel queue works fine.
Hopefully someone will help me. I will also point this issue in laravel.

syntax error, unexpected token "list", expecting "("

Serializable Closure Version

1.3.3

PHP Version

8.2.15

Description

Recently I upgraded my Laravel app from 8.x to 10.x. Along with PHP from 7.4 to 8.2. Since doing this, I'm running into the following exception(s):

syntax error, unexpected token "list", expecting "("

On laravel-serializable-closure://function list(\Illuminate\Http\Request $request)
    {
        // Check if we're filtering based on team or not
        $teamPublicKey = $request->get('team_public_key', false);
        $userId        = (int)$request->get('user_id', 0);
        // Check if we should load the team's tags or the personal tags
        $tagCategoryName = $teamPublicKey ? \App\Models\Tags\TagCategory::DUNGEON_ROUTE_TEAM : \App\Models\Tags\TagCategory::DUNGEON_ROUTE_PERSONAL;
        $tagCategoryId   = \App\Models\Tags\TagCategory::ALL[$tagCategoryName];

        // Which relationship should be load?
        $tagsRelationshipName = $teamPublicKey ? 'tagsteam' : 'tagspersonal';

        $routes = \App\Models\DungeonRoute\DungeonRoute::with(['faction', 'specializations', 'classes', 'races', 'dungeon', 'affixes',
                                      'author', 'routeattributes', 'ratings', 'metricAggregations', $tagsRelationshipName])
            // Specific selection of dungeon columns; if we don't do it somehow the Affixes and Attributes of the result is cleared.
            // Probably selecting similar named columns leading Laravel to believe the relation is already satisfied.
            ->selectRaw('dungeon_routes.*, mapping_versions.enemy_forces_required_teeming, mapping_versions.enemy_forces_required, MAX(mapping_versions.id) as dungeon_latest_mapping_version_id')
            ->join('dungeons', 'dungeons.id', '=', 'dungeon_routes.dungeon_id')
            ->join('mapping_versions', 'mapping_versions.id', 'dungeon_routes.mapping_version_id')
            // Only non-try routes, combine both where() and whereNull(), there are inconsistencies where one or the
            // other may work, this covers all bases for both dev and live
            ->where(function (\Illuminate\Database\Eloquent\Builder $query) {
                $query->where('expires_at', 0);
                $query->orWhereNull('expires_at');
            })
            // required for the enemy forces calculation
            ->groupBy(['dungeon_routes.id', 'mapping_versions.dungeon_id']);

        /** @var User $user */
        $user = \Illuminate\Support\Facades\Auth::user();
        $mine = false;

        // If we're viewing a team's route this will be filled
        $team = null;

        $requirements = $request->get('requirements', []);

        // Enough enemy forces
        if (in_array('enough_enemy_forces', $requirements, true)) {
            // Clear group by
            $routes = $routes
                ->whereRaw('IF(dungeon_routes.teeming, dungeon_routes.enemy_forces >= mapping_versions.enemy_forces_required_teeming,
                                    dungeon_routes.enemy_forces >= mapping_versions.enemy_forces_required)');
        }

        $tags = $request->get('tags', []);

        // Must have these tags
        if (!empty($tags)) {
            $routes = $routes
                ->join('tags', 'dungeon_routes.id', '=', 'tags.model_id')
                ->where('tags.tag_category_id', $tagCategoryId)
                ->whereIn('tags.name', $tags)
                // https://stackoverflow.com/a/3267635/771270; this enables AND behaviour for multiple tags
                ->havingRaw(sprintf('COUNT(DISTINCT tags.name) >= %d', count($tags)));
        }

        // If logged in
        if ($user !== null) {
            $mine = $request->get('mine', false);

            // Filter by our own user if logged in
            if ($mine) {
                $routes = $routes->where('author_id', $user->id);
            }

            // Handle favorites
            if (in_array('favorite', $requirements, true) || $request->get('favorites', false)) {
                $routes = $routes->whereHas('favorites', function ($query) use (&$user) {
                    /** @var $query Builder */
                    $query->where('dungeon_route_favorites.user_id', $user->id);
                });
            }

            // Handle team if set
            if ($teamPublicKey) {
                // @TODO Policy?
                // You must be a member of this team to retrieve their routes
                $team = \App\Models\Team::where('public_key', $teamPublicKey)->firstOrFail();
                if (!$team->isUserMember($user)) {
                    abort(403, 'Unauthorized');
                }

                // If available, we need all routes which MAY be assigned to this team, so all routes where
                // team_id = null and the author is one of the team members
                $available = intval($request->get('available', 0));
                if ($available === 1) {
                    $routes = $routes->whereNull('team_id');
                    $routes = $routes->whereIn('author_id', $team->members->pluck(['id'])->toArray());
                } else {
                    // Where the route is part of the requested team
                    $routes = $routes->where('team_id', $team->id);
                }

                $routes = $routes->whereIn('published_state_id',
                    [\App\Models\PublishedState::ALL[\App\Models\PublishedState::TEAM], \App\Models\PublishedState::ALL[\App\Models\PublishedState::WORLD]]
                );
                //                $routes = $routes->whereHas('teams', function ($query) use (&$user, $teamId) {
                //                    /** @var $query Builder */
                //                    $query->where('team_dungeon_routes.team_id', $teamId);
                //                });
            }
        }

        // Add a filter for a specific user if the request called for it
        if ($userId > 0) {
            $routes = $routes->where('author_id', $userId);
        }

        // Only show routes that are visible to the world, unless we're viewing our own routes
        if ((!$mine && !$teamPublicKey) || $userId !== 0) {
            $routes = $routes->where('published_state_id', \App\Models\PublishedState::ALL[\App\Models\PublishedState::WORLD]);
        }

        // Visible here to allow proper usage of indexes
        if (!$mine) {
            $routes = $routes->visible();
        }

        $dtHandler = new \App\Logic\Datatables\DungeonRoutesDatatablesHandler($request);

        return $dtHandler->setBuilder($routes)->addColumnHandler([
            // Handles any searching/filtering based on dungeon
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\DungeonColumnHandler($dtHandler),
            // Handles any searching/filtering based on DR Affixes
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\DungeonRouteAffixesColumnHandler($dtHandler),
            // Sort by the amount of attributes
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\DungeonRouteAttributesColumnHandler($dtHandler),
            // Allow sorting by author name
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\AuthorNameColumnHandler($dtHandler),
            // Allow sorting by enemy forces
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\EnemyForcesColumnHandler($dtHandler),
            // Allow sorting by views
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\ViewsColumnHandler($dtHandler),
            // Allow sorting by rating
            new \App\Logic\Datatables\ColumnHandler\DungeonRoutes\RatingColumnHandler($dtHandler),
        ])->applyRequestToBuilder()->getResult();
    }:2 (code 0)
Stacktrace:
#0 [internal function]: Laravel\SerializableClosure\Serializers\Native->__unserialize()
#1 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php(22): unserialize()
#2 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Route.php(537): Illuminate\Routing\RouteSignatureParameters::fromAction()
#3 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php(80): Illuminate\Routing\Route->signatureParameters()
#4 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php(28): Illuminate\Routing\ImplicitRouteBinding::resolveBackedEnumsForRoute()
#5 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Router.php(959): Illuminate\Routing\ImplicitRouteBinding::resolveForRoute()
#6 [internal function]: Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#7 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Router.php(961): call_user_func()
#8 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Router->substituteImplicitBindings()
#9 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Routing\Middleware\SubstituteBindings->handle()
#10 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#11 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle()
#12 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#13 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#14 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#15 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#16 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Session\Middleware\StartSession->handle()
#17 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#18 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#19 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#20 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#21 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#22 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Router.php(805): Illuminate\Pipeline\Pipeline->then()
#23 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\Routing\Router->runRouteWithinStack()
#24 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\Routing\Router->runRoute()
#25 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\Routing\Router->dispatchToRoute()
#26 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\Routing\Router->dispatch()
#27 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()
#28 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#29 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#30 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle()
#31 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#32 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#33 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#34 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#35 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()
#36 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(99): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#37 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#38 /var/www/html/keystone.guru.staging/releases/19/vendor/beyondcode/laravel-server-timing/src/Middleware/ServerTimingMiddleware.php(36): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#39 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BeyondCode\ServerTiming\Middleware\ServerTimingMiddleware->handle()
#40 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#41 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\Pipeline\Pipeline->then()
#42 /var/www/html/keystone.guru.staging/releases/19/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#43 /var/www/html/keystone.guru.staging/releases/19/public/index.php(51): Illuminate\Foundation\Http\Kernel->handle()
#44 {main}

But also this one, which is much shorter:

syntax error, unexpected token "new", expecting "("

On laravel-serializable-closure://function new(): \Illuminate\View\View
    {
        return view('dungeonroute.new');
    }:2 (code 0)
Stacktrace:
#0 [internal function]: Laravel\SerializableClosure\Serializers\Native->__unserialize()
#1 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php(22): unserialize()
#2 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Route.php(537): Illuminate\Routing\RouteSignatureParameters::fromAction()
#3 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php(80): Illuminate\Routing\Route->signatureParameters()
#4 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php(28): Illuminate\Routing\ImplicitRouteBinding::resolveBackedEnumsForRoute()
#5 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Router.php(959): Illuminate\Routing\ImplicitRouteBinding::resolveForRoute()
#6 [internal function]: Illuminate\Routing\Router->Illuminate\Routing\{closure}()
#7 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Router.php(961): call_user_func()
#8 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(41): Illuminate\Routing\Router->substituteImplicitBindings()
#9 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Routing\Middleware\SubstituteBindings->handle()
#10 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#11 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle()
#12 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#13 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\View\Middleware\ShareErrorsFromSession->handle()
#14 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#15 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\Session\Middleware\StartSession->handleStatefulRequest()
#16 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Session\Middleware\StartSession->handle()
#17 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#18 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle()
#19 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#20 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Cookie\Middleware\EncryptCookies->handle()
#21 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#22 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Router.php(805): Illuminate\Pipeline\Pipeline->then()
#23 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Router.php(784): Illuminate\Routing\Router->runRouteWithinStack()
#24 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Router.php(748): Illuminate\Routing\Router->runRoute()
#25 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Routing/Router.php(737): Illuminate\Routing\Router->dispatchToRoute()
#26 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(200): Illuminate\Routing\Router->dispatch()
#27 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}()
#28 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#29 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#30 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle()
#31 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#32 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\Foundation\Http\Middleware\TransformsRequest->handle()
#33 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\TrimStrings->handle()
#34 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#35 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle()
#36 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(99): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#37 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle()
#38 /var/www/html/keystone.guru.staging/releases/18/vendor/beyondcode/laravel-server-timing/src/Middleware/ServerTimingMiddleware.php(36): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#39 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): BeyondCode\ServerTiming\Middleware\ServerTimingMiddleware->handle()
#40 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}()
#41 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(175): Illuminate\Pipeline\Pipeline->then()
#42 /var/www/html/keystone.guru.staging/releases/18/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(144): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter()
#43 /var/www/html/keystone.guru.staging/releases/18/public/index.php(51): Illuminate\Foundation\Http\Kernel->handle()
#44 {main}

I feel like something's not right in these files which causes the serializer to break. I've read a bunch in this Github issue tracker and the 2 issues I could find were both related to that. It's just that I have no idea where to possibly start looking.

I tried commenting all other code in the controller except those routes but to no avail, the issue persists. The strange thing is is that on my local environment using Docker this error doesn't come and everything works fine. No amount of clearing caches has resolved this either.

I'm hoping anyone here knows how to proceed since I'm effectively stuck with this one.

Steps To Reproduce

Two offending controllers:

https://github.com/Wotuu/keystone.guru/blob/development/app/Http/Controllers/Ajax/AjaxDungeonRouteController.php#L80
https://github.com/Wotuu/keystone.guru/blob/development/app/Http/Controllers/DungeonRouteController.php#L39

Accessing the routes associated with this function produces the linked error.

It seems that for both these files the first function is affected, but not the others. In other controllers all functions work fine.

See also https://staging.keystone.guru/new.

Sorry I do not have better reproduction steps. Again it works perfectly fine on localhost but not on my staging environment.

Stream wrapper collision

  • Serializable Closure Version: 1.0.2
  • Laravel Version: 8.62.0
  • PHP Version: 8.0.0
  • Database Driver & Version: Does not apply

Description:

We're seeing some exceptions thrown on our queues, because both of the libraries are trying to register the same stream protocol:

stream_wrapper_register(): Protocol closure:// is already defined.

opis/closure author says he gained the right to dont check if it's in use:
opis/closure#106

Maybe laravel/serializable-closure should register a different protocol name

Steps To Reproduce:

  1. Use laravel/seriazable-closure somewhere
  2. Try to use opis/closure on the same process (octane or just a queue)

An exception will be thrown


Related conversation laravel/framework#38801

Namespace resolution missing for named parameter during serialization

Serializable Closure Version

1.3.0

PHP Version

8.2.7

Description

Hi, I've hit an issue that I think may be a bug.
I previously thought it was was an issue in PHP-DI, but during my investigation I isolated it to this library (original report here: PHP-DI/PHP-DI#855).
Long story short: if a closure uses a combination of named parameters and a class that is not in the global namespace, it fails when the closure is unserialized.

Steps To Reproduce

// class.php
namespace My\Name\Space;
class MyClass {
  public const A = 1;

  public function __construct(string $arg1, int $arg2) {}
}
// main.php
require_once __DIR__ . '/vendor/autoload.php';
include __DIR__ . '/class.php';

use Laravel\SerializableClosure\UnsignedSerializableClosure;
use My\Name\Space\MyClass;

$closure = static function (): MyClass {
  return new MyClass(arg2: MyClass::A);
};

$s = serialize(new UnsignedSerializableClosure($closure));
var_dump(unserialize($s)->getClosure()());
$ php main.php 
PHP Fatal error:  Uncaught Error: Class "MyClass" not found in laravel-serializable-closure://static function (): \My\Name\Space\MyClass {
  return new \My\Name\Space\MyClass(arg2: MyClass::A);
}:3
Stack trace:
#0 /home/flavio/Documents/open-source/serialize-bug/main.php(14): {closure}()
#1 {main}
  thrown in laravel-serializable-closure://static function (): \My\Name\Space\MyClass {
  return new \My\Name\Space\MyClass(arg2: MyClass::A);
} on line 3

Unserialize from opis/closure serialization?

Hello,

We are migrating from opis/closure to this library, has anyone managed to unserialize data from opis/closure serialization into instances of Laravel\SerializableClosure\SerializableClosure ?
It would help with migration from one to the other. I would like to avoid to depend upon both library just for this. But I could not find much information about tricking php unserialize to use a class instead of another.

Serializable closure breaks the Symfony var-dumper

Serializable Closure Version

1.3.1

PHP Version

8.2.8

Description

This issue is again related to an Exception, but in a more typical way: when you try to dump() an Exception with laravel-serializable-closure in the stack trace, it will break inside the Symfony var-dumper:

Unexpected ErrorException thrown from a caster: is_file(): Unable to find the wrapper "laravel-serializable-closure" - did you forget to enable it when you configured PHP?

It's happening in the following part of Symfony\Component\VarDumper\Caster\ExceptionCaster, which attempts to analyze the stack trace:

                if (is_file($f['file']) && 0 <= self::$srcContext) {
                    if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {

This seems to be an actual bug, as dump() is a standard tool in Laravel.

Steps To Reproduce

As above, just dump() an Exception that's originated in the Serializable Closure.

I am not able to send serialized closure in queue job.

  • Serializable Closure Version: ^1.2
  • Laravel Version:8.75
  • PHP Version: 7.4

Description:

public function serializeRequest() {
        $closure = function() {
            return request();
        };
        return serialize(new SerializableClosure($closure));
}

$request = $this->serializeRequest();
dispatch(new ProcessRequest( $request)); //send request() in queue Job

when I send request() this way in queue Job:

I get this error:
Serialization of 'Closure' is not allowed
or
Serialization of 'PDO' is not allowed

Is there any other way I can send request() into queue job?

Serialization of 'CurlHandle' is not allowed

  • Serializable Closure Version: ^1.0
  • Laravel Version: 8.65
  • PHP Version: 8
  • Database Driver & Version:

Description:

I'm using laravel octane (v1.14) and when i want to perform a concurrent request i'll get this error:

Octane::concurrently([
            fn() => Telegram::sendMessage([]),
            fn() => Telegram::sendMessage([])
        ], 100);
Serialization of 'CurlHandle' is not allowed#0 /app/vendor/laravel/serializable-closure/src/Serializers/Signed.php(68): serialize()
#1 [internal function]: Laravel\SerializableClosure\Serializers\Signed->__serialize()
#2 /app/vendor/laravel/octane/src/Swoole/SwooleTaskDispatcher.php(37): Swoole\Server->taskWaitMulti()
#3 /app/vendor/laravel/octane/src/Concerns/ProvidesConcurrencySupport.php(28): Laravel\Octane\Swoole\SwooleTaskDispatcher->resolve()
#4 /app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php(261): Laravel\Octane\Octane->concurrently()

Syntax errors caused by namespace resolution

Serializable Closure Version

1.3.2

PHP Version

8.2

Description

It seems that when there is a switch statement that contains a class reference the namespace resolution that happens during serialization causes the colon to be removed at the end of the case line, steps to reproduce contains a CLI command to replicate this behavior.

syntax error, unexpected token "return"

Steps To Reproduce

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Laravel\SerializableClosure\Serializers\Native;

class DebugCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'debug';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     */
    public function handle()
    {
        $cacheClosure = static function(): array {
            $var = new \stdClass();

            switch(true) {
                case $var instanceof \stdClass:
                    return true;

                default:
                    return false;
            }
        };

        $cacheData = [
           'helloWorld' =>  $cacheClosure
        ];

        Native::wrapClosures($cacheData, new \SplObjectStorage());
        $cacheContent = serialize($cacheData);

        dump($cacheContent);exit;

        unserialize($cacheContent);exit;
    }
}

Support for PHP 8.1 enums

Hi, good job with this fork!

I recently ran into a situation, where a class has an enum property, which prevents the call to ReflectionClass->newInstanceWithoutConstructor(), since an enum cannot be instantiated:

PHP Fatal error:  Uncaught Error: Cannot instantiate enum Project\AnEnum in ...\vendor\laravel\serializable-closure\src\Serializers\Native.php:261
Stack trace:
#0 ...\vendor\laravel\serializable-closure\src\Serializers\Native.php(261): ReflectionClass->newInstanceWithoutConstructor()
#1 ...\vendor\laravel\serializable-closure\src\Serializers\Native.php(282): Laravel\SerializableClosure\Serializers\Native::wrapClosures(Object(Project\AnEnum), Object(Laravel\SerializableClosure\Support\ClosureScope))
#2 ...\vendor\laravel\serializable-closure\src\Serializers\Native.php(122): Laravel\SerializableClosure\Serializers\Native::wrapClosures(Object(Project\ParentClass), Object(Laravel\SerializableClosure\Support\ClosureScope))
#3 [internal function]: Laravel\SerializableClosure\Serializers\Native->__serialize()
...

Any intention of supporting this use-case?

Serialization of an Exception is not possible inside the closure

Serializable Closure Version

1.3.1

PHP Version

8.2.8

Description

Serialization of an Exception inside the serializable closure results with the Serialization of 'Closure' is not allowed exception. This is most likely caused by an attempt to serialize the stack trace, which contains the serializable closure itself, but this time without the ability to do its magic.

And, frankly, I'm not sure if there's anything that can be done about it, other than adding another warning to the documentation. You can't do much with an already existing Exception object and its stack trace.

Steps To Reproduce

This issue is very easy to reproduce:

$closure = new \Laravel\SerializableClosure\SerializableClosure(function() { return serialize(new \Exception('boom')); });
echo $closure();

This works as expected:

$closure = function() { return serialize(new \Exception('boom')); };
echo $closure();

Call to undefined method Laravel\SerializableClosure\Serializers\Native::from()

  • Serializable Closure Version: 1.0.0
  • Laravel Version: 8.62.0
  • PHP Version: 8.0.11
  • Database Driver & Version: -

Description:

I get Call to undefined method Laravel\SerializableClosure\Serializers\Native::from() when I serialize a closure that is using a $this object that contains closures.

Steps To Reproduce:

class BindToMe
{
    private Closure $closure;

    public function __construct(Closure $closure)
    {
        $this->closure = $closure;
    }

    public function hello()
    {
        echo ($this->closure)();
    }
}

$serializable = new \Laravel\SerializableClosure\SerializableClosure(
    Closure::bind(
        function () {
            $this->hello();
        },
        new BindToMe(fn() => 'Hi')
    )
);

serialize($serializable);

Unable to find the called function

Serializable Closure Version

1.3.0

PHP Version

8.2.4

Description

I don't know how to explain the problem. so i try with an example:

This is my code:

use function DevDasher\PTB\_endConversation;
use function DevDasher\PTB\_input;
use function DevDasher\PTB\_row;
use function DevDasher\PTB\_text;
use function DevDasher\PTB\configurePTB;
use function DevDasher\PTB\KeyboardButton;
use function DevDasher\PTB\onMessage;
use function DevDasher\PTB\onMessageText;
use function DevDasher\PTB\ReplyKeyboardMarkup;
use function DevDasher\PTB\run;
use function DevDasher\PTB\sendMessage;

//...
//...
//...
//...
    _input(
        prompt: 'Send your name:',
        next_step: function() {
            _input(
                conversation_data: ['name' => _text()],
                prompt: 'Send your age:',
                next_step: function($name) {
                    _input(
                        conversation_data: ['age' => _text()],
                        prompt: fn() => sendMessage(
                            text: 'Pick your gender:',
                            reply_markup: ReplyKeyboardMarkup(
                                keyboard: [
                                    _row(KeyboardButton(text: 'Male'), KeyboardButton(text: 'Female')),
                                ],
                                resize_keyboard: true,
                            ),
                        ),
                        next_step: function($name, $age) {
                            $gender = _text();
                            $validGenders = ['male', 'female'];
                            if (!in_array(strtolower($gender), $validGenders)) {
                                return sendMessage(text: 'Invalid gender!');
                            }
                            sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: {$gender}");
                            _endConversation();
                        },
                    );
                },
            );
        }
    );
//...
//...
//...
//...

In the above code:

  • I'm sterilizing the value of the parameter next_step in the _input function each time and I store that in cache
  • In subsequent requests, I deserialize that and call the closure and pass some parameters to it.

But i get this long error:

PS D:\Documents\Code\ptb-php> php .\temp\bot.php
Listening...
PHP Fatal error:  Uncaught Error: Call to undefined function ReplyKeyboardMarkup() in laravel-serializable-closure://function($name) {
                \DevDasher\PTB\_input(
                    prompt: fn() => \DevDasher\PTB\sendMessage(
                        text: 'Pick your gender:',
                        reply_markup: ReplyKeyboardMarkup(
                            keyboard: [
                                \DevDasher\PTB\_row(\DevDasher\PTB\KeyboardButton(text: 'Male'), \DevDasher\PTB\KeyboardButton('Female')),
                            ],
                            resize_keyboard: true,
                        )
                    ),
                    next_step: function($name, $age) {
                        $gender = \DevDasher\PTB\_text();
                        $validGenders = ['male', 'female'];
                        if (!\in_array(\strtolower($gender), $validGenders)) {
                            return \DevDasher\PTB\sendMessage(text: 'Invalid gender!');
                        }
                        \DevDasher\PTB\sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: $gender");
                        \DevDasher\PTB\_endConversation();
                    },
                    conversation_data: ['age' => \DevDasher\PTB\_text()],
                );
            }:6
Stack trace:
#0 D:\Documents\Code\ptb-php\src\PTB.php(6617): {closure}()
#1 laravel-serializable-closure://function($name) {
                \DevDasher\PTB\_input(
                    prompt: fn() => \DevDasher\PTB\sendMessage(
                        text: 'Pick your gender:',
                        reply_markup: ReplyKeyboardMarkup(
                            keyboard: [
                                \DevDasher\PTB\_row(\DevDasher\PTB\KeyboardButton(text: 'Male'), \DevDasher\PTB\KeyboardButton('Female')),
                            ],
                            resize_keyboard: true,
                        )
                    ),
                    next_step: function($name, $age) {
                        $gender = \DevDasher\PTB\_text();
                        $validGenders = ['male', 'female'];
                        if (!\in_array(\strtolower($gender), $validGenders)) {
                            return \DevDasher\PTB\sendMessage(text: 'Invalid gender!');
                        }
                        \DevDasher\PTB\sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: $gender");
                        \DevDasher\PTB\_endConversation();
                    },
                    conversation_data: ['age' => \DevDasher\PTB\_text()],
                );
            }(3): DevDasher\PTB\_input(Object(Closure), Object(Closure), Array)
#2 D:\Documents\Code\ptb-php\src\PTB.php(6472): {closure}('Pooria')
#3 D:\Documents\Code\ptb-php\src\PTB.php(6380): DevDasher\PTB\__fireHandlers(Array)
#4 D:\Documents\Code\ptb-php\src\PTB.php(6728): DevDasher\PTB\__processCurrentUpdate()
#5 D:\Documents\Code\ptb-php\temp\bot.php(97): DevDasher\PTB\run()
#6 {main}
  thrown in laravel-serializable-closure://function($name) {
                \DevDasher\PTB\_input(
                    prompt: fn() => \DevDasher\PTB\sendMessage(
                        text: 'Pick your gender:',
                        reply_markup: ReplyKeyboardMarkup(
                            keyboard: [
                                \DevDasher\PTB\_row(\DevDasher\PTB\KeyboardButton(text: 'Male'), \DevDasher\PTB\KeyboardButton('Female')),
                            ],
                            resize_keyboard: true,
                        )
                    ),
                    next_step: function($name, $age) {
                        $gender = \DevDasher\PTB\_text();
                        $validGenders = ['male', 'female'];
                        if (!\in_array(\strtolower($gender), $validGenders)) {
                            return \DevDasher\PTB\sendMessage(text: 'Invalid gender!');
                        }
                        \DevDasher\PTB\sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: $gender");
                        \DevDasher\PTB\_endConversation();
                    },
                    conversation_data: ['age' => \DevDasher\PTB\_text()],
                );
            } on line 6

Fatal error: Uncaught Error: Call to undefined function ReplyKeyboardMarkup() in laravel-serializable-closure://function($name) {
                \DevDasher\PTB\_input(
                    prompt: fn() => \DevDasher\PTB\sendMessage(
                        text: 'Pick your gender:',
                        reply_markup: ReplyKeyboardMarkup(
                            keyboard: [
                                \DevDasher\PTB\_row(\DevDasher\PTB\KeyboardButton(text: 'Male'), \DevDasher\PTB\KeyboardButton('Female')),
                            ],
                            resize_keyboard: true,
                        )
                    ),
                    next_step: function($name, $age) {
                        $gender = \DevDasher\PTB\_text();
                        $validGenders = ['male', 'female'];
                        if (!\in_array(\strtolower($gender), $validGenders)) {
                            return \DevDasher\PTB\sendMessage(text: 'Invalid gender!');
                        }
                        \DevDasher\PTB\sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: $gender");
                        \DevDasher\PTB\_endConversation();
                    },
                    conversation_data: ['age' => \DevDasher\PTB\_text()],
                );
            }:6
Stack trace:
#0 D:\Documents\Code\ptb-php\src\PTB.php(6617): {closure}()
#1 laravel-serializable-closure://function($name) {
                \DevDasher\PTB\_input(
                    prompt: fn() => \DevDasher\PTB\sendMessage(
                        text: 'Pick your gender:',
                        reply_markup: ReplyKeyboardMarkup(
                            keyboard: [
                                \DevDasher\PTB\_row(\DevDasher\PTB\KeyboardButton(text: 'Male'), \DevDasher\PTB\KeyboardButton('Female')),
                            ],
                            resize_keyboard: true,
                        )
                    ),
                    next_step: function($name, $age) {
                        $gender = \DevDasher\PTB\_text();
                        $validGenders = ['male', 'female'];
                        if (!\in_array(\strtolower($gender), $validGenders)) {
                            return \DevDasher\PTB\sendMessage(text: 'Invalid gender!');
                        }
                        \DevDasher\PTB\sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: $gender");
                        \DevDasher\PTB\_endConversation();
                    },
                    conversation_data: ['age' => \DevDasher\PTB\_text()],
                );
            }(3): DevDasher\PTB\_input(Object(Closure), Object(Closure), Array)
#2 D:\Documents\Code\ptb-php\src\PTB.php(6472): {closure}('Pooria')
#3 D:\Documents\Code\ptb-php\src\PTB.php(6380): DevDasher\PTB\__fireHandlers(Array)
#4 D:\Documents\Code\ptb-php\src\PTB.php(6728): DevDasher\PTB\__processCurrentUpdate()
#5 D:\Documents\Code\ptb-php\temp\bot.php(97): DevDasher\PTB\run()
#6 {main}
  thrown in laravel-serializable-closure://function($name) {
                \DevDasher\PTB\_input(
                    prompt: fn() => \DevDasher\PTB\sendMessage(
                        text: 'Pick your gender:',
                        reply_markup: ReplyKeyboardMarkup(
                            keyboard: [
                                \DevDasher\PTB\_row(\DevDasher\PTB\KeyboardButton(text: 'Male'), \DevDasher\PTB\KeyboardButton('Female')),
                            ],
                            resize_keyboard: true,
                        )
                    ),
                    next_step: function($name, $age) {
                        $gender = \DevDasher\PTB\_text();
                        if (!\in_array(\strtolower($gender), $validGenders)) {
                            return \DevDasher\PTB\sendMessage(text: 'Invalid gender!');
                        }
                        \DevDasher\PTB\sendMessage(text: "Thank you!\n\nName: {$name}\nAge: {$age}\nGender: $gender");
                        \DevDasher\PTB\_endConversation();
                    },
                    conversation_data: ['age' => \DevDasher\PTB\_text()],
                );
            } on line 6

The problem is that it looks like the package laravel/serializable-closure can not find this function: ReplyKeyboardMarkup

But as you can see, at the above of the code I added the use function DevDasher\PTB\ReplyKeyboardMarkup;, But i don't know why it can't find that!

I hope you understand what I am saying and solve the problem

Thank you.

Steps To Reproduce

.................................................................................

PHP 8.1RC5: Cannot instantiate enum testEnum when serializing closure that uses an native enum

  • Serializable Closure Version: v1.0.3
  • Laravel Version: v8.70.1
  • PHP Version: v8.1.0RC5
  • Database Driver & Version: not required in this case

Description:

I am currently updating my code to use native enums from PHP 8.1. This package does not support them yet. This is not a bug yet, but it will be when people start using PHP 8.1 which is released on November 25th.

Steps To Reproduce:

Ofcourse have PHP 8.1.0RC5 installed, and run the following script with it

enum testEnum
{
    case HELLO;
    case WORLD;
}

$enum = testEnum::HELLO;

$closure = function () use ($enum) {
    return $enum->name;
};

SerializableClosure::setSecretKey('secret'); // commenting this out gives the same result

$serialized = serialize(new SerializableClosure($closure)); // throws `Cannot instantiate enum testEnum` error here
$closure = unserialize($serialized)->getClosure(); 

echo $closure(); // HELLO;

Job chain can't serialize named argument in closure (Parsing error)

  • Laravel Version: 8.73.2
  • PHP Version: 8.0.7
  • Database Driver & Version: mysql Ver 8.0.22 for osx10.16 on x86_64 (Homebrew)

Description:

The closure fails to serialize with:

syntax error, unexpected token ":", expecting ")" {"userId":7,"exception":"[object] (ParseError(code: 0): syntax error, unexpected token \":\", expecting \")\" at laravel-serializable-closure://fn () => $this->requestUpdate(
    \\App\\Models\\clearCollectionCache: false,
    \\App\\Jobs\\Duda\\RefreshSite: true,
):3)
Bus::chain([
    new CreateSite($this),
    fn () => $this->requestUpdate(
        clearCollectionCache: false,
        refreshSite: true,
    ),
])->dispatch();

Steps To Reproduce:

Just add a closure with a named argument call inside and it will fail to parse. Example above.

Workaround

Remove the named argument:

Bus::chain([
    new CreateSite($this),
    fn () => $this->requestUpdate(false, true),
])->dispatch();

PHP Error: Call to a member function bindTo() on null

  • Serializable Closure Version: dev-master (e4970ee)
  • Laravel Version: 8.75
  • PHP Version: 8.0.15
  • Database Driver & Version: mysql

Description:

I have a very similar problem to this one here: #32

However, latest commit doesn't seem to be working for me.

Steps To Reproduce:

composer create-project laravel/laravel test
php artisan queue:batches-table
php artisan migrate
composer require laravel/serializable-closure:dev-master

Then >>

โžœ  php artisan tinker
Psy Shell v0.11.1 (PHP 8.0.15 โ€” cli) by Justin Hileman
>>> \Illuminate\Support\Facades\Bus::batch([])->name("test2")->then(function ($b) {
... echo 'asd';
... })->dispatch();
<warning>PHP Warning:  file_get_contents(/Users/user/work/testeval()'d code): Failed to open stream: No such file or directory in /Users/user/work/test/vendor/laravel/serializable-closure/src/Support/ReflectionClosure.php on line 805</warning>
PHP Error:  Call to a member function bindTo() on null in /Users/user/work/test/vendor/laravel/serializable-closure/src/Serializers/Native.php on line 193


Passing an array with a job to the batch method also gives the same result.

Exception: call to a member function bindTo() on null

  • Serializable Closure Version: 1.0.5
  • Laravel Version: 8.81.0
  • PHP Version: 8.1.1
  • Database Driver & Version: postgresql 13

Description:

I'm having this error

[2022-01-27 12:50:19] local.ERROR: Call to a member function bindTo() on null {"userId":1,"exception":"[object] (Error(code: 0): Call to a member function bindTo() on null at /home/vagrant/code/vendor/laravel/serializable-closure/src/Serializers/Native.php:193)
[stacktrace]
#0 [internal function]: Laravel\\SerializableClosure\\Serializers\\Native->__unserialize()
#1 /home/vagrant/code/vendor/laravel/serializable-closure/src/Serializers/Signed.php(86): unserialize()
#2 [internal function]: Laravel\\SerializableClosure\\Serializers\\Signed->__unserialize()
#3 /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Bus/DatabaseBatchRepository.php(322): unserialize()
#4 /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Bus/DatabaseBatchRepository.php(341): Illuminate\\Bus\\DatabaseBatchRepository->unserialize()
#5 /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Bus/DatabaseBatchRepository.php(85): Illuminate\\Bus\\DatabaseBatchRepository->toBatch()
#6 /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Bus/DatabaseBatchRepository.php(112): Illuminate\\Bus\\DatabaseBatchRepository->find()
#7 /home/vagrant/code/vendor/laravel/framework/src/Illuminate/Bus/PendingBatch.php(255): Illuminate\\Bus\\DatabaseBatchRepository->store()
#8 /home/vagrant/code/app/MyJob.php(51): Illuminate\\Bus\\PendingBatch->dispatch()

when trying to dispatch a batch with laravel :

 Bus::batch($jobs)
    ->then($this->synchronizationSucceeded(...))
    ->dispatch();

Defined with

 Bus::batch($jobs)
    ->then(fn() => $this->synchronizationSucceeded())
    ->dispatch();

everything goes well.

Steps To Reproduce:

class Test {

    public function test_first_class_callable(): void
    {
        $closure = new SerializableClosure($this->foo(...));

        $serialized = serialize($closure);

        $unserialized = unserialize($serialized); // Error : Call to a member function bindTo() on null
    }

    public function foo()
    {
    }
}

Serialization of 'Closure' is not allowed

  • Serializable Octane: 1.2.14
  • Laravel Version: 9.19.0
  • PHP Version: 8.1.0
  • Database Driver & Version: postgres 14

Description:

I am using octane. And when I start the application, I periodically get such an error in the logs. I can't figure out what it is related to? There is no information about what event is in question. Or maybe about the listeners, the job?

Serialization of 'Closure' is not allowed {"userId":1,"exception":"[object] (Exception(code: 0): Serialization of 'Closure' is not allowed at /var/www/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:158)
[stacktrace]
#0 /var/www/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(158): serialize(Object(Illuminate\\Events\\CallQueuedListener))
#1 /var/www/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(127): Illuminate\\Queue\\Queue->createObjectPayload(Object(Illuminate\\Events\\CallQueuedListener), NULL)
#2 /var/www/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(105): Illuminate\\Queue\\Queue->createPayloadArray(Object(Illuminate\\Events\\CallQueuedListener), NULL, '')
#3 /var/www/api/vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php(38): Illuminate\\Queue\\Queue->createPayload(Object(Illuminate\\Events\\CallQueuedListener), NULL, '')
#4 /var/www/api/vendor/laravel/framework/src/Illuminate/Queue/Queue.php(57): Illuminate\\Queue\\SyncQueue->push(Object(Illuminate\\Events\\CallQueuedListener), '', NULL)
#5 /var/www/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(591): Illuminate\\Queue\\Queue->pushOn(NULL, Object(Illuminate\\Events\\CallQueuedListener))
#6 /var/www/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(515): Illuminate\\Events\\Dispatcher->queueHandler('App\\\\Listeners\\\\F...', 'handle', Array)
#7 /var/www/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(441): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}(Object(Laravel\\Octane\\Events\\RequestTerminated))
#8 /var/www/api/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php(249): Illuminate\\Events\\Dispatcher->Illuminate\\Events\\{closure}('Laravel\\\\Octane\\\\...', Array)
#9 /var/www/api/vendor/laravel/octane/src/DispatchesEvents.php(20): Illuminate\\Events\\Dispatcher->dispatch('Laravel\\\\Octane\\\\...')
#10 /var/www/api/vendor/laravel/octane/src/ApplicationGateway.php(52): Laravel\\Octane\\ApplicationGateway->dispatchEvent(Object(Illuminate\\Foundation\\Application), Object(Laravel\\Octane\\Events\\RequestTerminated))
#11 /var/www/api/vendor/laravel/octane/src/Worker.php(110): Laravel\\Octane\\ApplicationGateway->terminate(Object(Illuminate\\Http\\Request), Object(Illuminate\\Http\\JsonResponse))
#12 /var/www/api/vendor/laravel/octane/bin/swoole-server(118): Laravel\\Octane\\Worker->handle(Object(Illuminate\\Http\\Request), Object(Laravel\\Octane\\RequestContext))
#13 [internal function]: {closure}(Object(Swoole\\Http\\Request), Object(Swoole\\Http\\Response))
#14 /var/www/api/vendor/laravel/octane/bin/swoole-server(164): Swoole\\Server->start()

Steps To Reproduce:

Start Octane server

When I used `php_strip_whitespace` to compress my PHP code, this library didn't work as expected.

Serializable Closure Version

1.3.1

PHP Version

8.2.0

Description

When I used php_strip_whitespace to compress my PHP code, this library didn't work as expected. Is a bug?

Steps To Reproduce

  1. I defined a function go to use this Library.
function go(Closure $function, int $timeout = 300)
{
    if (App::$cli) return null;
    return MyCustomClass::start($function, $timeout);
}
  1. In this method start, I used
serialize(new SerializableClosure($function));

and I saved it to a cache file.

  1. When I used the function go:

     public static function start($bool): void
        {
            if ($bool) {
               go(function () {
                       //some functions...
                    }, 0);
            } else {
                Log::record("Error");
            }
        }
  2. If I used php_strip_whitespace to compress my code, it means my code will display like this:

     public static function start($bool): void{if($bool){go(function(){}, 0);} else {Log::record("Error");}}

    It will cache the code:

    if($bool){go(function(){}, 0);} else {Log::record("Error");

    But if I don't compress my code, it will cache the code:

    function(){}

    When only uncompressed, it meet expectations. Is this a bug?

Memory leak in job queue delivery

Serializable Closure Version

v1.3.3

PHP Version

7.4

Description

The following code has a memory leak of 8

Steps To Reproduce

        return \application\Jobs\Common\ForkStockRunJob::dispatch(
            $title,
            'customer:' .  $customer_id,
            $func
        )->onQueue(\system\helper\WorkermanHelper::QUEUE_NAME_TRADE_B_FORK_STOCk);
<?php

namespace application\Jobs\Common;

class ForkStockRunJob extends \application\Jobs\Base\BaseJob
{
//    use \Illuminate\Queue\SerializesModels;

    /**
     * @var \Laravel\SerializableClosure\SerializableClosure|callable
     */
    protected $func;
    protected $title;
    protected $key;
    protected $time;

    /**
     * @var null|\Laravel\SerializableClosure\SerializableClosure
     */
    protected $unlockLocalFunc = null;

    public function __construct($title, $key, $func)
    {
        $a = 1;
        $this->func = serialize(new \Laravel\SerializableClosure\SerializableClosure(function ()use($a){

        }));
        $this->title = $title;
        $this->key = $key;
        $this->time = time();

    }

    /**
     * @param callable $unlockLocalFunc
     * @return $this
     */
    public function setUnlockLocalFunc($unlockLocalFunc)
    {
        $a = 2;
        $this->unlockLocalFunc = serialize(new \Laravel\SerializableClosure\SerializableClosure(function ()use($a){

        }));

        return $this;
    }


    protected function handlePro()
    {
//        $a = function (){
//            $b = 1;
//        };
//        new \Laravel\SerializableClosure\SerializableClosure(function ()use($a){
//            $b = 1;
//        });
        if ($this->func) {
            $this->func->serializable = null;
        }
        if ($this->unlockLocalFunc) {
            $this->unlockLocalFunc->serializable = null;
        }
        unset($this->func);
        unset($this->unlockLocalFunc);
        return;

Error: File name too long[36]

  • Serializable Closure Version: 1.0.5
  • Laravel Version: 8.81.0
  • PHP Version: 8.1.1
  • Database Driver & Version: MariaDB 10.6

Description:

Using Octane to run some concurrent functions I get the following :
[2022-02-01 14:31:06 ^76940.11] WARNING Server::task_unpack(): open(ravel\SerializableClosure\SerializableClosure":1:{s:12:"serializable";O:46:"Laravel\SerializableClosure\Serializers\Signed":2:{s:12:"serializable";s:721:"O:46:"Laravel\SerializableClosure\Serializers\Native":5:{s:3:"use";a:2:{s:11:"current_job";O:45:"Illum) failed, Error: File name too long[36]

Steps To Reproduce:


Octane::concurrently([
                    fn () => (isset($track_input[0]) ? $this->jobtrack->insert($track_input) : null),
                    function () use ($image_input, $document_input) {
                        $this->job_images->insert($image_input);
                        $this->job_documents->insert($document_input);
                    }
                ]);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.