2011-02-09 6 views
5

Questo è più di un 'Come dovrebbe I?' piuttosto che "Come do I?" domanda.PHP: best practice per il passaggio di variabili ad includere file

In genere, qual è il modo migliore per passare le variabili a un file incluso?

Ad esempio, supponiamo che io stia utilizzando un frammento per un menu e che uno degli elementi del menu (quello corrente) abbia un determinato nome di classe (questo è un esempio molto generico - non qualcosa che sono effettivamente utilizzando):

<?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> 

chiamerò il precedente 'menu.inc.php'. ovviamente sta cercando una variabile (int) chiamata $active_index per determinare a quale collegamento assegnare la classe '.active'.

così - si poteva semplicemente definire $active_index prima di chiamare l'inclusione, ma questo mi sembra una cattiva pratica dal momento che forse una variabile di quel nome potrebbe essere stata definita per qualcos'altro prima e una parte successiva dello script è ancora in cerca di esso.

o - si potrebbe usare un percorso assoluto e aggiungere variabili utilizzando una querystring (include 'menu.inc.php?active_index=1'), ma ancora una volta che sembra una cattiva idea, dato che potrebbe essere necessario il 'reale' $_GET all'interno di un dato include.

o - si potrebbe iniziare ogni inclusi file con ob_start e tornare ob_end_clean(), quindi usare qualcosa di simile a questo per ottenere il ritorno:

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

ma anche questo sembra avere un certo numero di svantaggi (dover ristrutturare tutto i file include di conseguenza con le funzioni ob e una dichiarazione return).

risposta

4

mi piace un oggetto per questo, come descritto in this MVC stack post. In un file chiamato 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"); 
    } 
    } 

Definire $ active_link all'interno del metodo vista contiene la portata variabile $ active_link alla all'interno del metodo. Quindi chiama questo codice:

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

Tuttavia, sono quasi nuovo a MVC in PHP e accolgo il rimprovero.

+1

Questo è simile all'approccio adottato nelle viste Zend Framework. Il controller imposta il modello nella vista ('ViewMenu' assume sia il controller che i ruoli del modello sopra) e quindi esegue uno script di visualizzazione tramite' include' all'interno del metodo 'render()' della vista. È possibile ottenere lo stesso effetto sopra rilasciando la variabile locale '$ active_link' e accedendola nello script incluso usando' $ this-> active_link'. –

1

Personalmente, vorrei solo definire $active_index prima di includerlo, o, essendo forse un po 'più in linea con buone pratiche di codifica, rendere il menu di generazione una funzione con un parametro $active_index.

Ad esempio (perdonate la confusione che segue):

<?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> 
} 

e:

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

grazie per la risposta rfw, ma come ho già detto sembra una cattiva pratica in quanto tali nomi di variabili sarebbero globali. inoltre, puoi usare querystring con include se usi percorsi assoluti (vedi esempio 3 qui: http://php.net/manual/en/function.include.php), ma per i motivi sopra elencati non penso che questo sia il miglior approccio generale (dato che hai perso le variabili $ _GET originali) – momo

+0

@Big MoMo forse ti piacerebbe che il mio approccio funzioni meglio? – rfw

+0

l'approccio della funzione ha un paio di inconvenienti (menzionati nel post originale) e richiede la ristrutturazione dei file 'view' - idealmente, i file di visualizzazione sono html con pochissimo php - quanto basta per fornire il contenuto (smarty e codeigniter sono buoni esempi , anche se ognuno di questi ha i suoi pro e contro. inoltre, una funzione del genere può risultare un po 'macchinosa quando si gestiscono file di grandi dimensioni e non fa molto per separare la logica dal contenuto. – momo