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!

2
  • 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. Commented May 12, 2013 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. Commented May 13, 2013 at 0:12

1 Answer 1

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');
Sign up to request clarification or add additional context in comments.

5 Comments

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
aah.. agree .. for some reason I only read as "only function name" and no mention of class variable..
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. 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?
Oh, also, in the name of best practices, is it considered good PHP best practice to always put {} around your variable names?
"->" 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..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.