Dalam PHP, deklarasi string HEREDOC sangat berguna untuk mengeluarkan blok html. Anda bisa membuatnya mengurai dalam variabel hanya dengan memberi awalan $, tetapi untuk sintaks yang lebih rumit (seperti $ var [2] [3]), Anda harus meletakkan ekspresi Anda di dalam {} tanda kurung.
Dalam PHP 5, itu adalah mungkin untuk benar-benar membuat panggilan fungsi dalam {} kurung di dalam string heredoc, tetapi Anda harus melalui sedikit pekerjaan. Nama fungsi itu sendiri harus disimpan dalam variabel, dan Anda harus memanggilnya seperti fungsi yang dinamai secara dinamis. Sebagai contoh:
$fn = 'testfunction';
function testfunction() { return 'ok'; }
$string = <<< heredoc
plain text and now a function: {$fn()}
heredoc;
Seperti yang Anda lihat, ini sedikit lebih berantakan daripada hanya:
$string = <<< heredoc
plain text and now a function: {testfunction()}
heredoc;
Ada cara lain selain contoh kode pertama, seperti keluar dari HEREDOC untuk memanggil fungsi, atau membalik masalah dan melakukan sesuatu seperti:
?>
<!-- directly output html and only breaking into php for the function -->
plain text and now a function: <?PHP print testfunction(); ?>
Yang terakhir memiliki kelemahan bahwa output secara langsung dimasukkan ke dalam aliran output (kecuali saya menggunakan buffering output), yang mungkin bukan yang saya inginkan.
Jadi, inti dari pertanyaan saya adalah: adakah cara yang lebih elegan untuk melakukan pendekatan ini?
Edit berdasarkan tanggapan: Memang terlihat seperti beberapa jenis mesin templat akan membuat hidup saya lebih mudah, tetapi pada dasarnya saya harus membalikkan gaya PHP saya yang biasa. Bukan berarti itu buruk, tapi itu menjelaskan kelembaman saya .. Saya siap untuk mencari cara untuk membuat hidup lebih mudah, jadi saya mencari template sekarang.
Text {$string1} Text {$string2} Text
di heredoc.Jawaban:
Saya tidak akan menggunakan HEREDOC sama sekali untuk ini, secara pribadi. Itu tidak membuat sistem "pembuatan template" yang baik. Semua HTML Anda dikunci dalam string yang memiliki beberapa kelemahan
Dapatkan mesin templat dasar, atau cukup gunakan PHP dengan penyertaan - itulah alasan bahasa memiliki
<?php
dan?>
pembatas .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');
sumber
<?=$valueToEcho;?>
atau<%=$valueToEcho;%>
tergantung pada pengaturan INI Anda.<?=$title?>
ini jauh lebih bagus daripada <? Php echo $ title; ?>. Sisi negatifnya adalah, ya, untuk distribusi banyak tag pendek off. Tapi , coba tebak ?? Mulai PHP 5.4 , tag pendek diaktifkan di PHP terlepas dari pengaturan ini! Jadi jika Anda membuat kode dengan persyaratan 5.4+ (katakanlah Anda menggunakan ciri-ciri, misalnya), lanjutkan dan gunakan tag pendek yang mengagumkan itu !!Jika Anda benar-benar ingin melakukan ini tetapi sedikit lebih sederhana daripada menggunakan kelas, Anda dapat menggunakan:
function fn($data) { return $data; } $fn = 'fn'; $my_string = <<<EOT Number of seconds since the Unix Epoch: {$fn(time())} EOT;
sumber
$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;};
harus menjadi yang terpendekSaya akan melakukan hal berikut:
$string = <<< heredoc plain text and now a function: %s heredoc; $string = sprintf($string, testfunction());
Tidak yakin apakah Anda akan menganggap ini lebih elegan ...
sumber
Coba ini (baik sebagai variabel global, atau dibuat instance-nya saat Anda membutuhkannya):
<?php class Fn { public function __call($name, $args) { if (function_exists($name)) { return call_user_func_array($name, $args); } } } $fn = new Fn(); ?>
Sekarang pemanggilan fungsi apa pun melewati
$fn
instance. Jadi fungsinya sudah adatestfunction()
bisa dipanggil secara heredoc dengan{$fn->testfunction()}
Pada dasarnya kita membungkus semua fungsi menjadi instance kelas, dan menggunakan
__call magic
metode PHP untuk memetakan metode kelas ke fungsi sebenarnya yang perlu dipanggil.sumber
call_user_func_array
, terakhir kali di komentar di php.net: php.net/manual/en/function.call-user-func-array.php # 97473Untuk kelengkapannya, Anda juga bisa menggunakan hack
!${''}
black magicparser :echo <<<EOT One month ago was ${!${''} = date('Y-m-d H:i:s', strtotime('-1 month'))}. EOT;
sumber
false == ''
. Tentukan variabel dengan nama panjang 0 (''
). Setel ke nilai yang Anda inginkan (${''} = date('Y-m-d H:i:s', strtotime('-1 month'))
). Negasikan itu (!
) dan ubah menjadi variabel (${false}
).false
perlu diubah menjadi string, dan(string)false === ''
. Jika Anda mencoba mencetak nilai yang salah, itu akan menjadi kesalahan. String berikut bekerja pada kedua truthy dan nilai-nilai falsy, dengan mengorbankan menjadi lebih terbaca:"${(${''}=date('Y-m-d H:i:s', strtotime('-1 month')))!=${''}}"
.NAN
juga, gunakan"${(${''} = date('Y-m-d H:i:s', strtotime('-1 month')) )==NAN}"
.Saya agak terlambat, tapi saya kebetulan menemukannya. Untuk pembaca yang akan datang, inilah yang mungkin akan saya lakukan:
Saya hanya akan menggunakan buffer keluaran. Jadi pada dasarnya, Anda memulai buffering menggunakan ob_start (), lalu memasukkan "file template" Anda dengan fungsi, variabel, dll. Di dalamnya, dapatkan konten buffer dan menuliskannya ke string, lalu tutup buffer. Kemudian Anda telah menggunakan variabel apa pun yang Anda butuhkan, Anda dapat menjalankan fungsi apa pun, dan Anda masih memiliki penyorotan sintaks HTML di IDE Anda.
Inilah yang saya maksud:
File Template:
<?php echo "plain text and now a function: " . testfunction(); ?>
Naskah:
<?php ob_start(); include "template_file.php"; $output_string = ob_get_contents(); ob_end_clean(); echo $output_string; ?>
Jadi skrip menyertakan template_file.php ke dalam buffernya, menjalankan fungsi / metode apa pun dan menugaskan variabel apa pun di sepanjang jalan. Kemudian Anda cukup merekam konten buffer ke dalam variabel dan melakukan apa yang Anda inginkan dengannya.
Dengan begitu, jika Anda tidak ingin menampilkannya langsung ke halaman pada saat itu juga, Anda tidak perlu melakukannya. Anda dapat melakukan loop dan terus menambahkan string sebelum mengeluarkannya.
Saya pikir itulah cara terbaik untuk pergi jika Anda tidak ingin menggunakan mesin templating.
sumber
Cuplikan ini akan menentukan variabel dengan nama fungsi yang Anda tetapkan dalam userscope dan mengikatnya ke string yang berisi nama yang sama. Biar saya tunjukkan.
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;
Sekarang akan bekerja.
sumber
menemukan solusi yang bagus dengan fungsi pembungkus di sini: 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)}";
sumber
Saya pikir menggunakan heredoc bagus untuk menghasilkan kode HTML. Misalnya, saya menemukan yang berikut ini hampir tidak terbaca sama sekali.
<html> <head> <title><?php echo $page_title; ?></title> </head> <body> <?php echo getPageContent(); ?> </body>
Namun, untuk mencapai kesederhanaan, Anda dipaksa untuk mengevaluasi fungsi sebelum Anda mulai. Saya tidak percaya itu kendala yang mengerikan, karena dengan melakukan itu, Anda akhirnya memisahkan perhitungan Anda dari tampilan, yang biasanya merupakan ide yang bagus.
Menurut saya yang berikut ini cukup mudah dibaca:
$page_content = getPageContent(); print <<<END <html> <head> <title>$page_title</title> </head> <body> $page_content </body> END;
Sayangnya, meskipun itu adalah saran bagus yang Anda buat dalam pertanyaan Anda untuk mengikat fungsi ke variabel, pada akhirnya, itu menambah tingkat kerumitan pada kode, yang tidak layak, dan membuat kode kurang dapat dibaca, yaitu keuntungan utama dari heredoc.
sumber
Saya akan melihat Smarty sebagai mesin templat - Saya belum pernah mencoba yang lain, tetapi itu telah membantu saya dengan baik.
Jika Anda ingin tetap menggunakan template tanpa pendekatan Anda saat ini , apa buruknya buffering keluaran? Ini akan memberi Anda lebih banyak fleksibilitas daripada harus mendeklarasikan variabel yang merupakan nama string dari fungsi yang ingin Anda panggil.
sumber
Anda lupa tentang fungsi lambda:
$or=function($c,$t,$f){return$c?$t:$f;}; echo <<<TRUEFALSE The best color ever is {$or(rand(0,1),'green','black')} TRUEFALSE;
Anda juga bisa menggunakan fungsi create_function
sumber
Agak terlambat tapi tetap saja. Ini mungkin dalam heredoc!
Lihat di manual php, bagian "Sintaks kompleks (keriting)"
sumber
Berikut contoh yang bagus menggunakan proposal @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>";
Misalnya, penggunaan sintaks HEREDOC yang baik adalah menghasilkan formulir besar dengan hubungan detail master dalam Database. Seseorang dapat menggunakan fitur HEREDOC di dalam kontrol FOR, menambahkan sufiks setelah setiap nama bidang. Ini adalah tugas sisi server yang khas.
sumber
Cowok harus memperhatikan bahwa ini juga berfungsi dengan string yang dikutip ganda.
http://www.php.net/manual/en/language.types.string.php
Tip menarik sih.
sumber
<div><?=<<<heredoc Use heredoc and functions in ONE statement. Show lower case ABC=" heredoc . strtolower('ABC') . <<<heredoc ". And that is it! heredoc ?></div>
sumber
Ini sedikit lebih elegan hari ini di php 7.x
<?php $test = function(){ return 'it works!'; }; echo <<<HEREDOC this is a test: {$test()} HEREDOC;
sumber
<?php echo <<<ETO <h1>Hellow ETO</h1> ETO;
kamu harus mencobanya . setelah mengakhiri ETO; perintah Anda harus memasukkan.
sumber