ทำไมคนเราจะละเว้นแท็กปิด?


373

ฉันอ่านต่อไปมันเป็นวิธีปฏิบัติที่ไม่ดีในการใช้แท็กปิด PHP ?>ที่ท้ายไฟล์ ปัญหาส่วนหัวดูเหมือนไม่เกี่ยวข้องในบริบทต่อไปนี้ (และนี่เป็นอาร์กิวเมนต์ที่ดีเพียงอย่างเดียวจนถึงตอนนี้):

PHP เวอร์ชันโมเดิร์นตั้งค่าสถานะ output_buffering ใน php.ini หากเปิดใช้งานการบัฟเฟอร์เอาต์พุตคุณสามารถตั้งค่าส่วนหัว HTTP และคุกกี้หลังจากเอาท์พุท HTML ได้เนื่องจากโค้ดส่งคืนจะไม่ถูกส่งไปยังเบราว์เซอร์ทันที

หนังสือฝึกหัดและ wiki ที่ดีทุกเล่มเริ่มต้นด้วย 'กฎ' นี้ แต่ไม่มีใครเสนอเหตุผลที่ดี มีอีกเหตุผลที่ดีที่จะข้ามแท็ก PHP สิ้นสุดหรือไม่


3
ซ้ำกันเป็นไปได้ของ [ทำไมในบางสคริปต์พวกเขาละเว้นแท็กปิด php?>] ( stackoverflow.com/questions/3219383/… )
Gordon

@ คริสตชน - คุณหมายถึงว่าการใช้ output_buffering เป็นสิ่งที่ขี้เกียจหรือไม่สนใจที่?>จะขี้เกียจ?
El Yobo

4
@ กอร์ดอน - ฉันไม่คิดว่ามันเป็นคู่หู OP รู้เหตุผลที่ชัดเจนเพียงแค่ต้องการทราบว่ามันได้รับการแก้ไขอย่างสมบูรณ์ด้วยบัฟเฟอร์บัฟเฟอร์
El Yobo

5
คำถามที่ดีกว่าคือ: ทำไมต้องมีแท็กปิด? รหัสเป็นสิ่งชั่วร้าย รหัสที่ดีที่สุดคือไม่มีรหัสเลย หากสามารถขจัดปัญหาได้แทนที่จะแก้ไขด้วยโค้ดนี่จะดีกว่าการใช้โค้ด ในกรณีนี้ไม่มีปัญหาที่ต้องแก้ไข รหัสทำงานได้ดีโดยไม่มีแท็กปิด
still_dreaming_1

19
โอ้พระเจ้านี้ไม่ได้เป็นสถานที่สำหรับแท็บเทียบกับพื้นที่สงครามศักดิ์สิทธิ์ฮ่า ๆ :)
เควินล้อ

คำตอบ:


321

การส่งส่วนหัวก่อนหน้าของหลักสูตรปกติอาจส่งผลกระทบที่ไกลออกไป ด้านล่างเป็นเพียงไม่กี่คนที่เกิดขึ้นในใจของฉันในขณะนี้:

  1. ในขณะที่รีลีส PHP ปัจจุบันอาจมีบัฟเฟอร์ส่งออกเซิร์ฟเวอร์การผลิตจริงที่คุณจะปรับใช้โค้ดของคุณจะมีความสำคัญมากกว่าการพัฒนาหรือทดสอบเครื่องใด ๆ และพวกเขามักจะไม่ติดตามแนวโน้ม PHP ล่าสุดทันที

  2. คุณอาจปวดหัวกับการสูญเสียฟังก์ชันที่อธิบายไม่ได้ สมมติว่าคุณกำลังติดตั้งเกตเวย์การชำระเงินบางประเภทและเปลี่ยนเส้นทางผู้ใช้ไปยัง URL ที่ระบุหลังจากได้รับการยืนยันจากผู้ประมวลผลการชำระเงินที่ประสบความสำเร็จ หากมีข้อผิดพลาด PHP บางประเภทแม้กระทั่งคำเตือนหรือมีการสิ้นสุดของบรรทัดส่วนเกินการชำระเงินอาจยังไม่ได้ดำเนินการและผู้ใช้อาจยังไม่ได้เรียกเก็บเงิน นี่เป็นอีกสาเหตุหนึ่งที่ทำให้การเปลี่ยนเส้นทางโดยไม่จำเป็นเป็นสิ่งชั่วร้ายและหากต้องใช้การเปลี่ยนเส้นทางจะต้องใช้ด้วยความระมัดระวัง

  3. คุณอาจได้รับข้อผิดพลาดประเภท "การโหลดหน้าถูกยกเลิก" ใน Internet Explorer แม้ในรุ่นล่าสุด นี่เป็นเพราะAJAX response / json include มีบางอย่างที่ไม่ควรมีเพราะส่วนเกินของไฟล์ในไฟล์ PHP บางไฟล์สิ้นสุดลงเช่นเดียวกับที่ฉันพบเมื่อไม่กี่วันที่ผ่านมา

  4. หากคุณมีการดาวน์โหลดไฟล์ในแอปของคุณพวกเขาสามารถทำลายได้ด้วยเหตุผลนี้ และคุณอาจไม่สังเกตเห็นแม้หลังจากหลายปีเพราะนิสัยการทำลายที่เฉพาะเจาะจงของการดาวน์โหลดขึ้นอยู่กับเซิร์ฟเวอร์เบราว์เซอร์ชนิดและเนื้อหาของไฟล์ (และอาจเป็นปัจจัยอื่น ๆ ที่ฉันไม่ต้องการให้คุณเบื่อ) .

  5. ในที่สุดเฟรมเวิร์ค PHP จำนวนมากรวมถึงSymfony , Zendและ Laravel (ไม่มีการกล่าวถึงเรื่องนี้ในแนวทางการเขียนโค้ดแต่มันตามหลังชุดสูท) และมาตรฐานPSR-2 (รายการ 2.2) จำเป็นต้องละเว้นแท็กปิด คู่มือ PHP เอง ( 1 , 2 ), Wordpress , Drupalและซอฟต์แวร์ PHP อื่น ๆ อีกมากมายฉันเดาว่าแนะนำให้ทำเช่นนั้น หากคุณสร้างนิสัยในการติดตามมาตรฐาน (และการติดตั้งPHP-CS-Fixerสำหรับรหัสของคุณ) คุณสามารถลืมปัญหาได้ มิฉะนั้นคุณจะต้องคำนึงถึงปัญหานี้เสมอ

