laravelS插件运行下 laravel-admin兼容性问题及解决汇总

我现在用的laravelS版本是3.7。比起旧的版本而言,官方已经对laravel-admin兼容做了一定的工作。有一个官方提供的cleaner清理器,但是使用过程中还是发现了不少其他兼容性bug

Posted by 昆山吴彦祖 on 2021.12.28

excel导出

这个问题之前在我个人blog有写过就不在写了 链接

laravel-admin 初始化时自定义的一些按钮、自定义组件会多次渲染输出

初始化文件app/admin/bootstrap.php 中可以进行一些自定义组件,但是在swoole模式下每次刷新页面会这些自定义组件会多出一个


通过查看源码,发现是 laravel-admin 的相关代码是每次把回调函数存储到静态变量中,而swoole是全局变量是不会自动销毁的,导致每次刷新页面变量内容都会被叠加


解决办法

拓展下laravelS提供的laravelAdminCleaner,把laravelAdminCleaner加入到laravelS配置文件的cleaners中

namespace App\\Cleaners;

use Illuminate\\Container\\Container;
use Illuminate\\Support\\Facades\\Facade;
use Hhxsv5\\LaravelS\\Illuminate\\Cleaners\\BaseCleaner;

class LaravelAdminCleaner extends BaseCleaner
{
    const   ADMIN_CLASS = [
        'Encore\\Admin\\Admin',
        'Encore\\Admin\\Form',
        'Encore\\Admin\\Grid',
    ];

    private $reflections;

    protected $properties = [
        [
            'deferredScript'   => [],
            'script'           => [],
            'style'            => [],
            'css'              => [],
            'js'               => [],
            'html'             => [],
            'headerJs'         => [],
            'manifest'         => 'vendor/laravel-admin/minify-manifest.json',
            'manifestData'     => [],
            'extensions'       => [],
            'minifyIgnores'    => [],
            'metaTitle'        => null,
            'favicon'          => null,
            'bootingCallbacks' => [],
            'bootedCallbacks'  => [],
        ],
        [
            'initCallbacks'   => [],
        ],
        [
            'initCallbacks'   => [],
        ],
    ];
    

    public function __construct(Container $currentApp, Container $snapshotApp)
    {
        parent::__construct($currentApp, $snapshotApp);
        foreach(self::ADMIN_CLASS as $class){
            $this->reflections[] = new \\ReflectionClass($class);
        }
        
    }

    public function clean()
    {
        foreach ($this->reflections as $k=>$reflection) {
            
            foreach ($this->properties[$k] as $name => $value) {
                if ($reflection->hasProperty($name)) {
                    $property = $reflection->getProperty($name);
                    if ($property->isStatic()) {
                        if (!$property->isPublic()) {
                            $property->setAccessible(true);
                        }
                        $property->setValue($value);
                    }
                }
            }
            $this->currentApp->forgetInstance(self::ADMIN_CLASS[$k]);
            Facade::clearResolvedInstance(self::ADMIN_CLASS[$k]);
        }
    }
}

laravel-admin 自定义form组件(extensions)可能报不存在

如果我们引入一些form如editor latlong,有概率会出现 报错 组件不存在,实验后发现如果当前的请求是新进程处理,就会出现这个报错。

最后也没有找出具体的错误原因。

不过因为所有的extension都是由provider进行注册绑定的,所以直接把相关的provider放到laravelS的配置文件 register_providers数组中即可。


form错误请求后跳转错误

form错误请求(比如你表单数据没填完整导致数据库抛出exception)正常情况下应该跳转回form请求页面。但是laravelS下会出现请求错误后跳回错误的页面。

查看源码发现是因为 laravel-admin 发生错误请求后,会通过redirect实例进行back()操作,操作前正常应该是先进行实例化,把当前request数据注入redirect实例中。

但是laravel的redirect是一个单例类,这就导致swoole模式下redirect不会被重新实例化。所以back()操作时的request数据也不会被更新。

解决办法

写一个redirectCleaner,把redirectCleaner加入到laravelS配置文件的cleaners中

namespace App\\Cleaners;

use Illuminate\\Container\\Container;
use Illuminate\\Support\\Facades\\Facade;
use Hhxsv5\\LaravelS\\Illuminate\\Cleaners\\BaseCleaner;

class RedirectCleaner extends BaseCleaner
{
    const   ADMIN_CLASS = [
        'Illuminate\\Routing\\Redirector',
    ];
    

    public function clean()
    {
        $this->currentApp->forgetInstance('redirect');
        Facade::clearResolvedInstance('redirect');
    }
}

目前来说就发现这几个laravelS 和 laravel-admin的兼容性bug,后续有新的再更新

laravels swoole