W PHP deklaracje ciągów HEREDOC są bardzo przydatne do wyświetlania bloku html. Możesz go przeanalizować w zmiennych, po prostu poprzedzając je przedrostkiem $, ale dla bardziej skomplikowanej składni (np. $ Var [2] [3]), musisz umieścić swoje wyrażenie w nawiasach {}.
W PHP 5, to jest możliwe, aby właściwie wykonywać połączenia funkcjonować w {} szelki wewnątrz łańcucha heredoc, ale trzeba przejść przez trochę pracy. Sama nazwa funkcji musi być przechowywana w zmiennej i należy ją nazywać tak, jakby była funkcją o nazwie dynamicznej. Na przykład:
$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;
Jak widać, jest to trochę bardziej bałaganiarskie niż tylko:
$string = <<< heredoc
plain text and now a function: {testfunction()}
heredoc;
Oprócz pierwszego przykładu kodu istnieją inne sposoby, takie jak wyjście z HEREDOC w celu wywołania funkcji lub odwrócenie problemu i wykonanie czegoś takiego:
?>
<!-- directly output html and only breaking into php for the function -->
plain text and now a function: <?PHP print testfunction(); ?>
Ta ostatnia ma tę wadę, że dane wyjściowe są bezpośrednio umieszczane w strumieniu wyjściowym (chyba że używam buforowania wyjściowego), co może nie być tym, czego chcę.
A więc sedno mojego pytania brzmi: czy istnieje bardziej elegancki sposób podejścia do tego?
Edycja na podstawie odpowiedzi: Z pewnością wydaje się, że jakiś rodzaj silnika szablonów znacznie ułatwiłby mi życie, ale wymagałby ode mnie zasadniczo odwrócenia mojego zwykłego stylu PHP. Nie żeby to było złe, ale wyjaśnia moją bezwładność. Jestem gotów na wymyślanie sposobów na ułatwienie życia, więc teraz zajmuję się szablonami.
Text {$string1} Text {$string2} Text
w heredoc.Odpowiedzi:
Osobiście nie użyłbym do tego w ogóle HEREDOC-a. To po prostu nie jest dobrym systemem do „budowania szablonów”. Cały twój HTML jest zamknięty w ciągu, który ma kilka wad
Zdobądź podstawowy silnik szablonów lub po prostu użyj PHP z dołączeniami - dlatego język ma ograniczniki
<?php
i?>
.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');
źródło
<?=$valueToEcho;?>
lub<%=$valueToEcho;%>
zależny od ustawień INI.<?=$title?>
jest o wiele ładniejszy niż <? Php echo $ title; ?>. Wadą jest to, że w przypadku dystrybucji wiele ini ma krótkie znaczniki. Ale zgadnij co? Od wersji PHP 5.4 krótkie tagi są włączone w PHP niezależnie od ustawień ini! Więc jeśli kodujesz z wymaganiem 5.4+ (powiedzmy, że używasz na przykład cech), śmiało i używaj tych niesamowitych krótkich tagów !!Jeśli naprawdę chcesz to zrobić, ale jest to nieco prostsze niż użycie klasy, możesz użyć:
function fn($data) { return $data; } $fn = 'fn'; $my_string = <<<EOT Number of seconds since the Unix Epoch: {$fn(time())} EOT;
źródło
$my_string = "Half the number of seconds since the Unix Epoch: {$fn(time() / 2 . ' Yes! Really!')}";
$fn = function fn($data) { return $data; };
$fn = function ($data) { return $data; };
$fn=function($data){return $data;};
rhis powinno być najkrótszeZrobiłbym co następuje:
$string = <<< heredoc plain text and now a function: %s heredoc; $string = sprintf($string, testfunction());
Nie jestem pewien, czy uważasz to za bardziej eleganckie ...
źródło
Spróbuj tego (jako zmienna globalna lub utworzona, gdy jej potrzebujesz):
<?php class Fn { public function __call($name, $args) { if (function_exists($name)) { return call_user_func_array($name, $args); } } } $fn = new Fn(); ?>
Teraz każde wywołanie funkcji przechodzi przez
$fn
instancję. Tak więc istniejącą funkcjętestfunction()
można wywołać w heredoc z{$fn->testfunction()}
Zasadniczo pakujemy wszystkie funkcje w instancję klasy i używamy
__call magic
metody PHP do mapowania metody klasy na rzeczywistą funkcję, która ma zostać wywołana.źródło
call_user_func_array
, ostatnio w komentarzach na php.netAby uzyskać kompletność, możesz również użyć
!${''}
czarnej magiiparsera :echo <<<EOT One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}. EOT;
źródło
false == ''
. Zdefiniuj zmienną o nazwie o długości 0 (''
). Ustaw żądaną wartość (${''} = date('Y-m-d H:i:s', strtotime('-1 month'))
). Neguj to (!
) i zamień na zmienną (${false}
).false
musi zostać przekonwertowany na ciąg, a(string)false === ''
. Jeśli spróbujesz wydrukować fałszywą wartość, zamiast tego wystąpi błąd. Następujący ciąg działa zarówno truthy i wartości falsy, kosztem bycia jeszcze bardziej nieczytelne:"${(${''}=date('Y-m-d H:i:s', strtotime('-1 month')))!=${''}}"
.NAN
, użyj"${(${''} = date('Y-m-d H:i:s', strtotime('-1 month')) )==NAN}"
.Trochę się spóźniłem, ale przypadkowo trafiłem na to. Oto, co prawdopodobnie bym zrobił dla przyszłych czytelników:
Po prostu użyłbym bufora wyjściowego. Więc w zasadzie zaczynasz buforowanie za pomocą ob_start (), następnie umieszczasz w nim swój "plik szablonu" z dowolnymi funkcjami, zmiennymi itp., Uzyskujesz zawartość bufora i zapisujesz ją w łańcuchu, a następnie zamykasz bufor. Następnie użyłeś dowolnych potrzebnych zmiennych, możesz uruchomić dowolną funkcję i nadal masz podświetlanie składni HTML dostępne w swoim IDE.
Oto o co mi chodzi:
Plik szablonu:
<?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; ?>
Tak więc skrypt włącza plik template_file.php do swojego bufora, uruchamiając wszystkie funkcje / metody i przypisując po drodze wszelkie zmienne. Następnie po prostu rejestrujesz zawartość bufora w zmiennej i robisz z nią, co chcesz.
W ten sposób, jeśli nie chcesz odbijać tego na stronie w tej chwili, nie musisz tego robić. Możesz zapętlić i kontynuować dodawanie do ciągu przed jego wyprowadzeniem.
Myślę, że to najlepszy sposób, jeśli nie chcesz używać silnika szablonów.
źródło
Ten fragment kodu zdefiniuje zmienne z nazwami zdefiniowanych funkcji w ramach usercope i powiąże je z łańcuchem o takiej samej nazwie. Pokażę.
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;
Teraz zadziała.
źródło
znalazłem fajne rozwiązanie z funkcją zawijania 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)}";
źródło
Myślę, że użycie heredoc jest świetne do generowania kodu HTML. Na przykład uważam, że następujące informacje są prawie całkowicie nieczytelne.
<html> <head> <title><?php echo $page_title; ?></title> </head> <body> <?php echo getPageContent(); ?> </body>
Jednak, aby osiągnąć prostotę, jesteś zmuszony ocenić funkcje przed rozpoczęciem. Nie wierzę, że jest to tak straszne ograniczenie, ponieważ robiąc to, w końcu oddzielasz swoje obliczenia od wyświetlania, co zwykle jest dobrym pomysłem.
Myślę, że to jest całkiem czytelne:
$page_content = getPageContent(); print <<<END <html> <head> <title>$page_title</title> </head> <body> $page_content </body> END;
Niestety, mimo że była to dobra sugestia, którą poczyniłeś w swoim pytaniu, aby powiązać funkcję ze zmienną, w końcu dodaje to poziom złożoności do kodu, co nie jest warte, i sprawia, że kod jest mniej czytelny, co jest główna zaleta heredoc.
źródło
Spojrzałbym na Smarty'ego jako silnik szablonu - Nie próbowałem pozostałe nie ja, ale to zrobiła mi dobrze.
Jeśli chcesz trzymać się obecnego podejścia bez szablonów, co jest takiego złego w buforowaniu danych wyjściowych? Zapewnia znacznie większą elastyczność niż konieczność deklarowania zmiennych, które są nazwami ciągów funkcji, które chcesz wywołać.
źródło
zapominasz 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ż użyć funkcji create_function
źródło
Trochę późno, ale nadal. W heredoc jest to możliwe!
Zajrzyj do podręcznika PHP, w sekcji „Złożona (kędzierzawa) składnia”
źródło
Oto ładny przykład z wykorzystaniem propozycji @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>";
Na przykład dobrym zastosowaniem składni HEREDOC jest generowanie w bazie danych ogromnych formularzy z relacją wzorzec-szczegół. Można użyć funkcji HEREDOC wewnątrz kontrolki FOR, dodając sufiks po każdej nazwie pola. To typowe zadanie po stronie serwera.
źródło
Chłopaki powinni pamiętać, że działa to również w przypadku ciągów w cudzysłowie.
http://www.php.net/manual/en/language.types.string.php
W każdym razie ciekawa wskazówka.
źródło
<div><?=<<<heredoc Use heredoc and functions in ONE statement. Show lower case ABC=" heredoc . strtolower('ABC') . <<<heredoc ". And that is it! heredoc ?></div>
źródło
To jest trochę bardziej eleganckie dzisiaj na php 7.x.
<?php $test = function(){ return 'it works!'; }; echo <<<HEREDOC this is a test: {$test()} HEREDOC;
źródło
<?php echo <<<ETO <h1>Hellow ETO</h1> ETO;
powinieneś spróbować . po zakończeniu ETO; polecenie należy wprowadzić.
źródło