remove - ¿Cómo se consigue PHP, Symlinks y__FILE__ para trabajar juntos muy bien?
symlink ubuntu (6)
En localhost. Tengo la siguiente estructura de directorio:
/share/www/trunk/wp-content/plugins/otherfolders
/share/www/portfolio/wp-content/symlink
Donde symlink
es un enlace simbólico a /trunk/.../plugins/
. Básicamente, esto se debe a que necesito probar varias instalaciones de WordPress y configurarlas, pero no quiero tener que mover los complementos y copiarlos y pegarlos en todas partes.
Sin embargo, a veces tengo que rastrear el árbol de directorios para incluir un archivo de configuración:
$root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists($root.''/wp-load.php'')) {
// WP 2.6
require_once($root.''/wp-load.php'');
}
La carpeta siempre resuelve a:
/share/www/trunk
Incluso cuando el complemento se está ejecutando e incluido en
/share/www/portfolio/
.
¿Es posible en PHP incluir archivos en el directorio share/www/portfolio
desde un script que se ejecuta en un enlace simbólico al directorio /share/www/trunk/.../plugins
?
Si bien este problema solo ocurre en mi servidor de prueba, me gustaría tener una solución de distribución segura, por lo que no es una opción instalarse en un nivel adicional .
Aquí está la solución a ese problema: https://github.com/logical-and/symlink-detective
$root = dirname(dirname(dirname(dirname(__FILE__))));
if (file_exists(SymlinkDetective::detectPath($root.''/wp-load.php''))) {
// WP 2.6
require_once(SymlinkDetective::detectPath($root.''/wp-load.php''));
}
o puedes intentar eso
try {
$root = dirname(dirname(dirname(dirname(__FILE__))));
require_once SymlinkDetective::detectPath($root.''/wp-load.php'', '''',
false /* this would throw an exception if file doesn''t exists */);
}
catch (Exception $e) {
// nothing to do if file doesn''t exists
}
El intérprete de PHP resuelve los enlaces simbólicos antes de procesarlos. Puede hacerlo usted mismo con la función readlink
. PHP resuelve los enlaces porque es más eficiente para *_once
funciones y cachés de códigos como APC, Xcache, etc.
Lo que probablemente necesita es otra forma de encontrar dónde una instalación en particular almacena sus archivos. Recomiendo usar {$_SERVER[''DOCUMENT_ROOT'']}/wp-content/wp-load.php
asumiendo /share/www/portfolio
es la raíz del documento.
El problema que veo con su código es que __FILE__
resuelve automáticamente los enlaces simbólicos.
Del Manual de PHP sobre Constantes Mágicas
... Desde PHP
__FILE__
,__FILE__
siempre contiene una ruta absoluta con enlaces simbólicos resueltos ...
Puede intentar usar $_SERVER["SCRIPT_FILENAME"]
lugar.
$root = realpath(dirname(dirname(dirname(dirname($_SERVER["SCRIPT_FILENAME"])))));
if (file_exists($root.''/wp-load.php'')) {
// WP 2.6
require_once($root.''/wp-load.php'');
}
Tenga en cuenta que agregué la realpath()
al directorio raíz. Dependiendo de su configuración, puede o no necesitarlo.
EDITAR: Use $_SERVER["SCRIPT_FILENAME"]
lugar de $_SERVER["PHP_SELF"]
para la ruta del sistema de archivos.
En algunos casos es posible cambiar el directorio de trabajo y usar getenv (''PWD''):
$root = dirname(dirname(dirname(getenv(''PWD''))));
if (file_exists($root.''/wp-load.php'')) {
// WP 2.6
require_once($root.''/wp-load.php'');
}
Y cambie el directorio de trabajo antes de ejecutar este código:
cd /var/www/wp-content/themes/twenty_twelve/ && php script.php
Puede usar este fragmento de código para obtener una ruta donde los enlaces simbólicos no se resuelvan. Si no tiene bash disponible, probablemente haya un comando diferente que puede usar, pero funciona en entornos linux.
Creo que es una mala práctica que php resuelva enlaces simbólicos en FILE , ya que no hay forma de obtener la ruta con enlaces simbólicos. De lo contrario, podríamos obtenerlo usando realpath.
Oh bien.
<?php
$output = array();
exec(''pwd'', &$output);
define(''__LINK__'', $output[0].substr(__FILE__, strpos(__FILE__, DIRECTORY_SEPARATOR)));
?>
Si estuviera tratando de resolver esto, dividiría __FILE__
largo de los bits de ruta y crearía un SplFileInfo para cada uno en el camino, probaría con isDir y isLink , y luego trataría de determinar cómo manejar la reconstrucción de la ruta una vez que se sabe que es diferente de lo esperado para que pueda sacar desde el directorio correcto. (Si es más un tipo de procedimiento, está is_dir y is_link ).
Dicho esto, creo que ya descalificó esta solución. Tal vez las herramientas son lo suficientemente inteligentes como para hacerlo por usted. Intente comparar el resultado de getRealPath con getPath ? getRealPath dice expresamente que resuelve enlaces simbólicos, mientras que getPath no lo dice expresamente.
Incluso entonces, este rastreo podría no ser seguro en los sitios de los clientes, dependiendo de quién sea el host. He visto algunas configuraciones de sistema de archivos de alojamiento compartido bastante creativas . Puede agregar un cheque a php_uname y extraer el nombre de host de la máquina, y si no es su cuadro dev, no haga el trabajo adicional.