ทำไม PHP Devs หลายคนเกลียดการใช้ isset () และ / หรือฟังก์ชั่นการป้องกันที่คล้ายกันของ PHP อย่างใดอย่างหนึ่งเช่น empty ()


27

ใน stackoverflow ฉันเห็นปัญหานี้หมดไปตลอดเวลา:

แม้แต่Pekka (ผู้ที่ให้คำแนะนำ PHP ที่เป็นของแข็งจำนวนมาก) ก็เจอกับE_NOTICEสัตว์ประหลาดที่หวั่นกลัวและหวังว่าจะได้ทางออกที่ดีกว่าการใช้isset(): isset () และเปล่า () ทำให้โค้ดน่าเกลียด

โดยส่วนตัวแล้วฉันใช้isset()และempty()ในหลาย ๆ ที่เพื่อจัดการการไหลของแอปพลิเคชันของฉัน ตัวอย่างเช่น:

public function do_something($optional_parameter = NULL) {
    if (!empty($optional_parameter)) {
        // do optional stuff with the contents of $optional_parameter
    }
    // do mandatory stuff
}  

แม้แต่ตัวอย่างง่ายๆเช่นนี้:

if (!isset($_REQUEST['form_var'])) {
    // something's missing, do something about it.
}

ดูเหมือนว่าฉันมีเหตุผลมาก ดูเหมือนว่ามันจะไม่บวมดูเหมือนรหัสที่เสถียร แต่จำนวนมากของนักพัฒนาไฟขึ้นการใช้งานของพวกเขาด้วยE_NOTICE's เปิดใช้งานการค้นพบจำนวนมากที่น่าผิดหวัง 'ดัชนีอาร์เรย์เตรียม' ประกาศแล้วแสยะที่คาดหมายของการตรวจสอบสำหรับตัวแปรที่กำหนดไว้และ 'เกลื่อน' isset()รหัสของพวกเขาด้วย

ฉันถือว่าภาษาอื่นจัดการสิ่งต่าง ๆ เมื่อพูดถึงประสบการณ์ JavaScript จะไม่สุภาพเท่า PHP โดยทั่วไปแล้วตัวแปรที่ไม่ได้กำหนดจะหยุดการทำงานของสคริปต์ นอกจากนี้ยังพูดจากไม่มีประสบการณ์ ) ฉันแน่ใจว่าภาษาเช่น C / C ++ จะปฏิเสธที่จะรวบรวม

ดังนั้น PHP devs ขี้เกียจแค่ไหน? (ไม่ได้พูดถึงคุณ Pekka ฉันรู้ว่าคุณกำลัง refactoring แอปพลิเคชันเก่า) หรือว่าภาษาอื่น ๆ จัดการกับตัวแปรที่ไม่ได้กำหนดอย่างสง่างามมากกว่าที่ต้องการให้โปรแกรมเมอร์ตรวจสอบก่อนว่าพวกเขาถูกกำหนดหรือไม่?

(ฉันรู้ว่ามีE_NOTICEข้อความอื่นนอกเหนือจากตัวแปรที่ไม่ได้กำหนด แต่ดูเหมือนว่าจะเป็นข้อความที่ทำให้เกิดความผิดหวังมากที่สุด)

ภาคผนวก
จากคำตอบจนถึงตอนนี้ฉันไม่ใช่คนเดียวที่คิดว่าisset()ไม่ใช่รหัสที่ขยายตัว ดังนั้นฉันสงสัยว่าตอนนี้มีปัญหากับโปรแกรมเมอร์ในภาษาอื่นที่สะท้อนสิ่งนี้หรือไม่? หรือนี่เป็นเพียงปัญหาทางวัฒนธรรมของ PHP เท่านั้น?


4
น่าเศร้าที่ฉันเห็น php devs ทำงานกับ "คำเตือน" ก็ปิดเช่นกัน
Viper_Sb

อุ๊ยตาย นั่นเป็นเรื่องน่าเศร้า
สตีเฟ่น

1
ไม่ใช่ผู้ใช้ PHP ฉันสงสัยว่า: ทำไมคุณต้องตรวจสอบตัวแปรที่ไม่ได้กำหนด?
Winston Ewert

2
@ Winston: ปัญหาเกี่ยวกับ PHP (ตรงกันข้ามกับภาษาอื่น ๆ ) คือ PHP อนุญาตให้มีการกำหนดค่าหลายอย่าง ตัวอย่างเช่นโปรแกรมเมอร์สามารถตัดสินใจที่จะละเว้นคำเตือนประกาศและการแจ้งเตือนการคัดค้าน นักพัฒนาที่มีประสบการณ์มากขึ้นจะทำงานกับ error_reporting set เพื่อรายงานทุกอย่าง PHP ยังมีฟังก์ชั่นมากมายที่ทำให้เกิดข้อผิดพลาดและส่งคืนรหัสสถานะแทนที่จะโยนข้อยกเว้น หนึ่งจะต้องมีความใกล้ชิดกับภาษาเพื่อให้สามารถป้องกันรหัสและประสบความสำเร็จ ภาษาอื่นจำนวนมากไม่อนุญาตให้เลือก เข้มงวดมักจะเป็นค่าเริ่มต้นและตัวเลือกเท่านั้น
Wil Moore III

