ตรวจสอบว่า var มีอยู่ก่อนที่จะยกเลิกการตั้งค่าใน PHP หรือไม่?


89

ด้วยการรายงานข้อผิดพลาดหรือแม้แต่แนวทางปฏิบัติที่ดีที่สุดเมื่อยกเลิกการตั้งค่าตัวแปรใน PHP คุณควรตรวจสอบว่ามีอยู่ก่อนหรือไม่ (ในกรณีนี้ไม่มีอยู่เสมอไป) และไม่ได้ตั้งค่าหรือไม่ได้ตั้งค่า

<?PHP
if (isset($_SESSION['signup_errors'])){
    unset($_SESSION['signup_errors']);
}

// OR

unset($_SESSION['signup_errors']);
?>


1
มีประสิทธิภาพในการNOTใช้งานissetมากขึ้น ดูคำตอบของฉัน ฉันได้ทำการทดสอบเพื่อหาความแตกต่างของความเร็วแล้ว
Dan Bray

คำตอบ:


171

เพียงแค่ยกเลิกการตั้งค่าหากไม่มีอยู่จะไม่มีอะไรทำ


3
ฉันไม่รู้ว่ามันจะเตือนหรือแจ้งให้ทราบ
JasonDavis

20
@SilentGhost ฉันเห็นด้วยดูเหมือนว่าจะเป็นการทดสอบง่ายๆ แต่พวกเขากำลังขอคำแนะนำจากผู้เชี่ยวชาญและในขณะที่บันทึกข้อผิดพลาดอาจไม่มีข้อผิดพลาด / คำเตือน / การแจ้งเตือนที่ไม่ตั้งค่าตัวแปรที่ไม่ได้กำหนดอาจมีปัญหาอื่น ๆ ที่ไม่ได้บันทึกไว้ เช่นการเรียก unset หมายถึง PHP raking ผ่านข้อมูล var ทั้งหมดเนื่องจากไม่พบอะไรเลยในขณะที่การใช้งานif setอาจมีรูปแบบการจัดทำดัชนีที่ดีกว่า (เพียงตัวอย่างก่อนหน้านี้น่าจะเป็นนักพายเรือและทั้งสองวิธีใช้วิธีการตรวจสอบข้อมูลเดียวกัน)
James

จริงและมีประสิทธิภาพมากขึ้นด้วย มีลักษณะที่คำตอบของฉันเพราะฉันมีการทดสอบความเร็วของการใช้ข้อพระคัมภีร์ไม่ได้ใช้isset isset
Dan Bray

โหวตลง - คุณไม่สามารถยกเลิกการตั้งค่าคีย์อาร์เรย์ที่ไม่ได้กำหนดไว้
Behnam

1
@jascha ฉันบอกว่าเราไม่สามารถ!
Behnam

48

จากคู่มือ PHP :

เกี่ยวกับความสับสนก่อนหน้านี้ในบันทึกเหล่านี้เกี่ยวกับสิ่งที่ทำให้ unset () เรียกใช้การแจ้งเตือนเมื่อยกเลิกการตั้งค่าตัวแปรที่ไม่มีอยู่ ....

การยกเลิกการตั้งค่าตัวแปรที่ไม่มีอยู่เช่นเดียวกับใน

<?php
unset($undefinedVariable);
?>

ไม่ทริกเกอร์การแจ้งเตือน "ตัวแปรที่ไม่ได้กำหนด" แต่

<?php
unset($undefinedArray[$undefinedKey]);
?>

เรียกใช้การแจ้งเตือนสองรายการเนื่องจากรหัสนี้มีไว้สำหรับการยกเลิกการตั้งค่าองค์ประกอบของอาร์เรย์ ทั้ง $ undefinedArray หรือ $ undefinedKey ต่างก็ไม่ได้ถูกตั้งค่า แต่เป็นเพียงการใช้เพื่อค้นหาสิ่งที่ไม่ควรตั้งค่า ท้ายที่สุดถ้าพวกเขามีอยู่จริงคุณจะยังคงคาดหวังให้ทั้งคู่อยู่ใกล้ ๆ ในภายหลัง คุณไม่ต้องการให้อาร์เรย์ทั้งหมดของคุณหายไปเพียงเพราะคุณ unset () หนึ่งในองค์ประกอบของมัน!


42
สิ่งนี้ต้องการคำชี้แจงเพิ่มเติมเล็กน้อย คุณสามารถยกเลิกการตั้งค่าคีย์อาร์เรย์ที่ไม่ได้กำหนดไว้ตราบเท่าที่ยังมีอาร์เรย์อยู่
kingmaple

@kristovaher แน่นอน - นี่ไม่ได้กล่าวถึงสถานการณ์เฉพาะที่ OP อธิบายเลย
Mark Amery

23

การใช้ unsetตัวแปรที่ไม่ได้กำหนดจะไม่ทำให้เกิดข้อผิดพลาดใด ๆ (เว้นแต่ว่าตัวแปรนั้นเป็นดัชนีของอาร์เรย์ (หรือวัตถุ) ที่ไม่มีอยู่)

