laravel 支持 ftp,但需手动安装 league/flysystem-ftp 包,且 config/filesystems.php 中 driver 必须为字面量 'ftp'(不可用 env()),同时 .env 中 ftp_host、ftp_username、ftp_password 均不能为空,否则报 “driver [] is not supported”。

能用,但默认不启用,且配置错一个地方就直接报“Driver [] is not supported”或“Path cannot be empty”——不是代码写错了,是驱动没真正加载起来。
为什么 Storage::disk('ftp')->put() 报 “Driver [] is not supported”
这个错误本质是 Laravel 没识别到 ftp 驱动名,常见于三种情况:
-
config/filesystems.php中'driver' => env('FTP_DRIVER')这类写法:如果.env里没定义FTP_DRIVER,env()返回null,最终变成'driver' => null,Laravel 就当没设驱动 - 把
'driver' => 'ftp'写成了'driver' => env('ftp')(小写、带引号、键名错) - 没装 Flysystem 的 FTP 扩展包,Laravel 启动时跳过了 FTP 驱动注册逻辑
验证方式:运行 php artisan tinker,输入 Storage::disk('ftp'),如果抛出异常或返回空对象,说明驱动根本没注册成功。
必须安装的 Composer 包和配置顺序
Laravel 自身不带 FTP 驱动实现,依赖 league/flysystem-ftp(注意不是 flysystem-aws-s3-v3 那种命名风格)。Laravel 8+ 推荐用以下命令安装:
composer require league/flysystem-ftp
装完后,config/filesystems.php 中的 'ftp' 磁盘才可能被正确解析。配置必须满足:
-
'driver' => 'ftp'是字面量字符串,不能是env()表达式 -
'host'、'username'、'password'必须全部非空;'port'和'root'可缺省但建议显式写 -
'passive' => true几乎必加,否则多数共享主机连接失败
FTP_ROOT 路径怎么填才不报 “Path cannot be empty”
这个报错通常发生在调用 put() 时传入空字符串或 null 路径,但根源常在 FTP_ROOT 配置上:
-
FTP_ROOT值必须是 FTP 用户登录后**可见的相对路径**,比如public_html/uploads,不是服务器绝对路径/home/user/public_html/uploads - 末尾不能带
/,env('FTP_ROOT', 'uploads')比env('FTP_ROOT', 'uploads/')更安全 - 如果
FTP_ROOT在.env里为空或注释掉,env('FTP_ROOT')返回null,Flysystem 初始化时会把root设为null,后续任何路径拼接都崩 - 测试方法:在控制器里临时加一行
dd(Storage::disk('ftp')->getAdapter()->getPathPrefix());,看输出是否是你预期的目录前缀
上传后文件看不见?别只盯 storage:link
php artisan storage:link 只对 public 磁盘生效,跟 FTP 完全无关。FTP 文件存的是远程服务器,访问方式只能是:
- 用 FTP 客户端直接连上去查,确认文件真在
FTP_ROOT下生成了 - 用
Storage::disk('ftp')->url('xxx.jpg')—— 但注意:这个方法默认返回空字符串,因为 FTP 驱动不实现 URL 生成逻辑;你得自己拼:https://your-ftp-domain.com/+env('FTP_ROOT')+/xxx.jpg - 如果 FTP 服务器本身不支持 Web 直链(比如没开 HTTP 访问权限),那再怎么拼域名也没用
最易忽略的一点:FTP 用户权限。很多报错表面是路径问题,实际是用户没写入权限——先用 FileZilla 登录试试手动上传一个文件,成功了再回头调 Laravel。











