文字列に基づいて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;
単純です。$ obj-> {$ obj-> Name}中かっこは、変数変数のようにプロパティをラップします。
これは上位の検索でした。しかし、これは$ thisを使用していた私の質問を解決しませんでした。中括弧を使用する私の状況の場合にも役立ちました...
Code Igniterのインスタンスを取得する例
親クラスのインスタンスを持つ何かと呼ばれるソースライブラリクラス内
$this->someClass='something';
$this->someID=34;
親インスタンスを含む別のクラスからのソースを必要とするライブラリクラス
echo $this->CI->{$this->someClass}->{$this->someID};
他の誰かが未知の深さの深いプロパティを見つけたい場合、私はすべての子供たちのすべての既知のプロパティをループする必要なしに以下を思いつきました。
たとえば、$ 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に移動して、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";
?>
この関数が行うことは、子のこのクラスにプロパティが存在するかどうかをチェックし、存在する場合は値を取得し、それ以外の場合はnullを返します。したがって、プロパティはオプションで動的になります。
/**
* 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);
なぜ編集するか:before:eval(evil)を使うafter:evalをまったく使わない。この言語で古いこと。