Domanda

In PHP, le dichiarazioni di stringhe HEREDOC sono davvero utili per emettere un blocco di HTML. Puoi analizzarlo nelle variabili semplicemente anteponendole a $, ma per una sintassi più complicata (come $ var [2] [3]), devi inserire la tua espressione tra {} parentesi graffe.

In PHP 5, è possibile effettivamente effettuare chiamate di funzione tra parentesi graffe {} all'interno di una stringa HEREDOC, ma è necessario un po 'di lavoro. Il nome della funzione stessa deve essere memorizzato in una variabile e devi chiamarlo come se fosse una funzione con nome dinamico. Ad esempio:

$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;

Come puoi vedere, questo è un po 'più disordinato di un semplice:

$string = <<< heredoc
plain text and now a function: {testfunction()}
heredoc;

Esistono altri modi oltre al primo esempio di codice, come uscire da HEREDOC per chiamare la funzione o invertire il problema e fare qualcosa del tipo:

?>
<!-- directly output html and only breaking into php for the function -->
plain text and now a function: <?PHP print testfunction(); ?>

Quest'ultimo ha lo svantaggio che l'output viene inserito direttamente nel flusso di output (a meno che non stia utilizzando il buffering dell'output), che potrebbe non essere quello che voglio.

Quindi, l'essenza della mia domanda è: esiste un modo più elegante di affrontarlo?

Modifica in base alle risposte: Sicuramente sembra che una sorta di template engine mi renderebbe la vita molto più semplice, ma mi richiederebbe sostanzialmente di invertire il mio solito stile PHP. Non che sia una brutta cosa, ma spiega la mia inerzia. Sono pronto a capire come rendere la vita più semplice, quindi sto cercando modelli ora.

È stato utile?

Soluzione

Non userei HEREDOC per questo, personalmente. Semplicemente non è un buon & Quot; template building & Quot; sistema. Tutto il tuo HTML è bloccato in una stringa che presenta diversi svantaggi

  • Nessuna opzione per WYSIWYG
  • Nessun completamento del codice per HTML da IDE
  • Output (HTML) bloccato su file logici
  • Alla fine devi usare gli hack come quello che stai cercando di fare ora per ottenere modelli più complessi, come il looping

Ottieni un motore modello di base o usa semplicemente PHP con include: ecco perché la lingua ha i delimitatori <?php e ?>.

template_file.php

<html>
<head>
  <title><?php echo $page_title; ?></title>
</head>
<body>
  <?php echo getPageContent(); ?>
</body>

index.php

<?php

$page_title = "This is a simple demo";

function getPageContent() {
    return '<p>Hello World!</p>';
}

include('template_file.php');

Altri suggerimenti

Se vuoi davvero farlo, ma un po 'più semplice rispetto all'utilizzo di una classe puoi usare:

function fn($data) {
  return $data;
}
$fn = 'fn';

$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;

Vorrei fare quanto segue:

$string = <<< heredoc
plain text and now a function: %s
heredoc;
$string = sprintf($string, testfunction());

Non sono sicuro che lo consideri più elegante ...

Prova questo (come variabile globale o istanziato quando ne hai bisogno):

<?php
  class Fn {
    public function __call($name, $args) {
      if (function_exists($name)) {
        return call_user_func_array($name, $args);
      }
    }
  }

  $fn = new Fn();
?>

Ora qualsiasi chiamata di funzione passa attraverso l'istanza $fn. Quindi la funzione esistente testfunction() può essere chiamata in eredità con {$fn->testfunction()}

Fondamentalmente stiamo avvolgendo tutte le funzioni in un'istanza di classe e usando il metodo __call magic di PHP per mappare il metodo di classe sulla funzione effettiva che deve essere chiamata.

Sono un po 'in ritardo, ma l'ho trovato a caso. Per i futuri lettori, ecco cosa probabilmente farei:

Vorrei solo usare un buffer di output. Quindi, fondamentalmente, si avvia il buffering usando ob_start (), quindi si include il & Quot; file modello & Quot; con qualsiasi funzione, variabile, ecc. al suo interno, ottenere il contenuto del buffer e scriverli in una stringa, quindi chiudere il buffer. Quindi hai utilizzato tutte le variabili di cui hai bisogno, puoi eseguire qualsiasi funzione e hai ancora l'evidenziazione della sintassi HTML disponibile nel tuo IDE.

Ecco cosa intendo:

File modello:

<?php echo "plain text and now a function: " . testfunction(); ?>

Script:

<?php
ob_start();
include "template_file.php";
$output_string = ob_get_contents();
ob_end_clean();
echo $output_string;
?>

Quindi lo script include template_file.php nel suo buffer, eseguendo qualsiasi funzione / metodo e assegnando qualsiasi variabile lungo il percorso. Quindi semplicemente registra il contenuto del buffer in una variabile e fai quello che vuoi con esso.

In questo modo, se non vuoi riecheggiarlo sulla pagina in quel preciso istante, non devi farlo. Puoi eseguire il loop e continuare ad aggiungere alla stringa prima di inviarla.

Penso che sia il modo migliore se non vuoi usare un motore di template.

Per completezza, puoi anche utilizzare la !${''} magia nera hacker parser :

echo <<<EOT
One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}.
EOT;

