ถือว่าเป็นการใช้งาน PHP ที่ไม่ดีหรือไม่


55

หลายต่อหลายครั้งบนเว็บไซต์นี้ฉันเห็นคนพยายามทำสิ่งนี้:

<script type="text/javascript">
  $(document).ready(function(){

     $('<?php echo $divID ?>').click(funtion(){
       alert('do something');
     });

  });
</script>

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

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

การวางค่าคงที่ของแอพพลิเคชั่นในจาวาสคริปต์ของคุณนั้นเป็นแบบไดนามิกหรือไม่ดังนั้นคุณไม่ต้องแก้ไขสองไฟล์ ตัวอย่างเช่น...

MYAPP.constants = <php echo json_encode($constants) ?>;

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

ChartLibrary.datapoints = <php echo json_encode($chartData) ?>;   

หรือเราควรโทร AJAX ทุกครั้ง?


4
มันดูเหมือนว่าฉันว่าthis question will likely solicit opinion, debate, arguments, polling, or extended discussion....
DaveRandom

7
@ M.Babcock นี่จะเป็นส่วนหนึ่งของไฟล์. php ดังนั้นโค้ด php จะถูกเรียกใช้งานฝั่งเซิร์ฟเวอร์และไคลเอนต์จะเห็นผลลัพธ์ของเสียงสะท้อนเท่านั้น

8
ทุกคนที่สร้าง JavaScript ที่สร้างขึ้นแบบไดนามิกจะถูกนำออกไปและจัดการกับ
Raynos

5
@ Matt แล้วฉันจะใช้ google ออกหลังและจัดการกับพวกเขา
Raynos

4
"คุณมีจาวาสคริปต์ใน PHP ของฉัน!" "ไม่คุณมี PHP ในจาวาสคริปต์ของฉัน !"
Josh Darnell

คำตอบ:


83

โดยปกติจะเป็นการปฏิบัติที่ดีที่จะใช้ภาษา X เพื่อสร้างรหัสในภาษาวาย

ลอง decoupling สองภาษาโดยการทำให้ข้อมูลที่อินเตอร์เฟซของพวกเขาเท่านั้น - ไม่ปะปนรหัส

ในตัวอย่างของคุณคุณสามารถปรับปรุงโค้ดโดยใช้ PHP เพื่อเติมcfgโครงสร้างที่มีให้กับ JavaScript:

<script type="text/javascript">
  var cfg = {
    theId: "<?php echo $divID ?>",
    ...
  };

  $(document).ready(function(){
     $("#" + cfg.theId).click(funtion(){
       alert('do something');
     });
  });
</script>

ด้วยวิธีนี้ PHP ให้ความสำคัญกับการเติมโครงสร้างข้อมูลเท่านั้นและ JavaScript สนใจเพียงเกี่ยวกับการใช้โครงสร้างข้อมูลเท่านั้น

decoupling นี้ยังนำไปสู่วิธีการโหลดข้อมูลแบบอะซิงโครนัส (JSON) ในอนาคต

ปรับปรุง:

เพื่อตอบคำถามเพิ่มเติมที่คุณถามกับการอัปเดตของคุณใช่มันเป็นการดีที่จะใช้หลักการ DRY และให้ PHP และ JavaScript แชร์ออบเจ็กต์การกำหนดค่าเดียวกัน:

<script type="text/javascript">
  var cfg = <?php echo json_encode($cfg) ?>;

  ...

ไม่มีอันตรายใด ๆ ในการแทรกการแสดง JSON ของการกำหนดค่าของคุณโดยตรงในหน้าของคุณเช่นนี้ คุณไม่จำเป็นต้องดึงข้อมูลผ่าน XHR


21
จำไว้ว่าอย่าใส่รหัสผ่าน MySQL ของคุณใน $ cfg !!
โทมัส Bonini

13
"ทำให้ข้อมูลเป็นอินเทอร์เฟซเดียวของพวกเขา - อย่ารวมรหัส" ฉันคิดว่านี่น่าจะเป็นประเด็นหลักของปัญหาและเป็นกฎง่ายๆเมื่อใช้สองภาษาด้วยกัน ขอบคุณสำหรับความเข้าใจ
Greg Guida

6
คุณสามารถรวม JSON นั้นไว้ในdata-แอตทริบิวต์ใน HTML ของคุณ <body data-cfg="{...}">สิ่งที่ชอบ
kapa

1
@bazmegakapa ฉันคิดว่านั่นอาจเป็นตัวเลือกที่ดีที่สุด โดยเฉพาะอย่างยิ่งจะช่วยให้การใช้ API เช่น HTML DOM ที่ช่วยลดความเสี่ยงของการฉีด XSS
luiscubal

