というわけでファイル所有者の件で、少しまとめておく。
php から普通にファイルをつくると所有者は apache になるようだ。
ファイルをつくった時 chown() すればいいのかなと思い php マニュアルをみたら:
>スーパーユーザのみがファイルの所有者を変更できます。
と書いてあるので、レンタルサーバーなどで運用している場合使えない。しかし apache 所有だと FTP クライアントから消したりできんので非常にうっとおしいのも事実だ。
ぐぐってみると、「 CGI 版 php を使う」「php の ftp関数を使う」という逃げ方があるという話だけ見つかった。(意外にも、同じ問題で困っている人の質問は見つかったが、ずばり解決な情報は見つからなかった。)
ここで、この問題がなぜ起こるのかを考えてみた。要は「 php で作ったファイルやディレクトリが ftpクライアントからいじれない。」というわけだ。その理由は「 php の fopen() で新規にファイルをつくるとき、その所有者を指定して開くことができない。」ことと、「作成したファイルの所有者を変更する関数 chown() はスーパーユーザー(簡単に言うとルート権限をもつユーザー。)しか使用不可能という仕様。」だからだ。
一言で言うと、いきなりでなんだが「八方塞がり」だ。(笑)
だが、もし php から作るときにも ftp 経由で普段のユーザーとしてログインし「ファイルをつくる」ことができれば、問題はなさそうだ。
もしかしたら php の ftp関数を使うことで ftp 転送したときと同じ所有者にできるかも知れない。(ファイル転送ではなく、新規作成ができなければ実現できないが…普通 FTP といえばファイルを get/put するための仕組みだろうから、もしかしたら、いきなりでなんだが新規作成などということは無理かも知れない。(^^;)
また、画像ファイルなどをアップロードする XML-RPC API newMediaObject() の仕様として「転送先ディレクトリが存在しなければその場で作る。」というのがある。 php の ftp関数でディレクトリが新規に作れるかどうかは知らない。
というわけで、 FTP 転送時と同じ所有者でファイルとディレクトリを作るようにしたいところだが、とりあえずは apache 所有者で作られても ftp で手でファイルを消したりしようとしない限り普通に使えるし、よい解決方法がみつかるまではこれでいいかと。
しかし…「ファイルを1つつくる」などという基本的なことでけっこう頭を抱えなければならないんですなぁ。(苦笑)
php のマニュアルで ftp 関数を調べてみた。
>ftp_mkdir -- ディレクトリを作成する
ディレクトリの作成はできそうだ。
>ftp_fput -- オープン中のファイルをFTPサーバーにアップロードする
ファイルの新規作成については、こんなのがあった。ファイルポインタで指定して、ファイルの終端までをアップロードするそうだ。
この関数は、既存のファイルを開いて取得したファイルストリームを受け取って、ファイルストリームの末尾までを一気にリモートにアップロードする仕様らしい。
XML-RPC API 側でファイルを作成するときに、メモリストリームをつくり、受け取った記事内容をストリームから一定量ずつ流し込むなり fwrite 系の一定量ずつメモリブロックを読み書きするなりできるような関数があれば、今回やりたいことを実現できるのだが、上の関数では、一気に最後まで書き込んでファイルをつくる仕様なので無理だ。 php にはメモリストリームをあつかうためのクラスもないようだ。
困った…。
- FTP 転送自体を php でフルスクラッチする。
- php 以外のサーバーサイドスクリプトをつかう。
- 一旦 apache 所有のファイルを新規作成し、しかる後に、そのファイルから ftp_fput する。
1. は大変すぎだしプラットフォームによっては動かないようなものしかつくれそうにない。
2. は rn_xmlrpc.php の API との連携が大変。
3. なら実現できるだろうが…。無駄が多くてバカバカしいんだがなぁ。(いったん apache 所有でつくって、put して消すので、処理中のディスクサイズがファイルサイズの2倍必要になる。記事ならそれほど問題にならないだろうし newMediaObject で転送するファイルも過去の実測でいうと 1.5MB 程度までしか転送できなかったので、運用上いいっちゅやいいんだが…。(^^;)
理想的には、ファイルの転送をシミュレートするような ftp_fwrite , ftp_fread, ftp_fseek みたいなものがあればそれがズバリなのだが…