108 votes

Appeler des fonctions PHP dans les chaînes HEREDOC

En PHP, la HEREDOC chaîne déclarations sont vraiment utiles pour la sortie d'un bloc de code html. Vous pouvez le faire analyser dans les variables en les préfixant avec $, mais pour plus de syntaxe compliquée (comme $var[2][3]), vous devez mettre votre expression à l'intérieur d'accolades {}.

En PHP 5, il est possible de faire des appels de fonction dans les accolades {} à l'intérieur d'un HEREDOC de la chaîne, mais vous devez passer par un peu de travail. Le nom de la fonction elle-même doit être stocké dans une variable, et vous devez l'appeler comme il est dynamiquement, un nom de fonction. Par exemple:

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

Comme vous pouvez le voir, c'est un peu plus bordélique que juste:

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

Il y a d'autres façons d'ailleurs le premier exemple de code, tels que la rupture de la HEREDOC pour appeler la fonction, ou d'inverser la question et de faire quelque chose comme:

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

Ce dernier présente l'inconvénient que la sortie est mis directement dans le flux de sortie (sauf si je suis en utilisant le tampon de sortie), ce qui pourrait ne pas être ce que je veux.

Donc, l'essence de ma question est: est-il une façon plus élégante de cette approche?

Modifier sur la base des réponses: Il n'est certainement sembler comme une sorte de moteur de template rendrait ma vie beaucoup plus facile, mais cela m'obligerait essentiellement les inverser mon habitude PHP style. Pas que c'est une mauvaise chose, mais il explique mon inertie.. je suis pour trouver des moyens de rendre la vie plus facile si, si je suis à la recherche dans des modèles maintenant.

79voto

CJ Dennis Points 565

Si vous voulez vraiment faire cela mais un peu plus simplement que d’utiliser une classe, vous pouvez utiliser:

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

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

57voto

Peter Bailey Points 62125

Je ne voudrais pas utiliser HEREDOC à tous pour ce, personnellement. Il n'a tout simplement pas de quoi en faire un bon "modèle " bâtiment" du système. Tout votre HTML est verrouillé vers le bas dans une chaîne de caractères qui a plusieurs inconvénients

  • Pas d'option pour WSYIWYG
  • Pas de completion de code HTML à partir de l'Ide
  • De sortie (HTML) verrouillé à la logique des fichiers
  • Vous finissez par avoir à utiliser des hacks comme ce que vous êtes en train d'essayer de faire pour atteindre les plus complexes de création de modèles, tels que la boucle

Obtenir une base de moteur de template, ou tout simplement utiliser PHP avec comprend - c'est pourquoi nous avons les délimiteurs.

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' );

48voto

boxxar Points 2051

Je voudrais faire ce qui suit:

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

Je ne sais pas si vous considériez cela comme plus élégant ...

17voto

Isofarro Points 131

Essayez ceci (en tant que variable globale ou instanciée quand vous en avez besoin):

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

  $fn = new Fn();
?>
 

Désormais, tout appel de fonction passe par l’instance $fn . Ainsi, la fonction existante testfunction() peut être appelée dans un heredoc avec {$fn->testfunction()}

Fondamentalement, nous encapsulons toutes les fonctions dans une instance de classe et utilisons la méthode __call magic PHP pour mapper la méthode de classe sur la fonction à appeler.

10voto

BraedenP Points 4232

Je suis un peu en retard, mais j'ai accidentellement tombé sur elle. Pour les futurs lecteurs, voici ce que je serais probablement faire:

Je voudrais juste utiliser un tampon de sortie. Donc, fondamentalement, vous démarrez la mise en mémoire tampon à l'aide de ob_start(), puis d'inclure votre "modèle de fichier" avec toutes les fonctions, variables, etc. à l'intérieur de cela, obtenir le contenu de la mémoire tampon et de les écrire dans une chaîne de caractères, puis fermer le tampon. Ensuite, vous avez utilisé toutes les variables dont vous avez besoin, vous pouvez exécuter n'importe quelle fonction, et vous avez encore de la syntaxe HTML soulignant disponible dans votre IDE.

Voici ce que je veux dire:

Fichier De Modèle:

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

Ainsi, le script inclut les template_file.php dans son mémoire tampon, l'exécution de toutes les fonctions/méthodes et l'affectation des variables le long du chemin. Ensuite, il vous suffit d'enregistrer la mémoire tampon est contenu dans une variable et faire ce que vous voulez avec elle.

De cette façon, si vous ne voulez pas en faire l'écho sur la page de droite, à cette seconde, vous n'avez pas à. Vous pouvez faire une boucle et continuer à ajouter à la chaîne avant de le reproduire.

Je pense que c'est la meilleure voie à suivre si vous ne voulez pas utiliser un moteur de template.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X