1
ฉันไม่ชอบ isset () เพราะมันใช้คำฟุ่มเฟื่อย รูปแบบที่ดีขึ้นของ @ จะเป็นทางเลือกที่ดี
Kzqai

คำตอบ:


34

ฉันรหัสไปE_STRICTและไม่มีอะไรอื่น

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

โองการผลที่ตามมาของการไม่ใช้พวกเขาอย่างน้อยที่สุดคำเตือน


7
สภาพแวดล้อมการพัฒนาของฉันก็เช่นE_STRICTกัน ฉันระงับข้อผิดพลาดทั้งหมดในการผลิต แต่นั่นเป็นเพียงเพื่อให้แน่ใจว่าไม่มีอะไรหลุดผ่านมาฉันในการพัฒนา
สตีเฟ่น

2
+1 Josh ฉันก็เหมือนกัน เมื่อคุณโปรแกรมใน E_STRICT คุณรู้ว่าคุณจะไม่มีทางประหลาดใจในรหัสของคุณ วิธีเดียวในการบิน imo
EricBoersma

3
@Stephen: ปิดข้อผิดพลาดเสมอสำหรับการผลิต นั่นเป็นเพียงตาข่ายความปลอดภัย การพัฒนาควรจะ (IMO) E_STRICTจะเสมอ เขียนรหัสและแก้ไขคำเตือนและข้อผิดพลาดทั้งหมด
Josh K

คุณแกล้งฉันไหม :)
Stephen

@ สตีเฟ่น: ฉันเห็นด้วย :)
Josh K

17

ฉันคิดว่าประกาศเกี่ยวกับองค์ประกอบที่ไม่รู้จักเป็นความผิดพลาดในการออกแบบใน PHP ฉันไม่แน่ใจว่าเป็นไปได้ที่จะแก้ไขข้อผิดพลาดในขณะนี้ แต่มันสร้างรหัสสำเร็จรูปจำนวนมากเช่นif(isset($foo['abc']) && $foo['abc'] == '123')- รหัสนี้ไม่ควรมีissetเนื่องจากจุดประสงค์คือการตรวจสอบว่ามี '123' อยู่ในที่ที่แน่นอน$fooหรือไม่ ไม่แน่นอน '123' เหตุผลเดียวที่คุณต้องเขียนโค้ดมากถึงสองเท่านั่นก็เพราะความผิดพลาดในการออกแบบของ PHP และการแจ้งเตือนนั้นมีราคาแพงมากใน PHP แต่น่าเสียดายที่การปิดใช้งานนั้นไม่ใช่ตัวเลือกสำหรับรหัสที่ประสิทธิภาพนั้นเป็นปัญหา

ใช่แล้วมันทำให้ IMHO น่าเกลียดและทำให้ฉันรำคาญ และไม่ใช่เพราะขาดประสบการณ์ - ฉันใช้ PHP ตั้งแต่ปี 1998 และฉันจำได้เมื่อมีการ.php3ต่อเติมและมันหมายถึง "ไม่ใช่ PHP 2" บางทีฉันอาจขี้เกียจ :) แต่ความเกียจคร้าน - อย่างน้อยมันก็เป็นข้อดีสำหรับโปรแกรมเมอร์

ในทางกลับกันการใช้งานที่ถูกต้องของissetและemptyเช่นเดียวกับที่อยู่ในโพสต์ต้นฉบับนั้นใช้ได้ ฉันแค่คิดว่า PHP มีความกระตือรือร้นอย่างมากเกี่ยวกับคำเตือนในสถานที่ที่isset/emptyไม่จำเป็นจริงๆ


3
ขวา. มันเป็นเรื่องของการใช้คำฟุ่มเฟื่อย $eg = isset($_GET['eg'])? $_GET['eg'] : null;verbose ขัน ฉันหวังว่าจะมีโอเปอเรเตอร์รายอื่นที่ไม่ใช่ "การควบคุมข้อผิดพลาด" ต่อ se เพื่อให้ได้ความหมายสั้น ๆ ของคำว่า$eg = @$_GET['eg'];"accept-the-non-existant-of-this-array ฉันมักจะใช้ฟังก์ชั่นสั้น ๆ วันนี้
Kzqai

