Como definir um objeto vazio no PHP

384

com uma nova matriz eu faço isso:

$aVal = array();

$aVal[key1][var1] = "something";
$aVal[key1][var2] = "something else";

Existe uma sintaxe semelhante para um objeto

(object)$oVal = "";

$oVal->key1->var1 = "something";
$oVal->key1->var2 = "something else";
ed209
fonte
13
$var = (object) (boolean) (string) (int) (array) new StdClass; Você sabe, apenas para estar seguro.
Xeoncross
11
Google indexou este título pergunta como: Arrays - How to define an empty object in PHP. Não tem nada a ver com matrizes
Kolob Canyon

Respostas:

848
$x = new stdClass();

Um comentário no manual resume melhor:

stdClass é o objeto PHP padrão. stdClass não possui propriedades, métodos ou pai. Ele não suporta métodos mágicos e não implementa interfaces.

Ao converter um escalar ou matriz como Objeto, você obtém uma instância de stdClass. Você pode usar stdClass sempre que precisar de uma instância de objeto genérica.

zombat
fonte
5
$ o = (objeto) NULL; - Se um objeto é convertido em um objeto, ele não é modificado. Se um valor de qualquer outro tipo for convertido em um objeto, uma nova instância da classe interna stdClass será criada. Se o valor for NULL, a nova instância estará vazia. As matrizes são convertidas em um objeto com propriedades nomeadas por chaves e valores correspondentes. Para qualquer outro valor, uma variável de membro denominada escalar conterá o valor.
DDS
11
Eu acabei de dizer stdClassna minha cabeça como "classe standard"
sjagr
11
Se você continuar esquecendo uso minha resposta :)
RafaSashi
26
Se você encontrar "não encontrado": new \stdClass(); Espaço para nome PHP Doc
2540625 6/17
3
@IvanCastellanos você poderia explicar como se lembra stdClass()da palavra AIDS?
Adam
117

A maneira padrão de criar um objeto "vazio" é:

$oVal = new stdClass();

Mas, com o PHP> = 5.4, eu pessoalmente prefiro usar:

$oVal = (object)[];

É mais curto e, pessoalmente, considero mais claro, porque stdClass pode ser enganoso para programadores iniciantes (ou seja, "Ei, eu quero um objeto, não uma classe!" ...).

O mesmo com o PHP <5.4 é:

$oVal = (object) array();

(object)[]é equivalente a new stdClass().

Veja o manual do PHP ( aqui ):

stdClass : criado digitando o objeto.

e ( aqui ):

Se um objeto é convertido em um objeto, ele não é modificado. Se um valor de qualquer outro tipo for convertido em um objeto, uma nova instância da classe interna stdClass será criada .


No entanto, lembre-se de que vazio ($ oVal) retorna falso , como @PaulP disse:

Objetos sem propriedades não são mais considerados vazios.

Em relação ao seu exemplo, se você escrever:

$oVal = new stdClass();
$oVal->key1->var1 = "something"; // PHP creates  a Warning here
$oVal->key1->var2 = "something else";

O PHP cria o seguinte aviso, criando implicitamente a propriedade key1(um objeto em si)

Aviso: Criando Objeto Padrão a partir do Valor Vazio

Isso pode ser um problema se sua configuração (consulte o nível de relatório de erros ) mostrar esse aviso ao navegador. Este é outro tópico inteiro, mas uma abordagem rápida e suja pode estar usando o operador de controle de erros (@) para ignorar o aviso:

$oVal = new stdClass();
@$oVal->key1->var1 = "something"; // the warning is ignored thanks to @
$oVal->key1->var2 = "something else";
cgaldiolo
fonte
3
Em vez de corrigir o problema, você está criando um novo. O problema que precisa ser corrigido é que as pessoas devem saber o que stdClassfaz.
Pacerier 25/03
2
Eu escrevi o que stdClassfaz. Eu usei stdClasso código que responde à pergunta. Sinto muito, mas não estou criando um novo problema, essa era minha opinião pessoal (como escrevi).
Cgaldiolo 25/03
6
"preferência pessoal"! = "problema"
cgaldiolo 30/03
4
@ Pacerier, não entendo sua teimosia. A pergunta era 'Como definir um objeto vazio no PHP'. Minha resposta está correta e escrevi para usar "new stdClass ()". O código que forneci ao usuário 'ed209' está correto e usei "new stdClass ()". Além disso, acrescentei uma opinião pessoal e usei um negrito "pessoalmente" para deixar claro que esse não era o caminho "padrão" a seguir. Na minha humilde opinião, um problema que merece tantos comentários deve ser pelo menos uma resposta errada. Em vez disso, se você considerar uma opinião pessoal um problema, talvez isso é um problema para uma partilha construtiva de ideias.
cgaldiolo
9
Eu realmente gosto da abreviação(object) []
Rahil Wazir
35

Quero ressaltar que no PHP não existe um objeto vazio no sentido:

$obj = new stdClass();
var_dump(empty($obj)); // bool(false)

mas é claro que $ obj estará vazio.

Por outro lado, array vazio significa vazio em ambos os casos

