PHP verifica se existe propriedade no objeto ou classe

159

Entendo que o PHP não tem uma variável de objeto puro, mas quero verificar se uma propriedade está no objeto ou na classe em questão.

$ob = (object) array('a' => 1, 'b' => 12); 

ou

$ob = new stdClass;
$ob->a = 1;
$ob->b = 2;

Em JS, eu posso escrever isso para verificar se a variável aexiste em um objeto:

if ('a' in ob)

Em PHP, algo assim pode ser feito?

Muito obrigado pelo seu conselho.

Micah
fonte
2
Apenas mencionando ... quando fazemos OOP, dizemos propriedade não variável, como dizemos método, não função.
Christopher Bonitz

Respostas:

254

property_exists (classe $ mista, string $ propriedade)

if (property_exists($ob, 'a')) 

isset (misto $ var [, misto $ ...])

if (isset($ob->a))

isset () retornará false se a propriedade for nula

Exemplo 1:

$ob->a = null
var_dump(isset($ob->a)); // false

Exemplo 2:

class Foo
{
   public $bar = null;
}

$foo = new Foo();

var_dump(property_exists($foo, 'bar')); // true
var_dump(isset($foo->bar)); // false
Peter
fonte
12
Não necessariamente, se a propriedade existe, mas não está definida, isset () retornará false. us3.php.net/manual/en/types.comparisons.php
Mitchell
isset () pode ser combinado com empty () para verificar a propriedade e o valor.
4
Enquanto isset () é a resposta errada, se você está ciente da ressalva de que é consideravelmente mais rápido do que property_exists ()
Nico Westerdale
É uma situação em que empty()existe uma solução melhor? !empty($var)?
b_dubb
1
@b_dubb não, array vazio, 0, falsa, null, '' tudo return true por `esvaziar ()'
Peter
61

Para verificar se a propriedade existe e se é nulo também, você pode usar a função property_exists().

Documentos: http://php.net/manual/en/function.property-exists.php

Ao contrário de isset (), property_exists () retorna TRUE mesmo se a propriedade tiver o valor NULL.

bool property_exists (classe $ mista, string $ propriedade)

Exemplo:

if (property_exists($testObject, $property)) {
    //do something
}
Chiara Perino
fonte
7
Isso deve ser marcado como a resposta aceita, uma vez que responde a resposta explícita muito precisa. O isset não é útil para testar a existência de uma propriedade em um objeto.
Christopher Bonitz
11

Nem isset nem property_exists funcionam para mim.

  • isset retorna false se a propriedade existir, mas for NULL.
  • property_exists retornará true se a propriedade fizer parte da definição de classe do objeto, mesmo se tiver sido desconfigurada.

Acabei indo com:

    $exists = array_key_exists($property, get_object_vars($obj));

Exemplo:

    class Foo {
        public $bar;

        function __construct() {
            $property = 'bar';

            isset($this->$property); // FALSE
            property_exists($this, $property); // TRUE
            array_key_exists($property, get_object_vars($this)); // TRUE

            unset($this->$property);

            isset($this->$property); // FALSE
            property_exists($this, $property); // TRUE
            array_key_exists($property, get_object_vars($this)); // FALSE

            $this->$property = 'baz';

            isset($this->$property); // TRUE
            property_exists($this, $property); // TRUE
            array_key_exists($property, get_object_vars($this));  // TRUE
        }
    }
smariot
fonte
property_exist + unset property talvez cause comportamento de buggy. Este parece ser o método mais seguro
Thanh Trung
array_key_exists () está obsoleto no php 7.4
Ali_Hr 15/12/19
A palavra-chave em "Usando array_key_exists () em objetos está obsoleta" é objetos. get_object_vars () retorna uma matriz, por isso ainda somos bons.
Smariot 16/12/19
7

Solução

echo $person->middleName ?? 'Person does not have a middle name';

Mostrar como isso ficaria em uma declaração if para obter mais clareza sobre como isso está funcionando.

if($person->middleName ?? false) {
    echo $person->middleName;
} else {
    echo 'Person does not have a middle name';
}

Explicação

A maneira tradicional do PHP de verificar a existência de algo é:

if(isset($person->middleName)) {
    echo $person->middleName;
} else {
    echo 'Person does not have a middle name';
}

OU para uma maneira mais específica de classe:

if(property_exists($person, 'middleName')) {
    echo $person->middleName;
} else {
    echo 'Person does not have a middle name';
}

Ambos são bons em declarações de formato longo, mas em declarações ternárias tornam-se desnecessariamente pesados ​​da seguinte maneira:

isset($person->middleName) ? echo $person->middleName : echo 'Person does not have a middle name';

Você também pode conseguir isso apenas com o operador ternário da seguinte forma:

echo $person->middleName ?: 'Person does not have a middle name';

Mas ... se o valor não existe (não está definido), ele gera uma E_NOTICEe não é uma prática recomendada. Se o valor for null, não gerará a exceção.

Portanto, operador ternário para o resgate, fazendo desta uma pequena resposta pura:

echo $person->middleName ?? 'Person does not have a middle name';

Roubar
fonte
Ótima explicação!
DasBen 23/04
4

Se você deseja saber se existe uma propriedade em uma instância de uma classe que você definiu, basta combinar property_exists()com isset().

public function hasProperty($property)
{
    return property_exists($this, $property) && isset($this->$property);
}
Anthony Rutledge
fonte
1
A chamada property_exists($this, $property)é meio redundante aqui, pois seu código sempre terá o mesmo resultado que isset($this->$property)sozinho.
MarthyM
Este é um exame mais completo dos fatos, porque isset()não podemos dizer se uma propriedade é um membro verdadeiro da definição de classe. Vou procurar novamente mais tarde para ter certeza.
Anthony Rutledge
Isso é verdade, a saída será a mesma para as propriedades reais da classe. Se você tiver propriedades virtuais com métodos mágicos __get()mais importantes __isset(), a saída será diferente em alguns casos.
MarthyM
1

Para verificar se algo sai, você pode usar a função PHP isset (), veja php.net . Esta função irá verificar se a variável está definida e não é NULL.

Exemplo:

if(isset($obj->a))
{ 
  //do something
}

Se você precisar verificar se existe uma propriedade em uma classe, poderá usar a construção na função property_exists ()

Exemplo:

if (property_exists('class', $property)) {
    //do something
}
Tjoene
fonte
1

Usar array_key_exists () em objetos é preterido no php 7.4

Em vez disso, isset () ou property_exists () devem ser usados

referência: php.net

Ali_Hr
fonte
0

Apenas colocando meus 2 centavos aqui.

Dada a seguinte classe:

class Foo
{
  private $data;

  public function __construct(array $data)
  {
    $this->data = $data;
  }

  public function __get($name)
  {
    return $data[$name];
  }

  public function __isset($name)
  {
    return array_key_exists($name, $this->data);
  }
}

o seguinte acontecerá:

$foo = new Foo(['key' => 'value', 'bar' => null]);

var_dump(property_exists($foo, 'key'));  // false
var_dump(isset($foo->key));  // true
var_dump(property_exists($foo, 'bar'));  // false
var_dump(isset($foo->bar));  // true, although $data['bar'] == null

Espero que isso ajude alguém

Vencedor
fonte