Pergunta

Em PHP, as declarações de cordas heredoc são realmente úteis para a saída de um bloco de html. Você pode tê-lo analisar em variáveis ??apenas prefixando-os com US $, mas para sintaxe mais complicada (como $ var [2] [3]), você tem que colocar o seu interior expressão {} chaves.

No PHP 5, ele é realmente possível fazer chamadas de função dentro {} chaves dentro de uma string heredoc, mas você tem que passar por um pouco de trabalho. O próprio nome da função tem de ser armazenado em uma variável, e você tem que chamá-lo como se fosse uma função dinamicamente nomeado. Por exemplo:

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

Como você pode ver, este é um pouco mais confuso do que apenas:

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

Existem outras maneiras além do primeiro exemplo de código, como sair do heredoc para chamar a função, ou reverter o problema e fazer algo como:

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

O último tem a desvantagem de que a saída está diretamente colocado no fluxo de saída (a menos que eu estou usando o buffer de saída), que pode não ser o que eu quero.

Assim, a essência da minha pergunta é: se existe uma maneira mais elegante de abordar este

Editar com base nas respostas: Ele certamente parece ser algum tipo de modelo de motor faria minha vida muito mais fácil, mas me exigem basicamente invertido meu estilo PHP habitual. Não que isso seja uma coisa ruim, mas explica a minha inércia .. Eu estou aqui para descobrir maneiras de tornar a vida mais fácil, então eu estou olhando para modelos agora.

Foi útil?

Solução

Eu não usaria heredoc em tudo para isso, pessoalmente. Ele simplesmente não faz para um bom sistema de "construção de modelo". Todo o seu HTML é bloqueado em uma corda que tem várias desvantagens

  • Sem opção para WYSIWYG
  • No conclusão de código para código HTML IDEs
  • Saída (HTML) bloqueado para arquivos lógicos
  • Você acaba tendo que hacks uso como o que você está tentando fazer agora para conseguir modelagem mais complexa, como looping

Obter um motor básico modelo, ou simplesmente usar o PHP com inclui. - É por isso que a língua tem os delimitadores <?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');

Outras dicas

Se você realmente quer fazer isso, mas um pouco mais simples do que usar uma classe que você pode usar:

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

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

Eu faria o seguinte:

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

Não tenho certeza se você considerar que este seja mais elegante ...

Tente este (seja como uma variável global, ou instanciado quando você precisar dele):

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

  $fn = new Fn();
?>

Agora, qualquer chamada de função passa a instância $fn. Assim, o testfunction() função existente pode ser chamado em um heredoc com {$fn->testfunction()}

Basicamente, estamos envolvendo todas as funções em uma instância de classe, e usando o método __call magic do PHP para mapear o método de classe para a função real necessidade de ser chamado.

Eu sou um pouco tarde, mas eu vim aleatoriamente em toda ela. Para quaisquer futuros leitores, aqui está o que eu provavelmente faria:

Gostaria apenas de usar um buffer de saída. Então, basicamente, você iniciar o ob_start buffer usando (), em seguida, incluir o seu "arquivo de modelo" com quaisquer funções, variáveis, etc. no interior do mesmo, obter o conteúdo do buffer e gravá-los para uma cadeia, e em seguida, feche o buffer. Então você já usou todas as variáveis ??que você precisa, você pode executar qualquer função, e você ainda tem a sintaxe HTML destacando disponíveis no seu IDE.

Aqui está o que eu quero dizer:

arquivo de modelo:

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

Assim, o roteiro inclui o template_file.php em seu buffer, correndo quaisquer funções / métodos e atribuir quaisquer variáveis ??ao longo do caminho. Então você simplesmente gravar o conteúdo do buffer em uma variável e fazer o que quiser com ele.

Dessa forma, se você não quer fazer eco-lo para a direita página naquele segundo, você não tem que. Você pode fazer um loop e continuar a acrescentar para a cadeia antes de emitir-lo.

Eu acho que é o melhor caminho a percorrer se você não quiser usar um motor de templates.

Para completar, você pode também usar o !${''} magia negra analisador corte :

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

Este trecho irá definir variáveis ??com o nome de suas funções definidas dentro userscope e ligá-los a uma string que contém o mesmo nome. Deixe-me demonstrar.

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;

Agora vai trabalhar.

Acho que usando heredoc é ótimo para gerar código HTML. Por exemplo, eu acho o seguinte quase completamente ilegível.

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

No entanto, a fim de alcançar a simplicidade que você são forçados a avaliar as funções antes de começar. Eu não acredito que é um terrível constrangimento tal, uma vez que ao fazê-lo, você acaba separando o seu cálculo de exposição, que é geralmente uma boa idéia.

Eu acho que o seguinte é bastante legível:

$page_content = getPageContent();

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

Infelizmente, apesar de ter sido uma boa sugestão que você fez na sua pergunta para ligar a função a uma variável, no final, ele adiciona um nível de complexidade ao código, que não vale a pena, e torna o código menos legível , que é a grande vantagem do heredoc.

encontrou solução agradável com a função de embrulho aqui: 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)}";

eu dar uma olhada Smarty como um modelo de motor - Eu não tentei qualquer outra queridos mim mesmo, mas ele tem me feito bem.

Se você quisesse ficar com sua abordagem atual sans modelos, o que é tão ruim sobre o buffer de saída? Vai dar-lhe muito mais flexibilidade do que ter que declarar variáveis ??que são os nomes sting das funções que deseja chamar.

Um pouco tarde, mas ainda. Isto é possível em heredoc!

Dê uma olhada em o manual do PHP, seção "Complex (curvas) sintaxe"

Aqui um exemplo agradável usando @CJDennis proposta:

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

Por exemplo, um bom uso para a sintaxe heredoc é gerar enormes formas com relação mestre-detalhe em um banco de dados. Pode-se usar o recurso heredoc dentro de um controle FOR, adicionando um sufixo após cada nome de campo. É uma tarefa lado do servidor típico.

você está esquecendo função lambda:

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

Você também pode usar a função create_function

Os indivíduos devem notar que ele também funciona com strings delimitadas por aspas.

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

dica interessante de qualquer maneira.

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

Você deve experimentá-lo. depois de terminar o ETO; ordeno que você deve dar um entrar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top