$arr = array();
var_dump(empty($arr));

Citação da função changelog vazia

Objetos sem propriedades não são mais considerados vazios.

PaulP
fonte
Não consegui encontrar essa citação no changelog vazia.
Powpow12
@ powpow12 Costumava estar lá . Foi alterado na 5.0.0.
Stanley Umeanozie 18/10/19
18

php.net disse que é melhor:

$new_empty_object = new stdClass();
HungryCoder
fonte
Sim, com certeza é o caminho recomendado.
Hudson Pereira
14

Eu amo como é fácil criar objetos de tipo anônimo em JavaScript:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: "Bar value"
};
console.log(myObj.foo); //Output: Foo value

Então, eu sempre tento escrever esse tipo de objetos em PHP como o javascript :

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => "Bar value"
];

//PHP < 5.4
$myObj = (object) array(
    "foo" => "Foo value",
    "bar" => "Bar value"
);

echo $myObj->foo; //Output: Foo value

Mas como esse é basicamente um array, você não pode fazer coisas como atribuir funções anônimas a uma propriedade, como js faz:

//JavaScript
var myObj = {
    foo: "Foo value",
    bar: function(greeting) {
        return greeting + " bar";
    }
};
console.log(myObj.bar("Hello")); //Output: Hello bar

//PHP >= 5.4
$myObj = (object) [
    "foo" => "Foo value",
    "bar" => function($greeting) {
        return $greeting . " bar";
    }
];
var_dump($myObj->bar("Hello")); //Throw 'undefined function' error
var_dump($myObj->bar); //Output: "object(Closure)"

Bem, você pode fazer isso, mas o IMO não é prático / limpo:

$barFunc = $myObj->bar;
echo $barFunc("Hello"); //Output: Hello bar

Além disso, usando esta sintaxe, você pode encontrar algumas surpresas engraçadas , mas funciona bem na maioria dos casos.

acampamentos
fonte
11
Esta deve ser a resposta aceita
Mike Aron
11

Além da resposta do zombat, se você continuar esquecendo stdClass

   function object(){

        return new stdClass();

    }

Agora você pode fazer:

$str='';
$array=array();
$object=object();
RafaSashi
fonte
Eu amo essa técnica, embora a maioria dos IDEs não destaque o termo "objeto" como uma função que pode ser confusa para outros programadores. Mas ei, isso funciona para mim!
Brixster 22/08/19
7

Você pode usar new stdClass()(o que é recomendado):

$obj_a = new stdClass();
$obj_a->name = "John";
print_r($obj_a);

// outputs:
// stdClass Object ( [name] => John ) 

Ou você pode converter uma matriz vazia em um objeto que produz uma nova instância vazia da classe interna stdClass:

$obj_b = (object) [];
$obj_b->name = "John";
print_r($obj_b);

// outputs: 
// stdClass Object ( [name] => John )  

Ou você pode converter o nullvalor em um objeto que produz uma nova instância vazia da classe interna stdClass:

$obj_c = (object) null;
$obj_c->name = "John";
print($obj_c);

// outputs:
// stdClass Object ( [name] => John ) 
Amr
fonte
5

para acessar dados em um stdClass da mesma maneira que você faz com uma matriz associativa, basta usar a sintaxe {$ var}.

$myObj = new stdClass;
$myObj->Prop1 = "Something";
$myObj->Prop2 = "Something else";

// then to acces it directly

echo $myObj->{'Prop1'};
echo $myObj->{'Prop2'};

// or what you may want

echo $myObj->{$myStringVar};
GCoro
fonte
4

Como outros já apontaram, você pode usar stdClass. No entanto, eu acho que é mais limpo sem o (), assim:

$obj = new stdClass;

No entanto, com base na pergunta, parece que o que você realmente deseja é poder adicionar propriedades a um objeto em tempo real. Você não precisa usar stdClass para isso, embora possa. Realmente você pode usar qualquer classe. Basta criar uma instância de objeto de qualquer classe e começar a definir propriedades. Eu gosto de criar minha própria classe, cujo nome é simplesmente o com algumas funcionalidades estendidas básicas que eu gosto de usar nesses casos e é bom para estender a partir de outras classes. Basicamente, é minha própria classe de objeto base. Também gosto de ter uma função chamada simplesmente o (). Igual a:

class o {
  // some custom shared magic, constructor, properties, or methods here
}

function o() {
  return new o;
}

Se você não gosta de ter seu próprio tipo de objeto base, pode simplesmente ter o () retornado um novo stdClass. Uma vantagem é que o é mais fácil de lembrar do que stdClass e é mais curto, independentemente de você o usar como nome de classe, nome de função ou ambos. Mesmo se você não tiver nenhum código dentro da sua classe, ainda é mais fácil memorizar do que o stdClass com letras maiúsculas e desajeitadamente (que pode invocar a idéia de uma 'classe de doença sexualmente transmissível'). Se você customizar a classe o, poderá encontrar um uso para a função o () em vez da sintaxe do construtor. É uma função normal que retorna um valor menos limitado que um construtor. Por exemplo, um nome de função pode ser passado como uma sequência para uma função que aceita um parâmetro que pode ser chamado. Uma função também suporta encadeamento. Então você pode fazer algo como:

