2008-10-03 16 views
5

Tengo una función que incluye un archivo basado en la cadena que se le pasa, es decir, la variable de acción de la cadena de consulta. Utilizo esto con fines de filtrado, etc. para que las personas no puedan incluir archivos que no deberían poder y, si el archivo no existe, se carga un archivo predeterminado. El problema es que cuando la función se ejecuta e incluye el alcance del archivo, se pierde porque el include se ejecutó dentro de una función. Esto se convierte en un problema porque utilizo un archivo de configuración global, luego utilizo archivos de configuración específicos para cada módulo en el sitio. La forma en que lo estoy haciendo en este momento es definir las variables que quiero usar como globales y luego sumarlas en la parte superior de la función de filtrado.PHP Conservar ámbito al llamar a una función

¿Hay alguna manera más fácil de hacerlo, es decir, conservando el alcance cuando se realiza una llamada de función o existe algo así como las macros de PHP?

Editar: ¿Sería mejor utilizar extracto ($ _ GLOBALS); dentro de mi llamada de función en su lugar?

Editar 2: Para cualquier persona que le haya importado. Me di cuenta de que ya estaba pensando en el problema y que, en lugar de usar una función, debería usar un include, duh! De esa manera puedo mantener mi alcance y tener mi pastel también.

+0

En mi caso recurrir a su "Edición 2" y simplemente utilizando un include no funcionó porque he tengo muchas más cosas sucediendo. Básicamente, piense en ello como una clase "Ver" que requiere un viewcript.php que, dado que estamos en un ámbito de complemento, quiero pasar el alcance "global" al viewcript sin necesidad de declarar todas las variables como globales en el " doInclude "función. –

Respuesta

5

Editar: Bueno, he re-leer su pregunta y creo que entiendo lo que está hablando ahora:
quieres algo como esto para trabajar:

// myInclude.php 
$x = "abc"; 

// ----------------------- 
// myRegularFile.php 

function doInclude() { 
    include 'myInclude.php'; 
} 
$x = "A default value"; 
doInclude(); 
echo $x; // should be "abc", but actually prints "A default value" 

Si solo están cambiando un par de variables, y usted sabe de antemano qué variables se van a definir en el include, las declara como global en la función doInclude().

Alternativamente, si cada uno de sus incluye podría definir cualquier número de variables, se puede poner a todos en una matriz:

// myInclude.php 
$includedVars['x'] = "abc"; 
$includedVars['y'] = "def"; 

// ------------------ 
// myRegularFile.php 
function doInclude() { 
    global $includedVars; 
    include 'myInclude.php'; 
    // perhaps filter out any "unexpected" variables here if you want 
} 

doInclude(); 
extract($includedVars); 
echo $x;  // "abc" 
echo $y;  // "def" 

respuesta original:

este tipo de cosas se conoce como "cierres" y se están introduciendo en PHP 5.3

http://steike.com/code/php-closures/

¿Sería mejor utilizar extracto ($ _ GLOBALS); dentro de mi llamada de función en su lugar?

dear lord, no. si desea acceder a una variable global desde dentro de una función, simplemente use la palabra clave global. por ejemplo:

$x = "foo"; 
function wrong() { 
    echo $x; 
} 
function right() { 
    global $x; 
    echo $x; 
} 

wrong();  // undefined variable $x 
right();  // "foo" 
+0

Este es exactamente el problema que me he encontrado. Estoy intentando desarrollar un complemento para un script, pero desafortunadamente ese script hace algunas cosas extrañas con los globales. Me duele hacer un seguimiento de todos los diversos globales que necesito y declararlos en la función "doInclude". Oh, bueno ... pensé que $ GLOBALS funcionaría, pero eso no funciona debido al orden de las funciones e incluye. Tal es la vida de un desarrollador de complementos, supongo. –

0

Cuando se trata de opciones de configuración (especialmente rutas de archivos y similares) generalmente solo las defino con rutas absolutas usando un define(). Algo así como:

define('MY_CONFIG_PATH', '/home/jschmoe/myfiles/config.inc.php'); 

De esa manera siempre son accesibles a nivel mundial, independientemente de los cambios de alcance y, a menos que migrar a una estructura de archivos diferente que siempre es capaz de encontrar todo.

+0

Tengo la mayoría de las variables de configuración configuradas de esta manera, pero tengo una serie de códigos de país, un objeto de base de datos, etc. que no se pueden definir de esta manera. – Joshua

0

Si he entendido bien, tiene un código largo de las líneas de:

function do_include($foo) { 
    if (is_valid($foo)) 
    include $foo; 
} 

do_include(@$_GET['foo']); 

Una solución (que puede o no puede ser simple, dependiendo de la base de código) es mover los incluyen en el mundial alcance:

if (is_valid(@$_GET['foo'])) 
    include $_GET['foo']; 

Otras soluciones existe (como usted ha mencionado: declarando variables globales, trabajando con la matriz $ _GLOBALS directamente, etc), pero la ventaja de esta solución es que usted no tiene que recordar esas convenciones en todo los archivos incluidos

0

Por qué no devolver un valor desde las necesidades de inclusión y luego ajustar el valor de la llamada incluir a una variable:

config.php

return array(
    'foo'=>'bar', 
    'x'=>23, 
    'y'=>12 
); 

script.php

$config = require('config.php'); 
var_dump($config); 

n necesita estropear el lugar con las variables globales

0

¿Hay alguna manera más fácil de hacer esto, es decir, mediante la preservación de alcance cuando se hace una llamada a la función

que puede usar:

function doInclude($file, $args = array()) { 
    extract($args); 
    include($file); 
} 

Si no desea pasar explícitamente las variables, podría llamar doInclude con get_defined_vars como argumento, por ejemplo .:

doInclude('test.template.php', get_defined_vars()); 

Personalmente preferiría pasar una matriz explícita, en lugar de usar esto, pero funcionaría.

+0

Esto no responde a la pregunta, sino que dice "lo estás haciendo mal". Gracias Steve. A veces hay situaciones en las que * sería * bueno ejecutar una función utilizando un alcance deseado (es decir, global) 'call_user_func_array_with_scope ('function', $ args, $ this)' sería ingenioso si existiera ... (O pasando) nulo "o global para rebotar en el ámbito global. Sería útil al construir un complemento para trabajar dentro de algunas limitaciones bien definidas. –

0

Se puede declarar variables en el archivo incluido como global, asegurando que tengan alcance mundial:

//inc.php 
global $cfg; 
$cfg['foo'] = bar; 

//index.php 
function get_cfg($cfgFile) { 
    if (valid_cfg_file($cfgFile)) { 
     include_once($cfgFile); 
    } 
} 
... 
get_cfg('inc.php'); 
echo "cfg[foo]: $cfg[foo]\n"; 
Cuestiones relacionadas