ど素人から毛を生やす。<延>

FTPS中のファイルを更新日時順で取得したかった話。

Web > PHP 2018年10月31日(最終更新:6年前)

2018年10月31日に作成されたページです。
情報が古かったり、僕が今以上のど素人だった頃の記事だったりする可能性があります。

どもです。

FTPS上にアップされたCSVをDBに落とすプログラムを作成していたのですが、このときにファイル名は問わないという縛りがあり、では何を基準に複数ファイルがあったときの処理順を定めるべきか。

普通に考えたらファイルの更新日時かアップロード日時ですな。
ファイル更新日時の昇順といたしましょう。

さて、どうすればそれが適うのか。

ローカルのファイルの日時を取得するなら…

filemtimeですな。

使い方はこちらのサイト様がとてもわかりやすい。

しかし、今回はFTPなので、絶対パスで指定するfilemtimeではない。さて。

ftp_nlistって引数lsコマンド使えるのか→できないな…、何故だ。

ftp_nlistってlsコマンドが使えたんですね。


// 接続を確立する
$conn_id = ftp_connect($ftp_server);

// ユーザー名とパスワードでログインする
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

// カレントディレクトリの内容を得る
$contents = ftp_nlist($conn_id, "-lt /dir");

これで良し。
と思ったのですが、いざ出力してみると、どうにもソートができていないよう。
色々試してみましたが、コマンドが無効化されてしまっています。サーバーのせい?参ったな_(:3」∠)_

ftp_mdtmで一度取得したCSVを並び替えてみるか→レファレンスとちょっと違うことになったけど…

アプローチを変えてみましょ。ftp_mdtmを使います。
これだとファイルひとつひとつでFTP接続するので重そうな気はしますが、今回は大量のファイルを捌くわけでないので良しとしましょう。

ftp_nlistで取得した配列をなんやかんやして、ファイル名を獲得しまして…、


$fileList = array();
foreach($contents as $file_name){
	$tmp = ftp_mdtm($conn_id, $file_name);
	if(isset($fileList[$buff])){
		//同日時ファイルが複数あった場合の回避
		$i = 0;
		do{
			$i++;
			$tmp = $buff.'_'.$i;
		}while(isset($fileList[$tmp]));
		$buff = $tmp;
	}
	$fileList[$tmp] = $remotePath;
}
ksort($fileList);

これで良し。
と思ったのですが、これだとftp_mdtmでエラー、返り値が-1になってしまうよう。
色々試してみたところ、$file_nameをフルパスにしたら正しい値を返してくれました。
よって、今回はこちらを採用。

FTPSだから?それともサーバー依存?

いちおう解決したものの、ことごとくレファレンス通りにいかないのが腑に落ちなく。_(:3」∠)_

FTPでなくFTPSだからか、PHPのバージョンが古めだからか、それともサーバー由来の問題があるのか。
おいおい追及するとして、まぁ今回は、こーいった事例もあったよということでひとつ。

この記事は役に立ちましたか?
  • _(:3」∠)_ 面白かった (0)
  • (・∀・) 参考になった (0)
  • (`・ω・´) 役に立った (0)