プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
PHP、サーバにアップロードしたファイルのパーミッションをFTP経由で変更する(chmod関数で変更できない場合の対処)
現象として

1.プログラムでアップロードしたファイルのアクセス権がたまに600になる
 ※通常は644でアップロードされている

2.PHPの「chmod()」関数を使っても修正できない
 ※変更権限が無い?別ユーザとして実行されている?

3.FFFTP等のソフトを使い、FTP経由でアクセス権の変更は可能
 ※600→644に修正できる

という問題に遭遇しました。

そもそも「アップロードしたファイルのアクセス権がなんで600になるんだよ?」が疑問なのですが、
そこは調べても分からなかったので放置しました。
600だとアップロードしたは良いけど表示されない状況になるようなので、
至急644になるようにしなくてはいけませぬ。

問題を聞いた当初は、簡単じゃん。ほれφ(--)

<?php
    $targetFile = "hoge.jpg";    //実際には動的に取得
    chmod($targetFile, 0644);
?>

とやったのですが、変わらず(-A-)
ファイルをアップロードしたスクリプト内で実行しているのでユーザ違いとかはないと思うのですが、
やっぱりよく分からず。

そんな経緯からFTP経由でアクセス権を変更することにしました。
具体的にはこんなコードですφ(--)

<?php
    //-------------------------------
    //FTPであれこれするよ~
    //-------------------------------
    //処理対象ファイル
    $target="hoge.jpg"    //実際には動的に取得
    //FTPサーバ
    $ftp_host = "hoge.example.com";
    //FTPポート
    $ftp_port = 21;
    //FTPユーザ名
    $ftp_user = "ftpuser";
    //FTPパスワード
    $ftp_pwd = "ftppwd";

    //FTP サーバに接続する。
    if($res_ftp = ftp_connect($ftp_host, $ftp_port)){
        print "FTP サーバへの接続に成功しました。<br />";
    }else{
        print "FTP サーバへの接続に失敗しました。<br />";
        exit;
    }

    //接続した FTP サーバにログインする。
    if(ftp_login( $res_ftp, $ftp_user, $ftp_pwd)){
        print "FTP サーバへのログインに成功しました。<br />";
    }else{
        print "FTP サーバへのログインに失敗しました。<br />";
        exit;
    }

    //アクセス権を変更
    if(ftp_chmod($res_ftp, 0644, $target) !== false){
        echo "「" . $target . "」のアクセス権変更に成功しました。<br />";
    }else{
        echo "「" . $target . "」のアクセス権変更に失敗しました。<br />";
    }

    //FTP サーバから切断する。
    ftp_close($res_ftp);
?>

よっしゃ!これでバッチリ!と思ったのですがFTP接続できず(つд`)

あっ、そうだ。
このサーバ、POP-AUTHが導入されてるんだったΣ( ̄◇ ̄;

POP-AUTHは平たく言うと「FTPする前にメール受信しろよ」な仕組みね。
POP認証を経由することでアクセス元の身元保証を云々カンヌンです。

めんどくさいなーと思いつつ、FTP前にPOP認証を行いますか。
ソケット接続でログインしとけばいーべ、ということでこんなコードに改造φ(--)

<?php
    //-------------------------------
    //POP認証するよ~
    //-------------------------------
    //POPサーバ
    $mail_host = "mail.example.com";
    //ポート
    $mail_port = 110;
    //ユーザ
    $mail_user = "mailuser";
    //パスワード
    $mail_pwd = "mailpwd";

    //接続
    $fp = fsockopen($mail_host, $mail_port);

    //ログイン
    $line = fgets($fp, 512);
    fputs($fp, "USER $mail_user\r\n");    // USER名
    $line = fgets($fp, 512);        
    fputs($fp, "PASS $mail_pwd\r\n");    // パスワード
    $line = fgets($fp, 512);
    if(!eregi("OK", $line)){    // ログイン失敗?
        fclose($fp);
        exit;
    }

    //切断
    fputs($fp, "QUIT\r\n");
    fclose($fp);



    //-------------------------------
    //FTPであれこれするよ~
    //-------------------------------
    //処理対象ファイル
    $target="hoge.jpg"    //実際には動的に取得
    //FTPサーバ
    $ftp_host = "hoge.example.com";
    //FTPポート
    $ftp_port = 21;
    //FTPユーザ名
    $ftp_user = "ftpuser";
    //FTPパスワード
    $ftp_pwd = "ftppwd";

    //FTP サーバに接続する。
    if($res_ftp = ftp_connect($ftp_host, $ftp_port)){
        print "FTP サーバへの接続に成功しました。<br />";
    }else{
        print "FTP サーバへの接続に失敗しました。<br />";
        exit;
    }

    //接続した FTP サーバにログインする。
    if(ftp_login( $res_ftp, $ftp_user, $ftp_pwd)){
        print "FTP サーバへのログインに成功しました。<br />";
    }else{
        print "FTP サーバへのログインに失敗しました。<br />";
        exit;
    }

    //アクセス権を変更
    if(ftp_chmod($res_ftp, 0644, $target) !== false){
        echo "「" . $target . "」のアクセス権変更に成功しました。<br />";
    }else{
        echo "「" . $target . "」のアクセス権変更に失敗しました。<br />";
    }

    //FTP サーバから切断する。
    ftp_close($res_ftp);
?>

これで無事にFTP経由でアクセス権の変更ができました。

今回の内容を最後にもう一度まとめると

1.PHPでのアクセス権の変更は、普通は「chmod()」関数を使えばOK
2.「1.」で上手く行かない場合、FTP経由でchmodすると変更できる場合もある
3.「2.」でFTP接続できない場合は、PHP-AUTHを考慮してあげる必要があるかも

となります。

なんかいろいろ腑に落ちない部分はありますが、
取りあえず目の前の問題は解決できたので良しとします。
前にもちょこっと調べたけど、なんで600になるのかは分からずじまいでした。

取りあえず、完了\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● PHP  thema:システム開発 - genre:コンピュータ  Posted by ササキマコト 

  関連記事