Pergunta

Como sabemos, criar objetos anônimos em JavaScript é fácil, como no código abaixo:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ] } ; 
alert(object.p1[1]) ;

Saída:

an alert is raised with value "johnny"

Essa mesma técnica pode ser aplicada no caso do PHP?Podemos criar objetos anônimos em PHP?

Foi útil?

Solução

Já se passaram alguns anos, mas acho que preciso manter as informações atualizadas!


No php-7 é possível criar classes anônimas, então você pode fazer coisas assim:

<?php

    class Foo {}
    $child = new class extends Foo {};

    var_dump($child instanceof Foo); // true

?>

Você pode ler mais sobre isso na RFC (é aceito): https://wiki.php.net/rfc/anonymous_classes

Mas não sei o quão semelhante é implementado ao Javscript, então pode haver algumas diferenças entre classes anônimas em javascript e php.

Editar:

A partir dos comentários postados, aqui está o link para o manual agora: http://php.net/manual/en/linguagem.oop5.anonymous.php

Outras dicas

“Anônimo” não é a terminologia correta quando se fala de objetos.Seria melhor dizer "objeto de anonimato tipo", mas isso não se aplica ao PHP.

Todos os objetos em PHP possuem uma classe.A classe "padrão" é stdClass, e você pode criar objetos desta maneira:

$obj = new stdClass;
$obj->aProperty = 'value';

Você também pode aproveitar lançando um array para um objeto para uma sintaxe mais conveniente:

$obj = (object)array('aProperty' => 'value');
print_r($obj);

No entanto, esteja ciente de que a conversão de um array para um objeto provavelmente produzirá resultados "interessantes" para as chaves do array que não são nomes de variáveis ​​PHP válidos - por exemplo, aqui está uma resposta minha que mostra o que acontece quando as chaves começam com dígitos.

Sim, é possível!Usando este simples Objeto anônimo PHP aula.Como funciona:

// define by passing in constructor
$anonim_obj = new AnObj(array(
    "foo" => function() { echo "foo"; }, 
    "bar" => function($bar) { echo $bar; } 
));

$anonim_obj->foo(); // prints "foo"
$anonim_obj->bar("hello, world"); // prints "hello, world"

// define at runtime
$anonim_obj->zoo = function() { echo "zoo"; };
$anonim_obj->zoo(); // prints "zoo"

// mimic self 
$anonim_obj->prop = "abc";
$anonim_obj->propMethod = function() use($anonim_obj) {
    echo $anonim_obj->prop; 
};
$anonim_obj->propMethod(); // prints "abc"

É claro que este objeto é uma instância de AnObj class, portanto não é realmente anônimo, mas torna possível definir métodos dinamicamente, como o JavaScript faz.

Até recentemente, era assim que eu criava objetos dinamicamente.

$someObj = json_decode("{}");

Então:

$someObj->someProperty = someValue;

Mas agora eu vou com:

$someObj = (object)[];

Então como antes:

$someObj->someProperty = someValue;

Claro que se você já conhece as propriedades e valores você pode configurá-los como foi mencionado:

$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];

Observação:Não sei em quais versões do PHP isso funciona, então você precisa estar atento a isso.Mas acho que a primeira abordagem (que também é curta se não houver propriedades para definir na construção) deve funcionar para todas as versões que possuem json_encode/json_decode

Se você deseja imitar JavaScript, você pode criar uma classe Object, e assim obter o mesmo comportamento.É claro que isso não é mais anônimo, mas funcionará.

<?php 
class Object { 
    function __construct( ) { 
        $n = func_num_args( ) ; 
        for ( $i = 0 ; $i < $n ; $i += 2 ) { 
            $this->{func_get_arg($i)} = func_get_arg($i + 1) ; 
        } 
    } 
} 

$o = new Object( 
    'aProperty', 'value', 
    'anotherProperty', array('element 1', 'element 2')) ; 
echo $o->anotherProperty[1];
?>

Isso produzirá elemento 2.Isto foi roubado de um comentário sobre PHP:Classes e objetos.

Converter array em objeto:

$obj = (object)  ['myProp' => 'myVal'];

Se você deseja criar um objeto (como em javascript) com propriedades dinâmicas, sem receber um aviso de propriedade indefinida, quando não tiver definido um valor para propriedade

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

Essa mesma técnica pode ser aplicada no caso do PHP?

Não - porque o javascript usa protótipos/declaração direta de objetos - em PHP (e em muitas outras linguagens OO) um objeto só pode ser criado a partir de uma classe.

Então a questão é: você pode criar uma classe anônima.

Novamente a resposta é não - como você instanciaria a classe sem poder referenciá-la?

Para quem deseja um objeto recursivo:

$o = (object) array(
    'foo' => (object) array(
        'sub' => '...'
    )
);

echo $o->foo->sub;

Na documentação do PHP, mais alguns exemplos:

<?php

$obj1 = new \stdClass; // Instantiate stdClass object
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[]; // Cast empty array to object

var_dump($obj1); // object(stdClass)#1 (0) {}
var_dump($obj2); // object(class@anonymous)#2 (0) {}
var_dump($obj3); // object(stdClass)#3 (0) {}

?>

$obj1 e $obj3 são do mesmo tipo, mas $obj1 !== $obj3.Além disso, todos os três irão json_encode() para um objeto JS simples {}:

<?php

echo json_encode([
    new \stdClass,
    new class{},
    (object)[],
]);

?>

Saídas:

[{},{},{}]

https://www.php.net/manual/en/linguagem.types.object.php

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top