0

一部のサーバーは 777 のアクセス許可を必要とし、一部のサーバーは 755 を超えるファイルをブロックし、一部はとにかく変更するために使用する chmod 関数をブロックします。 file_get_contents を使用して単純なファイルをサーバーに書き込みたいのですが、スクリプトで非常に多様な多くの異なるサーバーで配布および使用される予定です。少なくとも PHP5 を前提として、単純なテキスト ファイルを書き込み/上書きする最も「クロスサーバー」および「クロスホスト」な方法は何ですか? 以前は次のようなものを使用していました。

@chmod($filePath, 0755);
$result = file_put_contents($filePath, $fileData);

可能な限り多くのサーバーで動作することを前提としています: 可能であればアクセス許可を正しく設定しますが、そうでない場合はエラーなしで設定します (一部のサーバーでは file_put_contents は正常に動作しますが、実際には必要のない chmod でエラーがスローされます。ただし、他のサーバーには chmod が必要です)。しかし、考えられるすべてのサーバーの近くで動作するソリューションが必要です (PHP5+ を想定)。ここの誰かがより良い方法でより多くの経験を持っていますか?

説明:

誰かが世界を救うとは思っていません。すべてのサーバーで機能するわけではないかもしれませんが、できるだけ多くのサーバーで機能させることはできます。それが私が達成したいと考えていることです。少なくとも、できるだけ多くの問題を解決するすべての方法を使い果たし、できるだけ多くの方法でそれを書き込もうとしましょう。

例えば:

file_put_contents($filePath, $fileData);

ファイルを書き込みます。わーい!ただし、一部のサーバーまたは状況によっては、ファイルのアクセス許可が原因で失敗する場合があります。ダン。では、もう少し良くしてみましょう。

chmod($filePath, 0777);
file_put_contents($filePath, $fileData);

これで、最初に許可が変更されます! クールです。さらに数人のサーバーで動作します。ただし、一部のサーバーは 0777 を拒否するため、0755 は 0777 よりもいくつか多くのサーバーで機能する可能性があります。

chmod($filePath, 0755);
file_put_contents($filePath, $fileData);

これで、より多くのユーザーのサーバーで機能するようになりました。しかし待ってください: 一部のサーバーは chmod 機能をブロックします。しかし、それはファイルがまだ書き込み可能ではないという意味ではありません。これは、書き込み可能ではない場合に備えた単なるバックアップであるため、少なくとも書き込みを試みますが、chmod が実行されないサーバーでエラーをスローしないようにしてください。とにかくうまくいくかもしれないので、うまくいきません(そして、後でそれがうまくいったかどうかをいつでもテストできるので、静かに失敗することはありません).

@chmod($filePath, 0755);
file_put_contents($filePath, $fileData);

などなどなど。すでに機能している場所を壊さないようにしながら、機能を追加する方法を確認して、機能を追加する方法を確認してください。「何があってもchmodを機能させる」ように誰かに頼んでいるわけではありません。誰かがこの思考の道を歩み続けた経験があり、回避できるファイル書き込みが失敗する場所をさらに見つけて、それが可能な限り最高のファイル書き込みスニペットになるまで、彼らのスニペットでそれらを説明したかどうかを尋ねています。できるだけ多くの場所で。すべてではないかもしれませんが、上記のスニペットが行うより多くの場所で。私よりも多様なサーバー環境での経験があり、私よりもうまくできる (または既に実行している) 人がいるはずです。

フィードバックに基づく追加:

1) フィードバックの 1 つは、パーミッションはサーバーによって異なる動作をしないというものです。技術的には、はい。しかし、ある意味ではそれほど単純ではありません。