Questo frammento definirà le variabili con il nome delle funzioni definite all'interno di userscope e le assocerà a una stringa che contiene lo stesso nome. Lasciami dimostrare.

function add ($int) { return $int + 1; }
$f=get_defined_functions();foreach($f[user]as$v){$$v=$v;}

$string = <<< heredoc
plain text and now a function: {$add(1)}
heredoc;

Ora funzionerà.

Penso che usare heredoc sia ottimo per generare codice HTML. Ad esempio, trovo quanto segue quasi completamente illeggibile.

<html>
<head>
  <title><?php echo $page_title; ?></title>
</head>
<body>
  <?php echo getPageContent(); ?>
</body>

Tuttavia, per ottenere la semplicità sei costretto a valutare le funzioni prima di iniziare. Non credo che sia un vincolo così terribile, poiché così facendo finisci per separare il tuo calcolo dal display, che di solito è una buona idea.

Penso che quanto segue sia abbastanza leggibile:

$page_content = getPageContent();

print <<<END
<html>
<head>
  <title>$page_title</title>
</head>
<body>
$page_content
</body>
END;

Sfortunatamente, anche se è stato un buon suggerimento che hai fatto nella tua domanda per associare la funzione a una variabile, alla fine, aggiunge un livello di complessità al codice, che non vale la pena, e rende il codice meno leggibile , che è il principale vantaggio di heredoc.

ho trovato una bella soluzione con la funzione wrapping qui: http://blog.nazdrave.net/?p= 626

function heredoc($param) {
    // just return whatever has been passed to us
    return $param;
}

$heredoc = 'heredoc';

$string = <<<HEREDOC
\$heredoc is now a generic function that can be used in all sorts of ways:
Output the result of a function: {$heredoc(date('r'))}
Output the value of a constant: {$heredoc(__FILE__)}
Static methods work just as well: {$heredoc(MyClass::getSomething())}
2 + 2 equals {$heredoc(2+2)}
HEREDOC;

// The same works not only with HEREDOC strings,
// but with double-quoted strings as well:
$string = "{$heredoc(2+2)}";

Darei un'occhiata a Smarty come motore modello - non ho provato nessun altro io stesso, ma mi ha fatto bene.

Se si desidera attenersi ai modelli sans del proprio approccio attuale, cosa c'è di male nel buffering dell'output? Ti darà molta più flessibilità rispetto a dover dichiarare le variabili che sono i nomi delle funzioni che vuoi chiamare.

Un po 'in ritardo ma comunque. Questo è possibile in eredità!

Dai un'occhiata a il manuale php, sezione " Sintassi (riccia) complessa "

Ecco un bell'esempio usando la proposta di @CJDennis:

function double($i)
{ return $i*2; }

function triple($i)
{ return $i*3;}

$tab = 'double';
echo "{$tab(5)} is $tab 5<br>";

$tab = 'triple';
echo "{$tab(5)} is $tab 5<br>";

Ad esempio, un buon uso della sintassi HEREDOC è generare enormi moduli con relazioni master-dettaglio in un database. È possibile utilizzare la funzione HEREDOC all'interno di un controllo FOR, aggiungendo un suffisso dopo il nome di ciascun campo. È un'attività tipica lato server.

ti stai dimenticando della funzione lambda:

$or=function($c,$t,$f){return$c?$t:$f;};
echo <<<TRUEFALSE
    The best color ever is {$or(rand(0,1),'green','black')}
TRUEFALSE;

Puoi anche usare la funzione create_function

I ragazzi dovrebbero notare che funziona anche con stringhe tra virgolette doppie.

http://www.php.net/manual/en /language.types.string.php

Consiglio interessante comunque.

<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
".  And that is it!
heredoc
?></div>
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;

dovresti provarlo. dopo fine ETO; comando dovresti dare un invio.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top