0

I am fairly new to PHP and just had a learning experience that I am sharing here to help others who, like me, may need help to find the cause of this error and also because I still don't know what the solution is and am sure there is simply a syntax that I just haven't found yet to do what I need to do.

So, the problem can be demonstrated with something like this:

class Sample {
    protected $foo = array();
    public function magicSampleSetFunc($property, $key, $value) {
        $this->$property[$key] = $value;
    }
}
...
$s = new Sample();
$s->magicSampleSetFunc('foo', 'someKey', 'someVal');

Obviously, this isn't my real code (nor have I run it) this is just a minimal example to explain my situation. Here we have a member variable foo that is clearly an array and a generic function that is going to try to set a key and value into it. I can var_dump $this->$property and see that it is an array, but on the $this->$property[$key] line I get the error message: "Warning: Illegal string offset 'someKey' in ...".

At first I though it was saying that 'someKey' was an illegal string to use as an array offset, which didn't make sense. And, even if I wrap it in an isset it complains. The first thing I learned is that if you have a string in php, you can use the array access operator to get a character out of that string. So the warning message is actually complaining that 'someKey' is not a valid offset into a string (because it is not an integer offset). Okay, but I just var_dumped $this->$property and see that it is an array, so what gives? The second lesson was one of operator precedence. The array operator "[]" binds tighter than the indirection operator "->". So, the binding of that statement is actually something like: ( $this-> ( $property[$key] ) ). So, it is illegally trying to offset the string in $property by the index in $key. What I wanted was to offset the array in $this->$property by the index in $key.

So, now we come to my question. The third lesson I need to learn, and haven't figured out yet is how do I override this operator precedence issue? I tried ($this->$property)[$key] but that appears to be a sytax error. Is there some other syntax I can use to get the interpreter to understand what I meant to do? Or, do I have to assign $this->$property to a temporary variable first? If I do, wouldn't that mean that my actual member variable array is not updated? Do I need a temp reference or something? What's the right syntax for my situation here? Thanks!

Daniel Skarbek
  • 554
  • 4
  • 14
  • If it's not your real code, and you haven't run it, then how are you so certain it's representative of your issue? (Hint: it's not.) First post your real code and any error information, so we can give you a more specific answer. –  May 12 '13 at 23:21
  • Without seeing my real code, how do you know this is not representative of it? My real code is many, many files whatever I post must be a summary of the real thing, and there is always the danger that I have mis-summarized. I feel that this is an accurate summary of the code I am working with. I invite you to answer according to the issue in this code and if that isn't my actual issue because I have mis-summarized then that is on me. – Daniel Skarbek May 13 '13 at 00:12

1 Answers1

2

this is the way to do it: Your variable name is basically {$property} so when you do $this->$property[$key] I think PHP parser gets confused. I usually make sure that to explicitly state it to the parser that my variable name is $property which is done by using curly braces around variable.

Curly braces are used to explicitly specify the end of a variable name

class Sample {
    protected $foo = array();
    public function magicSampleSetFunc($property, $key, $value) {
        $this->{$property}[$key] = $value;
    }
}
...
$s = new Sample();
$s->magicSampleSetFunc('foo', 'someKey', 'someVal');
Dinesh
  • 3,065
  • 1
  • 18
  • 19
  • to clarify: the curly brackets are used for dynamically changing variable/function -names, in this case you want to output the contents of the $property variable in order to use it as the function name or class-variable name – xorinzor May 12 '13 at 23:44
  • aah.. agree .. for some reason I only read as "only function name" and no mention of class variable.. – Dinesh May 12 '13 at 23:46
  • This does indeed solve the issue. And, it kind-a makes sense to me. I'm clarifying that `$property[$key]` is not the variable that I want to get my member name from. The other part that I had missed is that "->" is not on the operator precedence list [here](http://php.net/manual/en/language.operators.precedence.php). When I saw "[]" near the very top I assumed it bound tighter than "->". So, does "->" actually bind tighter? Why isn't "->" listed on the operator precedence list -- isn't it considered an operator? – Daniel Skarbek May 13 '13 at 00:17
  • Oh, also, in the name of best practices, is it considered good PHP best practice to always put {} around your variable names? – Daniel Skarbek May 13 '13 at 00:18
  • 1
    "->" is called T_OBJECT_OPERATOR and since it has no meaning until we know object has been initialized I believe the precedence is left to right.. but I think the error is not because of precedence but of how php interprets a variable. else if someone can correct me.. – Dinesh May 13 '13 at 00:26