โบนัส: gotchas สองสามอัน (อันที่จริงแล้วปัจจุบันหนึ่ง) ที่เกี่ยวข้องกับ 2 ตัวอักษรเหล่านี้

  1. ?>แม้บางห้องสมุดที่รู้จักกันดีอาจจะมีตอนจบบรรทัดส่วนเกินหลัง ตัวอย่างคือ Smarty แม้แต่เวอร์ชันล่าสุดของทั้ง 2 * และ 3 * branch มีสิ่งนี้ ดังนั้นเช่นเคยดูรหัสของบุคคลที่สาม โบนัสเป็นโบนัส: Regex สำหรับการลบตอนจบ PHP ที่ไม่จำเป็น: แทนที่(\s*\?>\s*)$ด้วยข้อความว่างเปล่าในไฟล์ทั้งหมดที่มีโค้ด PHP

Regex ที่แตกต่างกันเล็กน้อยฉันใช้เพื่อค้นหาแท็กด้วย Netbeans IDE สำหรับกล่องโต้ตอบค้นหา & แทนที่: \?>(?s:.){0,10}\Z คำอธิบายสั้น ๆ : changeset.hr/blog/miscellaneous/catch-near-eof-with-regex
frnhr

@Cek ก็จับข้อความใด ๆ -including Code- ที่เป็น 10 ตัวอักษรหรือน้อยกว่าหลัง?>: เช่นมันตรงและอื่นจะ delete- ใน?> Hello <?php echo "test"; ?> Helloเราต้องการลบเฉพาะแท็กปิดเท่านั้น
Halil Özgür

6
เลวร้ายยิ่งกว่า apache 2.4.6 กับ PHP 5.4 จริง ๆ แล้วข้อบกพร่อง seg บนเครื่องผลิตของเราเมื่อมีพื้นที่ว่างด้านหลังแท็กปิด ฉันเพิ่งเสียเวลาหลายชั่วโมงจนกระทั่งในที่สุดฉันก็ จำกัด ข้อบกพร่องด้วย strace นี่คือข้อผิดพลาดที่ Apache [core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)พ่น:
Artem Russakovskii

3
@INTPnerd โอ้คำถามและคำตอบส่วนใหญ่อ้างถึงหัวข้อส่วนหัวดังนั้นฉันคิดว่าใครก็ตามที่อ่านหัวข้อนี้จะมีความคิดเกี่ยวกับเรื่องนี้ ปัญหาพื้นฐานและสาเหตุที่แท้จริงของปัญหาในหลาย ๆ คำตอบที่นี่คือช่องว่างที่ไม่จำเป็นหลังจาก?>นั้นซึ่ง (เช่นเดียวกับผลลัพธ์ใด ๆ ) ทำให้ส่วนหัวถูกส่งทันทีที่ส่งออก ไม่มี "ส่วนหัว HTML" (นอกเหนือจาก<header>แท็กHTML5 ที่ไม่เกี่ยวข้อง)
Halil Özgür

2
สิ่งนี้จะได้ผลโดยไม่คำนึงถึงตัวดัดแปลงทั่วโลก: \ s * \?> \ s * \ Z สังเกต '\ Z' ที่ส่วนท้าย จะช่วยให้แน่ใจว่าคุณกำลังจับภาพแท็กปิด php หากว่าไม่ใช่พื้นที่ว่างสุดท้ายที่ส่วนท้ายสุดของไฟล์
Erutan409

122

เหตุผลที่คุณควรออกจากแท็กปิด php ( ?>) คือเพื่อให้โปรแกรมเมอร์ไม่ได้ส่งตัวอักษรขึ้นบรรทัดใหม่พิเศษโดยไม่ได้ตั้งใจ

เหตุผลที่คุณไม่ควรละทิ้งแท็กปิด php เป็นเพราะมันทำให้เกิดความไม่สมดุลในแท็ก php และโปรแกรมเมอร์ที่มีใจครึ่งหนึ่งจำได้ว่าอย่าเพิ่มพื้นที่สีขาวเพิ่มเติม

ดังนั้นสำหรับคำถามของคุณ:

มีอีกเหตุผลที่ดีในการข้ามแท็ก php สิ้นสุดหรือไม่

ไม่มีมีไม่ได้เป็นอีกเหตุผลที่ดีที่จะข้ามแท็กสิ้นสุด PHP

