2

I've commented the code for easier readibility.

function logRequest($cached = false) {

    // This function logs the number of two types of events: (1) cached and (2) uncached/upstream request

    // References to frequently addressed array keys, for brevity
    $lc = &$_SESSION['loads']['cache'];
    $lu = &$_SESSION['loads']['upstream'];

    // Add to one session variable or the other, depending on the type of event
    $s = ($cached ? &$lc : &$lu);
    $s = (isset($s) ? $s : 0) + 1; 

    // Begin dumping the counts to a file, but only every 25 calls for each client
    if(($lc ?? 0) + ($lu ?? 0) < 25) return;
    $logArray = (file_exists($logFile = '../runtime/requests.json') ? json_decode(file_get_contents($logFile),true) : []); 

    // Define array structure for dumping to a file
    $today = (new DateTime())->format('Y-m-d');
    $ac = &$logArray[$today]['cache access'];
    $au = &$logArray[$today]['upstream request'];

    // Do incrementing
    $ac = (isset($ac) ? $ac : 0) + $lc;
    $au = (isset($au) ? $au : 0) + $lu;

    // Reset counters in the session
    $lc = $lu = 0;

    // Finally, save to file
    file_put_contents($logFile, json_encode($logArray, JSON_PRETTY_PRINT));
}

The line I am talking about is this:

$s = ($cached ? &$lc : &$lu);

And the error is:

Parse error: syntax error, unexpected '&' in...

How do I go about assigning a reference in this case? Surely there must be a way to use the ternary operator, right?

P.S. I am a very casual programmer so I would be grateful if you could point out any other bad practices in my code.

Meekelis
  • 33
  • 5
  • Why are you using ampersands to begin with is what I'd like to know. – Funk Forty Niner Aug 26 '18 at 01:32
  • It'd be nice to know on which line that's happening. But I'm pretty sure it starts before that line of code you say the error's on. – Funk Forty Niner Aug 26 '18 at 01:33
  • @FunkFortyNiner I am working with references. The very next line modifies the referenced variable; The line I've quoted is indeed the one that's causing the error. If I rewrite it to if/else, everything works well. In fact, "$s = &${$cached ? 'lc': 'lu'};" works just as well. I'm just not entirely sure it's a good practice. – Meekelis Aug 26 '18 at 09:48

2 Answers2

2

try this

$cached ? $s = &$lc : $s = &$lu;

Add some explanation about the code. Sorry for my bad english, I am ashamed to express in English.

If the value of the first subexpression is TRUE (non-zero), then the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.

this is from php expressions manual.

the reason of we can't use $s = $cached ? &$lc : &$lu; is ternary operator need a expression but &$lc and &$lu not a expression.

we can test this code

<?php
$a = 5;
$a;

It's no error.

but this

<?php
$a = 5;
&$a;

throw an error.

Parse error: syntax error, unexpected '&', expecting end of file in /usercode/file.php on line 3

The above is my opinion, I hope you can understand.

It's too difficult to using english for me.(ㄒoㄒ)

Zane
  • 209
  • 1
  • 8
  • 2
    Can you give some explanation about that? – Nico Haase Aug 26 '18 at 07:05
  • Thanks, Zane. What a clever solution, that's probably not what the ternary operator was made for. But it works. @NicoHaase, depending on whether $cached evaluates to true or false, either $=&$lc, or $s=&$lu will be evaluated next. But in order to evaluate assignment operators, php will do the assignment. To the variable $s in the function scope, in this case. In other words, the ternary operator syntax is: condition ? do_if_condition_evaluates_to_true : do_if_evaluates_to_false; – Meekelis Aug 26 '18 at 09:58
  • 1
    There should be some explanation added to the answer itself such that people can learn from it - it's not about me not knowing what that code does – Nico Haase Aug 26 '18 at 10:25
0

A working alternative would be employing dynamic variable names:

$s = &${$cached ? 'lc': 'lu'};

Further reading: https://stackoverflow.com/a/35772533/9986646

Meekelis
  • 33
  • 5