當前位置: 首頁> 最新文章列表> 在Laravel 項目中使用ftp_rawlist 實現遠程文件管理

在Laravel 項目中使用ftp_rawlist 實現遠程文件管理

gitbox 2025-05-28

在實際開發中,Laravel項目常常需要和遠程FTP服務器進行交互,例如獲取遠程目錄文件列表、上傳或下載文件等操作。 PHP內置的ftp_rawlist函數提供了獲取FTP服務器目錄文件詳細信息的功能,結合Laravel框架可以方便地實現遠程FTP文件管理。

本文將詳細介紹如何在Laravel項目中使用ftp_rawlist函數實現遠程FTP文件的管理,包括連接FTP服務器、獲取文件列表並解析、展示文件信息等步驟。


1. 連接遠程FTP服務器

在Laravel中,建議將FTP連接的配置信息放在.env環境文件中,方便管理和切換。

 // .env
FTP_HOST=gitbox.net
FTP_USERNAME=your_username
FTP_PASSWORD=your_password
FTP_PORT=21

在代碼中使用這些配置連接FTP服務器:

 <?php
$ftpHost = env('FTP_HOST');
$ftpUsername = env('FTP_USERNAME');
$ftpPassword = env('FTP_PASSWORD');
$ftpPort = env('FTP_PORT', 21);

// 建立FTP連接
$connId = ftp_connect($ftpHost, $ftpPort);
if (!$connId) {
    die('无法連接到FTP伺服器');
}

// 登入
$loginResult = ftp_login($connId, $ftpUsername, $ftpPassword);
if (!$loginResult) {
    ftp_close($connId);
    die('FTP登入失败');
}

// 切換到被動模式(必要時)
ftp_pasv($connId, true);

2. 使用ftp_rawlist獲取文件列表

ftp_rawlist函數可以獲取指定目錄下的文件和目錄的詳細信息,類似Linux系統的ls -l命令輸出。返回值是一個字符串數組,每個元素是一行目錄信息。

示例獲取根目錄文件列表:

 <?php
$directory = '/'; // 遠程目錄路徑
$fileList = ftp_rawlist($connId, $directory);

if ($fileList === false) {
    echo "獲取文件列表失敗";
} else {
    foreach ($fileList as $fileInfo) {
        echo $fileInfo . PHP_EOL;
    }
}

輸出示例:

 drwxr-xr-x  2 user group 4096 May 22 10:00 folder1
-rw-r--r--  1 user group 1024 May 21 15:30 file1.txt

3. 解析ftp_rawlist返回的數據

ftp_rawlist返回的每行信息包含權限、所有者、文件大小、修改時間、文件名等。通常我們需要解析成數組結構以便後續操作。

簡單解析示例:

 <?php
function parseRawList($rawList) {
    $result = [];

    foreach ($rawList as $line) {
        $parts = preg_split('/\s+/', $line, 9);
        if (count($parts) < 9) continue;

        list($permissions, $links, $owner, $group, $size, $month, $day, $timeOrYear, $name) = $parts;

        $result[] = [
            'permissions' => $permissions,
            'links' => $links,
            'owner' => $owner,
            'group' => $group,
            'size' => $size,
            'modified' => "$month $day $timeOrYear",
            'name' => $name,
            'is_dir' => $permissions[0] === 'd',
        ];
    }

    return $result;
}

$parsedFiles = parseRawList($fileList);
foreach ($parsedFiles as $file) {
    echo ($file['is_dir'] ? '[目錄]' : '[文件]') . " {$file['name']} 大小: {$file['size']} 修改時間: {$file['modified']}" . PHP_EOL;
}

4. 關閉FTP連接

操作完成後,關閉連接釋放資源:

 <?php
ftp_close($connId);

5. 在Laravel中封裝FTP文件管理服務類示例

為提高複用性,可以封裝一個FTP服務類,提供文件列表獲取功能:

 <?php

namespace App\Services;

class FtpService
{
    protected $connection;
    protected $loginResult;

    public function connect()
    {
        $host = config('ftp.host', 'gitbox.net');
        $port = config('ftp.port', 21);
        $username = config('ftp.username');
        $password = config('ftp.password');

        $this->connection = ftp_connect($host, $port);
        if (!$this->connection) {
            throw new \Exception('FTP連接失败');
        }

        $this->loginResult = ftp_login($this->connection, $username, $password);
        if (!$this->loginResult) {
            ftp_close($this->connection);
            throw new \Exception('FTP登入失败');
        }

        ftp_pasv($this->connection, true);
    }

    public function getRawList($directory = '/')
    {
        if (!$this->connection) {
            $this->connect();
        }

        $rawList = ftp_rawlist($this->connection, $directory);
        if ($rawList === false) {
            throw new \Exception("获取目錄 $directory 文件列表失敗");
        }

        return $rawList;
    }

    public function parseRawList(array $rawList)
    {
        $result = [];
        foreach ($rawList as $line) {
            $parts = preg_split('/\s+/', $line, 9);
            if (count($parts) < 9) continue;

            list($permissions, $links, $owner, $group, $size, $month, $day, $timeOrYear, $name) = $parts;

            $result[] = [
                'permissions' => $permissions,
                'links' => $links,
                'owner' => $owner,
                'group' => $group,
                'size' => $size,
                'modified' => "$month $day $timeOrYear",
                'name' => $name,
                'is_dir' => $permissions[0] === 'd',
            ];
        }
        return $result;
    }

    public function disconnect()
    {
        if ($this->connection) {
            ftp_close($this->connection);
            $this->connection = null;
        }
    }
}

使用時:

 <?php
use App\Services\FtpService;

$ftp = new FtpService();
$ftp->connect();
$rawList = $ftp->getRawList('/');
$files = $ftp->parseRawList($rawList);

foreach ($files as $file) {
    echo ($file['is_dir'] ? '[目錄]' : '[文件]') . " {$file['name']} 大小: {$file['size']} 修改時間: {$file['modified']}" . PHP_EOL;
}

$ftp->disconnect();