0

My code is as follows. In my understanding from diverse websites and the php documentation, empty() is a language construct that checks whether the key exists, just like isset() (only that it also does a loose 'false'-comparison in case the Variable or Key exists...

37     $origin = 
38                !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] :
39                !empty($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] :
40                !empty($_SERVER['ORIGIN']) ? $_SERVER['ORIGIN'] :
41                "Unknown Origin";

Error:

Undefined index: ORIGIN in somePHPFile.php:40

Update: I fixed it by wrapping the else-parts in parentheses. When i have discovered the exact problem (associativity or else...) i will update this answer again.

        $origin = 
            (!empty($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] :
            ((!empty($_SERVER['HTTP_ORIGIN'])) ? $_SERVER['HTTP_ORIGIN'] :
            (!empty($_SERVER['ORIGIN']) ? $_SERVER['ORIGIN'] :
            "Unbekannte Herkunft"));
5
  • 2
    Using nested ternary operations like that should be illegal. It's hard to read and debug. Commented Jan 30, 2018 at 14:48
  • 1
    Add some parenthesis to your ternaries so it's processed properly. When you don't use parenthesis, things get weird. Commented Jan 30, 2018 at 14:49
  • 1
    Interesting. What php version is this? Please provide a minimal but working code example for us to test this. Thanks. Commented Jan 30, 2018 at 14:52
  • I will try to provide a working minimal example, as well as the php version by thursday - if the real cause (might be the associativity) is not found, earlier. Commented Jan 30, 2018 at 15:07
  • 1
    Just a heads up. Right now, that might look good to you, but when you go back in a few weeks/months or even years, and need to read/update that code (or worse, someone else needs to do it), you're gonna regret it. Lines in a file are cheap. You should try to make the code more readable. Plus, if you did that, this would probably not have been an issue to start with. Commented Jan 30, 2018 at 15:10

1 Answer 1

4

The reason for this error is associativity of ternary operator in PHP - it's left-to-right, while in most other languages it's right-to-left. That's why nested ternaries are very cumbersome both to read and to write in PHP. )

In this particular case it means, in particular, the following: if HTTP_REFERER header is set, the value of $_SERVER['HTTP_ORIGIN'] will be checked as well.

To solve this, you need to either wrap the conditions in parenthesis, use plain old if-elseif-else combination, or (makes most sense to me) do some abstraction over your code:

$origin = 'Unknown Origin';
$headersToCheck = ['HTTP_REFERER', 'HTTP_ORIGIN', 'ORIGIN'];
foreach ($headersToCheck as $header) {
  if (!empty($_SERVER[$header]) {
    $origin = $_SERVER[$header];
    break;
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

It works, because no check succeeds. This version shows what happens in the OP code.
Ah. Of course. It's so obvious when you show it that way... :-)
I wrapped the else-parts in parentheses, not the conditions - see my update. But you put me on the right track. Thank you. Also thanks for the alternative method you provided.
@Toastgeraet You need to wrap each condition in the order you want processed e.g. (false === true ? true : (false === false ? true : false)) See: 3v4l.org/pKP1C for an example.

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.