ฉันจะจบด้วยข้อโต้แย้งบางอย่างที่ไม่รบกวนแท็กปิด:

  1. ผู้คนสามารถทำผิดพลาดได้เสมอไม่ว่าเขาจะฉลาดแค่ไหน การปฏิบัติตามแนวทางที่ช่วยลดจำนวนข้อผิดพลาดที่เป็นไปได้คือ (IMHO) เป็นความคิดที่ดี

  2. PHP ไม่ใช่ XML PHP ไม่จำเป็นต้องปฏิบัติตามมาตรฐานที่เข้มงวดของ XML เพื่อให้สามารถเขียนและใช้งานได้ดี หากแท็กปิดที่หายไปทำให้คุณรำคาญคุณจะได้รับอนุญาตให้ใช้แท็กปิดนั่นไม่ใช่กฎการตั้งค่าแบบทางเดียวหรืออื่น ๆ


2
> โปรแกรมเมอร์ใด ๆ ที่มีจิตใจครึ่งหนึ่งสามารถจำได้ว่าจะไม่เพิ่มพื้นที่สีขาวพิเศษ ยิ่งไปกว่านั้นนักพัฒนาที่มีความคิด 1/2 ใจสามารถเพิ่ม hook ล่วงหน้าไว้ใน SVC เพื่อให้ช่องว่างต่อท้ายถูกลบโดยอัตโนมัติ: ไม่ยุ่งยากไม่ยุ่งยาก
BryanH

6
@BryanH จนกว่าคุณจะมีไฟล์ที่ต้องการช่องว่างต่อท้ายอย่างแน่นอน แต่นั่นหายากมาก
zzzzBov

1
แน่นอนว่าคุณพูดถูก ตรวจสอบคำตอบของมาริโอสำหรับทางเลือกที่ยอดเยี่ยม
BryanH

> "เหตุผลที่คุณไม่ควรละทิ้งแท็กปิด php นั้นเป็นเพราะมันทำให้เกิดความไม่สมดุลในแท็ก php และโปรแกรมเมอร์ที่มีจิตใจครึ่งหนึ่งจำได้ว่าอย่าเพิ่มพื้นที่สีขาวเพิ่มเติม" บน Windows อาจจะ บนระบบเหมือน UNIX ไฟล์ทั้งหมดลงท้ายด้วย \ n และโปรแกรมเพิ่มให้คุณ แก้ไข:อ้า! ตามที่ระบุไว้ด้านล่างโดย @mario PHP กินจริง ๆ แล้ว
Andrea

2
สิ่งสำคัญยิ่งกว่านั้นคือแม้โปรแกรมเมอร์ที่มีจิตใจสองในสามคนก็ยังเป็นมนุษย์และลืมสิ่งต่าง ๆ
เซบาสเตียนมัค

57

มันเป็นมือใหม่เข้ารหัสคำแนะนำสไตล์ , เจตนาดีและได้รับคำแนะนำจากคู่มือการใช้งาน

  • ละทิ้ง?>แต่แก้เพียงหยดของส่วนหัวทั่วไปได้ส่งสาเหตุแล้ว (เอาท์พุทดิบ, BOM , ประกาศ, ฯลฯ ) และปัญหาการติดตามของพวกเขา

  • PHP มีเวทย์มนตร์ในการกิน linebreaks เดียวหลังจาก?>โทเค็นปิด แม้ว่าจะมีปัญหาทางประวัติศาสตร์และทำให้ผู้มาใหม่ยังคงไวต่อการบรรณาธิการที่ไม่สม่ำเสมอและการสับในช่องว่างอื่น ๆ?>โดยไม่ได้ตั้งใจ

  • นักพัฒนาบางคนชอบดู<?phpและ?>ตามคำแนะนำในการประมวลผลแท็ก / XML ของ SGML แสดงถึงความสอดคล้องที่สมดุลของโทเค็นใกล้เคียงต่อท้าย (btw ใดที่มีประโยชน์สำหรับคลาสการพึ่งพาการเชื่อมต่อรวมถึงการแทนที่การโหลดอัตโนมัติแบบไม่มีประสิทธิภาพต่อไฟล์)

  • ค่อนข้างเปิดที่ผิดปกติ<?phpมีลักษณะเป็น PHPs shebang (และเป็นไปได้อย่างเต็มที่ต่อbinfmt_misc ) จึงตรวจสอบความซ้ำซ้อนของแท็กปิดที่สอดคล้องกัน

  • มีความแตกต่างที่เห็นได้ชัดระหว่างให้คำแนะนำเป็นคู่มือไวยากรณ์คลาสสิก PHPอิง?>\nและยิ่งคนล่าสุด (PSR-2)เห็นพ้องกับการละเลย
    (สำหรับเร็กคอร์ด: Zend Framework ที่อ้างถึงหนึ่ง ๆ เหนืออื่น ๆ ไม่ได้หมายความถึงความเหนือกว่าโดยธรรมชาติของมันมันเป็นความเข้าใจผิดที่ผู้เชี่ยวชาญถูกดึงไปยัง / กลุ่มเป้าหมายของ API ที่เทอะทะ)

  • SCMและ IDE ที่ทันสมัยนำเสนอโซลูชั่นในตัวซึ่งส่วนใหญ่ช่วยบรรเทาการดูแลแท็กใกล้ชิด

การกีดกันการใช้?>แท็กปิดใด ๆเพียง แต่ล่าช้าอธิบายพฤติกรรมการประมวลผล PHP ขั้นพื้นฐานและความหมายของภาษาเพื่อหลีกเลี่ยงปัญหาที่พบบ่อย มันยังคงใช้งานได้จริงสำหรับการพัฒนาซอฟต์แวร์ที่ทำงานร่วมกันเนื่องจากความหลากหลายของผู้เข้าร่วม

