จะถูกob_start()
ใช้สำหรับoutput buffering
เพื่อให้ส่วนหัวเป็น buffered และไม่ได้ส่งไปยังเบราว์เซอร์? ฉันกำลังทำความเข้าใจที่นี่? ถ้าไม่เช่นนั้นทำไมเราควรใช้ob_start()
?
จะถูกob_start()
ใช้สำหรับoutput buffering
เพื่อให้ส่วนหัวเป็น buffered และไม่ได้ส่งไปยังเบราว์เซอร์? ฉันกำลังทำความเข้าใจที่นี่? ถ้าไม่เช่นนั้นทำไมเราควรใช้ob_start()
?
คำตอบ:
คิดถึง ob_start()
พูดว่า "เริ่มจดจำทุกสิ่งที่ปกติแล้วจะได้ผลลัพธ์ แต่ยังไม่ได้ทำอะไรกับมันเลย"
ตัวอย่างเช่น:
ob_start();
echo("Hello there!"); //would normally get printed to the screen/output to browser
$output = ob_get_contents();
ob_end_clean();
มีฟังก์ชั่นอื่นอีกสองอย่างที่คุณมักจะจับคู่กับ: ob_get_contents()
ซึ่งโดยทั่วไปจะให้สิ่งที่คุณ "บันทึก" ไว้ในบัฟเฟอร์ตั้งแต่เปิดใช้ob_start()
แล้วob_end_clean()
หรือหรือob_flush()
ซึ่งหยุดบันทึกสิ่งและยกเลิกสิ่งที่ถูกบันทึกหรือหยุดการบันทึก และส่งออกทั้งหมดในครั้งเดียวตามลำดับ
ob_start();
งานถูกต้องหรือไม่ จะเกิดอะไรขึ้นหากไม่ได้เปิดใช้งาน
ob_end_clean
มันใช้งานได้เหมือนมีเสน่ห์! ขอบคุณ @Riley Dutton
ฉันใช้สิ่งนี้เพื่อให้ฉันสามารถแยก PHP ด้วย HTML จำนวนมาก แต่ไม่สามารถแสดงผลได้ มันช่วยฉันจากการจัดเก็บเป็นสตริงที่ปิดการใช้งานการเข้ารหัสสี IDE
<?php
ob_start();
?>
<div>
<span>text</span>
<a href="#">link</a>
</div>
<?php
$content = ob_get_clean();
?>
แทน:
<?php
$content = '<div>
<span>text</span>
<a href="#">link</a>
</div>';
?>
ob_get_clean()
ไม่ใช่ ob_end_clean()
คำตอบที่ยอมรับได้ที่นี่อธิบายถึงสิ่งที่ob_start()
ไม่ - ทำไมมันถูกใช้ (ซึ่งเป็นคำถามที่ถาม)
ตามที่ระบุไว้ที่อื่นob_start()
สร้างบัฟเฟอร์ที่เขียนไป
แต่ไม่มีใครบอกว่าเป็นไปได้ที่จะสแต็คบัฟเฟอร์หลาย ๆ อันใน PHP ดูที่ob_get_level ()
ว่าทำไม ....
การส่ง HTML ไปยังเบราว์เซอร์ในกลุ่มที่มีขนาดใหญ่ขึ้นจะทำให้ได้รับประโยชน์ด้านประสิทธิภาพจากการลดค่าใช้จ่ายของเครือข่าย
การส่งข้อมูลออกจาก PHP ในกลุ่มที่ใหญ่ขึ้นจะช่วยเพิ่มประสิทธิภาพและความสามารถโดยลดจำนวนการสลับบริบทที่จำเป็น
การส่งข้อมูลจำนวนมากไปยัง mod_gzip / mod_deflate จะให้ประโยชน์ด้านประสิทธิภาพซึ่งการบีบอัดอาจมีประสิทธิภาพมากกว่า
การบัฟเฟอร์เอาต์พุตหมายความว่าคุณยังคงสามารถจัดการส่วนหัว HTTP ในภายหลังในรหัส
การล้างบัฟเฟอร์อย่างชัดเจนหลังจากเอาท์พุท [head] .... [/ head] สามารถอนุญาตให้เบราว์เซอร์เริ่ม marshaling ทรัพยากรอื่น ๆ สำหรับหน้าก่อนที่สตรีม HTML จะเสร็จสมบูรณ์
การจับเอาท์พุทในบัฟเฟอร์หมายความว่ามันสามารถเปลี่ยนเส้นทางไปยังฟังก์ชั่นอื่น ๆ เช่นอีเมลหรือคัดลอกไปยังไฟล์เป็นการแสดงเนื้อหาแคช
คุณมีมันย้อนหลัง ob_start ไม่ได้บัฟเฟอร์ส่วนหัวมันบัฟเฟอร์เนื้อหา การใช้ob_start
ช่วยให้คุณเก็บเนื้อหาไว้ในบัฟเฟอร์ฝั่งเซิร์ฟเวอร์จนกว่าคุณจะพร้อมที่จะแสดง
โดยทั่วไปจะใช้เพื่อให้หน้าสามารถส่งส่วนหัว 'หลังจาก' พวกเขา 'ส่ง' เนื้อหาบางส่วนไปแล้ว (เช่นการเปลี่ยนเส้นทางครึ่งทางผ่านการแสดงผลหน้า)
ฉันชอบ:
ob_start();
echo("Hello there!");
$output = ob_get_clean(); //Get current buffer contents and delete current output buffer
นี่คือชี้แจงเพิ่มเติมคำตอบ JD Isaaks ...
ปัญหาที่คุณพบบ่อยคือคุณกำลังใช้ php เพื่อส่งออก html จากแหล่ง php ที่แตกต่างกันและแหล่งเหล่านั้นมักจะด้วยเหตุผลใดก็ตามที่แสดงผลด้วยวิธีต่างๆ
บางครั้งคุณมีเนื้อหา html ตามตัวอักษรที่คุณต้องการส่งออกไปยังเบราว์เซอร์โดยตรง บางครั้งเอาต์พุตกำลังถูกสร้างแบบไดนามิก (ฝั่งเซิร์ฟเวอร์)
เนื้อหาแบบไดนามิกจะเป็นสตริงเสมอ (?) ตอนนี้คุณต้องรวม HTML แบบไดนามิกที่ทำให้เป็นสตริงกับ html ที่ตรงตามตัวอักษร ... เข้ากับโครงสร้างโหนด html ที่มีความหมายเดียว
สิ่งนี้มักจะบังคับให้นักพัฒนาห่อเนื้อหาที่ตรงไปยังแสดงในสตริง (ตามที่ JD Isaak กำลังพูดถึง) เพื่อให้สามารถส่ง / แทรกอย่างถูกต้องพร้อมกับ html แบบไดนามิก ... แม้ว่าคุณจะไม่ได้จริงๆ ต้องการห่อ
แต่ด้วยการใช้ ob _ ## วิธีการคุณสามารถหลีกเลี่ยงปัญหาการพันสายอักขระ เนื้อหาที่แท้จริงคือแทนที่จะส่งออกไปยังบัฟเฟอร์ จากนั้นในขั้นตอนเดียวเนื้อหาทั้งหมดของบัฟเฟอร์ (html ตัวอักษรทั้งหมดของคุณ) จะถูกรวมเข้ากับสตริง dynamic-html ของคุณ
(ตัวอย่างของฉันแสดง html ตามตัวอักษรที่ถูกส่งออกไปยังบัฟเฟอร์ซึ่งจะถูกเพิ่มไปยัง html-string ... ดูที่ตัวอย่าง JD Isaaks เพื่อดูการตัดคำ -html
<?php // parent.php
//---------------------------------
$lvs_html = "" ;
$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__without_ob( ) ;
$lvs_html .= "<div>more html</div>" ;
$lvs_html .= "----<br/>" ;
$lvs_html .= "<div>html</div>" ;
$lvs_html .= gf_component_assembler__with_ob( ) ;
$lvs_html .= "<div>more html</div>" ;
echo $lvs_html ;
// 02 - component contents
// html
// 01 - component header
// 03 - component footer
// more html
// ----
// html
// 01 - component header
// 02 - component contents
// 03 - component footer
// more html
//---------------------------------
function gf_component_assembler__without_ob( )
{
$lvs_html = "<div>01 - component header</div>" ; // <table ><tr>" ;
include( "component_contents.php" ) ;
$lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;
return $lvs_html ;
} ;
//---------------------------------
function gf_component_assembler__with_ob( )
{
$lvs_html = "<div>01 - component header</div>" ; // <table ><tr>" ;
ob_start();
include( "component_contents.php" ) ;
$lvs_html .= ob_get_clean();
$lvs_html .= "<div>03 - component footer</div>" ; // </tr></table>" ;
return $lvs_html ;
} ;
//---------------------------------
?>
<!-- component_contents.php -->
<div>
02 - component contents
</div>
ฟังก์ชั่นนี้ไม่ได้มีไว้สำหรับส่วนหัวเท่านั้น คุณสามารถทำสิ่งที่น่าสนใจมากมายกับสิ่งนี้ ตัวอย่าง: คุณสามารถแบ่งหน้าของคุณออกเป็นส่วน ๆ และใช้หน้านี้:
$someTemplate->selectSection('header');
echo 'This is the header.';
$someTemplate->selectSection('content');
echo 'This is some content.';
คุณสามารถจับภาพเอาท์พุทที่สร้างขึ้นที่นี่และเพิ่มลงในสองสถานที่ที่แตกต่างกันโดยสิ้นเชิงในเค้าโครงของคุณ
สิ่งต่อไปนี้ไม่ได้กล่าวถึงในคำตอบที่มีอยู่: การกำหนดค่าขนาดบัฟเฟอร์ HTTP ส่วนหัวและการซ้อน
การกำหนดค่าขนาดบัฟเฟอร์สำหรับ ob_start:
ob_start(null, 4096); // Once the buffer size exceeds 4096 bytes, PHP automatically executes flush, ie. the buffer is emptied and sent out.
โค้ดด้านบนปรับปรุงประสิทธิภาพของเซิร์ฟเวอร์เนื่องจาก PHP จะส่งชิ้นข้อมูลที่ใหญ่ขึ้นเช่น 4KB (ไม่มีการเรียกใช้ ob_start, php จะส่งแต่ละเสียงสะท้อนไปยังเบราว์เซอร์)
หากคุณเริ่มการบัฟเฟอร์โดยไม่มีขนาดชิ้น (เช่น. ob_start ()) จากนั้นหน้าจะถูกส่งหนึ่งครั้งในตอนท้ายของสคริปต์
การบัฟเฟอร์เอาต์พุตไม่มีผลกับส่วนหัว HTTP ซึ่งจะถูกประมวลผลด้วยวิธีที่ต่างกัน อย่างไรก็ตามเนื่องจากการบัฟเฟอร์คุณสามารถส่งส่วนหัวแม้หลังจากที่ส่งออกเพราะมันยังอยู่ในบัฟเฟอร์
ob_start(); // turns on output buffering
$foo->bar(); // all output goes only to buffer
ob_clean(); // delete the contents of the buffer, but remains buffering active
$foo->render(); // output goes to buffer
ob_flush(); // send buffer output
$none = ob_get_contents(); // buffer content is now an empty string
ob_end_clean(); // turn off output buffering
อธิบายอย่างดีที่นี่: https://phpfashion.com/everything-about-output-buffering-in-php
ไม่คุณคิดผิด แต่ทิศทางนั้นเหมาะสม;)
บัฟเฟอร์เอาท์พุทบัฟเฟอร์เอาต์พุตของสคริปต์ นั่นคือสิ่งที่เกิดขึ้นหลังจากนั้นecho
หรือ print
สิ่งที่มีส่วนหัวคือพวกเขาสามารถส่งได้ถ้าพวกเขายังไม่ได้ส่ง แต่ HTTP กล่าวว่าส่วนหัวนั้นเป็นสัญญาณแรกของการส่งสัญญาณ ดังนั้นหากคุณส่งออกบางอย่างเป็นครั้งแรก (ตามคำขอ) ส่วนหัวจะถูกส่งและคุณไม่สามารถตั้งค่าส่วนหัวอื่น ๆ
ob_get_contents()
ด้วยob_get_clean()
และลบob_end_clean()
เนื่องจากจะob_get_clean()
ทำหน้าที่ทั้งสองอย่างเป็นหลัก การอ้างอิง: php.net/manual/en/function.ob-get-clean.php (PHP 4> = 4.3.0, PHP 5)