Bagaimana cara mendapatkan properti di PHP berdasarkan string? Saya akan menyebutnya magic
. Jadi apa magic
?
$obj->Name = 'something';
$get = $obj->Name;
akan menjadi...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Bagaimana cara mendapatkan properti di PHP berdasarkan string? Saya akan menyebutnya magic
. Jadi apa magic
?
$obj->Name = 'something';
$get = $obj->Name;
akan menjadi...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Jawaban:
Seperti ini
<?php
$prop = 'Name';
echo $obj->$prop;
Atau, jika Anda memiliki kendali atas kelas, terapkan antarmuka ArrayAccess dan lakukan saja ini
echo $obj['Name'];
ArrayAccess
,, Countable
dan salah satu antarmuka iterator, itu sebagian besar tidak dapat dibedakan dari normalarray()
Jika Anda ingin mengakses properti tanpa membuat variabel perantara, gunakan {}
notasi:
$something = $object->{'something'};
Itu juga memungkinkan Anda untuk membangun nama properti dalam satu lingkaran misalnya:
for ($i = 0; $i < 5; $i++) {
$something = $object->{'something' . $i};
// ...
}
$this->{$property}[$name]
, jika tidak $this->$property[$name]
akan menimbulkan kesalahan
$this->$property[$name]
mungkin benar-benar berhasil, meskipun ini kemungkinan merupakan bug. $name
diam-diam dilemparkan ke bilangan bulat. Dalam kasus string non-numerik ini 0
. Kemudian indeks string dari nilai $property
ini digunakan sebagai nama properti. Jika $property
memegang nilai "abc", maka ini akan merujuk ke properti $this->a
(indeks 0). Jika ada properti seperti itu maka ini akan berhasil.
Apa yang Anda tanyakan disebut Variabel Variabel . Yang perlu Anda lakukan adalah menyimpan string Anda dalam variabel dan mengaksesnya seperti ini:
$Class = 'MyCustomClass';
$Property = 'Name';
$List = array('Name');
$Object = new $Class();
// All of these will echo the same property
echo $Object->$Property; // Evaluates to $Object->Name
echo $Object->{$List[0]}; // Use if your variable is in an array
Sesuatu seperti ini? Belum mengujinya tetapi harus bekerja dengan baik.
function magic($obj, $var, $value = NULL)
{
if($value == NULL)
{
return $obj->$var;
}
else
{
$obj->$var = $value;
}
}
Cukup simpan nama properti dalam variabel, dan gunakan variabel untuk mengakses properti. Seperti ini:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
Mungkin ada jawaban untuk pertanyaan ini, tetapi Anda mungkin ingin melihat migrasi ini ke PHP 7
sumber: php.net
Sederhana, $ obj -> {$ obj-> Name} kurung keriting akan membungkus properti seperti variabel variabel.
Ini adalah pencarian teratas. Tetapi tidak menyelesaikan pertanyaan saya, yang menggunakan $ this. Dalam hal keadaan saya menggunakan braket keriting juga membantu ...
contoh dengan Code Igniter get instance
di kelas pustaka sumber yang disebut sesuatu dengan instance kelas induk
$this->someClass='something';
$this->someID=34;
kelas perpustakaan yang perlu sumber dari kelas lain juga dengan contoh orang tua
echo $this->CI->{$this->someClass}->{$this->someID};
Sama seperti tambahan: Dengan cara ini Anda dapat mengakses properti dengan nama yang tidak dapat digunakan
$ x = StdClass baru;$ prop = 'a b'; $ x -> $ prop = 1; $ x -> {'x y'} = 2; var_dump ($ x);
object (stdClass) # 1 (2) { ["a b"] => int (1) ["x y"] => int (2) }(bukan bahwa Anda harus, tetapi jika Anda harus).
Seandainya ada orang lain yang ingin menemukan properti yang dalam dari kedalaman yang tidak diketahui, saya datang dengan yang di bawah ini tanpa perlu mengulang semua properti yang diketahui dari semua anak.
Misalnya, untuk menemukan $ Foo-> Bar-> baz, atau $ Foo-> baz, atau $ Foo-> Bar-> Baz-> dave, di mana $ path adalah string seperti 'foo / bar / baz'.
public function callModule($pathString, $delimiter = '/'){
//split the string into an array
$pathArray = explode($delimiter, $pathString);
//get the first and last of the array
$module = array_shift($pathArray);
$property = array_pop($pathArray);
//if the array is now empty, we can access simply without a loop
if(count($pathArray) == 0){
return $this->{$module}->{$property};
}
//we need to go deeper
//$tmp = $this->Foo
$tmp = $this->{$module};
foreach($pathArray as $deeper){
//re-assign $tmp to be the next level of the object
// $tmp = $Foo->Bar --- then $tmp = $Bar->baz
$tmp = $tmp->{$deeper};
}
//now we are at the level we need to be and can access the property
return $tmp->{$property};
}
Dan kemudian panggil dengan sesuatu seperti:
$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
Ini usahaku. Ini memiliki beberapa pemeriksaan 'kebodohan' yang umum, memastikan Anda tidak mencoba mengatur atau mendapatkan anggota yang tidak tersedia.
Anda dapat memindahkan cek 'property_exists' tersebut ke __set dan __get masing-masing dan memanggilnya langsung dalam magic ().
<?php
class Foo {
public $Name;
public function magic($member, $value = NULL) {
if ($value != NULL) {
if (!property_exists($this, $member)) {
trigger_error('Undefined property via magic(): ' .
$member, E_USER_ERROR);
return NULL;
}
$this->$member = $value;
} else {
if (!property_exists($this, $member)) {
trigger_error('Undefined property via magic(): ' .
$member, E_USER_ERROR);
return NULL;
}
return $this->$member;
}
}
};
$f = new Foo();
$f->magic("Name", "Something");
echo $f->magic("Name") , "\n";
// error
$f->magic("Fame", "Something");
echo $f->magic("Fame") , "\n";
?>
Apa fungsi ini adalah memeriksa apakah properti ada di kelas ini dari salah satu anaknya, dan jika demikian ia mendapat nilai sebaliknya mengembalikan nol. Jadi sekarang propertinya opsional dan dinamis.
/**
* check if property is defined on this class or any of it's childes and return it
*
* @param $property
*
* @return bool
*/
private function getIfExist($property)
{
$value = null;
$propertiesArray = get_object_vars($this);
if(array_has($propertiesArray, $property)){
$value = $propertiesArray[$property];
}
return $value;
}
Pemakaian:
const CONFIG_FILE_PATH_PROPERTY = 'configFilePath';
$configFilePath = $this->getIfExist(self::CONFIG_FILE_PATH_PROPERTY);
$classname = "myclass";
$obj = new $classname($params);
$variable_name = "my_member_variable";
$val = $obj->$variable_name; //do care about the level(private,public,protected)
$func_name = "myFunction";
$val = $obj->$func_name($parameters);
why edit: before: using eval (evil) after: no eval at all. sudah tua dalam bahasa ini.