1

I am using PHP7.

I have an Object I am trying to parse:

$RECORD = {
    'name' => 'Stephen Brad Taylor', 
    'address' => '432 Cranberry Hills, Pittsburg',
    'phone' => '708 865 456', 
    'Account' => (Object Vendor/Entity/User) {
         'email' => 'INeedThisEmail@pleaseHelp.com' // I want to access this property.
         'id' => 34,
         'accessible' => ['email', 'id]
    } 
}

I have an array which I am using to select certain fields from RECORD:

$fieldnames = [
     'name',
     'address',
     'phone',
     'Account["email"]'
];

I am trying to parse the fieldnames from RECORD as follows:

$data[] 
foreach($fieldnames as $k => $fieldname) {
    $data[k] = $RECORD->$fieldname
}

The method above works for the first-level attributes: name, address, and phone. However, email returns null.

I have tried the following below and none have worked:

$data[k] = RECORD->${$fieldname}

$propertyName = '$RECORD->$fieldname' 
$data[k] = ${$propertyName}

Does anyone know a way to access an object's properties using a string from an object reference?

Much gratitude <3

Paul Trimor
  • 320
  • 3
  • 15
  • Is the nested level only 2 levels deep? How does more than 2 look like? – nice_dev Aug 26 '19 at 13:50
  • is the account itself not an object? what happens with print_r($RECORDS->Account); – MHewison Aug 26 '19 at 13:51
  • Sorry if I'm mistaken, but it seems like you're trying to convert it to an array? IF so, try: `$array = json_decode(json_encode($RECORD), true);` – Brett Gregson Aug 26 '19 at 13:53
  • 1
    If you're using CakePHP and your objects implement `ArrayAccess` (which entities do by default), then don't reinvent the wheel, try [**`\Cake\Utility\Hash`**](https://book.cakephp.org/3.0/en/core-libraries/hash.html) and its path syntax. – ndm Aug 26 '19 at 14:05

2 Answers2

2

You can't use Account["email"] directly as a property accessor, it won't be split up to find the nested property. You need to parse it yourself.

foreach($fieldnames as $k => $fieldname) {
    if (preg_match('/^(.*)\["(.*)"\]$/', $fieldname, $match) {
        $data[$k] = $RECORD->{$match[1]}->{$match[2]};
    } else {
        $data[$k] = $RECORD->$fieldname;
    }
}

Also, you need $ in $k.

This code only works for 1 level deep. If you need to deal with arbitrary levels, you'll have to write a recursive procedure. See How to access and manipulate multi-dimensional array by key names / path? for examples of how to code this.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

I use anonymous functions for such cases. (PHP 7.4)

    $index = fn($item) => $item->dotaItem->prop_def_index;
    if (get_class($collection) === Collection::class) {
        $index = fn($item) => $item->prop_def_index;
    }
EXayer
  • 145
  • 1
  • 9