PHPオブジェクトのプロパティ名を動的に書き込むにはどうすればよいですか?


83

コードには、次のようなオブジェクトプロパティがあります。

$obj ->field_name_cars[0];
$obj ->field_name_clothes[0];

問題は、何百ものフィールド名があり、プロパティ名を動的に書き込む必要があることです。それ以外の場合、オブジェクト名とプロパティのキーは常に同じになります。だから私は試しました:

$obj -> $field[0];

プロパティの名前が動的に変更され、正しい値にアクセスすることを期待しています。しかし、私はstdClass :: $ fieldで '未定義のプロパティ$ fieldを取得し続けます。

多かれ少なかれ、適切な値を出力できるように、実行する前にphpを動的に書き込もうとしています。これにアプローチする方法についての考え?

回答:


210

PHP7.0のアップデート

PHP 7では、パーサーレベルでの間接変数とプロパティの処理方法に変更が加えられました(詳細については、対応するRFCを参照してください)。これにより、実際の動作が期待に近づき、この場合$obj->$field[0]、期待される結果が得られることを意味します。

(現在改善されている)デフォルトの動作が望ましくない場合でも、以下に示すように、中括弧を使用してオーバーライドできます。

元の回答

次のようにアクセスを記述します。

$obj->{$field}[0]

この「中括弧で囲む」トリックは、変数変数によるあいまいさが存在する場合はいつでもPHPで役立ちます。

最初のコードを考えてみましょう。$obj->$field[0]これは、「名前が指定されているプロパティにアクセスする$field[0]」、または「0名前が指定されているプロパティのキーを使用して要素にアクセスする」という意味$fieldですか?中括弧を使用すると、明示的にすることができます。


この生のステートメントは私のコードで機能します:echo $ json_dump-> ometry [6]-> obs [2]-> hayabusa2-> delay_from; しかし、「geometry [6]-> obs [2]-> hayabusa2-> delay_from」を$ pathに割り当て、echo $ json_dump-> {$ path}を使用して「シミュレート」することはできません。「未定義のプロパティ:stdClass: :$
ometry

31

他の配列/オブジェクトから値にアクセスするときに、次のような中括弧構文を使用して最もよく達成される変数-変数型表記を探していると思います。

$obj->{field[0]}

12

魔法の方法__getはあなたの友達です:

class MyClass
{
   private $field = array();

   public function __get($name)
   {
      if(isset($this->field[$name]))
        return $this->field[$name];
      else
        throw new Exception("$name dow not exists");
   }
}

使用法:

$myobj = new MyClass();
echo $myobj->myprop;

説明:すべてのフィールド・データは配列に保管されています。アクセスすると$myobj->myprop、そのプロパティは明らかにクラスに存在しません。それが__get呼ばれるところです。配列__get内の名前を検索し、field正しい値を返します。


4
これをしないでください。__get関数は、予期しない動作でいくつかの深刻な問題を引き起こすことに加えて、可能な場合は使用を避けるべきパフォーマンスの低下です。この例は、開発者が存在しない属性にアクセスして例外をスローすることを計画していない場合に深刻なアプリ破壊動作を引き起こす可能性がある例外をスローし、単純な属性アクセスを潜在的な致命的なエラーに変えるため、特に怖いです。
moberemk 2015

1

今日、私はその課題に直面しています。私はそのスタイルの開発に行き着きました

$countTickets = new \stdClass;

foreach ($tickets as $key => $value) {

    if(!isset($countTickets->total)){
        $countTickets->total = 0;
    }

    if(!isset($countTickets->{$value['categoryname']})){
        $countTickets->{$value['categoryname']} = 0;
    }

    $countTickets->total += $value['number'];
    $countTickets->{$value['categoryname']} += $value['number']; 
}

0

動的に作成されたオブジェクトプロパティを使用するいくつかのコードに取り組みました。動的に作成されたオブジェクトプロパティを使用するのはかなりクールだと思いました(私の意見では本当です)。しかし、私のプログラムは実行に7秒かかりました。動的オブジェクトプロパティを削除し、各クラス(この場合はパブリック)の一部として宣言されているオブジェクトプロパティに置き換えました。CPU時間は7秒以上から0.177秒になりました。それはかなり重要です。

動的オブジェクトプロパティを使用していた方法で何か間違ったことをしていた可能性があります。私の設定が何らかの形で壊れている可能性もあります。もちろん、私は自分のマシンに非常に単純なバニラPHP構成を持っていると言わなければなりません。


この逸話は、コードの小さな断片を表示することで改善できます。あなたのコードはここでの答えの1つに基づいていましたか?他の場所の情報によってあなたはリンクを与えることができますか?必要なのはワンライナーだけかもしれません。オブジェクトプロパティを動的に作成する例。そして後でそのプロパティを参照します。また、平均して、各プロパティを何回使用(参照)しましたか?オブジェクトにいくつの動的プロパティを追加しましたか?6未満ですか?20以上?
ToolmakerSteve
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.