Laravel多租户(Tenancy)+Filament文件上传路径错误求助
我用Tenancy for Laravel(v3.8.2)和Filament(v3.1.47)开发多租户应用,不同域名访问正常,但文件上传功能出问题。上传时提示错误:Unable to retrieve the file_size for file at location: livewire-tmp/40LsuTIsnBtUsTOvGIrcpexFpm0Y2T-metaYWZsb2dvLnBuZw==-.png.
观察到文件被上传至storage/app/public/livewire-tmp/40LsuTIsnBtUsTOvGIrcpexFpm0Y2T-metaYWZsb2dvLnBuZw==-.png,但预期应该存储在tenant1/app/...这类租户隔离路径下,推测这就是无法获取文件大小的原因。和同事排查许久没头绪,附上相关代码片段,求各位给解决建议。
相关代码片段
app/Filament/App/Resources/TenantProjectResource.php
return $form ->schema([ Forms\Components\TextInput::make('name') ->required(), Forms\Components\FileUpload::make('image') ->image() ->label('Project Default Image') ->disk('public') ->columns(1) ->directory('projects') ->moveFiles() ->maxSize(2048) ->columnSpanFull(), ]);
config/tenancy.php
'bootstrappers' => [ //Stancl\Tenancy\Bootstrappers\DatabaseTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\CacheTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\FilesystemTenancyBootstrapper::class, Stancl\Tenancy\Bootstrappers\QueueTenancyBootstrapper::class, // Stancl\Tenancy\Bootstrappers\RedisTenancyBootstrapper::class, // Note: phpredis is needed ],
config/filesystems.php
'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'throw' => false, ],
解决建议
配置租户专属文件磁盘
当前使用的public磁盘是全局路径,未做租户隔离。在config/filesystems.php中新增租户专属磁盘:'tenant_public' => [ 'driver' => 'local', 'root' => tenancy()->tenant ? storage_path("app/tenants/{tenancy()->tenant->id}/public") : storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', 'throw' => false, 'tenant_disk' => true, // 标记为租户磁盘,让Tenancy包自动处理路径替换 ],然后修改Filament的FileUpload组件,指定使用该磁盘:
->disk('tenant_public')完善文件系统引导器配置
确认config/tenancy.php的filesystem配置项,将租户磁盘加入隔离列表:'filesystem' => [ 'disks' => ['tenant_public'], // 加入你的租户磁盘 ],若要直接覆盖原
public磁盘实现隔离,可修改root_override:'filesystem' => [ 'root_override' => [ 'public' => storage_path('app/tenants/{tenant_id}/public'), ], ],调整Livewire临时文件路径
Livewire默认临时文件存在全局public磁盘,需修改config/livewire.php让它使用租户磁盘:'temporary_file_upload' => [ 'disk' => 'tenant_public', // 改为租户磁盘 'rules' => 'file|max:2048', 'directory' => 'livewire-tmp', 'middleware' => 'throttle:5,1', 'preview_mimes' => [ 'png', 'gif', 'bmp', 'svg', 'wav', 'mp4', 'mov', 'avi', 'wmv', 'mp3', 'm4a', 'jpg', 'jpeg', 'webp', 'pdf', ], ],这样临时文件会先存入租户隔离路径,后续移动时路径正常,就能正确获取文件大小。
检查目录权限
确保storage/app/tenants目录有读写权限,执行:chmod -R 755 storage/app/tenants chown -R www-data:www-data storage/app/tenants # 根据服务器运行用户调整清除配置缓存
修改配置后执行以下命令生效:php artisan config:clear
内容的提问来源于stack exchange,提问作者Sam Jenkins

