Hi,
I'm just recovering from some nerve-shredding debugging on a live survey which was behaving very badly.
The root cause was that some LEM expressions evaluate differently in javascript (client side) than they do in PHP (server side).
This, I believe, originates from an early mistake of deciding to follow javascipt type flexibility in return types which is not easy to replicate in PHP.
For example, strpos returns an int (if found) or false (yuk). But the int can be zero if the $needle is found as position zero of $haystack. If not careful, this zero can be interpreted as 'false', e.g. strpos('abc','a') == false.
The javascript thing to do then is to use '===' operator to type match, so:
strpos(haystack,needle)!==false
Unfortunately LEM doesn't understand or support '===' or '!===', presumably because this would be very difficult to replicate in PHP?
I thought all might be saved when I saw the is_int() LEM function. But it does not work consistently in javascript LEM implementation and PHP.
to illustrate...
is_int(strpos('abcd','e'))
evaluates to true(!!) in PHP side but false in javascript.
This led to a situation where the PHP decided that a group (with this condition) should be shown to the respondent, and that a mandatory question with the same condition inside the group should be required, but when rendered in the browser, the javascript hides the mandatory question and the user cannot continue!
Clearly having PHP and javascript LEM expressions making different decisions is... ahem... "sub-optimal" to put it politely.
I can find no documented acknowledgement of this problem in the Limesurvey manuals. What is the general view on how to work around these issues and/or resolve them in the long-term?
My own view is that following javascript type flexibility in the first place was probably a mistake and that life would be much simpler if functions like these returned -1 (int) rather than an entirely different type as in javascript. That would allow consistent implementation across javascript and PHP (or any other strongly typed language in future). But I appreciate that would be a breaking change so would require newly named versions of the functions (e.g. f_strpos) with a recommendation to migrate to / use these in future survey scripts to guarantee consistency between server-side and client-side interpretation?
For the time being my hack is to prepend $haystack with a filler character and then offset the search by 1 so that strpos will always return > 0 if it finds a match, e.g.
(strpos(join('#',haystack), needle, 1) > 0) or !(strpos(join('#',haystack), needle, 1) > 0)
So far, this appears to behave consistently between the server and client-side expression managers. Can't have been the original plan though, right?
The topic has been locked.