Reputation: 11181
I'm trying to build a simple sql statement:
// build sql statement
$sql = "select * from some_tbl where ";
if(strlen($mydetails['city']) > 0) {
$sql .= "cityname in (".$mydetails['city'].") and ";
}
$sql .= 'fromdate <= expirydate and expirydate >= curdate() order by rand()';
But $sql is missing everything between < and >. The debugger shows the value of $sql as:
select * from tbl_adsinfo where fromdate = curdate() order by rand()
This is so basic I'm just lost. I don't think that < or > are special characters right? I've tried escaping them and using double quotes instead and it's the same.
What's up here?
Upvotes: 2
Views: 319
Reputation: 11181
Ok, I got it. The problem had nothing to do with PHP, it was Zend Studio and/or the XDebugger.
Getting Zend to use a debugger at all took me days and I'm sure it probably isn't entirely kosher the way I got it to run.
If you hover over a variable while debugging in Zend Studio a little window pops up to show you the contents of that variable (sometimes). This window does cut off anything that follows '<'. The variable still contains the correct string, but the IDE/Debugger is pretty misleading. Unfortunately since this particular character is a common problem because of html parsing this was a pretty confusing bug to identify. The issue is compounded if you try to compare output from a php page or if you are looking at very long output (for very long strings it seems you can only see 1024 characters in the debug variable window so the string may appear truncated).
Sadly, this is still the best IDE I've come up with for PHP so far.
Upvotes: 0
Reputation: 85378
Why not use the BETWEEN operator?
$sql .= 'expirydate BETWEEN fromdate AND curdate() ORDER BY rand()';
EDIT:
Looking it over you need the equals as well, try splitting up the actions
$sql .= 'fromdate <= expirydate and expirydate >= curdate() order by rand()';
to:
$sql .= 'expirydate >= curdate() ';
$sql .= 'AND fromdate <= expirydate ';
$sql .= 'ORDER BY rand()';
Or reverse the order of the operator: make the = first
$sql .= 'AND fromdate =< expirydate ';
$sql .= 'ORDER BY rand()';
Upvotes: 0
Reputation: 8582
You wouldn't happen to be running the $sql variable through the striptags() function, would you? This would be consistent with it stripping out "<= expirydate and expirydate >", as it would assume it to be an HTML tag.
Upvotes: 1
Reputation: 9577
I am not sure what is causing the problem. Apparently there is something stripping the html tags off as a sort of security maybe . One suggestion is to try to replace the '<' and '>' with their ASCII codes:
$sql .= 'fromdate '.chr(60).'= expirydate and expirydate '.chr(62).'= curdate() order by rand()';
edit: You may also use NOT BETWEEN statement like below:
$sql .= '(expirydate NOT BETWEEN fromdate AND curdate()) AND (expirydate NOT BETWEEN fromdate AND 17530101) ORDER BY rand()
The 17530101 is meant to be the least value for a datetime possible. In the previous code you are checking if the expirydate isn't between fromdate and curdate() AND expirydate isn't less than any of them. That means that expirydate should be greater than fromdate,curdate for the statement to return true, which is what you are trying to achieve.
Upvotes: 0