Php anonim nesneler oluşturma


141

Bildiğimiz gibi, aşağıdaki kod gibi JavaScript'te anonim nesneler oluşturmak kolaydır:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ]
};

alert(object.p1[1]);

Çıktı:

an alert is raised with value "johnny"

Aynı teknik PHP'de de uygulanabilir mi? PHP'de anonim nesneler oluşturabilir miyiz?


1
Not: Bu eski bir soru, bu nedenle kabul edilen cevap güncel değil. İstenen bu özellik PHP 7'ye eklenmiştir. @ Rizier123'ün aşağıdaki cevabına bakınız.
Simba

@Simba - Gösterdiğiniz için teşekkürler. Gelecekteki ziyaretçilere yardımcı olmak için bu sayfada StackOverflow'a bir cevap göndermek ister misiniz?
Sujit Agarwal

1
Gerek yok; bu bilgi ile zaten bir cevap var (aşağıya bakınız, @ Rizier123).
Simba

Yanıtlar:


40

Birkaç yıl oldu, ama bilgileri güncel tutmam gerektiğini düşünüyorum!

PHP 7'den beri anonim sınıflar oluşturmak mümkün oldu, bu yüzden böyle şeyler yapabilirsiniz:

<?php

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

    var_dump($child instanceof Foo); // true

?>

Bununla ilgili daha fazla bilgiyi kılavuzda okuyabilirsiniz

Ancak JavaScript'e ne kadar benzer uygulandığını bilmiyorum, bu yüzden JavaScript ve PHP'deki anonim sınıflar arasında birkaç fark olabilir.


@risyasin Teşekkürler, cevabı güncelleyin ve manuel bağlantıyı içine koyun.
Rizier123

Php7 son değişiklikleri takip etmek için cevabınızı doğru olarak işaretleme. Rizier123
Agarwal

3
Bu ilginç ama soruyu gerçekten ele almıyor, çünkü OP bir sınıf oluşturmadan çeşitli üyelerle bir nesneyi başlatmak için uygun bir yol soruyordu. Ben php anonim sınıflar bunu yapmak için kullanılabilir olup olmadığını emin değilim ve eğer, bunu nasıl açıklamak vermedi.
amh15

228

"Anonim" nesneler hakkında konuşurken doğru terminoloji değildir. "Anonim türdeki bir nesne" demek daha iyi olur , ancak bu PHP için geçerli değildir.

PHP'deki tüm nesnelerin bir sınıfı vardır. "Default" sınıfıdır stdClassve bu şekilde nesneler oluşturabilirsiniz:

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

Daha uygun bir sözdizimi için bir diziyi bir nesneye yayınlamaktan da yararlanabilirsiniz :

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

Ancak, bir nesneye bir dizi döküm geçerli PHP değişken adları olmayan bu dizi anahtarları için "ilginç" sonuçlar muhtemeldir hatırlatırız - örneğin, burada benim bir cevap bu tuşlar basamağı ile başlar ne olur gösterilmektedir.


1
birden fazla değerli dizi de itebilir miyim?
Sujit Agarwal

2
@CodingFreak: Şunları yapabilirsiniz, ancak : dizi alt diziler içeriyorsa ve bunları nesne olarak da istiyorsanız, her birini açıkça nesneye dökmeniz gerekir.
Jon

21

Evet mümkün! Bu basit PHP Anonim Nesne sınıfını kullanma. Nasıl çalışır:

// 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"

Elbette bu nesne bir AnObjsınıf örneğidir , bu yüzden gerçekten anonim değildir, ancak JavaScript'in yaptığı gibi anında yöntem tanımlamayı mümkün kılar.


Anonim işlevi taklit etmek için create_function kullanabilirsiniz .
Mihailoff

Ben sadece bazı değerlerle bir stdClass nesnesi başlatmak için düzgün bir yol istedi düşünüyorum. Bunu yaklaşımınızla yapabilir misiniz?
amh15

18

Yakın zamana kadar nesneleri anında bu şekilde yarattım.

$someObj = json_decode("{}");

Sonra:

$someObj->someProperty = someValue;

Ama şimdi:

$someObj = (object)[];

Sonra daha önce olduğu gibi:

$someObj->someProperty = someValue;

Tabii ki özellikleri ve değerleri zaten biliyorsanız, yukarıda belirtildiği gibi ayarlayabilirsiniz:

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

Not: Bunun hangi PHP sürümleri üzerinde çalıştığını bilmiyorum, bu yüzden dikkatli olmanız gerekir. Ama bence ilk yaklaşım (bu da inşaatta ayarlamak için hiçbir özellik yoksa kısa) json_encode / json_decode tüm sürümleri için çalışması gerekir


1
Bunun $ someObj = new \ stdClass () yönteminden gitmenin farkı nedir?
JamesNZ

9

Diziyi nesneye dönüştür (ancak alt alt öğelere yinelemeli değildir):

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

7

JavaScript'i taklit etmek isterseniz, bir sınıf oluşturabilir Objectve böylece aynı davranışı elde edebilirsiniz. Tabii ki bu artık anonim değil, ama işe yarayacak.

<?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];
?>

Bu, eleman 2'yi çıktılar . Bu PHP: Sınıflar ve Nesneler üzerine bir yorum çalındı .


3

Anonim sınıflar için destek PHP 7.0'dan beri mevcuttur ve soruda verilen JavaScript örneğine en yakın analogdur.

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
};

echo $object->p1[1];

Özelliklerle ilgili görünürlük bildirimi atlanamaz (sadece vardaha kısa olduğu için kullanıyorum public.)

JavaScript gibi, sınıf için yöntemler de tanımlayabilirsiniz:

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
    function foo() {return $this->p;}
};

echo $object->foo();

1

PHP dokümantasyonundan birkaç örnek daha:

<?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 ve $ obj3 aynı türdür, ancak $ obj1! == $ obj3. Ayrıca, her üçü de json_encode () yöntemini basit bir JS nesnesine {} ekler:

<?php

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

?>

Çıktılar:

[{},{},{}]

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


0

Tanımlanmamış bir özellik uyarısı almadan dinamik özelliklere sahip nesne (javascript'teki gibi) oluşturmak istiyorsanız, özelliğe bir değer ayarlamadığınızda

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

0

Aynı teknik PHP durumunda da uygulanabilir mi?

Hayır - javascript prototipleri / nesnelerin doğrudan bildirimini kullandığından - PHP'de (ve diğer birçok OO dilinde) bir nesne sadece bir sınıftan oluşturulabilir.

Böylece soru - anonim bir sınıf oluşturabilir misiniz?

Yine cevap hayırdır - sınıfa başvurmadan nasıl somutlaştırırsınız?


Anonim bir sınıf örneği oluşturmak için bir ada ihtiyacınız yoktur. Java: Object var = new Object() { ... };- C ++:class { ... } var;
ta TheOperator

1
Artık PHP'de anonim sınıflar oluşturabilirsiniz.
Victor

0

Özyinelemeli bir nesne isteyenler için:

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

echo $o->foo->sub;

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.