为了账号安全,请及时绑定邮箱和手机立即绑定

如何区分 PHP 属性是否未定义或设置为 NULL

如何区分 PHP 属性是否未定义或设置为 NULL

PHP
qq_笑_17 2023-09-08 14:19:46
所以我面临这个问题。我有一个类代表数据库中的一条记录(本例中为 User)。该类具有与数据库表的列一样多的属性。为简单起见,我的示例中只有三个:$id- 用户的ID(对于注册用户必须设置为正整数,对于尚未保存在数据库中的用户对象可能设置为0)$name- 用户名(必须为每个用户设置,但在从数据库加载之前可能未定义)$email- 用户的电子邮件地址(如果用户未提交电子邮件地址,则可能为 NULL)我的(简化的)课程如下所示:<?phpclass User{  private $id;  private $name;  private $email;    public function __construct(int $id = 0)  {      if (!empty($id)){ $this->id = $id; }      //If $id === 0, it means that the record represented by this instance isn't saved in the database yet and the property will be filled after calling the save() method  }    public function initialize(string $name = '', $email = '')  {      //If any of the parameters isn't specified, prevent overwriting curent values      if ($name === ''){ $name = $this->name; }      if ($email === ''){ $email = $this->email; }            $this->name = $name;      $this->email = $email;  }    public function load()  {      if (!empty($this->id))      {          //Load name and e-mail from the database and save them into properties      }  }  public function save()  {      if (!empty($this->id))      {          //Update existing user record in the database       }      else      {          //Insert a new record into the table and set $this->id to the ID of the last inserted row      }  }    public function isFullyLoaded()  {      $properties = get_object_vars($this);      foreach ($properties as $property)      {          if (!isset($property)){ return false; }   //TODO - REPLACE isset() WITH SOMETHING ELSE      }      return true;  }    //Getters like getName() and getId() would come here}现在终于解决我的问题了。正如您所看到的,可以在不设置所有属性的情况下创建此类的实例。getName()如果我想在名称未知的情况下进行调用(未通过initialize()方法设置并且未调用 load() ),那么这是一个问题。为此,我编写了一种方法isFullyLoaded(),该方法检查所有属性是否已知,如果不已知,load()则应调用(从调用的方法中调用isFullyLoaded())。问题的核心是,某些变量可能是空字符串('')、零值(0 )甚至 null (如$email属性)。所以我想区分设置了任何值(包括 null)的变量和从未分配过任何值的变量。TL:DR PHP中如何区分未定义变量和已赋值为NULL的变量?
查看完整描述

3 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

这是引入自定义Undefined类(作为单例)的另一种方法。此外,请确保键入您的类属性:


class Undefined

{

    private static Undefined $instance;


    protected function __constructor()

    {

    }


    protected function __clone()

    {

    }


    public function __wakeup()

    {

        throw new Exception("Not allowed for a singleton.");

    }


    static function getInstance(): Undefined

    {

        return self::$instance ?? (self::$instance = new static());

    }

}


class Person

{

    private int $age;


    public function getAge(): int|Undefined

    {

        return $this->age ?? Undefined::getInstance();

    }

}


$person = new Person();


if ($person->getAge() instanceof Undefined) {

    // do something

}

但使用单例模式有一个缺点,因为应用程序中所有未定义的对象将严格彼此相等。否则,每个返回未定义值的get 操作都会产生副作用,即另一块分配的 RAM。


查看完整回答
反对 回复 2023-09-08
?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

PHP 不像 javascript 那样具有未定义的值。但它不是严格类型的,所以如果您没有找到更好的解决方案,这里有一个自定义类型 UNDEFINED


<?php

class UNDEFINED { }


class Test {

var $a;


    function __construct( $a='' ) {

            $this->a = new UNDEFINED();

            if( $a !== '' ) {

                    $this->a = $a;

            }

    }



    function isDefined() {

            $result =true;

            if(gettype($this->a) === 'object'){

             if(get_class($this->a) === 'UNDEFINED') {

               $result=false;

             }

            }


            echo gettype($this->a) . get_class($this->a);

            return $result;

    }


}


$test= new Test();


$test->isDefined();

这是一个可能更好的版本,它使用 instanceof 而不是 get_call 和 getType


<?php

class UNDEFINED { }


class Test {

  var $id;

  var $a;

  var $b;


  function __construct( $id) {

    $this->id = $id;

    $this->a = new UNDEFINED();

    $this->b = new UNDEFINED();

  }


  function init( $a = '' , $b = '') {

    $this->a = $this->setValue($a,$this->a);

    $this->b = $this->setValue($b,$this->b);

  }


  function setValue($a,$default) {

    return $a === '' ? $default : $a;

  }


  function isUndefined($a) {

    return $a instanceof UNDEFINED;

  }

 

  public function isFullyLoaded()

  {

    $result = true;

    $properties = get_object_vars($this);

    print_r($properties);

    foreach ($properties as $property){

      $result = $result && !$this->isUndefined($property);

      if ( !$result) break;

    }

    return $result;

  }


  function printStatus() {

    if($this->isFullyLoaded() ) {

      echo 'Loaded!';

    } else {

      echo 'Not loaded';

    }

  }

}


$test= new Test(1); 

$test->printStatus();

$test->init('hello');

$test->printStatus();

$test->init('', null);

$test->printStatus();


查看完整回答
反对 回复 2023-09-08
?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

用途property_exists():


<?php


error_reporting(E_ALL);


// oop:


class A {

    public $null_var = null;

}


$a = new A;


if(property_exists($a, 'null_var')) {

    echo "null_var property exists\n";

}


if(property_exists($a, 'unset_var')) {

    echo "unset_var property exists\n";

}


// procedural:


$null_var = null;


if(array_key_exists('null_var', $GLOBALS)) {

    echo "null_var variable exists\n";

}


if(array_key_exists('unset_var', $GLOBALS)) {

    echo "unset_var variable exists\n";

}


// output:

// null_var property exists

// null_var variable exists


查看完整回答
反对 回复 2023-09-08
  • 3 回答
  • 0 关注
  • 66 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信