Membuat objek anonim di php


141

Seperti yang kita ketahui, membuat objek anonim dalam JavaScript itu mudah, seperti kode di bawah ini:

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

alert(object.p1[1]);

Keluaran:

an alert is raised with value "johnny"

Bisakah teknik yang sama diterapkan dalam PHP? Bisakah kita membuat objek anonim di PHP?


1
Catatan: ini adalah pertanyaan lama, jadi jawaban yang diterima sudah kedaluwarsa. Fitur yang diminta sekarang telah ditambahkan ke PHP 7. Lihat jawaban di bawah ini oleh @ Rizier123.
Simba

@ Simba - Terima kasih telah menunjukkannya. Apakah Anda ingin memposting jawaban di StackOverflow di sini di halaman ini untuk membantu pengunjung masa depan?
Sujit Agarwal

1
Saya tidak perlu; sudah ada jawaban dengan info ini (lihat di bawah, oleh @ Rizier123).
Simba

Jawaban:


40

Sudah beberapa tahun, tapi saya pikir saya perlu menjaga informasi tetap terbaru!

Sejak PHP 7 memungkinkan untuk membuat kelas anonim, sehingga Anda dapat melakukan hal-hal seperti ini:

<?php

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

    var_dump($child instanceof Foo); // true

?>

Anda dapat membaca lebih lanjut tentang ini di manual

Tapi saya tidak tahu seberapa mirip itu diterapkan ke JavaScript, jadi mungkin ada beberapa perbedaan antara kelas anonim dalam JavaScript dan PHP.


@risyasin Terima kasih, memperbarui jawabannya dan memasukkan tautan manual ke dalamnya.
Rizier123

Menandai jawaban Anda sebagai benar untuk mengikuti perubahan terbaru di php7. Terima kasih @ Rizier123
Sujit Agarwal

3
Ini menarik tetapi tidak benar-benar menjawab pertanyaan, karena OP bertanya tentang cara yang nyaman untuk menginisialisasi objek dengan berbagai anggota tanpa membuat kelas. Saya tidak yakin apakah kelas anonim di php dapat digunakan untuk melakukan itu, dan jika bisa, Anda tidak menjelaskan caranya.
amh15

228

"Anonim" bukanlah terminologi yang benar ketika berbicara tentang objek. Akan lebih baik untuk mengatakan "objek tipe anonim ", tetapi ini tidak berlaku untuk PHP.

Semua objek di PHP memiliki kelas. Kelas "default" adalah stdClass, dan Anda dapat membuat objek dengan cara ini:

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

Anda juga dapat memanfaatkan casting array ke objek untuk sintaksis yang lebih nyaman:

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

Namun, maklum bahwa casting array ke objek cenderung menghasilkan hasil "menarik" untuk kunci array yang bukan nama variabel PHP yang valid - misalnya, inilah jawaban saya yang menunjukkan apa yang terjadi ketika kunci dimulai dengan angka.


1
bisakah saya mendorong beberapa array bernilai juga?
Sujit Agarwal

2
@CodingFreak: Anda bisa, tetapi : jika array berisi sub-array dan Anda menginginkannya sebagai objek juga, Anda harus melemparkan setiap orang untuk objek secara eksplisit.
Jon

21

Ya itu mungkin! Menggunakan kelas Objek PHP Anonim sederhana ini . Bagaimana itu bekerja:

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

Tentu saja objek ini adalah turunan dari AnObjkelas, sehingga tidak benar-benar anonim, tetapi memungkinkan untuk mendefinisikan metode dengan cepat, seperti JavaScript lakukan.


Anda dapat menggunakan create_function untuk meniru fungsi anonim.
Mihailoff

Saya pikir dia hanya ingin cara yang rapi untuk menginisialisasi objek stdClass dengan beberapa nilai. Bisakah Anda melakukannya dengan pendekatan Anda?
amh15

18

Sampai baru-baru ini adalah bagaimana saya membuat objek dengan cepat.

$someObj = json_decode("{}");

Kemudian:

$someObj->someProperty = someValue;

Tapi sekarang saya pergi dengan:

$someObj = (object)[];

Maka seperti sebelumnya:

$someObj->someProperty = someValue;

Tentu saja jika Anda sudah tahu properti dan nilai-nilai Anda dapat mengaturnya seperti yang telah disebutkan:

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

NB: Saya tidak tahu versi PHP mana ini bekerja sehingga Anda harus memperhatikan hal itu. Tapi saya pikir pendekatan pertama (yang juga singkat jika tidak ada properti untuk ditetapkan pada konstruksi) harus bekerja untuk semua versi yang memiliki json_encode / json_decode


1
Bagaimana itu berbeda dengan $ someObj = new \ stdClass ()?
JamesNZ

9

Konversi array ke objek (tapi ini tidak rekursif ke sub-anak):

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

7

Jika Anda ingin meniru JavaScript, Anda bisa membuat kelas Object, dan dengan demikian mendapatkan perilaku yang sama. Tentu saja ini bukan lagi anonim, tetapi akan berhasil.

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

Itu akan menampilkan elemen 2 . Ini dicuri dari komentar di PHP: Kelas dan Objek .


3

Dukungan untuk kelas anonim telah tersedia sejak PHP 7.0, dan merupakan analog terdekat dengan contoh JavaScript yang disediakan dalam pertanyaan.

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

echo $object->p1[1];

Deklarasi visibilitas pada properti tidak dapat dihilangkan (saya hanya menggunakan varkarena lebih pendek dari public).

Seperti JavaScript, Anda juga dapat menentukan metode untuk kelas:

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

echo $object->foo();

1

Dari dokumentasi PHP, beberapa contoh lagi:

<?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 dan $ obj3 adalah tipe yang sama, tetapi $ obj1! == $ obj3. Selain itu, ketiganya akan json_encode () ke objek JS sederhana {}:

<?php

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

?>

Output:

[{},{},{}]

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


0

Jika Anda ingin membuat objek (seperti dalam javascript) dengan properti dinamis, tanpa menerima peringatan properti tidak terdefinisi, saat Anda belum menetapkan nilai ke properti

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

Bisakah teknik yang sama diterapkan untuk PHP?

Tidak - karena javascript menggunakan prototipe / pernyataan langsung objek - dalam PHP (dan banyak bahasa OO lainnya) objek hanya dapat dibuat dari kelas.

Jadi pertanyaannya menjadi - dapatkah Anda membuat kelas anonim.

Sekali lagi jawabannya adalah tidak - bagaimana Anda akan membuat instance kelas tanpa bisa referensi itu?


Anda tidak perlu nama untuk membuat turunan kelas anonim. Java: Object var = new Object() { ... };- C ++:class { ... } var;
TheOperator

1
Anda dapat membuat kelas anonim di PHP sekarang.
Victor

0

Untuk orang yang menginginkan objek rekursif:

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

echo $o->foo->sub;

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.