What's wrong with this line of code in light of the server recently updating its version of PHP?

Bruce Gust
Bruce Gust used Ask the Experts™
on
I'm working with a client who's experiencing a great deal of angst because of some functions on her page suddenly not working because of, what I believe to be, an update to the PHP version her sight is using.

I've already repaired a scenario where the site was using mysql as opposed to mysqli, but I'm looking at something now that I'm not familiar with and i'm hoping someone can give me some insight knowing that the server has recently been updated.

Here's the code that's throwing the error:

for ($k=1;$k<=50;$k++)
    {
      global $$SitelokCustom[$k];
      $cu[$k]=$$SitelokCustom[$k];
    }  

...and here's the error:

Parse error: syntax error, unexpected '[', expecting ',' or ';' in /home1/nomasint/public_html/_vibralogix/vibralinklokipn/linklokipn.php on line 3318

I've never seen two $ signs before, but apparently that was working at one point. I started by eliminating that, but it didn't have any affect.

Any ideas?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
David FavorFractional CTO
Distinguished Expert 2018

Commented:
PHP is to complex to guess about compatibility problems.

Use https://github.com/PHPCompatibility/PHPCompatibility to know, rather than guess.

The phpcs command finds compatibility issues.

The phpcbf command auto fixes many compatibility issues.
David FavorFractional CTO
Distinguished Expert 2018

Commented:
The double $$ does look odd + no way to guess with such a small fragment of code.

If all the code worked prior to an update + fails after an update phpcs will likely help.

And... could be you were running a very old PHP, so this code may have never worked correctly + newer versions of PHP simply raise an exception for code that never worked.

Commented:
The double $ is technically fine. Basically, it is a variable variable. PHP evaluates the inner variable first and uses the result as the outer variable name. For example:

$apple_color = "red";
$grape_color = "green";

$dynamic_color = "apple_color";
echo $$dynamic_color; // "red"

$dynamic_color = "grape_color";
echo $$dynamic_color; // "green"

Usually $$ is a pretty bad idea. It opens up code to more security risks, especially if a user can manipulate the inner variable contents.

Chances are that in your case, there is some other problem and the output of that error or warning is getting into your inner variable ($SitelokCustom) and when it tries to evaluate the outer variable, it's not a valid variable.

You can echo the inner variable to see if the contents have something unexpected. Either way, I would suggest rewriting that bit of code to NOT use the $$ functionality.
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

Dave BaldwinFixer of Problems
Most Valuable Expert 2014

Commented:
At first I thought that 'global' was an error but apparently not.
http://php.net/manual/en/language.variables.scope.php

Apparently $$ is used to create variable variable names.
http://php.net/manual/en/language.variables.variable.php
Commented:
So I just noticed your code is globaling an element in an array or a character in a string:

global $$variable[$index];

I just validated that specific situation will not work in 7.x, but it "works" in 5.2.

If I have this code:

$a = "Hello";
$b = "World";
test();

function test()
{
  $index = 1;
  $string = "abc";
  global $$string[$index];
  echo $$string[$index];
}

... then I get "World" as the output. The way PHP 5 is interpreting this is that it evaluates $string[$index] first, so $string[1] would be the 2nd character in the string, which would be "b". Then it takes that result and does:

  global $b;
  echo $b;

...giving you the output of "World"

However, this is REALLY hacky, almost like output from a poorly-written code obfuscator or something.

If you wanted to tweak that bit of code to work AND assuming that the variable is a string, then you could do:

    for ($k=1;$k<=50;$k++)
    {
     $varname = $SitelokCustom[$k];
      global $$varname;
      $cu[$k]=$$varname;

    }  

It would work in both PHP 5 and PHP 7 and give the same output. But again, that assumes that $SitelokCustom is a string of 50 characters, where each character represents a variable.
Bruce GustPHP Developer

Author

Commented:
Gentlemen!

Thank you very much!

To answer your questions / concerns, this is antiquated code belonging to a client that has needed to put some things off, as far as updating her site, because of financial and logistical concerns. Recently, however, her site failed to function at some key points leaving customers hanging and she's now having to scramble.

Whether she's running PHP 5 or 4, I'm not certain. But it's old and, as noted, there are some questionable techniques being used that make a bad situation worse.

Gonzo, I used your bandaid and it worked. I'm downloading the rest of the code now to see where there are other "mysql" as opposed to my "mysqli" dynamics to see if we can't get this thing up and running. That's what I had been working with before, but "$$" was something new and I do appreciate the help!
David FavorFractional CTO
Distinguished Expert 2018

Commented:
You mentioned, "Whether she's running PHP 5 or 4, I'm not certain."

This is why phpcs is so useful.

No guessing. You can target specific versions like... having phpcs tell you...

Show me every line of code, in all my .php + .lib + .inc + .config + .html, which will fail on PHP-7.2 or PHP-7.3 or above.

Using phpcs will save you a massive amount of time.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial