Як отримати властивість у PHP на основі рядка? Я зателефоную magic
. То що таке magic
?
$obj->Name = 'something';
$get = $obj->Name;
було б як ...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Як отримати властивість у PHP на основі рядка? Я зателефоную magic
. То що таке magic
?
$obj->Name = 'something';
$get = $obj->Name;
було б як ...
magic($obj, 'Name', 'something');
$get = magic($obj, 'Name');
Відповіді:
Подобається це
<?php
$prop = 'Name';
echo $obj->$prop;
Або якщо у вас є контроль над класом, реалізуйте інтерфейс ArrayAccess і просто зробіть це
echo $obj['Name'];
ArrayAccess
, Countable
і один з інтерфейсів ітератора, він в основному не відрізняється від нормальногоarray()
Якщо ви хочете отримати доступ до ресурсу без створення проміжної змінної, використовуйте {}
позначення:
$something = $object->{'something'};
Це також дозволяє побудувати ім'я властивості в циклі, наприклад:
for ($i = 0; $i < 5; $i++) {
$something = $object->{'something' . $i};
// ...
}
$this->{$property}[$name]
, інакше $this->$property[$name]
викинете помилку
$this->$property[$name]
насправді може досягти успіху, хоча це, ймовірно, помилка. $name
мовчки передається до цілого числа. У випадку нечислового рядка це так 0
. Тоді цей рядовий індекс значення $property
використовується як ім'я властивості. Якщо $property
має значення "abc", то це стосуватиметься властивості $this->a
(індекс 0). Якщо є таке майно, то це вдасться.
Те, про що ви запитуєте, називається Змінні змінні . Все, що вам потрібно зробити, це зберегти рядок у змінній та отримати доступ до неї так:
$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
Щось на зразок цього? Не перевіряв, але повинен працювати чудово.
function magic($obj, $var, $value = NULL)
{
if($value == NULL)
{
return $obj->$var;
}
else
{
$obj->$var = $value;
}
}
Просто збережіть ім'я властивості у змінній та використовуйте змінну для доступу до ресурсу. Подобається це:
$name = 'Name';
$obj->$name = 'something';
$get = $obj->$name;
На це питання можуть бути відповіді, але ви можете побачити ці міграції до PHP 7
джерело: php.net
$ Obj -> {$ obj-> Name} фігурні дужки обернуть властивість так само, як і змінна змінна.
Це був найкращий пошук. Але не вирішив мого питання, що використовував $ this. У випадку моєї обставини використання фігурної дужки також допомогло ...
Приклад з кодом Igniter отримати екземпляр
в джерелі бібліотечного класу, який називається щось із екземпляром батьківського класу
$this->someClass='something';
$this->someID=34;
клас бібліотеки, який потребує джерела з іншого класу також з екземпляром батьків
echo $this->CI->{$this->someClass}->{$this->someID};
Як додаток: таким чином ви можете отримати доступ до властивостей з іменами, які були б інакше непридатними
$ x = новий StdClass;$ prop = 'a b'; $ x -> $ prop = 1; $ x -> {'x y'} = 2; var_dump ($ x);
об'єкт (stdClass) №1 (2) { ["a b"] => int (1) ["x y"] => int (2) }(не те, що вам слід, але у випадку, якщо вам доведеться).
Якщо хтось хоче знайти глибоку властивість невідомої глибини, я придумав нижченаведене, не потребуючи переглядати всі відомі властивості всіх дітей.
Наприклад, щоб знайти $ Foo-> Bar-> baz, або $ Foo-> baz, або $ Foo-> Bar-> Baz-> dave, де $ path - рядок, як '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};
}
А потім дзвоніть з чимось на кшталт:
$propertyString = getXMLAttribute('string'); // '@Foo/Bar/baz'
$propertyString = substr($propertyString, 1);
$moduleCaller = new ModuleCaller();
echo $moduleCaller->callModule($propertyString);
Ось моя спроба. У ньому вбудовані загальні чеки "глупості", які не намагаються встановити або отримати члена, який недоступний.
Ви можете перемістити ці чеки 'property_exists' до __set та __get відповідно та викликати їх безпосередньо в магії ().
<?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";
?>
Ця функція полягає в тому, щоб він перевіряє, чи існує властивість цього класу будь-якої його дитини, і якщо так, то воно отримує значення, інакше воно повертається в нулеве значення. Тож тепер властивості необов’язкові та динамічні.
/**
* 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;
}
Використання:
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);
чому редагувати: раніше: використання eval (зле) після: no eval зовсім. будучи старовинною цією мовою.