ดังนั้นสิ่งเดียวที่คุณต้องพิจารณาคือสิ่งที่มีประสิทธิภาพสูงสุด มีประสิทธิภาพมากกว่าที่จะไม่ทดสอบด้วย 'isset' เนื่องจากการทดสอบของฉันจะแสดง

ทดสอบ:

function A()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($defined);
    }
}

function B()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($undefined);
    }
}

function C()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($defined))
            unset($defined);
    }
}

function D()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($undefined))
            unset($undefined);
    }
}

$time_pre = microtime(true);
A();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function A time = $exec_time ";

$time_pre = microtime(true);
B();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function B time = $exec_time ";

$time_pre = microtime(true);
C();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function C time = $exec_time ";

$time_pre = microtime(true);
D();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function D time = $exec_time";
exit();

ผล:

  1. Function A time = 1.0307259559631
    • กำหนดโดยไม่มี isset
  2. Function B time = 0.72514510154724
    • ไม่ได้กำหนดโดยไม่มี isset
  3. Function C time = 1.3804969787598
    • กำหนดโดยใช้ isset
  4. Function D time = 0.86475610733032
    • ไม่ได้กำหนดโดยใช้ isset

สรุป:

การใช้งานมีประสิทธิภาพน้อยกว่าเสมอissetไม่ต้องพูดถึงเวลาเพิ่มเติมเล็กน้อยที่ต้องใช้ในการเขียน การพยายามunsetหาตัวแปรที่ไม่ได้กำหนดจะเร็วกว่าการตรวจสอบว่าเป็นunsetไปได้หรือไม่


1
นี่เป็นวิธีที่ดีกว่าคำตอบที่ยอมรับ! ขอขอบคุณที่เรียกใช้การทดสอบเหล่านี้
Adam Friedman

3

หากคุณต้องการยกเลิกการตั้งค่าตัวแปรคุณสามารถใช้ unset

unset($any_variable); // bool, object, int, string etc

การตรวจสอบการมีอยู่ของมันไม่มีประโยชน์เมื่อพยายามยกเลิกการตั้งค่าตัวแปร

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

unset($undefined_array['undefined_element_key']); // error - Undefined variable: undefined_array

unset($undefined_object->undefined_prop_name); // error - Undefined variable: undefined_object

นี้จะแก้ไขได้อย่างง่ายดายโดยการตัดunsetในif(isset($var)){ ... }บล็อก

if(isset($undefined_array)){
    unset($undefined_array['undefined_element_key']); 
}

if(isset($undefined_object)){
    unset($undefined_object->undefined_prop_name); 
}

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

if(isset($array)){
...
}

if(isset($object)){
...
}

.vs

$object->prop_name = null;
$array['element_key'] = null;

// This way elements/properties with the value of `null` can still be unset.

if(isset($array) && array_key_exists('element_key', $array)){
...
}

if(isset($object) && property_exists($object, 'prop_name')){
...
}

// or 

// This way elements/properties with `null` values wont be unset.

if(isset($array) && $array['element_key'])){
...
}

if(isset($object) && $object->prop_name)){
...
}

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

มันเหมือนกันเมื่อพยายามที่จะยกเลิกการตั้งค่าของอาร์เรย์หรือวัตถุหลายมิติ คุณต้องแน่ใจว่ามีคีย์ / ชื่อพาเรนต์อยู่

if(isset($variable['undefined_key'])){
    unset($variable['undefined_key']['another_undefined_key']);
}

if(isset($variable->undefined_prop)){
    unset($variable->undefined_prop->another_undefined_prop);
}

เมื่อจัดการกับวัตถุมีอีกสิ่งหนึ่งที่ต้องคิดและนั่นคือการมองเห็น

เพียงเพราะมีอยู่ไม่ได้หมายความว่าคุณได้รับอนุญาตให้แก้ไข


ในที่สุดคำตอบที่เหมาะสม ขอขอบคุณ.
wp78de

การอัปเดตขนาดเล็ก: ใน PHP 7.4 / 8.0 จะไม่มีข้อผิดพลาดเกิดขึ้นเมื่อคุณunsetมีคุณสมบัติของออบเจ็กต์หลักที่ไม่มีอยู่ อย่างไรก็ตามการยกเลิกการตั้งค่าคีย์ในอาร์เรย์ที่ไม่มีอยู่ใน PHP8 ไม่เพียง แต่เป็นการแจ้งเตือนเท่านั้น แต่ยังเป็นการเตือน (อาจมีการเปลี่ยนแปลง)
wp78de

1

ตรวจสอบลิงค์นี้ https://3v4l.org/hPAto

เครื่องมือออนไลน์แสดงความเข้ากันได้ของโค้ดสำหรับ PHP เวอร์ชันต่างๆ

ตามเครื่องมือนี้รหัส

unset($_SESSION['signup_errors']);

จะใช้ได้กับ PHP> = 5.4.0 โดยไม่ต้องแจ้งให้คุณทราบ / คำเตือน / ข้อผิดพลาดใด ๆ

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