0

This may not be possible, but it would be good to know either way.

I'm looking to use a method to run a process that's repeated in a custom class I wrote.

One of the function parameters, Target, needs to refer to an object key in $values, so in the snippet below, it relates to $value->Target.

public function format_array($post_id, $object, $values, Target, $meta_value) {
    $array = (array) $object;
    $feed_values = array();

    if ( !empty($array) ) {
        foreach ( $values as $value ) {
            $feed_values[] = $value->Target;
        }
    }

    unset($array);

    $db_values = get_post_meta( $post_id, $meta_value, true );

    $result = array_diff($feed_values, $db_values);

    if ( !empty($result) ) {
        $this->update_post_meta( $post_id, $meta_value, $feed_values );
    }
}

I know this code is currently broken...

Can this be done?

EDIT

Referring to $value->Target, where $value is the object example below, I'm trying to access 'Comment', so $value->comment:

object(stdClass)#411 (33) {
  ["Facilities"]=>
  object(stdClass)#413 (1) {
    ["FacilityInfo"]=>
    array(6) {
      [0]=>
      object(stdClass)#414 (4) {
        ["ID"]=>
        string(21) "xxxxx"
        ["PropertyID"]=>
        string(21) "xxxxx"
        ["Name"]=>
        string(5) "xxxxx"
        ["Comment"]=>
        string(9) "xxxxx"
      }
      [1]=>
      object(stdClass)#415 (4) {
        ["ID"]=>
        string(21) "xxxxx"
        ["PropertyID"]=>
        string(21) "xxxxx"
        ["Name"]=>
        string(15) "xxxxx"
        ["Comment"]=>
        string(20) "xxxxx"
      }
    }
  }
  ["Photos"]=>
  object(stdClass)#420 (1) {
    ["PhotoInfo"]=>
    array(5) {
      [0]=>
      object(stdClass)#421 (6) {
        ["ID"]=>
        string(21) "xxxxx"
        ["PropertyID"]=>
        string(21) "xxxxx"
        ["MainPhoto"]=>
        bool(true)
        ["Name"]=>
        string(8) "xxxxx"
        ["Type"]=>
        string(5) "Photo"
        ["PhotoUrl"]=>
        string(94) "xxxxxx"
      }
      [1]=>
      object(stdClass)#422 (6) {
        ["ID"]=>
        string(21) "xxxxx"
        ["PropertyID"]=>
        string(21) "xxxxx"
        ["MainPhoto"]=>
        bool(false)
        ["Name"]=>
        string(2) "xxxxx"
        ["Type"]=>
        string(5) "Photo"
        ["PhotoUrl"]=>
        string(94) "xxxxxxx"
      }
    }
  }
}

Example of how my working method currently looks, but I'd like to prevent having to reuse this for 3 different values:

$array = (array) $letmc->Facilities;
$comments = array();

if ( !empty($array) ) {
    foreach ( $letmc->Facilities->FacilityInfo as $Facility ) {
        $comments[] = $Facility->Comment;
    }
}

unset($array);

$property_comments = get_post_meta( $post_id, 'property_comments', true );

$result = array_diff($comments, $property_comments);

if ( !empty($result) ) {
    $this->update_post_meta( $post_id, 'property_comments', $comments );
}

$array = (array) $letmc->Photos;
$photos = array();

if ( !empty($array) ) {
    foreach ( $letmc->Photos->PhotoInfo as $Photo ) {
        $photos[] = $Photo->PhotoUrl;
    }
}

unset($array);

$property_photos = get_post_meta( $post_id, 'property_photos', true );

$result = array_diff($photos, $property_photos);

if ( !empty($result) ) {
    $this->update_post_meta( $post_id, 'property_photos', $photos );
}
Sam Holguin
  • 553
  • 2
  • 9
  • 24
  • The object's `Target` property has to have `public` access to enable you access it from outside its class definition. A better alternative will be to create an accessor public method to get that value, so, you'd have something like: `$value->getTarget()`; – NaijaProgrammer Apr 17 '15 at 15:55
  • You can use the `__get()` magic method to retrieve variable class members: http://stackoverflow.com/questions/4713680/php-get-and-set-magic-methods – CD001 Apr 17 '15 at 15:57
  • @NaijaProgrammer Can either of you flesh out your answers and I'll mark correct...I don't fully understand how to approach either solution – Sam Holguin Apr 17 '15 at 16:01
  • Maybe I haven't understood the question but why not pass the object? This would be done be reference and would not be a copy. – DanielM Apr 17 '15 at 16:05

3 Answers3

2

Not entirely sure what your question is, but... like so?

function foo($obj, $property) {
    echo $obj->$property;
}

$bar = new stdClass;
$bar->baz = 42;

foo($bar, 'baz');