ปิดแท็กรูปแบบต่างๆ

  • ปกติ ?>แท็กใกล้เคียงยังเป็นที่รู้จักกันT_CLOSE_TAGหรือทำให้ "โทเค็นปิด"

  • มันประกอบด้วยอีกสองสามสาขาเพราะ PHPs เวทมนตร์ขึ้นบรรทัดใหม่กิน :

    ?>\n (ฟีด Unix)

    ?>\r (Carriage return, MAC แบบคลาสสิก)

    ?>\r\n (CR / LF บน DOS / Win)

    PHP ไม่รองรับ Unicode combo linebreak NEL(U + 0085)

    PHP เวอร์ชันแรก ๆ นั้นมี IIRC ที่รวบรวมข้อ จำกัด ของแพลตฟอร์มผู้ไม่เชื่อเรื่องพระเจ้า (ค่อนข้างใช้เพียงแค่>เครื่องหมายปิด) ซึ่งเป็นต้นกำเนิดทางประวัติศาสตร์ของการหลีกเลี่ยงแท็กอย่างใกล้ชิด

  • มักจะมองข้าม แต่จนถึงPHP7 ขจัดพวกเขาที่ปกติ<?phpโทเค็นเปิดสามารถอย่างถูกต้องจับคู่กับที่ไม่ค่อยได้ใช้</script>เป็นโทเค็นปิดคี่

  • " แท็กปิดยาก " ไม่ได้เป็นแบบเดียวกัน - สร้างคำศัพท์นั้นขึ้นมาเพื่อการเปรียบเทียบ __halt_compilerอย่างไรก็ตามควรคำนึงถึงความคิดและการใช้งานที่ชาญฉลาดว่าเป็นโทเค็นใกล้เคียง

    __HALT_COMPILER();
    ?>

    ซึ่งโดยทั่วไปแล้วมี tokenizer ทิ้งรหัสใด ๆ หรือส่วน HTML ธรรมดาหลังจากนั้น ใน PHAR โดยเฉพาะอย่างยิ่งไม่สมบูรณ์ทำให้การใช้งานของที่ซ้ำซ้อนหรือการรวมกันกับ?>ที่ปรากฎเป็น

  • เช่นเดียวกันโมฆะก็return;ไม่สามารถแทนที่รวมสคริปต์ได้แสดงผลใด ๆ ที่ไม่มี?>ช่องว่างต่อท้าย

  • จากนั้นก็มีความหลากหลายของแท็กปิดแบบsoft / faux ไม่ค่อยมีคนรู้จักและไม่ค่อยได้ใช้ แต่มักจะเป็นโทเค็นที่แสดงความคิดเห็นต่อ:

    • การเว้นวรรคอย่างง่าย// ? >เพื่อหลีกเลี่ยงการตรวจจับโดย tokenizer ของ PHP

    • หรือสัญลักษณ์ทดแทน Unicode แฟนซี// ﹖﹥(U + FE56 เครื่องหมายคำถามเล็ก ๆ , U + FE65 เล็ก ๆ มุมยึด) ซึ่ง regexp สามารถเข้าใจ

    ทั้งคู่ไม่มีความหมายต่อ PHPแต่สามารถใช้ประโยชน์ได้จริงสำหรับชุดเครื่องมือภายนอกที่ไม่รู้จักหรือกึ่งตระหนักถึง PHP catสคริปต์ที่เข้าร่วมอีกครั้งคำนึงถึงผลการ// ? > <?phpต่อข้อมูลที่inline- เก็บการแบ่งส่วนไฟล์อดีต

ดังนั้นจึงมีทางเลือกขึ้นอยู่กับบริบท แต่ในทางปฏิบัติเพื่อการละเว้นแท็กปิดจำเป็น

การดูแล?>แท็กปิดแบบแมนนวลนั้นไม่ได้เป็นแบบร่วมสมัยมากนัก มีเครื่องมืออัตโนมัติอยู่เสมอสำหรับสิ่งนั้น (แม้ว่าจะเป็นเพียงแค่ sed / awk หรือ regex-oneliners) โดยเฉพาะอย่างยิ่ง:

แท็ก phptags tidier

https://fossil.include-once.org/phptags/

ซึ่งโดยทั่วไปสามารถใช้กับ--uncloseแท็ก php สำหรับรหัสของบุคคลที่สามหรือเพียงแค่แก้ไขปัญหาช่องว่าง / BOM จริง ๆ (และทั้งหมด):

  • phptags --warn --whitespace *.php

นอกจากนี้ยังจัดการ--longการแปลงแท็ก ฯลฯ สำหรับความเข้ากันได้ของรันไทม์ / การกำหนดค่า


7
ใช่ทู่ท่วงทำนองและวลีที่เร้าใจดึงดูด downvotes จากสิ่งที่ฉันได้อ่านเมื่อเวลาผ่านไปการละทิ้งโทเค็นการปิดไม่มีข้อเสียอย่างแน่นอนตราบใดที่คุณไม่ทำงานกับซอฟต์แวร์ที่ไม่สามารถจัดการได้ ถ้าคุณไม่สามารถพิสูจน์ได้ว่าการละเว้นโทเค็นการปิดนั้นไม่ดีและไม่มีอะไรให้ทำมากนัก downvote ของฉันยังคงอยู่)
jpeltoniemi

2
@Pichan: ฉันจะอนุญาต แต่ฉันคิดว่าคุณยังไม่เข้าใจสิ่งที่ถูกบอกที่นี่ ละทิ้งและหลีกเลี่ยงเป็นสองสิ่งที่แตกต่างกัน และปัญหาที่แก้ไขได้ครึ่งหนึ่งเป็นผลมาจากน้ำมันงูแนะนำ
มาริโอ

