subir servidores para paginas mejor ilimitado hostinger gratuitos gratuito gratis espaƱol dominio php apache2 cgi shared-hosting

php - servidores - sys_get_temp_dir en un entorno de alojamiento compartido



mejor hosting gratuito (7)

Nota: Esto también podría caber en superusuario.

Estoy configurando PHP 5.3.10 en un host compartido con apache2 mpm itk y open_basedir de manera que cada usuario no pueda ver o cambiar los archivos de otro usuario. En la configuración de apache2 vhost, agrego las entradas apropiadas para restringir al usuario:

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/

Ahora, la primera línea configura el usuario de Linux para usar para apache2, las siguientes tres líneas definen el basedir, el directorio de carga y la ruta de acceso de la sesión para que estén en el directorio del usuario. Volveré a la última línea en un segundo.

Ahora para el problema: sys_get_temp_dir() debería devolver el directorio temporal para php, que es / tmp predeterminado en un sistema Linux. Por razones de seguridad, este directorio debe residir en el open_basedir de userA. De acuerdo con la fuente php de 5.3.10, sys_get_temp_dir() -function utiliza la variable de entorno TMPDIR para obtener este directorio:

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

Esto es lo que debería hacer la quinta línea en la configuración anterior. Sin embargo, sys_get_temp_dir() simplemente devuelve el directorio del sistema global, ignorando la variable de entorno (que está perfectamente configurada en $ _SERVER, también visible a través de phpinfo() ).

Esto resulta en algunos errores desagradables con varios programas que se basan en sys_get_temp_dir() , ya que ese directorio está fuera de la configuración de open_basedir . He intentado establecer la variable directamente en $ _ENV y $ _SERVER sin un cambio en el comportamiento. He probado un putenv(''TMPDIR=/home/userA/www/tmp'') sin cambios.

Sin embargo, puedo cambiar la salida definiendo la variable en / etc / apache2 / envvars, lo cual es inútil para mí, ya que quiero que cada VHOST tenga su propia carpeta temporal.

La única solución que he encontrado hasta ahora es sobrescribir el sys_get_temp_dir() interno a través de una extensión como runkit y hacer cumplir su inclusión a través de auto_prepend_file . Pero esa solución está tan sucia que simplemente no puedo creer que no haya una solución mejor.

Entonces, mi pregunta: ¿Hay alguna forma de cambiar el resultado de sys_get_temp_dir() para que se establezca en un apache2 vhost, sin volver a implementar la función con runkit?

Edición: la versión de apache es 2.2.22, y actualmente uso mod_php. Como tendré que agregar todos los usuarios manualmente, también sería posible un fcgi o una configuración similar.


En caso de que la gente termine aquí, el problema no se resuelve con putenv ...

... para mí, funcionó para configurar el sys_temp_dir usando el sys_temp_dir php como este:

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

Estoy ejecutando PHP 5.5.9 (cli) en una máquina con windows8.


Esto es un error en php 5.2 - especifica temp dir por php.ini
Se fija en 5.5.
Usa esto como una solución temporal:

<?php putenv(''TMPDIR=/path/to/your/tmp''); ...your code here ... ?>


Has etiquetado tu pregunta cgi , sin embargo estás haciendo uso de

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

que es un ajuste para la versión del módulo apache de PHP, Mod_PHP . En ese caso, PHP se carga una vez que se inicia el servidor web.

Entonces haces uso de SetEnv :

SetEnv TMPDIR /home/userA/www/tmp/

esto es establecer una variable de entorno interno . Se pasa a otros módulos de Apache, sin embargo, creo que lo necesita con la solicitud, no con el servidor virtual. No lo sé específicamente, pero supongo que de acuerdo con su descripción, esta variable de entorno se restablecerá antes de invocar el script PHP.

Así que más un comentario que una respuesta real, pero espero que te ayude a aclarar algunas cosas.

Normalmente uso FCGI para entornos multiusuario para poder separar mejor a los usuarios. Nunca tuve problemas con la configuración de variables de entorno para cada usuario. Pero eso es solo otro comentario, no quiero decir que también tengas que usarlo. Solo para resaltar que necesita encontrar el lugar correcto dentro de apache para establecer la variable de entorno para que se establezca (aún) cuando se ejecuta el script.

