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

所以我面临这个问题。我有一个类代表数据库中的一条记录(本例中为 User)。该类具有与数据库表的列一样多的属性。为简单起见,我的示例中只有三个:

  1. $id- 用户的ID(对于注册用户必须设置为正整数,对于尚未保存在数据库中的用户对象可能设置为0)

  2. $name- 用户名(必须为每个用户设置,但在从数据库加载之前可能未定义)

  3. $email- 用户的电子邮件地址(如果用户未提交电子邮件地址,则可能为 NULL)

我的(简化的)课程如下所示:

<?php

class 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的变量?


qq_笑_17
浏览 98回答 3
3回答

慕桂英546537

这是引入自定义Undefined类(作为单例)的另一种方法。此外,请确保键入您的类属性:class Undefined{&nbsp; &nbsp; private static Undefined $instance;&nbsp; &nbsp; protected function __constructor()&nbsp; &nbsp; {&nbsp; &nbsp; }&nbsp; &nbsp; protected function __clone()&nbsp; &nbsp; {&nbsp; &nbsp; }&nbsp; &nbsp; public function __wakeup()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; throw new Exception("Not allowed for a singleton.");&nbsp; &nbsp; }&nbsp; &nbsp; static function getInstance(): Undefined&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return self::$instance ?? (self::$instance = new static());&nbsp; &nbsp; }}class Person{&nbsp; &nbsp; private int $age;&nbsp; &nbsp; public function getAge(): int|Undefined&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return $this->age ?? Undefined::getInstance();&nbsp; &nbsp; }}$person = new Person();if ($person->getAge() instanceof Undefined) {&nbsp; &nbsp; // do something}但使用单例模式有一个缺点,因为应用程序中所有未定义的对象将严格彼此相等。否则,每个返回未定义值的get 操作都会产生副作用,即另一块分配的 RAM。

慕尼黑5688855

PHP 不像 javascript 那样具有未定义的值。但它不是严格类型的,所以如果您没有找到更好的解决方案,这里有一个自定义类型 UNDEFINED<?phpclass UNDEFINED { }class Test {var $a;&nbsp; &nbsp; function __construct( $a='' ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this->a = new UNDEFINED();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( $a !== '' ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $this->a = $a;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; function isDefined() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $result =true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(gettype($this->a) === 'object'){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(get_class($this->a) === 'UNDEFINED') {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;$result=false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; echo gettype($this->a) . get_class($this->a);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return $result;&nbsp; &nbsp; }}$test= new Test();$test->isDefined();这是一个可能更好的版本,它使用 instanceof 而不是 get_call 和 getType<?phpclass UNDEFINED { }class Test {&nbsp; var $id;&nbsp; var $a;&nbsp; var $b;&nbsp; function __construct( $id) {&nbsp; &nbsp; $this->id = $id;&nbsp; &nbsp; $this->a = new UNDEFINED();&nbsp; &nbsp; $this->b = new UNDEFINED();&nbsp; }&nbsp; function init( $a = '' , $b = '') {&nbsp; &nbsp; $this->a = $this->setValue($a,$this->a);&nbsp; &nbsp; $this->b = $this->setValue($b,$this->b);&nbsp; }&nbsp; function setValue($a,$default) {&nbsp; &nbsp; return $a === '' ? $default : $a;&nbsp; }&nbsp; function isUndefined($a) {&nbsp; &nbsp; return $a instanceof UNDEFINED;&nbsp; }&nbsp;&nbsp; public function isFullyLoaded()&nbsp; {&nbsp; &nbsp; $result = true;&nbsp; &nbsp; $properties = get_object_vars($this);&nbsp; &nbsp; print_r($properties);&nbsp; &nbsp; foreach ($properties as $property){&nbsp; &nbsp; &nbsp; $result = $result && !$this->isUndefined($property);&nbsp; &nbsp; &nbsp; if ( !$result) break;&nbsp; &nbsp; }&nbsp; &nbsp; return $result;&nbsp; }&nbsp; function printStatus() {&nbsp; &nbsp; if($this->isFullyLoaded() ) {&nbsp; &nbsp; &nbsp; echo 'Loaded!';&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; echo 'Not loaded';&nbsp; &nbsp; }&nbsp; }}$test= new Test(1);&nbsp;$test->printStatus();$test->init('hello');$test->printStatus();$test->init('', null);$test->printStatus();

明月笑刀无情

用途property_exists():<?phperror_reporting(E_ALL);// oop:class A {&nbsp; &nbsp; public $null_var = null;}$a = new A;if(property_exists($a, 'null_var')) {&nbsp; &nbsp; echo "null_var property exists\n";}if(property_exists($a, 'unset_var')) {&nbsp; &nbsp; echo "unset_var property exists\n";}// procedural:$null_var = null;if(array_key_exists('null_var', $GLOBALS)) {&nbsp; &nbsp; echo "null_var variable exists\n";}if(array_key_exists('unset_var', $GLOBALS)) {&nbsp; &nbsp; echo "unset_var variable exists\n";}// output:// null_var property exists// null_var variable exists
打开App,查看更多内容
随时随地看视频慕课网APP