spatie / laravel-medialibrary

Associate files with Eloquent models
https://spatie.be/docs/laravel-medialibrary
MIT License
5.78k stars 1.08k forks source link

php 8.3.4 + laravel-medialibrary 11.4.5: opcache+jit error: Only arrays and Traversables can be unpacked #3568

Closed izica closed 5 months ago

izica commented 8 months ago

After turning on opcache+jit, after some time an error occurs: /var/www/backend/vendor/spatie/laravel-medialibrary/src/InteractsWithMedia.php:607 Only arrays and Traversables can be unpacked

        $preparedMediaConversions = collect($this->mediaConversions)
            ->each(fn (Conversion $conversion) => $conversion->performOnCollections($mediaCollection->name))
            ->values()
            ->toArray();

->     $this->mediaConversions = [...$actualMediaConversions, ...$preparedMediaConversions];
    });
    $this->registerMediaConversions($media);
}

this only happens after some time(5+ mins of requests), when opcache+jit is enabled in logs $actualMediaConversions === false (only after opcache+jit)

Code and settings:

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.jit_buffer_size=100M
opcache.jit=1235
class Compilation extends BaseCompilation implements HasMedia
{
    use InteractsWithMedia;

    const IMAGE = 'image';

    protected $hidden = [
        self::CREATED_AT,
        self::UPDATED_AT,
        'pivot'
    ];

    protected $fillable = [
        self::NAME,
        self::SLUG,
        self::IMAGE,
        self::AT_HEADER,
    ];

    protected $with = [
        'media'
    ];

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection(self::IMAGE)
            ->singleFile()
            ->useFallbackUrl(
                \Storage::disk(config('disks.assets'))->url('images/dummy.png')
            )
            ->registerMediaConversions(function () {
                $this->addMediaConversion('resized')
                    ->width(400)
                    ->height(400);
            });
    }
}
izica commented 8 months ago
            $this->mediaConversions = [
                ...(is_array($actualMediaConversions) ? $actualMediaConversions : []),
                ...(is_array($preparedMediaConversions) ? $preparedMediaConversions : []),
            ];

Sometimes when opcache+jit is enabled, somehow $actualMediaConversions or $preparedMediaConversions are false, not array. This happens only with singleFile collections. I inherited this trait and overridden method with a quick fix. Perhaps this is happening because I am using methods getRegisteredMediaCollections and getMediaCollection in custom attributes, and this registers the collections on every call $this->registerMediaCollections();

Also I tried to separate conversion to registerMediaConversions method, but the error still repeats.

timvandijck commented 6 months ago

Looks hard to reproduce: if anyone is also experiencing this let us know, I'm wondering how many users it's impacting.

I would be happy to accept a PR if something can be improved on our side.

sethphillips commented 2 months ago

Im running into this while adding ->withManipulations([ 'avatar' => [ 'manualCrop' => "custom props here", ], ]) during the adding of media to a single file collection with a registered media conversion