Laravel Flysystem SFTP:如何检查连接是否成功

问题描述 投票:0回答:3

我在 Laravel 8 中使用 Flysystem SFTP。我有多个 sftp 帐户,我循环使用每个帐户来制作适配器,然后从服务器读取文件。这一切都是通过控制台命令进行的,并在 Schedule 中注册。问题是,当任何连接由于用户名或密码问题而失败时,它会停止计划任务的执行并跳过剩余的任务。如何检查连接是否成功并继续下一个 sftp 连接。预先感谢。

foreach ($credentials as $cred) {
    try {
        $driver = Storage::createSFtpDriver($cred);
        if($driver->exists('/reports/')) {
          //Other code
        } else {
            continue;
        }
    } catch (Exception $e) {
        continue;
    }
}
php laravel exception laravel-8 flysystem
3个回答
2
投票

参见SFTP V3,那里

SftpConnectionProvider
写着:

连接检查器(必须是

League\Flysystem\PhpseclibV2\ConnectivityChecker
的实现,以检查是否可以建立连接(可选,如果不需要一些特殊处理来设置可靠连接,则可以省略)

所以答案是

SftpConnectivityChecker implements
ConnectivityChecker
...被传递到
SftpConnectionProvider
构造函数中。
interface
只有一个方法可以重写:

public class SftpConnectivityChecker implements ConnectivityChecker {
    public function isConnected(SFTP $connection): bool {
        $connected = false
        // TODO: inspect the $connection status.
        return $connected;
    }
}

可能的配置如下:

'sftp' => [

    'connectivityChecker' => 'SftpConnectivityChecker'
]

并且不要使用

continue
,而是处理异常而不是忽略它。


0
投票

我不知道这是否是好方法,但就我而言,它工作正常。我刚刚通过将

\
与 Exception 类一起应用来解决它,并且一切顺利。

foreach($credentials as $cred){
        try {
            $driver = Storage::createSFtpDriver($cred);
            if($driver->exists('/report/')){
              echo "Found for ".$cred["username"];
            }
            else{
                continue;
            }
        }
        catch (\Exception $e) {
            continue;
        }
    }

0
投票

如果你使用flysystem,你需要捕获Throwable。所有 Flysystem 异常实现均扩展自 Throwable。我犯了一个错误,捕获了异常,结果它就直接失败了。

foreach($credentials as $cred){
    try {
        $driver = Storage::createSFtpDriver($cred);
        if($driver->exists('/report/')){
          echo "Found for ".$cred["username"];
        }
        else{
            continue;
        }
    }
    catch (\Throwable $e) {
        continue;
    }
}

另一个问题是,如果您有一个长时间运行的进程,例如由supervisord管理的队列工作进程,那么在作业运行后,工作进程永远不会终止,因此连接永远不会正确断开。您可以通过多种方法来解决此问题,具体取决于您的需求:

使用连接检查器

declare(strict_types=1);
namespace Core\MyConnectivityChecker;
use phpseclib3\Net\SFTP;
use League\Flysystem\PhpseclibV3\ConnectivityChecker;

class MyConnectivityChecker implements ConnectivityChecker
{

    public function isConnected(SFTP $connection): bool
    {
        $connected = $connection->isConnected();
        if (!$connected) {
            // Ping will check if the connection if active or not.  If it's not active it will cleanly 
            // close the connection and reconnect again.
            $connection->ping();
        }

        return $connection->isConnected();
    }
}

另一个选项是在每次使用后显式断开连接:

foreach($credentials as $cred){
    try {
        $driver = Storage::createSFtpDriver($cred);
        if($driver->exists('/report/')){
          echo "Found for ".$cred["username"];
        }
        else{
            continue;
        }

        // force a disconnect
        $driver->getAdapter()->getProvideConnection()->disconnect();
    }
    catch (\Exception $e) {
        continue;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.