PHPで設定を解除する前に、varが存在するかどうかを確認しますか?


88

PHPで変数の設定を解除するときに、エラーレポートを使用して、またはベストプラクティスとして、変数が最初に存在するかどうか(この場合は常に存在するとは限りません)、設定を解除するか、単に設定を解除するかを確認する必要がありますか?

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

// OR

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


1
NOT使用する方が効率的issetです。私の答えを見てください。速度の違いを見つけるためにテストを行いました。
ダン・ブレイ

回答:


167

設定を解除するだけで、存在しない場合は何も行われません。


3
警告または通知がスローされるかどうかはわかりませんでした
JasonDavis 2009

19
@SilentGhost同意します。これは非常に単純なテストのようですが、専門家のアドバイスを求めています。エラーログには未定義の変数の設定を解除するエラー/警告/通知がない場合がありますが、ログに記録されない他の問題があった可能性があります。たとえば、unsetを呼び出すだけでは、PHPがすべてのvarデータを検索することを意味します。これは、PHPが何も見つからないためですが、使用if setすると、より優れたインデックススキームが得られる可能性があります。(ほんの一例ですが、前者はおそらくコブラーであり、どちらのアプローチも同じデータチェック方法を使用しています)。
ジェームズ

確かに、それもより効率的です。を使用しissetない詩を使用する速度をテストしたので、私の答えを見てくださいisset
ダン・ブレイ

反対票を投じる-定義されていない配列キーの設定を解除することはできません。
behnam 2018

1
@jascha私が言った、私たちはできません!
Behnam

48

PHPマニュアルから

存在しない変数の設定を解除するときにunset()が通知をトリガーする原因についての、これらのメモの前半の混乱に関して...

のように、存在しない変数の設定を解除する

<?php
unset($undefinedVariable);
?>

「未定義の変数」の通知はトリガーされません。だが

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

このコードは配列の要素の設定を解除するためのものであるため、2つの通知をトリガーします。$ undefinedArrayも$ undefinedKey自体も設定されておらず、設定されていないものを見つけるために使用されているだけです。結局のところ、それらが存在したとしても、後で両方が存在することを期待できます。要素の1つをunset()したからといって、配列全体が消えてしまうことは望ましくありません。


41
これにはもう少し説明が必要です。配列自体が存在する限り、定義されていない配列キーの設定を解除できます。
キングメープル2012

@kristovaher確かに-これは、OPが説明する特定のシナリオにはまったく対応していません。
マークアメリー2014

21

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
これは受け入れられた答えよりもはるかに優れています!これらのテストを実行していただきありがとうございます。
アダムフリードマン

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.