1
+1 สำหรับการแนะนำการใช้ข้อมูลเป็นอินเทอร์เฟซและรหัสท้อใจที่สร้างรหัส
แบรนดอน

21

JavaScript ที่สร้างขึ้นแบบไดนามิกนั้นเป็นวิธีปฏิบัติที่น่ากลัวและไม่ดี

สิ่งที่คุณควรทำคือเข้าใจว่าการแยกความกังวลและการเพิ่มประสิทธิภาพแบบก้าวหน้าหมายถึงอะไร

สิ่งนี้หมายความว่าคุณมี HTML แบบไดนามิกและ JavaScript แบบคงที่ (ซึ่งปรับปรุง HTML)

ในกรณีของคุณคุณอาจต้องการคลาสใน div ของคุณและเลือกด้วยตัวเลือกคลาส


10

ปัญหาที่ใหญ่ที่สุดของข้อมูลโค้ดของคุณคือคุณไม่มีตัวเลือก#เพื่อให้เป็นตัวเลือก jQuery ที่ถูกต้อง;)

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

<script type="text/javascript">
  $(document).ready(function(){

     $('.foo').click(funtion(){
       alert('do something');
     });

  });
</script> 

<div id="bar" class="<?php echo ($someCond ? 'foo' : ''); ?>">Hello</div>

มีเป็นสถานการณ์ที่คุณต้องรวม PHP ใน JavaScript ของคุณ แต่ฉันต้องยอมรับสิ่งเหล่านี้มีน้อยและอยู่ห่างไกล

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

var config = { assets: "<?php echo $yourConfig['asset_url']; ?>" };

ในส่วนที่เหลือของรหัส php จินตภาพของฉันฉันได้เพิ่ม#=) แต่อย่างจริงจังฉันยอมรับว่าคุณเป็นตัวอย่างเป็นวิธีที่ดีกว่าที่จะทำ ดูเหมือนว่าฉันจะทำแบบนั้นด้วยซ้ำ แล้วทำไมเราถึงเห็นมันบ่อยๆในที่ ๆ ไม่จำเป็น?
Greg Guida

โปรดทราบว่าการสะท้อนข้อมูลสแตติกในไฟล์กำหนดค่าสามารถหลีกเลี่ยงได้อย่างง่ายดายโดยการตั้งค่าสภาพแวดล้อมของคุณทั้งหมดด้วยวิธีเดียวกัน
Raynos

4
@ GregGuida: ฉันเดาว่าคงจะเป็นโปรแกรมเมอร์ที่ไม่ค่อยคุ้นเคยกับการจัดการกับไคลเอนต์ / เซิร์ฟเวอร์สถาปัตยกรรมเหมือนที่คุณได้รับในการพัฒนาเว็บ พวกเขาปฏิบัติต่อ DB <-> PHP <-> HTML / JS / CSS เป็นหนึ่งและไม่เข้าใจอย่างถ่องแท้ว่าควรจะไปที่ไหนและเลเยอร์ควรแยกออกจากกันอย่างไร
Matt

@ Matt ฉันคิดว่านั่นอาจเป็นคำอธิบายที่ดีที่สุด
Greg Guida

2
$divID = '#' . $element_id_value;- ไม่มีปัญหากับหัวหน้าตัวเลือก;)
rlemon

8

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

คุณสามารถทำสิ่งนี้แทน:

function setOnClick(divid) {
 $(divid).click(funtion(){
   alert('do something');
 });
}

จากนั้นคุณสามารถเรียกใช้ฟังก์ชันนี้ในไฟล์ php เพื่อทำให้สิ่งที่ผสมเหล่านี้มีขนาดเล็กที่สุดเท่าที่จะทำได้

$(function() {
  setOnClick('<?php echo $divId; ?>');
});

ด้วยการทำเช่นนี้ (มีไฟล์ JS ที่ใหญ่กว่าไม่ใช่ 2-3 บรรทัด) คุณสามารถใช้ประโยชน์จากการบีบอัดไฟล์ JS และนักพัฒนาส่วนหน้ารู้สึกสบายใจที่จะทำงานกับ JavaScript ได้มากขึ้นในความคิดของฉัน Python, Ruby ฯลฯ ไม่เพียง แต่ PHP - และโค้ดอาจใหญ่ขึ้นเรื่อย ๆ ขึ้นอยู่กับว่าคุณต้องทำอะไร)


2
Totaly เห็นด้วย btw ฉันไม่เคยใส่ PHP ใน JS ของฉัน ฉันเพิ่งเห็นมันในเว็บไซต์นี้ตลอดเวลา
Greg Guida

