Wywołanie funkcji PHP w ramach ciągi heredoc

głosy
78

W PHP deklaracje heredoc smyczkowe są naprawdę użyteczne dla wyprowadzania bloku html. Możesz mieć go analizować w zmiennych tylko poprzedzając je $, ale w przypadku bardziej skomplikowanej składni (jak $ var [2] [3]), trzeba umieścić swój wyraz wewnątrz {} szelki.

W PHP 5, to jest możliwe, aby rzeczywiście dokonać wywołania funkcji w ciągu {} szelki wewnątrz łańcucha heredoc, ale trzeba przejść przez trochę pracy. Sama nazwa funkcji musi być przechowywany w zmiennej, i trzeba to nazwać jak to dynamicznie nazwie funkcji. Na przykład:

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

Jak widać, jest to nieco bardziej brudny niż tylko:

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

Istnieją inne sposoby oprócz pierwszym przykładzie kodu, takich jak wyrwanie się z heredoc aby wywołać funkcję lub cofania problem i robi coś takiego:

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

Ten ostatni ma tę wadę, że wyjście jest bezpośrednio wprowadzone do strumienia wyjściowego (chyba Używam buforowanie wyjścia), który nie może być to, co chcę.

Zatem istotą moje pytanie brzmi: czy istnieje bardziej elegancki sposób podejść do tego?

Edycja na podstawie odpowiedzi: To na pewno wydaje się jak pewnego rodzaju silnika szablonów stałaby moje życie dużo łatwiejsze, ale wymagałoby to mnie po prostu odwrócić mój zwykły styl PHP. Nie dlatego, że to jest złe, ale to wyjaśnia mój bezwładność .. Jestem się na zastanawianie się sposobów, by ułatwić życie choć, więc szukam do szablonów teraz.

Utwórz 19/09/2008 o 19:54
źródło użytkownik
W innych językach...                            


16 odpowiedzi

głosy
52

Jeśli naprawdę chcesz to zrobić, ale nieco prostszy niż przy użyciu klasy można użyć:

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

$my_string = <<<EOT
Number of seconds since the Unix Epoch: {$fn(time())}
EOT;
Odpowiedział 23/05/2012 o 05:06
źródło użytkownik

głosy
51

Nie użyłbym heredoc w ogóle za to osobiście. To po prostu nie robi dla dobrego systemu „szablon budynku”. Cały Twój HTML jest zablokowana w ciąg, który ma kilka wad

  • Brak opcji dla WYSIWYG
  • Nie uzupełniania kodu HTML z IDE
  • Wyjście (HTML) zablokowane do plików logicznych
  • Skończyć się konieczności korzystania hacki jak co próbujesz zrobić teraz, aby osiągnąć bardziej złożony templating, takich jak zapętlenie

Uzyskać podstawowe silnika szablonów, lub po prostu korzystać z PHP zawiera - to dlaczego język ma <?phpi ?>separatory.

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');
Odpowiedział 19/09/2008 o 20:10
źródło użytkownik

głosy
37

Chciałbym wykonać następujące czynności:

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

Nie wiem, czy chcesz uznają to za bardziej eleganckie ...

Odpowiedział 19/09/2008 o 19:59
źródło użytkownik

głosy
17

Spróbuj tego (jako zmienną globalną lub instancja, gdy jest to potrzebne):

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

  $fn = new Fn();
?>

Teraz każdy wywołanie funkcji przechodzi $fninstancji. Więc istniejąca funkcja testfunction()może być wywołana w heredoc z{$fn->testfunction()}

Zasadniczo jesteśmy zawijania wszystkie funkcje do instancji klasy, a przy użyciu PHP __call magicmetody mapowania metody klasy do rzeczywistej funkcji konieczności nazwać.

Odpowiedział 22/12/2009 o 19:11
źródło użytkownik

głosy
9

Jestem trochę późno, ale przypadkowo natknąłem się nim. Dla przyszłych czytelników, oto co to pewnie zrobić:

Chciałbym po prostu użyć bufor wyjściowy. Więc w zasadzie, to rozpocząć buforowanie przy użyciu ob_start (), a następnie podać swój „plik szablonu” z żadnych funkcji, zmiennych, itd wewnątrz niej uzyskać zawartość bufora i zapisać je na sznurku, a następnie zamknąć bufor. Następnie używałem żadnych zmiennych trzeba, można uruchomić dowolną funkcję, a nadal masz składni HTML podkreślając dostępny w IDE.

Oto co mam na myśli:

Szablon pliku:

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

Scenariusz:

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

Więc skrypt zawiera template_file.php do bufora, bieganie żadnych funkcji / metod i przypisywanie żadnych zmiennych po drodze. Wtedy po prostu nagrać zawartość bufora do zmiennej i rób co chcesz z nim.

W ten sposób, jeśli nie chcą powtórzyć go na prawej stronie w tej sekundzie, nie musiał. Można pętlę i dodajemy do łańcucha przed wyprowadzanie go.

Myślę, że najlepszym sposobem, aby przejść jeśli nie chcesz używać silnika szablonów.

Odpowiedział 06/09/2009 o 21:49
źródło użytkownik

głosy
5

Myślę, że przy użyciu heredoc jest świetny do generowania kodu HTML. Na przykład uważam, że po prawie zupełnie nieczytelny.

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

Jednak w celu osiągnięcia prostoty jesteś zmuszony do oceny funkcji przed rozpoczęciem pracy. Nie wierzę, że to takie straszne ograniczenie, gdyż w ten sposób skończyć się oddzielając swoje obliczenia z wyświetlaczem, który jest zwykle dobrym pomysłem.

Myślę, że jest dość czytelny następujące:

$page_content = getPageContent();

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

Niestety, mimo że to była dobra sugestia dokonane w swoim pytaniu do wiązania funkcji do zmiennej, w końcu, dodaje się poziom złożoności do kodu, który nie jest wart, i sprawia, że ​​kod mniej czytelny, co jest główną zaletą heredoc.

Odpowiedział 17/06/2011 o 11:54
źródło użytkownik

głosy
5

Ten fragment będzie definiować zmienne z nazwą firmy określonych funkcji w ramach userscope i wiązać je na ciąg, który zawiera tę samą nazwę. Pozwól mi zademonstrować.

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;

Będzie teraz pracować.

Odpowiedział 08/12/2010 o 14:02
źródło użytkownik

głosy
4

Chciałbym spojrzeć na Smarty jako silnik szablonu - Nie próbowałem pozostałe nie ja, ale to zrobiła mi dobrze.

Jeśli chcesz trzymać się swojego obecnego podejścia sans szablonów, co jest tak źle o buforowanie wyjścia? Będzie to daje dużo większą elastyczność niż konieczności deklarowania zmiennych, które stanowią nazwy żądło funkcji chcesz zadzwonić.

Odpowiedział 20/09/2008 o 00:42
źródło użytkownik

głosy
3

Dla kompletności, można również użyć !${''}czarnej magii:

echo <<<EOT
One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}.
EOT;
Odpowiedział 24/03/2016 o 14:31
źródło użytkownik

głosy
3

znaleźć ładne rozwiązanie z funkcją owijania tutaj: 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)}";
Odpowiedział 20/11/2014 o 20:53
źródło użytkownik

głosy
2

Oto dobry przykład stosując @CJDennis propozycję:

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

Na przykład dobrego wykorzystania na składni heredoc jest generować ogromne formy z master-detail relacji w bazie danych. Można użyć funkcji heredoc wewnątrz FOR kontroli, dodając przyrostek po każdej nazwy pola. Jest to typowe zadanie po stronie serwera.

Odpowiedział 18/01/2013 o 05:24
źródło użytkownik

głosy
2

Trochę późno, ale jednak. Jest to możliwe w heredoc!

Mają wyglądać w podręczniku PHP, sekcja „Complex (kręcone) składnia”

Odpowiedział 08/04/2011 o 23:58
źródło użytkownik

głosy
1
<div><?=<<<heredoc
Use heredoc and functions in ONE statement.
Show lower case ABC="
heredoc
. strtolower('ABC') . <<<heredoc
".  And that is it!
heredoc
?></div>
Odpowiedział 17/09/2016 o 02:13
źródło użytkownik

głosy
1

jesteś zapominając o funkcji lambda:

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

Możesz również może korzystać z funkcji create_function

Odpowiedział 23/09/2013 o 10:02
źródło użytkownik

głosy
1

Faceci powinni pamiętać, że to działa również z podwójnych cudzysłowów.

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

Ciekawa końcówka tak.

Odpowiedział 10/05/2010 o 12:20
źródło użytkownik

głosy
0
<?php
echo <<<ETO
<h1>Hellow ETO</h1>
ETO;

powinieneś spróbować . po zakończeniu ETO; Polecenie należy otrzymując wejść.

Odpowiedział 03/09/2016 o 05:36
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more