6
@mario: มันเป็นข้อเสนอแนะรูปแบบการเข้ารหัสมือใหม่ ฉันไม่เห็นด้วย. Zend Framework ทั้งหมดละเว้นแท็กปิด ฉันคิดว่าเป็นตัวเลือกที่เป็นส่วนตัวฉันชอบปล่อย <<php ของฉันเปิดออกและฉันไม่รู้สึกว่าเป็นมือใหม่ :)
Daniele Vrut

1
แล้ว HTML ล่ะ จำเป็นหรือไม่ สำหรับตัวอย่าง<?php if($var): ?>Hello World<?php endif; ?>??? ฉันอยากรู้อยากเห็นอย่างแท้จริงเพราะมันไม่ได้กล่าวถึงโดยเฉพาะ
WASasquatch

1
@WASasquatch ใช่ หากคุณสลับระหว่างโหมด HTML และ PHP คุณจะต้องใช้โทเค็นใกล้ ๆ ไม่ว่าในกรณีใด (ไม่ได้จริงๆที่เกี่ยวข้องกับคำถามเดิมที่นี่.)
มาริโอ

22

มันไม่ใช่แท็ก ...

แต่ถ้าคุณมีคุณก็เสี่ยงที่จะมีพื้นที่สีขาวหลังจากนั้น

หากคุณใช้เป็นแบบรวมไว้ที่ด้านบนของเอกสารคุณสามารถสิ้นสุดการแทรกช่องว่าง (เช่นเนื้อหา) ก่อนที่คุณจะพยายามส่งส่วนหัว HTTP ... ซึ่งไม่ได้รับอนุญาต


10
หากไม่ใช่แท็กมันคืออะไร
danidacar

คุณช่วยยกตัวอย่างได้ไหม บางทีการกำหนดค่า php ของฉันอาจจะตี แต่ฉันไม่สามารถทำให้เกิดปัญหาได้อีก
danidacar

2
file1.php: <?php $i = 1; ?> จากนั้น file2.php:<?php include 'file1.php'; header('Location: http://www.google.com');?>
Quentin

1
มีข้อเสียในการบัฟเฟอร์การส่งออกเช่นกัน; มันใช้หน่วยความจำเพิ่มเติมบนเซิร์ฟเวอร์ (เนื่องจากเอาต์พุตทั้งหมดจะต้องถูกเก็บไว้ใน RAM จนกว่ามันจะออกโดยไม่บัฟเฟอร์เพียงแค่ไปทันที) มันช้ากว่าเดิมเล็กน้อย ในกรณีส่วนใหญ่จะไม่มีปัญหาเหล่านี้ แต่ฉันขี้เกียจอยู่แล้วดังนั้นทำไมไม่เพียงปิดแท็กปิด ฉันจะใช้phpcsเพื่อให้มั่นใจว่าแท็กปิดที่เหลือของทุกหนึ่งเดียวของไฟล์ของฉันแล้วฉันไม่ต้องกังวลเกี่ยวกับการส่งออกบัฟเฟอร์ :)
El Yobo

1
@danip: หากคุณตั้งค่าสถานะ output_buffer ในไฟล์กำหนดค่า php คุณจะไม่สามารถสร้างปัญหานี้ได้อีก
Jichao

16

มันมีประโยชน์ทีเดียวที่จะไม่ยอมปิดตัว?>ลง

ไฟล์ยังคงใช้งานได้กับ PHP (ไม่ใช่ข้อผิดพลาดทางไวยากรณ์) และตามที่ @David Dorward บอกว่าอนุญาตให้หลีกเลี่ยงการมี white space / break-line (สิ่งใดก็ตามที่สามารถส่งส่วนหัวไปยังเบราว์เซอร์) หลังจาก?>นั้น

ตัวอย่างเช่น,

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10);
    imagepng ( $img);
?>
[space here]
[break line here]

จะไม่ถูกต้อง

แต่

<?
    header("Content-type: image/png");
    $img = imagecreatetruecolor ( 10, 10 );
    imagepng ( $img );

จะ.

สำหรับครั้งคุณจะต้องขี้เกียจที่จะเป็นที่เชื่อถือได้


3
นั่นเป็นเหตุผลที่ฉันใส่ความปลอดภัยในตัวเอียง ช่วยป้องกันคุณจากข้อผิดพลาดที่อาจทำให้คุณเสียเวลามากสำหรับพื้นที่ที่ไม่ต้องการหลังจาก?>นั้น การรักษาความปลอดภัยอาจไม่ใช่คำที่ดีที่นี่ อย่างไรก็ตามมันไม่ได้แก้ไขอะไรเลย (มันไม่ใช่รหัสที่ไม่ดีสำหรับฉันที่จะป้องกันสิ่งต่าง ๆechoที่นี่จะเป็นรหัสที่ไม่ดี) แต่ / และยังคงใช้ได้ พิสูจน์ฉันผิดในเรื่องนี้
Shikiryu

ฉันไม่ได้ลงคะแนนให้คุณ btw แต่ประเด็นของฉันเข้ากันได้กับคุณ มันไม่ได้แก้ไขอะไรเลย ฉันไม่เคยบอกว่ามันไม่ถูกต้องดังนั้นฉันไม่จำเป็นต้องพิสูจน์อะไรเลย
Christian