See variable variables in PHP.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • Up voted as @deceze got there before me, and is correct. – DanielM Apr 17 '15 at 16:59
  • @SamHolguin if this isn't working (it should be) you could try putting curly braces around the property name when it's called in function foo() ... it **shouldn't** be necessary but it ensures that `$property` is evaluated before it's called : i.e. `echo $obj->{$property};` – CD001 Apr 20 '15 at 09:42
0

AS CD001, suggested, you could use the magic method __get(). For instance, in one of the classes whose properties you are trying to access, you'd do this:

class Foo
{
   protected $prop; //property you wish to access outside of the class

   //magic method
   public function __get($val)
   {
      return isset($this->$val) ? $this->$val : '';
   }
}
NaijaProgrammer
  • 2,892
  • 2
  • 24
  • 33
  • This won't work, `_get` takes a parameter. Why not just make an actual get method – DanielM Apr 17 '15 at 16:11
  • Can you expand on this @DanielM?? – Sam Holguin Apr 17 '15 at 16:17
  • 1
    http://php.net/manual/en/language.oop5.overloading.php#object.get The magic method is triggered by you going something like `$value = $object->propertyThatIsNotInScope`, that property is passed to the `_get` magic method. Your code will fire for every single attempt to access any property that is not accessible. Ironical, the only one it won't fire for is when you try to get $prop as you didn't specify visability so it's `public` – DanielM Apr 17 '15 at 16:40
  • @DanielM I've updated my answer, as per your comment. Nice one.Plus one to your comment – NaijaProgrammer Apr 17 '15 at 16:44
  • Sorry I was wrong, not specifying visability on properties is a fatal error. As is not specifying the parameter in $_get. After I fixed those, and added a bit of fluff to show what's happening, I came up with this. http://sandbox.onlinephpfunctions.com/code/47917d19446e7eca14d850205cdd12fbaf2f4ef1 – DanielM Apr 17 '15 at 16:45
  • You need to add $ in front of `val` before you use it to access the property, like this: http://sandbox.onlinephpfunctions.com/code/142694ee710d1acf0634ee464c40bf57f2ceaa87 I'd have updated your answer but it's only two characters. – DanielM Apr 17 '15 at 16:47
  • Inexperience shining through here....still don't fully understand how to work this into my class... I'll add an object example onto the bottom of my question – Sam Holguin Apr 17 '15 at 16:52
0

Updated question makes this nice and clear :)

public function format_array($post_id, $object, $values, $target, $meta_value) {

    ...

    if ( !empty($array) ) {
        foreach ( $values as $value ) {
            $feed_values[] = $value->$target;
        }
    }

    ...
}

You may wish to check the $target exists first though:

public function format_array($post_id, $object, $values, $target, $meta_value) {

    ...

    if ( !empty($array) ) {
        foreach ( $values as $value ) {
            if(property_exists($value, $target) {
                $feed_values[] = $value->$target;
            }
        }
    }

    ...
}

Potential edit:

I think maybe we're looking at the wrong thing, if you want the obejct at the entry for FacilityInfo then you need to do it like this (no loops).

if ( !empty($array) ) {
    $feed_values[] = $values->$target;
}

or to check first:

if ( !empty($array) && property_exists($values , $target)) {
    $feed_values[] = $values->$target;
}
DanielM
  • 6,380
  • 2
  • 38
  • 57
  • But then to call the function I'd have to use: format_array($post_id, $letmc->Facilities, $letmc->Facilities->FacilityInfo, 'Comment', 'property_comments'); which spits out an error? Sorry not sure how to format code in the comments section – Sam Holguin Apr 17 '15 at 16:58
  • I've added how my working code looks, the code I'd like to create a function for :) – Sam Holguin Apr 17 '15 at 17:01
  • For this example: Undefined property: stdClass::$FacilityInfo – Sam Holguin Apr 17 '15 at 17:06
  • `FacilityInfo` doesn't exist in the object dump you put up there. Try 'Comment'? – DanielM Apr 17 '15 at 17:10
  • lost me...pretty sure it exists :) Lets leave it, I'll have to stick with repeating the code and forgetting the function. Maybe it's not possible :) Thank you – Sam Holguin Apr 17 '15 at 17:11
  • Wait, do you want the object at `FacilityInfo` or do you want the value of `Comment` in the `FacilityInfo` object it? – DanielM Apr 17 '15 at 17:13
  • Value of 'Comment' in that example, and I've just posted another example above where I need 'PhotoURL'. I've also posted the full object...I'm pulling it from a SOAP feed. I should of provided everything from day 1, sorry – Sam Holguin Apr 17 '15 at 17:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/75534/discussion-between-danielm-and-sam-holguin). – DanielM Apr 17 '15 at 17:18