22

注:これはスーパーユーザーにも当てはまる可能性があります。

各ユーザーが別のユーザーのファイルを表示したり変更したりできないように、apache2mpmitkとopen_basedirを使用して共有ホストにPHP5.3.10をセットアップしています。apache2 vhost設定で、ユーザーを制限するための適切なエントリを追加します。

    AssignUserId     userA userA
    php_admin_value  open_basedir      /home/userA/www/
    php_admin_value  upload_tmp_dir    /home/userA/www/tmp/
    php_admin_value  session.save_path /home/userA/www/tmp/
    SetEnv           TMPDIR            /home/userA/www/tmp/

ここで、最初の行はLinuxユーザーがapache2に使用するように設定し、次の3行は、basedir、アップロードディレクトリ、およびセッションの保存パスがユーザーディレクトリにあることを定義します。すぐに最後の行に戻ります。

ここで問題が発生しますsys_get_temp_dir()。phpの一時ディレクトリを返す必要があります。これは、Linuxシステムではデフォルトで/tmpです。セキュリティ上の理由から、このディレクトリはuserAのopen_basedirに存在する必要があります。5.3.10のphp-sourceによると、sys_get_temp_dir()-functionは環境変数TMPDIRを使用してこのディレクトリを取得します。

     // php-src/main/php_open_temporary_file.c:217-219
     /* On Unix use the (usual) TMPDIR environment variable. */
     {
             char* s = getenv("TMPDIR");

これは、上記の構成の5行目が実行する必要があることです。ただし、sys_get_temp_dir()環境変数($ _SERVERで完全に設定され、からも表示可能phpinfo())を無視して、グローバルシステムディレクトリを返すだけです。

sys_get_temp_dir()そのディレクトリは設定の外にあるため、これにより、に依存するさまざまなソフトウェアでいくつかの厄介なバグが発生しopen_basedirます。動作を変更せずに、変数を$_ENVと$_SERVERに直接設定しようとしました。私はputenv('TMPDIR=/home/userA/www/tmp')変更なしで試しました。

ただし、変数を/ etc / apache2 / envvarsに定義することで出力を変更できます。これは、各VHOSTに独自の一時フォルダーを持たせたいので、私には役に立ちません。

私がこれまでに見つけた唯一の解決策は、runkitsys_get_temp_dir()のような拡張機能を介して内部を上書きし、 auto_prepend_fileを介してその包含を強制することです。しかし、その解決策は非常に汚いので、私は信じられません。これ以上の解決策はありません。

だから、私の質問:sys_get_temp_dir()runkitで関数を再実装せずに、apache2 vhost設定で設定される結果を変更する方法はありますか?

編集: Apacheのバージョンは2.2.22で、現在mod_phpを使用しています。すべてのユーザーを手動で追加する必要があるため、fcgiまたは同様のセットアップも可能です。

4

7 に答える 7

23

putenv('TMPDIR=/foo/bar') PHP内で実行すると、の結果に影響を与える可能性があるようですsys_get_temp_dir()auto_prepend_filePHPの一部を実行して、を設定しTMPDIR、の再定義を台無しにしないようにディレクティブを配置することができますsys_get_temp_dir()

編集:putenv('TMPDIR='.ini_get('open_basedir').'/tmp')また、質問でレイアウトしたディレクトリ構造に一時ディレクトリを設定するために簡単に使用できます。

おかしなことに、これも機能することがわかりSetEnv TMPDIR /foo/barます(Apache構成を維持している場合)。

putenv('TMPDIR='.getenv('TMPDIR'));

ノーオペレーションのように見えますが、実際にに影響を及ぼしますsys_get_temp_dir()。これはPHPの環境処理のバグであるに違いないと私は考え始めています。

于 2012-11-06T15:34:54.660 に答える
6

あなたはあなたの質問にタグを付けました、しかしあなたは利用しています

 php_admin_value  open_basedir      /home/userA/www/
 ^^^^^^^^^^^^^^^

これは、PHPのapacheモジュールバージョンであるMod_PHPの設定です。その場合、Webサーバーが起動するとPHPがロードされます。

次に、以下を利用しますSetEnv

 SetEnv           TMPDIR            /home/userA/www/tmp/

これは、内部環境変数を設定しています。他のapacheモジュールに渡されますが、仮想サーバーではなく、リクエストで必要になると思います。具体的にはわかりませんが、あなたの説明によれば、この環境変数はPHPスクリプトが呼び出される前にリセットされていると思います。

実際の答えよりもコメントの方が多いですが、うまくいけば、いくつかのことを明確にするのに役立ちます。

私は通常、マルチユーザー環境でFCGIを使用して、ユーザーをより適切に分離できるようにしています。ユーザーごとに環境変数を設定することに問題はありませんでした。しかし、それは単なる別のコメントです。あなたもそれを使わなければならないとは言いたくありません。スクリプトの実行時に(まだ)設定されるように環境変数を設定するには、apache内の適切な場所を見つける必要があることを強調するだけです。


また、適切な環境変数を設定していない可能性があります。環境変数に関するApacheドキュメントによると:

これらの変数は環境変数と呼ばれますが基盤となるオペレーティングシステムによって制御される環境変数と同じではありません。代わりに、これらの変数は内部Apache構造に格納および操作されます。これらは、CGIスクリプトおよびサーバーサイドインクルードスクリプトに提供された場合にのみ、実際のオペレーティングシステム環境変数になります。サーバー自体が実行されているオペレーティングシステム環境を操作する場合は、オペレーティングシステムシェルが提供する標準の環境操作メカニズムを使用する必要があります。

PHPのオペレーティングシステム環境変数を設定します。ただし、設定しているのは内部環境変数のみです。

Mod_PHPはそれらをスクリプトにインポートする可能性があるためgetenv('TMPDIR')、PHPを使用する場合はSAPI固有の実装が使用されます。これにより、これらの内部環境変数を確認できますが、php_get_temporary_directory関数はそれを使用していません。

質問にApacheとPHPのバージョンを追加してください。

于 2012-11-07T09:10:28.870 に答える
5

これによると-4歳のバグsys_get_temp_dir()仮想ホストでは動作しません。それで

  • この問題を修正したライブラリのみを使用してみることができます(修正しなかった場合はバグを開きます)
  • または、複数のディレクトリを保持できるため、(/tmpまたはOSが使用するものは何でも)追加します(たとえば、Windowsではそれを分離します) 。open_basedirinclude_path;:
于 2012-11-09T23:27:39.813 に答える
4

PHPソースを見るsys_get_temp_dir()と、次の優先順位で動作します。

  1. その値が以前に計算されている場合は、キャッシュされた値が使用されます。
  2. sys_temp_dirini構成でチェックされます。
  3. Windowsでは、GetTempPathW Win32 APIメソッドが使用され、そのドキュメントによると、以下が(この順序で)使用されます。
    1. TMP環境変数で指定されたパス。
    2. TEMP環境変数で指定されたパス。
    3. USERPROFILE環境変数で指定されたパス。
    4. Windowsディレクトリ。
  4. * nixでは、以下が(この順序で)使用されます。
    1. TMPDIR環境変数。
    2. P_tmpdirマクロ_
    3. /tmp(情報源によると、これは決して起こらないはずの最後の努力です)。

これにより、結果を制御するための十分なオプションが得られるはずですsys_get_temp_dir(たとえばini_set('sys_temp_dir', $tmpPath)putenv('TMPDIR=/foo/bar')他の人が言及したように)以前に計算されていない限り、私が知る限り、あなたはSOLであり、キャッシュされた値が使用されます(ただし、私はPHPは、そうでない場合は聞いてみたいです)。

于 2017-08-20T21:50:17.533 に答える
2

これはphp5.2のバグです-php.iniでtempdirを指定して
ください 5.5で修正されまし
たこれを一時的な解決策として使用してください:

<?php
putenv('TMPDIR=/path/to/your/tmp');
          ...your code here ...
于 2014-03-28T23:55:59.593 に答える
1

人々がここにたどり着いた場合、問題はputenvで解決されません...

...私にとっては、sys_temp_dir使用するphpを次のini_setように設定することができました。

$tmpPath = realpath(__DIR__.'/../app/tmp');
ini_set('sys_temp_dir', $tmpPath);

私はwindows8マシンでPHP5.5.9(cli)を実行しています。

于 2014-06-04T08:48:52.400 に答える
0

によって返される値を変更できるようですsys_get_temp_dir()。apache2.4とphp5.6.27を試してみました。

sys_temp_dir仮想ホストにを追加します。

php_admin_value sys_temp_dir "/var/www/alternc/f/fser/tmp"

Apacheを再起動し、次を使用してWebページに値を出力しますsys_get_temp_dir()

<?php 
echo sys_get_temp_dir () ;

期待される出力を生成します:/var/www/alternc/f/fser/tmp

于 2016-10-28T16:03:39.473 に答える