1
Chouchenos ฉันพนันได้เลยว่าคุณหมายถึงปลอดภัยมากกว่าปลอดภัย IMHO ข้อเสียสำหรับสิ่งนั้นมากเกินไป นำคุณกลับไปที่ตารางหนึ่ง ;-) คุณไม่ได้พูดอะไรผิดไป แม้แต่แนวทางการพัฒนา PHP ก็สนับสนุนให้คุณทำเช่นนั้น ในความเป็นจริงแล้วดีกว่ามากที่ต้องพึ่งพาการละเว้นแท็กปิดแทนที่จะเป็นบัฟเฟอร์บัฟเฟอร์เอาต์พุต หลังจะเหมือนกับการตั้งค่า display_errors เป็นปิด เพียวโกง และเป็นโอกาสที่ดีที่แอพของคุณจะไม่สามารถพกพาได้ ฉันคิดว่าตามกฎแล้วมันดีกว่าที่จะไม่พึ่งพาการบัฟเฟอร์เอาต์พุตเลย
maraspin

1
ฉันไม่ต้องการถามคนที่ชอบวาง?>ไฟล์ท้ายไฟล์ php เท่านั้น แต่คุณเคยต้องการแก้ไขข้อผิดพลาดบางอย่างที่เกิดจากช่องว่างต่อท้ายหรือไม่ นอกจากนี้เซิร์ฟเวอร์บางตัวยังไม่ได้กำหนดค่าแบบเดียวกันโดยเฉพาะเมื่อคุณย้ายไปยังโฮสต์อื่นการจับข้อผิดพลาดนั้นใช้เวลานานมาก ถ้าคุณต้องการ?>แค่ทำมันถ้าคุณเพิ่มช่องว่างท้ายและทีมของคุณต้องแก้จุดบกพร่องที่พร้อมจะตำหนิบนคอมไพล์ ^^
CoffeDeveloper

16

ตามเอกสารนั้นดีกว่าที่จะละเว้นแท็กปิดถ้ามันอยู่ท้ายไฟล์ด้วยเหตุผลดังต่อไปนี้:

หากไฟล์เป็นรหัส PHP แท้ๆคุณควรละเว้นแท็กปิด PHP ที่ท้ายไฟล์ สิ่งนี้จะช่วยป้องกันช่องว่างโดยไม่ตั้งใจหรือบรรทัดใหม่ที่ถูกเพิ่มหลังจากแท็กปิด PHP ซึ่งอาจทำให้เกิดผลข้างเคียงที่ไม่พึงประสงค์เพราะ PHP จะเริ่มบัฟเฟอร์ผลลัพธ์เมื่อไม่มีความตั้งใจจากโปรแกรมเมอร์ที่จะส่งออกใด ๆ ณ จุดนั้นในสคริปต์

คู่มือ PHP> การอ้างอิงภาษา> ไวยากรณ์พื้นฐาน> แท็ก PHP


10

ฉันรู้เหตุผล แต่ฉันไม่สามารถแสดงได้:

สำหรับไฟล์ที่มีรหัส PHP เท่านั้น?>จะไม่อนุญาตให้ใช้แท็กปิด ( ) มันไม่ได้ถูกต้องการโดย PHP และการละเว้นมันจะป้องกันการฉีดโดยไม่ได้ตั้งใจของพื้นที่สีขาวต่อท้ายในการตอบสนอง

ที่มา: http://framework.zend.com/manual/th/coding-standard.php-file-formatting.html


23
แท็กนั้นคือ "ไม่อนุญาต" อาจเป็นมาตรฐานการเข้ารหัส Zend แต่ไม่ใช่กฎไวยากรณ์สำหรับการจัดรูปแบบไฟล์ PHP
Matt Huggins

9

มีสองวิธีในการดูมัน

  1. โค้ด PHP ไม่มีอะไรมากไปกว่าชุดคำสั่งการประมวลผล XMLดังนั้นไฟล์ใด ๆ ที่มี.phpนามสกุลเป็นอะไรมากกว่าไฟล์ XML ที่เกิดขึ้นเพื่อแยกวิเคราะห์สำหรับโค้ด PHP
  2. PHP เกิดขึ้นเพื่อแบ่งปันรูปแบบคำสั่งการประมวลผล XML สำหรับแท็กเปิดและปิด ขึ้นอยู่กับว่าไฟล์ที่มี.phpส่วนขยายอาจเป็นไฟล์ XML ที่ถูกต้อง แต่ไม่จำเป็นต้องเป็น

หากคุณเชื่อว่าเป็นเส้นทางแรกไฟล์ PHP ทั้งหมดจะต้องปิดแท็กปิดท้าย หากไม่ต้องการจะสร้างไฟล์ XML ที่ไม่ถูกต้อง จากนั้นอีกครั้งโดยไม่ต้องมีการ<?xml version="1.0" charset="latin-1" ?>ประกาศเปิดคุณจะไม่มีไฟล์ XML ที่ถูกต้องอยู่แล้ว ... ดังนั้นจึงไม่ใช่ปัญหาหลัก ...

หากคุณเชื่อเส้นทางที่สองนั่นจะเป็นการเปิดประตูสำหรับ.phpไฟล์สองประเภท:

  • ไฟล์ที่มีรหัสเท่านั้น (ไฟล์ไลบรารีเช่น)
  • ไฟล์ที่มี native XML และ code (ตัวอย่างไฟล์เทมเพลต)

ขึ้นอยู่กับว่าไฟล์รหัสเท่านั้นตกลงที่จะสิ้นสุดโดยไม่มี?>แท็กปิด แต่ไฟล์โค้ด XML นั้นไม่สามารถสิ้นสุดได้หากไม่มีการปิด?>เพราะจะทำให้ XML ใช้ไม่ได้