รหัส php ไม่เคยทำให้เบราว์เซอร์! เพียงแค่โค้ดที่ได้รับการประเมินซึ่งตอนนี้ควรเป็นจาวาสคริปต์ธรรมดา ดังนั้นขนาด / การบีบอัดไฟล์จึงไม่ใช่ปัญหา ความคิดที่ไม่ดียังคงปฏิบัติ!
James Anderson

@ JamesAnderson ฉันคิดว่า alessioalex หมายถึง minification (เช่น Uglify) อาจเป็นไปได้ที่จะมีการเรียกใช้ php จากนั้นมีฟังก์ชั่น post-process php แยกวิเคราะห์การตอบสนองระบุแท็กสคริปต์เรียกใช้ผ่าน Uglify และแทนที่ JS ที่สร้างขึ้น php เดิมด้วยเวอร์ชันย่อก่อนส่งการตอบกลับ แต่การทำเช่นนั้นกับทุกคำขอดูเหมือนเป็นเรื่องง่าย! เข้าใกล้
jinglesthula

6

ฉันไม่คิดว่านี่เป็นการฝึกฝนที่ไม่ดี หากรหัสที่จำเป็นใน JavaScript ของคุณเป็นแบบไดนามิกไม่มีวิธีอื่นในการทำเช่นนี้


5
ทำไมในชื่อที่ไม่บริสุทธิ์ของ cuthulu คุณจะไม่รู้จักชื่อของแท็ก ID?
ไม่ระบุตัวตน

3
@Incognito มีหลายครั้งที่คุณไม่ทราบ ID ... หากคุณใช้ Ajax เพื่อสร้างบล็อกรหัสใหม่คุณอาจกำลังสร้าง ID ที่ไม่ซ้ำพร้อมกับ JS ใหม่ ... ในกรณีเหล่านี้คุณต้อง ตรวจสอบให้แน่ใจว่า ID ที่อ้างอิงนั้นเหมือนกันใน js นั้นอยู่ในบล็อคโค้ดที่ได้ มีอินสแตนซ์อีกมากมายเช่นนี้และมันก็ค่อนข้างธรรมดาเมื่ออาแจ็กซ์มีส่วนเกี่ยวข้องหรือมีบล็อคโค้ดขนาดใหญ่ขึ้นอยู่กับคำสั่ง if-else ฝั่งเซิร์ฟเวอร์และอื่น ๆ

7
@raynjamin ฉันไม่เข้าใจว่าคุณใส่ตัวเองอย่างไรในสถานการณ์ที่คุณกำลังทำ ... หรือเหตุผลที่คุณเลือกตามระดับชั้นเรียนจากนั้นจึงใส่รายการแท็กจากนั้นระบุแอตทริบิวต์ ID ซึ่งมีค่า css ที่ซ่อนอยู่ ... จริง ๆ แล้วมันทำให้ฉันลำบากที่จะดู ... ฉันไม่รู้ด้วยซ้ำว่าจะเริ่มต้นอย่างไร ... เช่น ... อะไรนะ? คุณกำลังตัด + วางบล็อคโค้ดขนาดใหญ่หรือบางอย่างเพื่อให้สิ่งต่าง ๆ สามารถทำงานได้กับหลาย ID หรือไม่ ฉันทำไม่ได้ ... เหมือน ... สมองของฉัน มันระเบิดที่นี่
ไม่ระบุตัวตน

3
ไปอ่านเกี่ยวกับ dom / html / อะไรก็ตาม ... ใช้เครื่องมือค้นหา ... ทำไมฉันไม่เคยทำอะไรแบบนี้กับ HTML แบบไดนามิก?
ไม่ระบุตัวตน

5
ไม่ คุณไม่เข้าใจว่าแท็ก ID ทำงานอย่างไร ฉันเข้าใจสิ่งที่คุณพูด
ไม่ระบุตัวตน

6

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

OWASP XSS แผ่นโกงมีรายละเอียดมากขึ้น แต่โดยทั่วไปคุณควรนำมาใช้รูปแบบนี้:

<script id="init_data" type="application/json">
    <?php echo htmlspecialchars(json_encode($yourdata)); ?>
</script>

จากนั้นในไฟล์. js แยกต่างหากที่ลิงก์จาก html หลักของคุณโหลดรหัสนี้

var dataElement = document.getElementById('init_data');
var jsonText = dataElement.textContent || dataElement.innerText  // unescapes the content of the span
var initData = JSON.parse(jsonText);

