1

Good Day, I know this is kinda easy to some, but I cant understand how to access data with this kind of structure..

this was the result when I print_r($Invoice);

and I get to access them using $Invoice->getId() for example.. ( though I dont really understand why)

now I want to check if the property exist so I could do and if else statement.

I tried using if(property_exist($Invoice,'DocNumber')){ echo "exist"; } but it seems not working.

Please help me do this things. Thanks

  QuickBooks_IPP_Object_Invoice Object
    (
        [_data:protected] => Array
            (
                [Id] => Array
                    (
                        [0] => {-183}
                    )

                [SyncToken] => Array
                    (
                        [0] => 2
                    )

                [MetaData] => Array
                    (
                        [0] => QuickBooks_IPP_Object_MetaData Object
                            (
                                [_data:protected] => Array
                                    (
                                        [CreateTime] => Array
                                            (
                                                [0] => 2017-06-21T01:16:22-07:00
                                            )

                                        [LastUpdatedTime] => Array
                                            (
                                                [0] => 2017-06-26T15:42:53-07:00
                                            )

                                    )

                            )

                    )

                [DocNumber] => Array
                    (
                        [0] => 4107
                    )

                [TxnDate] => Array
                    (
                        [0] => 2017-07-01
                    )

                [CurrencyRef] => Array
                    (
                        [0] => {-USD}
                    )

                [CurrencyRef_name] => Array
                    (
                        [0] => United States Dollar
                    )



            )

    )
melvnberd
  • 3,093
  • 6
  • 32
  • 69

2 Answers2

1

If the properties are protected, as indicated by [_data:protected] then you won't be able to access them directly, by using $Invoice->Id for example. You will only be able to read them if the class has accessor methods defined.

$Invoice->getId() works because it is a call to such an accessor method which is returning the value of the $Id property.

If you don't have access to the source code of this class, or some API documentation for it, then a good IDE may be able to tell you what methods are available on it.

Update

Looking at the source code of the Object class, which is an ancestor of the Invoice class, it implements a catch-all __call method which will be run for any method call that doesn't match an existing method. __call checks if the name of the method starts with get or set. If so it will return or update values in the _data array respectively, e.g. getSyncToken() will return the value of _data['SyncToken']. This is why your calls such as $Invoice->getId() return values even though there is no getId() method on the class.

robjingram
  • 306
  • 1
  • 7
  • Thanks for your answer @robjingram so therefore its kinda impossible / hard check if a function does exist or not Sir? – melvnberd Jul 14 '17 at 04:25
  • 1
    Obviously I don't know where you're getting this data from but you're on the back foot if you don't have any documentation for the API of the classes you're dealing with. The source does seem to be on github, and includes some examples in the docs, so if you have no other documentation they you could poke around that: https://github.com/consolibyte/quickbooks-php/ (though I'm only guessing that that is the official version of the code) – robjingram Jul 14 '17 at 04:43
  • 1
    A quick look at the source shows that the `Object` class has a general `get($field)` method that you can pass the name of the field you want to read but also implements a missing method approach that should mean that you can prefix any property name with `get` to return the value, e.g. `$invoice->getDocNumber()`: https://github.com/consolibyte/quickbooks-php/blob/master/QuickBooks/IPP/Object.php#L135 – robjingram Jul 14 '17 at 05:00
  • @melvnberd I've updated my answer to reflect the findings in my comment above – robjingram Jul 14 '17 at 21:32
1
if(property_exist($Invoice,'DocNumber')){ echo "exist"; }

does not work since 'DocNumber' is not a property of class Invoice. However,

 if(property_exist('Invoice','_data')){ echo "exist"; } 

will work, since, _data is property of class Invoice.

It would have been different if _data wasn't protected.

You can however, make this work using reflection. Create a function:

function accessProtected($obj, $prop) {
  $reflection = new ReflectionClass($obj);
  $property = $reflection->getProperty($prop);
  $property->setAccessible(true);
  return $property->getValue($obj);
}

$instance = new Invoice();
$access_properties = accessProtected($instance, '_data');
if(array_key_exists('DocNumber', $access_properties)) {
   echo "exists";
}

Function accessProtected is referred from here

Shuchi Sethi
  • 683
  • 7
  • 13