แต่ฉันรู้ว่าคุณกำลังคิดอะไรอยู่ คุณกำลังคิดว่ามันเป็นสิ่งสำคัญคุณจะไม่แสดงไฟล์ PHP โดยตรงดังนั้นใครจะสนใจว่าเป็น XML ที่ถูกต้อง ถ้าคุณออกแบบเทมเพลต หากเป็น XML / HTML ที่ถูกต้องเบราว์เซอร์ปกติจะไม่แสดงรหัส PHP (ถือว่าเป็นความคิดเห็น) ดังนั้นคุณสามารถเยาะเย้ยแม่แบบโดยไม่จำเป็นต้องเรียกใช้รหัส PHP ภายใน ...

ฉันไม่ได้บอกว่าสิ่งนี้สำคัญ มันเป็นเพียงมุมมองที่ฉันไม่เห็นบ่อยเกินไปดังนั้นสิ่งที่ดีกว่าที่จะแบ่งปัน ...

โดยส่วนตัวแล้วฉันไม่ปิดแท็กในไฟล์ไลบรารี แต่ทำในไฟล์เทมเพลต ... ฉันคิดว่ามันเป็นความชอบส่วนตัว (และแนวทางการเข้ารหัส) ซึ่งเป็นมากกว่าสิ่งที่ยาก ...


1
สิ่งนี้เป็นเท็จอย่างสมบูรณ์ PHP ไม่ได้แปลแท็กเหล่านั้นเป็น XML และทำให้ไม่มีการสร้างความไม่สมดุล
Drachenkatze

7
@ Felicitus: ฉันคิดว่าคุณพลาดส่วนที่กล่าวว่า"ฉันไม่ได้บอกว่านี่เป็นสิ่งสำคัญมันเป็นเพียงมุมมองที่ฉันไม่เห็นบ่อยเกินไปดังนั้นสิ่งที่ดีกว่าที่จะแบ่งปัน ... "มันไม่เกี่ยวกับ PHP แปลแท็กเป็น XML มันเกี่ยวกับสิ่งที่เกิดขึ้นเมื่อไฟล์ถูกตีความในบริบท XML (เช่น HTML หรือบรรณาธิการ ฯลฯ ) ... แต่ประเด็นที่พลาด ...
ircmaxell

7

นอกจากทุกสิ่งที่ถูกกล่าวไปแล้วฉันจะโยนด้วยเหตุผลอื่นที่เป็นความเจ็บปวดอย่างมากสำหรับเราในการแก้ไขข้อบกพร่อง

Apache 2.4.6 กับ PHP 5.4 แบ่งส่วนที่ผิดพลาดจริง ๆ บนเครื่องผลิตของเราเมื่อมีพื้นที่ว่างด้านหลังphpแท็กปิด ฉันเพียงแค่สูญเสียชั่วโมงจนในที่สุดผมก็แคบลงข้อผิดพลาดที่มีstrace

นี่คือข้อผิดพลาดที่ Apache พ่น:

[core:notice] [pid 7842] AH00052: child pid 10218 exit signal Segmentation fault (11)

6

"มีอีกเหตุผลที่ดี (นอกเหนือจากปัญหาส่วนหัว) เพื่อข้ามแท็ก php สิ้นสุดหรือไม่"

คุณไม่ต้องการส่งออกอักขระสีขาวที่ไม่เกี่ยวข้องโดยไม่ได้ตั้งใจเมื่อสร้างเอาต์พุตไบนารีข้อมูลCSVหรือเอาต์พุตอื่นที่ไม่ใช่ HTML


1
ฉันมีลูกค้าบ่นเพราะตัวแยกวิเคราะห์ XML ของพวกเขาปฏิเสธการแสดงผลของเราเมื่อมันมีบรรทัดว่างเพิ่มเติมในตอนต้น ยิ่งกว่านั้นมันเกิดขึ้นกับเซิร์ฟเวอร์เพียงหนึ่งในเจ็ดที่มีบรรทัดเพิ่มเติมหลังจากแท็กปิดในไฟล์กำหนดค่าที่ไม่ได้รับการแก้ไข
eswald

5

ข้อดี

  • จะเป็นตรรกะที่จะปิดแท็กที่เปิดอยู่เช่นเดียวกับภาษาอื่น ๆ ไม่เพียง แต่แท็ก X (HT) ML เท่านั้น แต่ยังมีเครื่องหมายปีกกาปีกกาวงเล็บ ...
  • หักสับสนสำหรับผู้เริ่มต้น

จุดด้อย

  • หลีกเลี่ยงการปวดหัวด้วยการเพิ่มช่องว่างหลังจากแท็กปิดโดยไม่ได้ตั้งใจเพราะมันทำลายพฤติกรรมของส่วนหัว () ... บรรณาธิการหรือไคลเอนต์ / เซิร์ฟเวอร์ FTP บางคน  รู้จักว่าจะเปลี่ยนจุดสิ้นสุดของไฟล์โดยอัตโนมัติ (อย่างน้อยมันเป็นค่าเริ่มต้น)
  • คู่มือ PHP กล่าวว่าแท็กปิดเป็นตัวเลือกและZend แม้กระทั่งห้ามมัน

ข้อสรุป

