OK, I am new to PHP coding and I tried to look over previous questions here so if I missed something, please let me know.
Using a PHP if statement, I am trying to have one known working PHP/MySQL codeset run between the hours of 11pm to 8am and another known working PHP/MySQL codeset the rest of the day.
Please let me know if you need any further elaboration to understand my question and thank you for the assistance!
<?php
if (date('H')>=23 || date('H')<=08) {
Runs a PHP/MySQL query that is know to work. The IF statement never runs this code.
}
else
{
Runs another PHP/MySQL query that is know to work. The IF statement always returns FALSE and runs this code.
}
?>
date('H')<=08
A number (not a quoted string) with a leading zero is treated as an octal value.... 08 is invalid as an octal value, and is treated as a numeric zero, so date('H')<=08 equivalent to date('H')<=0
EDIT
Either allow PHP's loose typing to convert your Hour string to an integer:
date('H')<=8
or use loose type comparison for both sides of the comparison (with 08 as a quoted string, which will loose cast to decimal 8):
date('H')<='08'
or use date format mask 'G'
date('G')<=8
Related
I am working on a section of PHP code for a project that compares a date in the YYYY-MM-DD format to the current date to see if it is less than the current date. At different points in the code two different methods were used for making this comparison. The first used get_timestamp() on the dates and ran the comparison off of the timestamps. In another place it just compared the string of the date to the output from date("Y-m-d"). My expectation was that the comparison of two date strings would not provide a correct response. However, when I set up several test cases I got the output expected. I reviewed two parts of the PHP manual for insight and I am still confused as to why the comparison works without conversion to a timestamp.
The comparison operators section of the PHP manual states that the strings are either being converted to numbers and a numerical comparison is then made or that it makes something called a lexical comparison. I couldn't find anything further on lexical comparisons, but when I read about string conversion to numbers and tried the examples using date strings I get the same numerical output for each date string I try.
Can someone help me understand why a greater than or less than comparison of two date strings works (or at least appears to be working)? What am I missing?
As a follow up, if it really does work, I am assuming it is a better practice to convert the date to a timestamp and do the comparison based on the timestamp. Which is the better function to use for converting a date to a timestamp: get_timestamp() or strtotime()?
Sample code of less than / more than comparison of two YYYY-MM-DD strings:
if ("2013-06-27" < "2013-06-28") { echo "less"; } // Output: less
if ("2013-06-27" > "2013-06-28") { echo "more"; } // Output: (none)
if ("2013-06-29" < "2013-06-28") { echo "less"; } // Output: (none)
if ("2013-06-29" > "2013-06-28") { echo "more"; } // Output: more
Sample code testing numeric value of a converted YYYY-MM-DD string
$foo = 1 + "2013-06-27";
echo "\$foo==$foo"; // Output: $foo = 2014
$foo = 1 + "2013-06-28";
echo "\$foo==$foo"; // Output: $foo = 2014
$foo = 1 + "2013-06-29";
echo "\$foo==$foo"; // Output: $foo = 2014
When you compare a string this way, it will go from left to right, and compare each character in the given string to see if they are different, until it finds a difference, then it will decide which string is bigger by comparing the ASCII value of this last character. Coincidentally, since you are using only numbers, the highest numbers are also higher on the ASCII table.
This solution will work as long as you use only numbers in your comparisons, and that each string has the same number of characters
Also note that this works only since you are using the YYYY-MM-DD format, if you used another format it would not work.
Use the DateTime class for comparing dates. It makes it a lot easier to understand, and you don't have to deal with type juggling.
I browsed through several similar questions, but they all only state the fact:
If ... comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically.
Okay, I got it. It explains what is going on when '00001' == '1' returns TRUE.
The question is: Why PHP does so?
What is the reason for probing strings for being numeric, and then casting if so? Why can't we just compare two strings already?
I can fairly understand what casting is required if two operands has different types. But why it does "usual math" when both are strings?
You can compare two strings.
"00001" === "1" // false
Remember == means equivalent === means equal
My only guess as to why this is the case is because in the beginning PHP strived to be a type-less language before they went the route of becoming a loosely typed language.
PHP was originally string processor that allowed for a little scripting inside of it. Since all inputs on the web are textual in nature it had to work hard given textual input to behave sanely when it came to dealing with numbers.
I could be wrong about this but I don't believe the ability to explicitly cast data types entered the stage until PHP 4 with the introduction of the *val functions (like intval) etc. and I think the casting notation, like (int) came around after that.
For the non comparison operations it was pretty easy because they all have a type associated with them (+ - / * all deal with numbers whereas . deals with strings) so a clear path to how things should be cast in those cases is apparent.
But with equality or equivalence checks between variables then the only way to do that was to treat everything that looked like a number as a number because at the time the only way it could be gotten would be by externally would be as a string and there was no way to make it otherwise.
Because, PHP produce a product for End-Users, not for Application Developers.
So when you produce such product like below:
if (isset($_POST['submit'])){
if ($_POST['myinput'] == "1") echo 'Yes'; //or == 1
else echo 'NO';
}
?>
<form name="myform" method="POST" action="">
<input name="myinput">
<input name="submit" type="submit">
</form>
If the user enter 1 or 0001, what do you expect to print in both case? Yes or NO?
the answer is clear. we expect to see Yes. so this is why PHP does so
If for any rare reason, we need to definitely compare them, then we should change == to ===
Ah, finally I got it. It was quite stupid of me.
Comparison involves not only "is equal" but also "less than" and "greater than". And for the latter two it is obviously critical to cast numerical operands before comparison, because numbers often being represented in PHP as strings, and 11 have to be greater than 9 even if both stored in strings.
So, as compare_function() does all the comparisons at once, returns either 1, 0, -1 to tell if first operand is bigger, equal or less than second respectively - well, it's fairly explains, why operands being cast.
I have a field in my mySQL db table of type decimal (15,4)
I've never experienced this before but if the value is 0.0000 my PHP if statement is returning true!
As a sanity check I even did:
if(0.0000) echo "Hello World";
And sure enough, Hello World echo'd out. What the hell is going on? Anybody got any ideas?
If it's a float value coming out from DB it will be treated like a string, not like a numeric value. You can try something this:
if(floatval($value) > 0) { ... }
Where $value contains the value from DB.
I think the problem is you got a string "0.0000" from db but not 0.0000.
Try again with:
if ((int)$your_value) echo "Hello World";
I don't have this behavior on my PHP version (5.3.3).
I suggest casting the number to bool before doing the check: if ((bool) $float).
I know it's been a long time since this question was opened but I thought it might help out someone else.
A float is actual an approximation of the Real Number. You will find that not all Real numbers can be represented by a float. This might be the reason why you are getting unexpected results. You should have a read of
http://php.net/manual/en/language.types.float.php.
If however you need higher precision you should look at using the BC Math lib's http://php.net/manual/en/ref.bc.php.
I have a loop that calculates a couple revenue values then adds them together, like this:
$SalesGrowth = $C2012Sales+$C2011Sales;
In some cases, this works, and I get the expected, e.g.: 761.9 + 759.0 = 1520.9
In others, it looks like PHP randomly decides to round incorrectly (??) AND change the units (??) and I get:
8,788.0 + 8,794.3 = 16
What is going on here? I've even tried echoing out the separate sales values separated by a space, and they show up correctly, so the underlying figures aren't wrong.
Interpreted as a number, 8,788.0 is just 8, and parsing stops at the comma.
You'll need some locale-aware number parsing if you want to allow gimmicks like thousands-separators.
Update: If you have the Zend Framework, you can do this:
require_once('Zend/Locale/Format.php');
$locale = new Zend_Locale('en_GB'); // #1
$v = "8,410.5";
$n = Zend_Locale_Format::getNumber($v, array('locale' => $locale,'precision' => 3));
echo 2 * $number; // prints "16821"
Instead of hard-coding the locale, you could try and take it from the environment: new Zend_Locale(setlocale(LC_ALL, ""))
Dude the comma issue....
remove all the commas from the numbers before adding them...
str_replace(",","",$no1);
This is pretty simple... When you ask PHP to use the + operator, it will implicitly convert these strings such as "8,788.0" to an numeric value. Since you have a , character, it terminates the usefulness of the number, and it results in it being interpreted as 8. And so on...
Get rid of the non [0-9.] characters and it will work better.
Notice that 761.9 is a valid number, while 8,788.0 is not (from PHP's point of view).
So 8,788.0 in number context will evaluate as 8, just like 8,794.3. And 8+8 = 16.
To fix this problem, process your data to make numbers formatted properly.
I am having trouble with a complex script which sometimes (About 2 or 3 times while calulating about 90'000 values), generates a '-0' and writes it into the database. I suspect it's a string (The values which are calulated can result in integers, floats or strings.)*
Is there any PHP calculation which might result in a '-0'?
* = Oh, how I miss strong typing sometimes...
Rounding a negative number toward positive infinity, as ceil() does, can produce -0.
echo ceil(-.7);
// -0
The same result comes with, e.g., round(-.2).
Both of these will resolve to true:
(-0 == 0)
(ceil(-.7) == 0)
While these will resolve to true and false, respectively:
(-0 === 0)
(ceil(-.7) === 0)
Edit: An interesting (and implemented) rfc can be read here.
As Gurdas says, you can have your strong typing in the database. That aside, I don't know the answer to your question but I know how would I approach the problem.
The problem, as I understand it, is that you don't know in which cases you get the '-0', which is a valid floating point representation of 0, by the way. So you have to find in which cases you are getting that. I'd take one of two routes:
Use Xdebug, raise an error in the database insertion code when the value is '-0' to get a stack_trace with arguments (use xdebug.collect_params=1)
Create an empty string at the beginning of the script, populating it with all the operations and operands being done as they are, with the result and line. Afterwards, in the insertion clause add an if ($value == '-0') { print $string; }