2011-02-09 19 views
5

Esto es más de un '¿Cómo debería I?' en lugar de '¿Cómo do I?' pregunta.PHP - La mejor práctica para pasar variables para incluir archivos

En general, ¿cuál es la mejor manera de pasar variables a un archivo incluido?

Por ejemplo, supongamos que estoy usando un fragmento para un menú, y quiero que uno de los elementos del menú (el actual) tenga un cierto nombre de clase (esta es una muestra muy genérica, no es algo que yo soy en realidad usando):

<?php 
$links = array(
    array('text' => 'home', 'href' => 'home.php'), 
    array('text' => 'about', 'href' => 'about.php'), 
    array('text' => 'contact', 'href' => 'contact.php') 
); 
?> 
<ul> 
<?php for($i = 0; $i < 3; $i++) : 
    $link = $links[$i]; 
    $is_active = ($i == $active_index); 
?> 
    <li><a <?=($is_active ? 'class="active"' : '')?> href="<?=$link['href']?>"><?=$link['text']?></a></li> 
<?php endfor; ?> 
</ul> 

Llamaré al 'menú.inc.php' anterior. obviamente está buscando una variable (int) llamada $active_index para determinar a qué enlace dar la clase '.active'.

así que podría simplemente definir $active_index antes de llamar al include, pero esto me parece una mala práctica ya que tal vez una variable de ese nombre podría haber sido definida para algo más anterior y una parte posterior del script todavía está buscando eso.

o - se puede utilizar una ruta absoluta y añadir variables utilizando una cadena de consulta (include 'menu.inc.php?active_index=1'), pero de nuevo que parece una mala idea ya que es posible que tenga la 'verdadera' $_GET dentro de cualquier include dada.

o - se puede empezar cada incluía archivo con ob_start y volver ob_end_clean(), a continuación, utilizar algo como esto para conseguir el retorno:

function load_view($file, $variables){ 
    extract($variables); 
    return include($file); 
} 
// passed like 
<?=load_view('menu.inc.php', array('active_index' => 2))?> 

pero de nuevo esto parece tener una serie de desventajas (tener que reestructurar toda Incluya sus archivos de acuerdo con las funciones ob y una declaración return).

Respuesta

4

I como un objeto para este, como se describe in this MVC stack post. En un archivo llamado viewMenu.class.php,

class viewMenu 
    { 
    private $active_link; 

    public function __construct ($active_link) 
    { 
    $this->active_link = $active_link; 
    } 
    //If the constructor doesn't work for you, try a "set" method. 

    public function view() 
    { 
    $active_link = $this->active_link; 
    include_once ("menu.inc.php"); 
    } 
    } 

Definir $ active_link dentro del método vista contiene el alcance de la variable $ a active_link dentro del método. A continuación, llame a este código:

$aViewMenu = new viewMenu($active_link); 
$aViewMenu->view(); 

Sin embargo, soy casi nuevo para MVC en PHP, y doy la bienvenida al reproche.

+1

Esto es similar al enfoque adoptado en las vistas de Zend Framework. El controlador configura el modelo en la vista ('ViewMenu' asume los roles de controlador y modelo anteriores) y luego ejecuta una secuencia de comandos de vista a través de' include' dentro del método 'render()' de la vista. Puede lograr el mismo efecto anterior al descartar la variable local '$ active_link' y acceder a ella en el script incluido usando' $ this-> active_link'. –

1

Personalmente, simplemente definiría $active_index antes de incluir, o, siendo tal vez un poco más en línea con buenas prácticas de codificación, haga que la generación del menú sea una función con un parámetro $active_index.

Por ejemplo (valga el lío que sigue):

<?php // menu.php 
$links = array(
    array('text' => 'home', 'href' => 'home.php'), 
    array('text' => 'about', 'href' => 'about.php'), 
    array('text' => 'contact', 'href' => 'contact.php') 
); 

function generate_menu($active_index) 
{ 
?> 
    <ul> 
    <?php 
    $linkcount = count($links); 
    for($i = 0; $i < $linkcount; $i++) 
    { 
     $link = $links[$i]; 
     $is_active = ($i == $active_index); 
    ?> 
     <li><a <?=($is_active ? 'class="active"' : '')?> href="<?=$link['href']?>"><?=$link['text']?></a></li> 
    <?php 
    } 
    ?> 
    </ul> 
} 

y:

<?php // mypage.php 
generate_menu(0); 
?> 
blah blah content goes here 
+0

gracias por la respuesta rfw, pero como mencioné esto parece una mala práctica ya que esos nombres de variables serían globales. también, puede usar querystring con includes si usa rutas absolutas (vea el ejemplo 3 aquí: http://php.net/manual/en/function.include.php), pero por las razones enumeradas anteriormente, no creo que esto sea el mejor enfoque general (ya que entonces habías perdido las variables $ _GET originales) – momo

+0

@ Big MoMo quizás te gustaría que mi función se acercara mejor? – rfw

+0

el enfoque de función tiene un par de inconvenientes (mencionados en la publicación original) y requiere una reestructuración de los archivos 'ver'; idealmente, los archivos de vista son html con muy poco php, solo lo suficiente para proporcionar contenido (smarty y codeignitador son buenos ejemplos , aunque cada uno de ellos tiene sus propios pros y contras). Además, una función como esa puede ser un poco engorrosa cuando se trata de archivos de vista grande, y no hace mucho para separar la lógica del contenido. – momo

Cuestiones relacionadas