Fatal Error: Unexpected BLOG

主に自分用の備忘録として

【PHP】PHPからcURLを利用してFTPでファイルをダウンロードする

PHPの公式マニュアルの通りにしても、エラーが返る。
ハマったのでメモ。

以下のサイトを参考にしました。

エラーが起きたコード

エラーが起きたコードは以下の通り。ちなみにリモートサーバの環境にも拠るようで、以下のコードでも問題なくダウンロード出来る場合もあった。

    $fp = fopen('path/to/local/file', 'w');
    $remote = "ftp://$user:$password@host.com/path/to/remote/file";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_URL, $remote);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    
    $res = curl_exec($ch);
    $err = curl_errno($ch);
    $err_mes = curl_error($ch);

上記のスクリプトを実行するとcURLが以下のエラーを返す。

    Server denied you to change to the given directory.

cURLデバッグトレースを有効にして出力を見る。

    * About to connect() to host.com port 21 (#0)
    *   Trying host.com... * connected
    * Connected to host.com port 21 (#0)
    < 220 ...
    > USER foo
    < 331 Password required for user.
    > PASS bar
    < 230 User foo logged in.
    > PWD
    < 257 "/path" is current directory.
    * Entry path is '/path'
    > CWD path
    < 550 : The system cannot find the file specified. 
    * Server denied you to change to the given directory
    * Connection #0 to host host.com left intact
    > QUIT
    < 221  
    * Closing connection #0

接続直後にPWDが実行された後、投げたパスを相対パスとして解釈してCWDを試みている。
つまり、「/path/path」へCWDしているということ。

成功したコード

明示的に絶対パスで指定してあげる必要があるようです。
以下のように変更したらエラーなくダウンロードに成功しました。

    $remote = "ftp://$user:$password@host.com/path/to/remote/file";
    ↓
    $remote = "ftp://$user:$password@host.com//path/to/remote/file";

めでたし。