ฉันจะบอกว่าข้อโต้แย้งในความโปรดปรานของการละเว้นแท็กดูแข็งแกร่ง (ช่วยหลีกเลี่ยงอาการปวดหัวใหญ่ด้วยส่วนหัว () + มันเป็น "แนะนำ" PHP / Zend ฉันยอมรับว่านี่ไม่ใช่คำตอบที่ "สวยงาม" ที่สุดเท่าที่ฉันเคยเห็นในแง่ของความสอดคล้องของไวยากรณ์ แต่สิ่งที่อาจจะดีกว่า


2

เนื่องจากคำถามของฉันถูกทำเครื่องหมายว่าซ้ำกับคำถามนี้ฉันคิดว่าการโพสต์เหตุผลที่ไม่ละเว้นแท็กปิด?>อาจเป็นเพราะเหตุผลบางอย่างที่ต้องการ

  • ด้วยคำสั่งในการประมวลผลที่สมบูรณ์ไวยากรณ์ ( <?php ... ?>) แหล่งที่มาของ PHP คือเอกสาร SGML ที่ถูกต้องซึ่งสามารถแยกวิเคราะห์และประมวลผลได้โดยไม่มีปัญหากับตัวแยกวิเคราะห์ SGML ด้วยข้อ จำกัด เพิ่มเติมสามารถเป็น XML / XHTML ที่ถูกต้องได้เช่นกัน

ไม่มีอะไรป้องกันคุณจากการเขียนรหัส XML / HTML / SGML ที่ถูกต้อง เอกสาร PHPรู้เรื่องนี้ ข้อความที่ตัดตอนมา:

หมายเหตุ: โปรดทราบด้วยว่าหากคุณฝัง PHP ไว้ใน XML หรือ XHTML คุณจะต้องใช้แท็ก <? php?> เพื่อให้สอดคล้องกับมาตรฐาน

แน่นอนว่า PHP ไวยากรณ์ไม่เข้มงวด SGML / XML / HTML และคุณสร้างเอกสารซึ่งไม่ใช่ SGML / XML / HTML เช่นเดียวกับที่คุณสามารถเปลี่ยน HTML เป็น XHTML ให้เป็นไปตาม XML ได้หรือไม่

  • ในบางจุดคุณอาจต้องการเชื่อมโยงแหล่งที่มา สิ่งนี้จะไม่ง่ายอย่างที่คิดcat source1.php source2.phpถ้าคุณมีความไม่สอดคล้องที่แนะนำโดยการข้าม?>แท็กปิด

  • โดยไม่?>ยากที่จะบอกได้ว่าเอกสารถูกทิ้งไว้ในโหมดหลบหนี PHP หรือโหมดละเว้น PHP ( <?phpอาจมีการเปิดแท็ก PI หรือไม่) ชีวิตจะง่ายขึ้นถ้าคุณปล่อยเอกสารไว้ในโหมดละเว้น PHP อย่างสม่ำเสมอ มันเหมือนกับการทำงานกับเอกสาร HTML ที่มีการจัดรูปแบบที่ดีเมื่อเทียบกับเอกสารที่มีแท็กที่ไม่ซ้อนกันและซ้อนกันไม่ดีเป็นต้น

  • มันดูเหมือนว่าบรรณาธิการบางอย่างเช่น Dreamweaver อาจมีปัญหากับ PI เปิดทิ้งไว้[1]


0

หากฉันเข้าใจคำถามอย่างถูกต้องเกี่ยวข้องกับการบัฟเฟอร์ผลลัพธ์และผลกระทบที่อาจเกิดขึ้นกับแท็กปิด / สิ้นสุด ฉันไม่แน่ใจว่าเป็นคำถามที่ถูกต้องทั้งหมด ปัญหาคือบัฟเฟอร์เอาต์พุตไม่ได้หมายความว่าเนื้อหาทั้งหมดจะถูกเก็บไว้ในหน่วยความจำก่อนที่จะส่งออกไปยังลูกค้า มันหมายถึงเนื้อหาบางส่วน

โปรแกรมเมอร์สามารถล้างบัฟเฟอร์หรือเอาท์พุทบัฟเฟอร์ดังนั้นตัวเลือกบัฟเฟอร์เอาต์พุตใน PHP จะเปลี่ยนวิธีการปิดแท็กที่มีผลต่อการเข้ารหัสหรือไม่ ฉันจะยืนยันว่ามันไม่ได้

และนั่นอาจเป็นเหตุผลว่าทำไมคำตอบส่วนใหญ่กลับไปที่สไตล์และไวยากรณ์ส่วนตัว


0

มีการใช้ php code ที่เป็นไปได้ 2 แบบ:

  1. โค้ด PHP เช่นนิยามคลาสหรือนิยามฟังก์ชัน
  2. ใช้ PHP เป็นภาษาแม่แบบ (เช่นในมุมมอง)

ในกรณีที่ 1. แท็กปิดไม่ได้ใช้อย่างสมบูรณ์, ฉันอยากจะเห็นเพียง 1 (หนึ่ง) php open tag และ NO (ศูนย์) แท็กปิดในกรณีเช่นนี้ นี่เป็นวิธีปฏิบัติที่ดีเนื่องจากทำให้โค้ดสะอาดและแยกตรรกะจากงานนำเสนอ สำหรับกรณีการนำเสนอ (2. ) บางคนพบว่าเป็นเรื่องธรรมดาที่จะปิดแท็กทั้งหมด (แม้แต่แท็กที่ประมวลผลด้วย PHP) ซึ่งนำไปสู่ความเชื่อมั่นเนื่องจาก PHP มีกรณีการใช้งานแยกต่างหาก 2 อันซึ่งไม่ควรผสม: ตรรกะ / แคลคูลัส และการนำเสนอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.