เหตุผลในการใช้ไฟล์. js แยกเป็นสองเท่า:

  • สามารถแคชได้ดังนั้นประสิทธิภาพจึงดีกว่า
  • ตัวแยกวิเคราะห์ HTML ไม่ถูกเรียกดังนั้นจึงไม่มีความเสี่ยงต่อข้อผิดพลาด XSS ที่ลื่นไหลโดยผู้ที่ใส่แท็ก <? php อย่างรวดเร็วในที่นั้น

+1 สำหรับอธิบายมุม XSS อย่างเต็มที่! วิธีการของคุณจะโหลดเร็วขึ้นเนื่องจาก json ถูกโหลดก่อน domready แต่ฉันชอบ json แบบอัตโนมัติในการแยกวิเคราะห์การใช้$.ajaxหรือสิ่งที่คล้ายกัน
roo2

5

บางคนอาจโต้แย้งว่าเป็นการปฏิบัติที่ไม่ดี ไม่ใช่เพราะเป็น PHP ภายใน JS แต่เป็นเพราะ inline JS และเบราว์เซอร์จะไม่ถูกแคชเพื่อให้ง่ายต่อการโหลดในครั้งต่อไป

IMO จะเป็นการดีกว่าถ้าใช้ JSON เพื่อส่งผ่านตัวแปรระหว่าง 2 ภาษา แต่ฉันคิดว่ามันขึ้นอยู่กับคุณ


5

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

<script>
window.config = <?php echo json_encode($config);?>;
</script>

แน่นอนว่าตัวเลือกอื่นคือการสร้างไฟล์กำหนดค่าจาวาสคริปต์จาก PHP ผ่านรูปแบบการสร้างสคริปต์ที่จะนำไฟล์นั้นลงในไฟล์. js


4

สิ่งเดียวที่ฉันคิดได้ว่าจะทำให้เกิดปัญหาคือเมื่อมีการตั้งค่าข้อผิดพลาดของ PHP ให้แสดงผลและผลักภาระ HTML ที่แสดงข้อผิดพลาด PHP ลงใน JavaScript ของคุณ

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


กรณีที่ดีซึ่งสิ่งนี้ทำให้เกิดข้อผิดพลาดครั้งใหญ่
Greg Guida

3

มันขึ้นอยู่กับใครและถ้าคุณถามฉันใช่ฉันจะพิจารณากลับมาฝึกด้วยเหตุผลไม่กี่ ก่อนอื่นฉันต้องการให้มีรหัส javascript ในไฟล์ JS ของตัวเองที่ php parser จะไม่สามารถสัมผัสได้

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

ในที่สุดสำหรับวัตถุประสงค์ขององค์กรสิ่งนี้อาจทำให้เกิดความรำคาญได้ มันไม่ดีพอที่จะผสม html และ php (ในความคิดของฉัน)


1

การที่มี PHP ลงในconfigออบเจ็กต์ข้อมูลนั้น 90% ของวิธีการ แต่วิธีปฏิบัติที่ดีที่สุดคือการแยกมันทั้งหมด คุณสามารถใช้ RESTful API เพื่อขอข้อมูลที่คุณต้องการเท่านั้นมันเป็นจาวาสคริปต์ที่เพิ่มขึ้นเล็กน้อย แต่มีข้อดีเล็กน้อย

  • สคริปต์เป็นแบบสแตติกและสามารถแคชอย่างถาวร
  • PHP ไม่มี XSS Vector
  • แยกความกังวลอย่างสมบูรณ์

ข้อเสีย:

  • ต้องมีคำขอ HTTP พิเศษ
  • จาวาสคริปต์ที่ซับซ้อนมากขึ้น

ต้นฉบับ

//pure javascript
$.on('domready',function({
    //load the data
    $.get({
       url:'/charts/3D1A2E', 
       success: function(data){
           //now use the chart data here
           ChartModule.init(data);
       }
    });
})

-3

ไม่ใช่วิธีปฏิบัติที่ไม่ดีเท่านั้นหากใช้สำหรับการเริ่มต้นโค้ดจาวาสคริปต์ (ในธีม WordPress ของฉันฉันเริ่มต้นวัตถุจาวาสคริปต์ด้วยฟังก์ชัน php เช่น site_url () เพราะเป็นวิธีเดียวที่จะจัดการมัน (บางทีเราอาจใช้คำขอ ajax เพื่อรับ a json และอื่น ๆ ... แต่มันเป็นความเจ็บปวดในตูด)

แนวปฏิบัติที่ดี:

ใหม่ javascriptObject ("");

การปฏิบัติที่ไม่ดี:

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