一部のサーバーは次のように設定されています...反逆者は他の言葉と同じくらい良いです...ファイルのアクセス許可を777などの755よりも緩く設定し、ファイルの読み取り/書き込み/実行をまったく許可しない場合は、 500 エラーを返します。他のサーバーでは、サーバーによると、あなたのphpコードはファイルの「所有者」ではないようです。その場合、グループを壁として7にする必要があるか、ファイルの所有権を変更する必要があると想定しています( 「クロスサーバー」の複雑さの他のグループ全体をアップします)。私は間違って何が起こっているのかを理解している可能性があることを認めます(もしそうなら、誰かが問題をより深く理解し、より洗練された解決策を提示することを望んでいます!) 、理論的には、すべてのサーバーで機能するわけではありません(実際、クライアントがこのタイプのコード スニペットをインストールしたサーバーの約 90% でしか機能しないと思います)。だから私は誰かがこのように多くのサーバーを扱っていて、より防弾の方法を持っているかどうか尋ねています.ランダムなホストがサーバーをセットアップする方法のさまざまな違いを回避できる方法です. 最初にファイルが書き込み可能であることを確認し、次にファイル自体を書き込むさまざまな方法を複数回試行する複数の手順があると思います。

2) そして、はい、ファイルは永続化する必要があります。それが要点です:) XML ファイルの編集や、CMS 内での新しい HTML ページの作成など。そして、これをつぼみに挟むために:「ファイルを書き込むのではなく、情報のためにデータベースを使用する必要がある」と言わないでください。それにも場所がありますが、ファイルの書き込みについては別の質問をしています。

3) ファイルを書き込めない状況があると思います。しかし、私が求めているのは、できるだけ多くの状況で機能するように、それを最小化した経験があるかどうかです。私が上に持っているものは、人間が可能な最も普遍的なスニペットではないことを知っているので、何ができるのか尋ねています:)

4

1 に答える 1

0

私はサーバー間の違いの専門家ではないので、そういう人からの回答を得たいと思っていましたが、コーディングの創造性はPHPコミュニティの強みではないようです:)それで私は自分で1つ書きました。 chmodを呼び出してからfile_put_contentsを呼び出すよりもはるかに優れていますが、私はサーバーの専門家ではないので、もっと優れていると思います...しかし、何もないよりはましです。(スクリプトは、私がテストしたサーバーの99%以上で機能しますが、chmodを呼び出してfile_put_contentsが機能していた85%〜90%とは対照的です)。

function makeFileWritable($filename, $perm = 0755)
{
    if (!file_exists($filename))
    {
        $folderpath = dirname($filename);
        if(is_writable($folderpath)) return true;

        @chmod($folderpath, $perm);
        if(is_writable($folderpath)) return true;

        if ($perm == 0755) return makeFileWritable($filename, 0775);
        return false;
    }
    else
    {
        $folderpath = dirname($filename);
        if(is_writable($folderpath) && is_writable($filename)) return true;
        if (!is_writable($folderpath)) @chmod($folderpath, $perm);
        if (!is_writable($filename)) @chmod($filename, $perm);
        if (is_writable($folderpath) && is_writable($filename)) return true;

        if ($perm == 0755) return makeFileWritable($filename, 0775);
        return false;
    }
}

@makeFileWritable($filePath);
$result = file_put_contents($filePath, $writeData);

基本的に、目的のファイルパスで@makeFileWritableを呼び出します。ファイルが存在する場合は、ファイルのアクセス許可とそれを含むフォルダーのアクセス許可を0755に設定しようとします。ファイルがまだ存在しない場合は、ファイルを含むフォルダーのアクセス許可を0755に変更しようとします。ファイルが書き込み可能になったかどうかを確認します。もしそうなら、それは終了です。そうでない場合は、(一種の再帰的な方法で)自分自身を再度呼び出しますが、サーバーが動作するためにグループ書き込み可能である必要がある場合に備えて、今回は0775で同じことを実行しようとします。しかし、ファイルがずっと書き込み可能であった場合でも、エラーは返されず、ファイルを書き込もうとしますが、書き込み可能かどうかを確認するためのテストは正確ではありませんでした(そして、最初の部分がサイレントに失敗しても問題ありません失敗します、

さて、そのスクリプトは、ファイルを書き込んでいない10台のサーバーのうち1台または2台が、ファイルを書き込んでいない基本的に0台のサーバーに変わるようにしました...そしてAS3/JSプログラマーはそれをたくさん書いたPHPプログラマーの多くは、問題が存在しないか、解決できないと彼に言いました。PHPコミュニティにもう少し創造性を注入する必要があると思います。彼らが少し創造的な筋をつけて、いくつかの改善を提案してくれることを願っています。 ((

于 2012-05-17T13:10:48.390 に答える