Este é um ótimo começo para uma "linguagem" básica para criar outras camadas de linguagem, com a camada superior sendo escrita em DSLs internas completas. Isso é semelhante ao estilo lisp de desenvolvimento, e o PHP suporta muito melhor do que a maioria das pessoas imagina. Sei que isso é um pouco tangente para a pergunta, mas a pergunta toca no que eu acho que é a base para utilizar totalmente o poder do PHP.

still_dreaming_1
fonte
2
@Pacerier você quer dizer parênteses? ;) cis.upenn.edu/~matuszek/General/JavaSyntax/parentheses.html
still_dreaming_1
11
Isso é um erro de digitação, deve ser sem parênteses.
Pacerier
@Pacerier good point english.stackexchange.com/questions/130219/…
still_dreaming_1
4

Se você deseja criar um objeto (como em javascript) com propriedades dinâmicas, sem receber um aviso de propriedade indefinida.

class stdClass {

public function __construct(array $arguments = array()) {
    if (!empty($arguments)) {
        foreach ($arguments as $property => $argument) {
            if(is_numeric($property)):
                $this->{$argument} = null;
            else:
                $this->{$property} = $argument;
            endif;
        }
    }
}

public function __call($method, $arguments) {
    $arguments = array_merge(array("stdObject" => $this), $arguments); // Note: method argument 0 will always referred to the main class ($this).
    if (isset($this->{$method}) && is_callable($this->{$method})) {
        return call_user_func_array($this->{$method}, $arguments);
    } else {
        throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
    }
}

public function __get($name){
    if(property_exists($this, $name)):
        return $this->{$name};
    else:
        return $this->{$name} = null;
    endif;
}

public function __set($name, $value) {
    $this->{$name} = $value;
}

}

$obj1 = new stdClass(['property1','property2'=>'value']); //assign default property
echo $obj1->property1;//null
echo $obj1->property2;//value

$obj2 = new stdClass();//without properties set
echo $obj2->property1;//null
fredtma
fonte
4

Você pode tentar dessa maneira também.

<?php
     $obj = json_decode("{}"); 
     var_dump($obj);
?>

Resultado:

object(stdClass)#1 (0) { }
Mukesh Jeengar
fonte
4

Use um objeto genérico e mapeie pares de valores-chave para ele.

$oVal = new stdClass();
$oVal->key = $value

Ou converter uma matriz em um objeto

$aVal = array( 'key'=>'value' );
$oVal = (object) $aVal;
Anthony Awuley
fonte
3

Se você não quiser fazer isso:

$myObj = new stdClass();
$myObj->key_1 = 'Hello';
$myObj->key_2 = 'Dolly';

Você pode usar um dos seguintes:

PHP> = 5.4

$myObj = (object) [
    'key_1' => 'Hello',
    'key_3' => 'Dolly',
];

PHP <5.4

$myObj = (object) array(
    'key_1' => 'Hello',
    'key_3' => 'Dolly',
);
Vasil Nikolov
fonte
3

Aqui está um exemplo com a iteração:

<?php
$colors = (object)[];
$colors->red = "#F00";
$colors->slateblue = "#6A5ACD";
$colors->orange = "#FFA500";

foreach ($colors as $key => $value) : ?>
    <p style="background-color:<?= $value ?>">
        <?= $key ?> -> <?= $value ?>
    </p>
<?php endforeach; ?>
fingerman
fonte
0

Você tem essa técnica ruim, mas útil:

$var = json_decode(json_encode([]), FALSE);
Kerollmops
fonte
0

stdClass é o objeto PHP padrão. stdClass não possui propriedades, métodos ou pai. Ele não suporta métodos mágicos e não implementa interfaces.

Ao converter um escalar ou matriz como Objeto, você obtém uma instância de stdClass. Você pode usar stdClass sempre que precisar de uma instância de objeto genérica.

<?php
// ways of creating stdClass instances
$x = new stdClass;
$y = (object) null;        // same as above
$z = (object) 'a';         // creates property 'scalar' = 'a'
$a = (object) array('property1' => 1, 'property2' => 'b');
?>

stdClass NÃO é uma classe base! As classes PHP não herdam automaticamente de nenhuma classe. Todas as classes são independentes, a menos que estendam explicitamente outra classe. O PHP difere de muitas linguagens orientadas a objetos a esse respeito.

<?php
// CTest does not derive from stdClass
class CTest {
    public $property1;
}
$t = new CTest;
var_dump($t instanceof stdClass);            // false
var_dump(is_subclass_of($t, 'stdClass'));    // false
echo get_class($t) . "\n";                   // 'CTest'
echo get_parent_class($t) . "\n";            // false (no parent)
?>

Você não pode definir uma classe chamada 'stdClass' no seu código. Esse nome já é usado pelo sistema. Você pode definir uma classe chamada 'Objeto'.

Você pode definir uma classe que estenda stdClass, mas não obterá nenhum benefício, pois stdClass não faz nada.

(testado no PHP 5.2.8)

Harshal Lonare
fonte