7
ตกลง 4 ปีต่อมาเข้าสู่ Null Coalesce Operator: wiki.php.net/rfc/isset_ternaryให้พวกเรา$eg = $_GET['eg'] ?? null;
Steve

$eg = @$_GET['eg'] ?: null;หรือเพียงแค่ทำมันตอนนี้มีผู้ประกอบการปราบปรามความผิดพลาดเช่น โดยทั่วไปฉันไม่ได้ใช้มัน แต่ในกรณีนี้เราคาดหวังข้อผิดพลาดนั้นอย่างชัดเจนและตัดสินใจเพิกเฉย มันเป็นตัวละครตัวหนึ่งที่ยาวกว่า null ที่รวมตัวกันและมันก็ไม่ดีเท่า (มันหยุดข้อผิดพลาดทั้งหมดและอาจมี ArrayAccess ทำสิ่งที่ขี้ขลาดนั่นไม่ใช่แค่อาร์เรย์) แต่โดยทั่วไปแล้วมันทำงานได้ดี
El Yobo

12

ฉันเชื่อว่า PHP เป็นภาษาฟรีที่ถูกตีความและใช้งานบนเว็บมีสัดส่วนที่สูงมากของผู้ไม่ใช้โค้ดที่ไม่ได้รับการฝึกหัดและไม่ทราบว่าทำไมพวกเขาจึงควรใช้รหัสป้องกันและเพิ่งเห็นคำเตือนว่าเป็นข้อผิดพลาดที่ไม่จำเป็น .

ฉันได้ยินประเด็นเหล่านี้จากนักพัฒนารุ่นเยาว์และผู้เขียนสคริปต์ที่เรียนรู้ด้วยตนเองตลอดเวลา:

  • ทำไมเริ่มต้นตัวแปรถ้ามันจะเกิดขึ้นต่อไป?
  • ทำไมตรวจสอบว่ามีบางสิ่งบางอย่างอยู่ก่อนที่เราจะใช้มันไม่ได้กำหนดเท่ากับเท็จแล้วล่ะ?
  • หากฉันนำหน้าด้วย @ จะแก้ไขรหัสของฉันได้อย่างไร

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

ปัจจัยที่แข็งแกร่งอีกประการหนึ่งคือการใช้งาน PHP ในอุตสาหกรรมเว็บซึ่งมีความกังวลกับปริมาณงานมากกว่าความปลอดภัยและคุณภาพของรหัส


10
"ฉันเชื่อว่า PHP [... ] มีสัดส่วนของตัวแปลงสัญญาณที่ไม่เป็นมืออาชีพและสูงมาก" ในฐานะที่เป็น PHP dev เฉพาะฉันไม่สามารถเห็นด้วยกับคุณได้มากกว่านี้ +1
สตีเฟน

@ สตีเฟ่นฉันใช้รหัสเป็นหลักใน PHP และ jQuery เมื่อเร็ว ๆ นี้แม้ว่าฉันจะมีการศึกษาอย่างเป็นทางการ แต่รหัสที่คุณเห็นว่าเป็นมืออาชีพที่คุณต้องรับผิดชอบก่อน ... มันท้าทายความเชื่อบางครั้ง ;-)
Orbling

1
ฉันคิดว่านั่นเป็นปัญหาที่แท้จริงของ PHP นอกเหนือจากนิสัยใจคอบางอย่างในภาษา (ซึ่งพวกเขากำลังค่อย ๆ แก้ไขในแต่ละเวอร์ชั่นใหม่) มีบรรยากาศของการสมัครเล่นรอบ ๆ มัน ฉันนึกได้ว่าการเป็นนักพัฒนา PHP มืออาชีพอาจทำให้คุณหงุดหงิดเพราะคุณเปรียบเทียบกับ 'หลานชายของหัวหน้าจากทั่วมุม'
Erik van Brakel

1
@Erik PHP เป็นญาติที่ค่อนข้างแย่ของ Perl เมื่อสิบปีที่แล้วตอนนี้มันเป็นภาษาที่ตีความค่อนข้างสมเหตุสมผลโดยเฉพาะอย่างยิ่งสำหรับการใช้งานเว็บ มีเหตุผลที่ บริษัท อย่าง Facebook ใช้ แต่เนื่องจากมีให้บริการทุกที่ชุดสมัครเล่นจึงใช้อย่างกว้างขวางและทำให้ชื่อเสียงเสื่อมเสีย
Orbling

5

ใช่พวกเขาขี้เกียจ ยังมีอีกมาก ...

น่าเสียดายที่ความคิดของตัวแปลงสัญญาณ PHP จำนวนมากคือ "ไม่มีจุดเข้ารหัสที่ป้องกันได้หากคุณสามารถรับผลลัพธ์ที่เร็วกว่าเดิมได้เร็วขึ้นโดยอาศัยภาษาในการจัดการข้อผิดพลาดที่เกิดจากตัวแปรที่ขาดหายไป ฯลฯ " ฉันรู้ว่าฉันทำงานกับพวกเขาหลายคน

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


