cxxi/ftp-client 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

cxxi/ftp-client

最新稳定版本:v1.0.1

Composer 安装命令:

composer require cxxi/ftp-client

包简介

Pure PHP FTP/FTPS/SFTP client (framework agnostic).

README 文档

README

PHP Version CI Tests codecov PHPStan Level License Packagist Downloads

Pure PHP FTP / FTPS / SFTP client (framework agnostic).

Simple, expressive API:

$clientFtp = FtpClient::fromUrl('ftp://user:pass@example.com:21/path');

$clientFtps = FtpClient::fromUrl('ftps://user:pass@example.com:21/path');

$clientSftp = FtpClient::fromUrl('sftp://user:pass@example.com:22/path');

A clean, testable and production-ready transport layer designed for:

  • Modern PHP applications (8.2+)
  • CLI tools & workers
  • Framework integration (Symfony bundle available)
  • High reliability environments

Supports:

  • Automatic protocol resolution (ftp://, ftps://, sftp://)
  • Safe retry policies with exponential backoff & jitter
  • SFTP host key verification (MD5 / SHA1)
  • PSR-3 logging
  • Clean architecture (Ports & Adapters)

Table of Contents

Why this library?

PHP already provides ext-ftp and ext-ssh2. So why wrap them?

Because raw extensions:

  • Expose global functions
  • Mix transport logic with application logic
  • Lack retry mechanisms
  • Provide no structured error handling
  • Are difficult to unit test
  • Offer no safety model for destructive operations

This library adds:

Unified API

Same interface for FTP, FTPS and SFTP.

Switch protocol by changing the URL scheme.

Built-in Retry Strategy

  • Configurable retry count
  • Exponential backoff
  • Optional jitter
  • Safe vs unsafe operation handling

Designed for unstable networks and production systems.

Secure SFTP Support

  • Host key algorithm control
  • MD5 / SHA1 fingerprint verification (via ext-ssh2)
  • Strict host key checking option

No silent trust of unknown hosts.

Clean Architecture

  • Ports & adapters
  • Fully mockable infrastructure layer
  • Decoupled from PHP global functions
  • Designed for strict static analysis (PHPStan level max (9) + strict rules + bleeding edge)

Framework Agnostic

Works in:

  • Plain PHP scripts
  • Symfony (recommended via the FtpClientBundle)
  • Laravel
  • CLI workers
  • Cron jobs

No framework dependency.

Production Ready

This library is:

  • Fully covered by unit tests (100%)
  • Integration tested against real FTP / FTPS / SFTP servers
  • Static analysis clean (PHPStan level max (9) + strict rules)
  • Free of global state
  • Designed for deterministic error handling

It is built to be used in critical environments where network instability and safe retries matter.

Installation

composer require cxxi/ftp-client

Requirements

  • PHP 8.2+
  • psr/log ^3.0

Optional extensions:

  • ext-ftp → required for FTP / FTPS
  • ext-ssh2 → required for SFTP

Note: FTPS requires ext-ftp with SSL support (ftp_ssl_connect() available).

Quick Start

use Cxxi\FtpClient\FtpClient;

$client = FtpClient::fromUrl('ftp://user:pass@example.com:21/path');

$client
    ->connect()
    ->loginWithPassword()
    ->listFiles('.');

URL Format

ftp://user:pass@host:21/path
ftps://user:pass@host:21/path
sftp://user:pass@host:22/path

Notes:

  • Credentials may be URL-encoded.
  • Transport is resolved automatically from the scheme.
  • Path becomes the working directory after connection.

Using Connection Options

You can pass a ConnectionOptions instance:

use Cxxi\FtpClient\Model\ConnectionOptions;

$options = new ConnectionOptions(
    timeout: 15,
    retryMax: 3,
    retryDelayMs: 500,
    retryBackoff: 2.0,
    retryJitter: true
);

$client = FtpClient::fromUrl(
    'ftps://user:pass@example.com:21/path',
    options: $options
);

Array format (canonical structure)

You can also build options from an array. The canonical structure groups transport-layer options under dedicated keys, so protocol-specific settings stay isolated and easy to extend.

$options = ConnectionOptions::fromArray([
    'timeout' => 15,
    'passive' => 'auto',

    'retry' => [
        'max' => 3,
        'delay_ms' => 500,
        'backoff' => 2.0,
        'jitter' => true,
        'unsafe_operations' => false,
    ],

    'ssh' => [
        'host_key_algo' => 'ssh-ed25519',
        'expected_fingerprint' => 'MD5:aa:bb:cc:dd:...',
        'strict_host_key_checking' => true,
    ],
]);

Protocol-specific keys are ignored when not applicable (e.g. passive is ignored for SFTP).

Supported Options

timeout

Type: int|null Applies to: FTP / FTPS / SFTP

  • FTP/FTPS → connect timeout
  • SFTP → stream timeout for transfers

passive (FTP / FTPS only)

Type: auto | true | false

  • true → force passive mode
  • false → active mode
  • auto → try passive, fallback to active

Ignored for SFTP.

SFTP Host Key Verification

SFTP supports strict host key verification using MD5 or SHA1 fingerprints (as supported by ext-ssh2).

$options = new ConnectionOptions(
    hostKeyAlgo: 'ssh-ed25519',
    expectedFingerprint: 'MD5:aa:bb:cc:dd:...',
    strictHostKeyChecking: true
);

If strictHostKeyChecking is enabled and fingerprint does not match, connection will fail.

SFTP Fingerprint Limitations (ext-ssh2)

When using the ext-ssh2 extension (PECL ssh2), only the following fingerprint algorithms are available via ssh2_fingerprint():

  • MD5
  • SHA1

The extension does not expose SHA256 fingerprints, even though the underlying libssh2 library supports it.

As a consequence:

  • SHA256: fingerprints (OpenSSH default format) cannot be verified when using ext-ssh2.
  • Only MD5: and SHA1: prefixed fingerprints are supported.
  • There is no automatic fallback between algorithms.

If a SHA256: fingerprint is provided, the connection will fail when strict host key checking is enabled.

This limitation comes from the PHP extension API, not from the library itself.

Retry Policy

Retry is disabled by default (retryMax = 0).

When enabled:

Safe operations are retried:

  • connect
  • login
  • listFiles
  • downloadFile
  • getSize
  • getMTime
  • isDirectory

Unsafe operations are not retried unless explicitly allowed:

  • deleteFile
  • rename
  • chmod
  • removeDirectory
  • removeDirectoryRecursive
  • makeDirectory

Enable unsafe retries:

$options = new ConnectionOptions(
    retryMax: 3,
    retryUnsafeOperations: true
);

Common Operations

Upload / Download

$client->putFile('remote.csv', '/local/file.csv');

$client->downloadFile('remote.csv', '/tmp/remote.csv');

Directory Utilities

$client->isDirectory('subdir');

$client->makeDirectory('subdir', recursive: true);

$client->removeDirectory('empty-dir');

$client->removeDirectoryRecursive('dir-to-delete');

File Utilities

$client->deleteFile('old.csv');

$client->rename('old.csv', 'new.csv');

$size = $client->getSize('file.csv');

$mtime = $client->getMTime('file.csv');

$client->chmod('file.csv', 0644);

FTP-only Advanced Listing

Available only on FTP / FTPS:

$raw = $client->rawList('.', recursive: false);

$mlsd = $client->mlsd('.');

Authentication

Password

$client
    ->connect()
    ->loginWithPassword();

Override credentials:

$client->loginWithPassword('user', 'pass');

SFTP Public Key

$client
    ->connect()
    ->loginWithPubkey(
        '/home/me/.ssh/id_rsa.pub',
        '/home/me/.ssh/id_rsa',
        user: 'my-user'
    );

Only valid for SFTP connections.

Logging

Pass a Psr\Log\LoggerInterface to the factory:

use Cxxi\FtpClient\FtpClient;

$client = FtpClient::fromUrl(
    'ftp://user:pass@example.com:21/path',
    logger: $logger
);

Logged events include:

  • connection attempts
  • authentication
  • transfers
  • destructive operations

Credentials are never logged.

Connection Lifecycle

Connections auto-close on destruction.

For long-running scripts:

$client->closeConnection();

Safe to call even if not connected.

Architecture

The library follows a clean architecture approach:

  • Transport contracts (Contracts)
  • Protocol-specific transports (FTP / SFTP)
  • Infrastructure ports (filesystem, streams, ssh2, ftp)
  • Native adapters
  • Retry wrapper with safe/unsafe semantics

This design allows easy mocking and full unit testing.

Quality & Tests

This library is designed for reliability in production environments.

Unit Tests

  • 100% code coverage on the core domain and infrastructure
  • Strict PHPUnit 11 configuration
  • Full mocking of native adapters
  • Error handling and retry semantics fully tested
  • PHPStan level max (9) clean (source + tests)
  • phpstan-strict-rules enabled
  • bleedingEdge rules enabled

Run unit tests:

composer test:unit

Generate coverage report:

composer test:coverage

Integration Tests

All protocols are tested against real Dockerized servers.

Protocol Server Tested Features
FTP pure-ftpd Active / Passive / Auto mode, transfers, directory ops, MLSD
FTPS pure-ftpd (TLS required) Explicit TLS, transfers, error cases
SFTP OpenSSH Password auth, public key auth, fingerprint verification

Each integration stack is fully isolated and reproducible.

Run individual protocol tests:

composer test:integration:ftp
composer test:integration:ftps
composer test:integration:sftp

Run all integration tests:

composer test:integration

Run everything (unit + integration):

composer test:all

Static Analysis

PHPStan level max (9) with strict rules and bleeding edge enabled:

composer phpstan

Configuration includes:

  • level: max (9)
  • phpstan-strict-rules
  • bleedingEdge.neon
  • treatPhpDocTypesAsCertain: true

Code Style

composer cs
composer cs:check

CI

All checks are enforced in CI:

  • Unit tests (100% coverage)
  • FTP integration tests
  • FTPS (TLS) integration tests
  • SFTP integration tests
  • PHPStan level max (9) + strict rules
  • Coding standards

Every protocol feature documented in this README is covered by automated tests.

Troubleshooting

FTPS: ftp_ssl_connect() not available

Make sure ext-ftp is compiled with SSL support. ftp_ssl_connect() must be available.

SFTP: host key verification fails

  • Ensure the fingerprint prefix matches (MD5: or SHA1:).
  • SHA256 fingerprints are not supported by ext-ssh2.

Passive mode issues (FTP/FTPS)

If transfers hang behind NAT/firewalls:

  • Try forcing passive mode (passive: true)
  • Or use passive: auto

Connection timeouts

Adjust the timeout option depending on network conditions.

Contributing

Contributions are welcome.

Before submitting a pull request:

  1. Ensure all unit tests pass.
  2. Ensure all integration tests pass.
  3. Run PHPStan (level max (9) must remain clean).
  4. Follow existing coding standards.

Useful commands:

composer test:all
composer phpstan
composer cs

Please open an issue first for significant changes or architectural discussions.

Security

If you discover a security vulnerability, please open a GitHub Security Advisory or contact the maintainer privately before disclosing it publicly.

Credentials are never logged by design.

see SECURITY.md.

Roadmap

The project roadmap is maintained separately to keep this README focused and concise.

Full roadmap available here: docs/ROADMAP.md

The roadmap covers:

  • SFTP backend improvements (phpseclib support, SHA256 fingerprints)
  • OpenSSH known_hosts integration
  • FTPS security enhancements (TLS controls, certificate validation)
  • Stream-based API & atomic uploads
  • Transfer progress callbacks
  • Resumable transfers
  • Long-running worker stability improvements
  • Observability & structured events
  • Advanced retry safety
  • Performance & scalability explorations

All roadmap items follow the project principles:

  • Clean architecture
  • Deterministic behavior
  • Strong safety guarantees
  • Backward compatibility (unless major version bump)

Community feedback is welcome via GitHub Issues and Discussions.

License

MIT — see LICENSE.

cxxi/ftp-client 适用场景与选型建议

cxxi/ftp-client 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 02 月 17 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「client」 「upload」 「ssh」 「sftp」 「ftp」 「download」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 cxxi/ftp-client 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 cxxi/ftp-client 我们能提供哪些服务?
定制开发 / 二次开发

基于 cxxi/ftp-client 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 29
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-02-17