También es posible que no esté configurando la variable de entorno correcta. Según la documentación de Apache sobre variables de entorno :

Aunque estas variables se conocen como variables de entorno , no son las mismas que las variables de entorno controladas por el sistema operativo subyacente. En su lugar, estas variables se almacenan y manipulan en una estructura interna de Apache. Solo se convierten en variables reales del entorno del sistema operativo cuando se proporcionan a scripts CGI y scripts Server Side Include. Si desea manipular el entorno del sistema operativo en el que se ejecuta el servidor, debe utilizar los mecanismos de manipulación de entorno estándar proporcionados por el shell de su sistema operativo.

Desea establecer la variable de entorno del sistema operativo para PHP. Pero está configurando la variable de entorno interno solamente.

Mod_PHP puede importarlos a la secuencia de comandos, por lo que si usa getenv(''TMPDIR'') se usa la implementación específica de SAPI de PHP, que le permite ver esas variables de entorno internas; sin embargo, la función php_get_temporary_directory no lo está utilizando.

Por favor agregue su versión de Apache y PHP a su pregunta.


La ejecución de un putenv(''TMPDIR=/foo/bar'') dentro de PHP parece ser capaz de afectar el resultado de sys_get_temp_dir() . Podría tener una directiva auto_prepend_file organizada para ejecutar un fragmento de PHP para configurar el TMPDIR y evitar la confusión con una redefinición de sys_get_temp_dir() .

Edición: Además, podría usar fácilmente putenv(''TMPDIR=''.ini_get(''open_basedir'').''/tmp'') para establecer el directorio temporal en la estructura de directorios que estableció en la pregunta.

Lo suficientemente divertido, esto también funciona (dado que mantienes el SetEnv TMPDIR /foo/bar en tu configuración de Apache):

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

Parece un no-op, pero en realidad tiene efecto en sys_get_temp_dir() . Estoy empezando a sospechar que esto tiene que ser un error de manejo del entorno en PHP.


Mirando la fuente de PHP , sys_get_temp_dir() trabaja con la siguiente prioridad:

  1. Si su valor se ha calculado anteriormente, se utiliza el valor almacenado en caché.
  2. sys_temp_dir se comprueba en la configuración ini.
  3. En Windows, se utiliza el método de la API Win32 de GetTempPathW y, según su documentación, se utilizan los siguientes (en este orden):
    1. La ruta especificada por la variable de entorno TMP .
    2. La ruta especificada por la variable de entorno TEMP .
    3. La ruta especificada por la variable de entorno USERPROFILE .
    4. El directorio de Windows.
  4. En * nix, se utilizan los siguientes (en este orden):
    1. La variable de entorno TMPDIR .
    2. La macro P_tmpdir
    3. /tmp (según la fuente, este es un esfuerzo de última hora que nunca debería ocurrir).

Eso debería darle suficientes opciones para controlar el resultado de sys_get_temp_dir (por ejemplo, ini_set(''sys_temp_dir'', $tmpPath) o putenv(''TMPDIR=/foo/bar'') como otros han mencionado). A menos que se haya calculado previamente, en cuyo caso usted '' Re SOL, por lo que sé y se utilizará el valor almacenado en caché (pero no tengo ningún conocimiento de PHP, por lo que me encantaría escuchar lo contrario).


Parece que puedes cambiar el valor devuelto por sys_get_temp_dir() , acabo de probar Apache 2.4 y PHP 5.6.27.

Agregue un sys_temp_dir en el host virtual:

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

Reinicie Apache e imprima el valor en una página web usando sys_get_temp_dir() :

<?php echo sys_get_temp_dir () ;

Produce la salida esperada: /var/www/alternc/f/fser/tmp .


Según este error de 4 años , sys_get_temp_dir() no funcionará con hosts virtuales; asi que

  • puede intentar usar solo las bibliotecas que solucionaron este problema (y abrir un error para aquellos que no lo hicieron)
  • o agregue /tmp (o lo que sea que use su sistema operativo) en su open_basedir , ya que puede contener múltiples directorios (como include_path - sepárelo con ; en Windows, de lo contrario)