【问题标题】:Avoiding `Undefined Property` in PHP when using `isset()` in a callback?在回调中使用`isset()`时避免PHP中的`Undefined Property`?
【发布时间】:2017-05-07 11:11:24
【问题描述】:

我为我的模型类编写了一个validation trait,以及一个错误报告库,它格式化并返回错误、警告等的 JSON 对象。

在我的validation 特质中,我有这个方法...

function hasValue($value)
{
  return (isset($value) && !(trim($value) === ''));
}

如果我只是尝试在告诉我变量未定义的条件中使用!(trim($value),PHP 将引发热度。所以,你必须这样做......

if (isset($value) && !(trim($value) === ''))
  //Do Something

我创建此方法是为了将需要两种方法的非常常见的任务合并到一个方法中,但我收到的警告与我单独使用 trim() 方法一样。

有没有办法在不关闭警告的情况下做到这一点?

编辑

似乎有些混乱。我需要它来处理变量和对象属性。我正在尝试扭转这个...

if (empty($obj->email) && $this->validateEmail($obj->email))
  //Do Something

进入这个...

if ($this->validateEmail($obj->email))
  //Do Something

通过让我的hasValue() 方法调用意志,并在validateEmail() 方法内部。

【问题讨论】:

  • 如果您想将所有内容保留在一行中,可以尝试(isset($value)) ? !(trim($value) === '') : false;
  • 不是每次都写不完,我在找可读性和可用性。我不想每次都写。
  • 也许我错过了什么,但我会做这样的事情......if ( (isset($value)) && (!empty($value))){$value = trim($value); do something } else { // error value was not set or was set to null value }
  • 我以为您试图避免将 isset() 与对 $value 的值的检查相结合而得到的 PHP 警告 - 我上面所说的应该提供与您当前的 hasValue 函数相同的结果,但不会发出警告
  • if(!empty($value)){} docs,如果需要,您可以使用if(!empty(trim((string) $value))){}

标签: php warnings trim isset


【解决方案1】:

您遇到的问题是您的函数 hasValue() 将两个语句 isset($value)!(trim($value) === '') 评估为 一个

相反,您应该评估 !(trim($value) === '') if isset($value) 等于 true。这是通过删除外括号来完成的。

function hasValue($value){
  return isset($value) && !(trim($value) === '');
  # if this ^^^^ is false this ^^^^ is never executed and no warning generated.
}

这将解决警告,但是hasValue() 听起来更像是一个检查任何变量是否有值的函数,也许可以这样做:

function hasValue($value){
  return isset($value) && !empty($value) || is_string($value) && !empty(trim($value));
}

var_dump(hasValue(null));  // false
var_dump(hasValue(true));  // true
var_dump(hasValue(false)); // false
var_dump(hasValue([]));    // false
var_dump(hasValue(''));    // false
var_dump(hasValue(' '));   // false
var_dump(hasValue('a'));   // true

interface validateInterface{
  public static function validateEmail($email);
  public static function validateEmailObj();
}

trait validateTrait{
  static function validateEmail($email){
    return filter_var($email, FILTER_VALIDATE_EMAIL); 
  }
  function validateEmailObj(){
    return filter_var($this->email, FILTER_VALIDATE_EMAIL); 
  }
}

# Implementing an interface is not required, but recommended as traits are easily overwritten.
class MyClass implements validateInterface{
  use validateTrait;

  public $email;

  function __construct($email){
    if(self::validateEmail($email)){
      echo 'works statically inside';
    }

    $this->email = $email;
  }
}

$mail = 'some@email.com';

if(MyClass::validateEmail($mail)){
  echo 'works statically outside class';
}

if((new MyClass($mail))->validateEmailObj()){
  echo 'works with objects';
}

有关 isset 和 empty 的更长值列表,请参见 here

【讨论】:

  • 您的代码不适用于我作为具有变量或对象属性的特征的方法。
【解决方案2】:

这可能是使用@ 修饰符来抑制警告的合理位置。

if (@trim($value) != '')

如果$value 未定义,它将被转换为空字符串。发生这种情况时,使用 @ 会抑制警告消息。

【讨论】:

  • 这仍然不能解决在validateEmail等其他验证函数中使用该函数的问题。
  • 我宁愿建议类型杂耍,if( !empty(trim((string)$value)) ){}。压制是last 度假村
  • 您需要在引用可能未定义的变量的位置使用@
猜你喜欢
  • 2011-04-23
  • 2018-10-31
  • 1970-01-01
  • 2012-03-16
  • 2010-12-29
  • 2013-02-22
  • 2019-08-30
  • 2020-11-26
相关资源
最近更新 更多