5
-1 สำหรับความคิดเห็นส่วนตัวเกี่ยวกับ PHP coders
Josh K

4
@ Josh ซึ่งเป็นผู้เขียนโค้ด PHP ระดับสูงมาเป็นเวลา 4 1/2 ปีและได้เปิดและปิดโค้ด PHP ตั้งแต่ปี 1999 ฉันเกรงว่าฉันค่อนข้างเป็นอัตนัย ฉันควรได้รับการรับรองด้วย "ในทางกลับกัน, ผู้เขียนโค้ด PHP ที่มีประสบการณ์มากขึ้นไม่ได้ขี้เกียจและทำสิ่งต่าง ๆ ได้อย่างถูกต้อง" ...
Gruffputs

1
ที่คุณควรมี
Josh K

5

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


วิธีการที่น่าสนใจมาก
Toby

2

หนึ่งในคำถามที่สงสัยคือของฉันดังนั้นฉันขอย้ำอีกครั้ง

นักพัฒนาหลายคนเข้าใจผิดisset()ว่ามีสัญลักษณ์คุณภาพมากมาย มันให้ภาพลักษณ์ของความน่าเชื่อถือและบางคนคิดว่ามันเป็นคุณสมบัติความปลอดภัย

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

ดังนั้น PHP devs ขี้เกียจแค่ไหน?

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

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

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

หรือนี่เป็นเพียงปัญหาทางวัฒนธรรมของ PHP เท่านั้น?

ไม่ "ข้อผิดพลาด" ตัวแปรที่ไม่ได้กำหนดไม่ใช่ปัญหา PHP เพียงอย่างเดียว Bash, TCL และ Perl หรือ JavaScript อนุญาตให้ใช้ตัวแปรที่ไม่ได้กำหนด คุณลักษณะภาษาที่อยู่ข้างนี้ไม่ได้ถูกมองว่าเป็นข้อบกพร่อง มีโครงสร้างภาษาที่คล้ายกันเพื่อตรวจสอบค่าที่ไม่ได้กำหนด อย่างไรก็ตามมันไม่ได้ถูกนำมาใช้อย่างต่อเนื่องเหมือนใน PHP เนื่องจากค่า undef ที่ไม่ถูกแปลงเป็น "ผิดพลาด"


1

น่าสนใจ ฉันแทบจะไม่เคยใช้ isset () รหัส PHP ของฉันไม่ค่อยอยู่ในสถานะที่ฉันไม่รู้ว่ามีการตั้งค่าตัวแปรไว้ตั้งแต่แรกหรือไม่ ตัวแปร GET หรือ POST ทุกตัวที่ใช้ถูกเข้าถึงผ่านฟังก์ชั่นที่จะให้ค่าเริ่มต้นหากไม่มีอยู่ ค่าเริ่มต้นในการเรียกใช้ฟังก์ชั่นโดยปกติจะถูกตั้งค่าเป็น 0 หรือสตริงว่าง


+1 ผ่านไปยังฟังก์ชั่นหรือวิธีการเรียนเป็นวิธีที่ดี จริง ๆ แล้วฉันทำสิ่งนี้ แต่ในตัวอย่างของฉันยังคงดูสะอาดและไม่ป่องให้ฉัน
สตีเฟ่น

0

ฉันใช้ isset และว่างเปล่ามากมาย แต่ส่วนใหญ่เป็นสถานที่ที่คุณพูดถึงเช่นการประมวลผล $ _REQUEST ในกรณีที่ทุกคนทำกับพารามิเตอร์ ในกรณีที่ฉันสามารถควบคุมตัวแปรทั้งหมดได้ฉันพบว่าฉันไม่ต้องการมัน


0

ฉันไม่ชอบใช้ isset แต่ถ้ามีรหัสจำนวนมากที่ทำโดยผู้อื่นมันอาจจะเป็นความประหยัด ฉันเขียนรหัส wee ด้านล่างเพื่อช่วยแก้ไขปัญหานี้แทนที่จะใช้ isset () isseter ($ a, $ b) จะคืนค่า $ b หาก $ a ไม่ได้ถูกกำหนดหรือว่างเปล่าหรือฟังก์ชั่นส่งคืนค่า null การปรับปรุงใด ๆ ยินดีต้อนรับ:

//returns var or NULL (if undefined)
//$reserve optional second value is returned as $default if undefined
function isseter(&$default,&$reserve=NULL)
{
$default = isset($default) ? $default : NULL;
$reserve = isset($reserve) ? $reserve : NULL;
if ((!$default) && ($reserve)) $default=$reserve;
return $default;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.