While
$w is an Array ( [0] => 4, [1] => 6 )
what does this statement mean:
$day == $w[0] || $day == $w[1] || $day < ((7 + $w[1] - $w[0]) % 7);
Please help. I have not seen the || operator inside other than an if or while statement. Thank you.
EDIT 01:
This is the original function where it is used to find the number of a particular day in a date range:
// find number of a particular day (sunday or monday or etc) within a date range
function number_of_days($day, $start, $end){
$w = array(date('w', $start), date('w', $end));
return floor( ( date('z', $end) - date('z', $start) ) / 7) + ($day == $w[0] || $day == $w[1] || $day < ((7 + $w[1] - $w[0]) % 7));
}
This was not created by me. But I wanted to edit this function because when the end day is a Saturday, it is taking the following Sunday into account too, which is wrong.
It's just a compound boolean expression that returns true if any of the following four sub-expressions is true:
$day == $w[0]
$day == $w[1]
$day < ((7 + $w[1] - $w[0]) % 7)
You were right in one of your comments that the boolean expression gets added as to the integer as 1 or 0.
If you cast a boolean value to an integer then FALSE gets 0 and TRUE gets 1.
If you add variables with different datatypes and one of the variable is an integer, then the other variables are casted to integers, which makes:
var_dump(1+true);
// Result: int(2)
Two links that explain what happens if you use + on different data types and what happens if a certain datatype is casted to an integer:
http://php.net/manual/en/language.types.type-juggling.php
http://www.php.net/manual/en/language.types.integer.php#language.types.integer.casting
$day == $w[0] || $day == $w[1] || $day < ((7 + $w[1] - $w[0]) % 7);
The statement will evaluate (nothing is assigned in the example) to a boolean value of true/false.
The statements are effectively computed in order
For example
true || false || false => true
false || false || false => false
This means that if any of the "subexpressions" are true then the whole expression will evaluate to true. This can be assigned to a variable $v = expression, or use in an if (expression)
|| is the logical OR operator. Please see the documentation for more
Related
I have this code bellow it works fine but when the time hits 24 till 1 it doesn't work. I'm not sure why.
The code I have:
<?php
$h = date('G'); //set variable $h to the hour of the day
$d = date('w'); //set variable $d to the day of the week.
$year = date('Y'); //set variable $year to the current year
//G is the date key for hours in 24 format (not 12), with no leading 0s, like 02.
// MONDAY SCHEDULE
if ($d == 1 && $h >= 0 && $h < 4) $text= 'bob';
else if ($d == 1 && $h >= 22 && $h < 23) $text= 'adam';
else if ($d == 1 && $h >= 23 && $h < 24) $text= 'tina';
else if ($d == 2 && $h < 0) $img = 'mark';
// TUESDAY SCHEDULE
if ($d == 2 && $h >= 0 && $h < 4) $text= 'alex';
else if ($d == 2 && $h >= 4 && $h < 8) $text= 'jason';
else if ($d == 3 && $h < 0) $text= 'gorge';
print $text;
?>
When it's mark's or gorge's turns it doesn't work. I would like to know how to fix it. Any help would be appreciated.
Thank you
Like stated in comments, the test on $h < 0 will always return false, as $h is an integer between 0 and 23.
But you could make your schedule more readable and manageable if you would create a data structure for it, like this:
mb_internal_encoding("UTF-8");
$persons = array(
'-' => '(no one)',
'a' => 'Bob',
'b' => 'Adam',
'c' => 'Tina',
'd' => 'Marc',
'e' => 'Alex',
'f' => 'Jason',
'g' => 'George'
);
$schedule = array(
// 012345678901234567890123
'------------------------', // Sunday
'aaaa------------------bc', // Monday
'eeeeffff----------------', // Tuesday
'------------------------', // Wednesday
'------------------------', // Thursday
'------------------------', // Friday
'------------------------', // Saturday
);
// Use mb_substr to support multi-byte characters (unicode)
print $persons[mb_substr($schedule[date('w')],date('G'),1)];
In the above code, each person gets a unique letter. That letter is used in a kind of grid, where each row represents a weekday, and each column (character position) an hour of the day (0-23).
This way you have a rather visual representation, which might be easier to manage. And as it turns out, to get the person that is scheduled for the current hour-slot just takes a single line of code.
I'm quite new to PHP and I've been asked to write a script that displays an image based on time. I've deducted that I need to use PHP's native 'date' function for this and up until I was asked to implement bank holidays and Christmas into it, all went well.
I tried to add the Christmas and bank holidays in as a separate if statement but that was when disaster struck and I haven't been able to figure out why it's come to a halt. I've tried using an online PHP validator to no avail.
Please don't be afraid to throw details and jargon at me as I really wish to expand my knowledge of PHP and rely less on the support of web forums in the future!
Here is the code:
<?php
// Date-time (day of month, month)
$d = date('j'); // Day of month: Numeric without leading zeroes
$m = date('n'); // Month: As above
$D = date('w'); // Day of week
$H = date('G'); // Hour of day
// REGULAR OPENING TIMES
// Closed before 9am on weekdays
if ($H < 9 && $D <= 5) :
$showroom_img = '/media/gbu0/pagehead/showroom_closed.jpg';
// Open before 5pm (but after 9, as first if statement overrides this) on weekdays
elseif ($H < 17 && $D <= 5) :
$showroom_img = = '/media/gbu0/pagehead/showroom_open.jpg';
// Closed before 10am on Saturdays
elseif ($H < 10 && $D == 6) :
$showroom_img = = '/media/gbu0/pagehead/showroom_closed.jpg';
// Open between 10am and 2pm on Saturdays
elseif ($H < 14 && $H > 10 && $D == 6) :
$showroom_img = = '/media/gbu0/pagehead/showroom_open.jpg';
// Any other time, display closed image :)
else :
$showroom_img = = '/media/gbu0/pagehead/showroom_closed.jpg';
endif;
// Holidays 2014
$xmas_starts = ($d == 23 && $m == 12 && $d > 17);
$xmas_ends = ($d == 26 && $m == 12);
$nyd = ($d == 1 && $m = 1);
// Easter Friday: April 18
// Easter Monday: April 21
// Early Spring B/H: May 5
// Late Spring B/H: May 26
// Summer B/H: August 25
// All bank holidays: 10am - 2pm
if( date >= $xmas_starts && $day <= $xmas_ends ) :
$xmas = true;
elseif( date = $nyd ) :
$nyd = true;
else :
$bankhol = false;
endif;
if( $xmas = true ) :
$showroom_img = "/media/gbu0/pagehead/showroom_xmas.jpg";
elseif( $bankhol = true && date('F', 'j') = strpos('April 18' || 'April 21' || 'May 5' || 'May 26' || 'August 25') || date('w') = 6 ) :
$showroom_img = "/media/gbu0/pagehead/showroom_bhol.jpg";
elseif( date('w') = 7 ) :
$showroom_img = "/media/gbu0/pagehead/showroom_closed.jpg";
else :
$showroom_img = "/media/gbu0/pagehead/showroom_open.jpg";
endif;
?>
First of all. I noticed a couple of bugs :
elseif( date = $nyd ) :
$nyd = true;
and
if( $xmas = true ) :
$showroom_img = "/media/gbu0/pagehead/showroom_xmas.jpg";
In PHP, '=' is the assignment operator, used to assign value to a variable. What you need here is the comparison operator, '=='. For example :
if( $xmas == true ) :
Or you could also do (it's pointed out in a comment already) :
if( $xmas ) :
Rgarding priority, the if statements are going to be checked in the order you write them in your code. TO ensure that a condition gets the highest priority, that has to be checked first.
Have you considered using the switch case function instead of elseif?
Switch case method:
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
}
Read more here: http://www.php.net/manual/en/control-structures.switch.php
if statements cannot conflict, and have no concept of priority. Each one is evaluated and executed in the order it appears, unless it gets skipped by code branching (e.g. an elseif would get skipped if a previous if or elseif in the same chain evaluated to true).
The cause of your problems is most likely your confusion of assignment and equality operators (= and ==).
In all situations, x = y is an assignment; i.e. it assigns the value of y to the variable x. This is the case even if you put it in an if statement, so it's usually something you want to avoid (although there are situations where it's useful).
In all situations, x == y is an equality comparison; i.e. it checks if the value of x is (or can be converted to) the same as the value of y. This is the one you usually want in an if condition.
To put it another way, you want to change this:
if( $xmas = true )
To this:
if( $xmas == true )
You'll need to do the same thing in a couple of other places as well.
Here is the function I'm not understanding:
$year = date("Y");
$leapYear = false;
if((($year%4==0) && ($year%100==0)) || ($year%400==0))
$leapYear = true;
Does that mean that, if the (($year is divided by 4 but not divided by 100) or (the year is divided by 400)) that is a leap year?
I'm new to PHP, please anyone help me to understand the statements.
I think you're likely confused because the code you've provided doesn't find leap years. Leap years are divisible by 4 but NOT 100.. unless they are also divisible by 400. If you flip the logic around, it's easier to look at. If it's divisible by 400, it's a leap year, no matter what. Otherwise, it's a leap year if it's divisible by 4 and NOT divisible by 100.
// pseudocode
if ( year % 400 == 0 || (year % 4 == 0 && year % 100 != 0))
return true;
else
return false;
You can play around with it and just say:
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)
The && means both sides have to be true in order for && to return true.
This is basically what is says in pseudo code
if(year is divisible by 4 or 100) {
leapyear = true
} else if (year is divisible by 400) {
//this will never be hit because it would meet the first case
leapyear = true
}
Based on your code, your second guess is correct.
if((($year % 4==0) && ($year % 100==0)) || ($year % 400==0))
means that EITHER of these must be true to be a leap year:
($year%4==0) && ($year%100==0)
$year%400==0
So a year is a leap year under these conditions:
year is divisible by 4 and divisible by 100
OR
year is divisible by 400
However, the code you posted is wrong in that it doesn't correctly define a leap year.
A year is a leap year if it is divisible by 4, except when it is divisible by 100 and not divisible by 400. So in your if statement the ($year % 100 == 0) should be ($year % 100 != 0)
So the proper logic would be this:
if ((($year % 4 == 0) && ($year % 100 != 0)) || ($year % 400 == 0))
$leapYear = true;
Regarding the &&:
&& means AND, and the expression A && B is either true or false.
By definition, A && B is true only if both A and B are true. If any of them are false, then A && B is false.
I am trying to switch our surf web cameras off at civilian twilight but having some difficulties with the if statement at the bottom of this code. I am pretty sure it's a syntax issue but can't see it.
//Sunrise
//Set Zenneth to 96 which is Civilian Twilight start. Normally set to 90 for "normal" sunrise
$sunrise = date_sunrise(time(), SUNFUNCS_RET_STRING, 51.575363, -4.037476, 96, 0);
$sunrise = (integer) str_replace(":", "", $sunrise);
// echo "Sunrise: ".$sunrise."</br>";
//Sunset
//Set Zenneth to 96 which is Civilian Twilight start. Normally set to 90 for "normal" sunrise
$sunset = date_sunset(time(), SUNFUNCS_RET_STRING, 51.575363, -4.037476, 96, 0);
$sunset = (integer) str_replace(":", "", $sunset);
// echo "Sunset: ".$sunset."</br>";
// get the current date using a 24 digit hour without leading zeros, as an int
$current_time = (Integer) date('Gi');
if ((($current_time >= 0000 && $current_time <= $sunrise) && ($current_time >= $sunset
&& $current_time <= 2359)) && ($_SERVER["REQUEST_URI"] == "/webcams/langland-webcam"
| $_SERVER["REQUEST_URI"] == "/webcams/caswell-webcam" || $_SERVER["REQUEST_URI"] ==
"/webcams/llangennith-webcam" || $_SERVER["REQUEST_URI"] == "/webcams/swansea-webcam"))
{
// Cameras are offline
return true;
}
Yikes. That is one huge if statement. I've broken it up a bit:
if (
(
($current_time >= 0000 && $current_time <= $sunrise)
&& ($current_time >= $sunset && $current_time <= 2359)
// ^^ Should be `||`
) && (
$_SERVER["REQUEST_URI"] == "/webcams/langland-webcam"
| $_SERVER["REQUEST_URI"] == "/webcams/caswell-webcam"
// ^ Should be `||`
|| $_SERVER["REQUEST_URI"] == "/webcams/llangennith-webcam"
|| $_SERVER["REQUEST_URI"] == "/webcams/swansea-webcam"
)
) {
As commented, first thing I notice: You should be using || on the first comparison. Additionally, you later use a single pipe | instead of a ||.
Overall, I would recommend that you refactor this code a bit. Perhaps move the allowed URIs into an array, then use in_array() to check it. Cumbersome ifs like this can cause problems--as you just discovered. Something like this:
$validUris = array("/webcams/langland-webcam", "/webcams/caswell-webcam", "/webcams/llangennith-webcam", "/webcams/swansea-webcam");
if (in_array($_SERVER["REQUEST_URI"], $validUris)) {
if (($current_time >= 0000 && $current_time <= $sunrise) || ($current_time >= $sunset && $current_time <= 2359)) {
// Cameras
return true;
}
}
I have a PHP calendar that generates a calendar based on the month and year. I use $_GET["year"]. So, it appears in the URL of the page. Therefore, the user can input any year. How can I verify that the year they entered is a year (like 2010) and not a random input (like 2t8e7sjj2)?
I figured out how to verify month like this:
$m = $_GET["month"];
if($m!=1 && $m!=2 && $m!=3 && $m!=4 && $m!=5 && $m!=6 && $m!=7 && $m!=8 && $m!=9 && $m!=10 && $m!=11 && $m!=12)
{
$m = date("m");
}
But I can't do this with year (since the year could be any number).
Also, is there a better way to verify the month other than above?
Thanks.
try http://php.net/manual/en/function.checkdate.php
if (checkdate($_GET['month'], 1, $_GET['year'])) ... okay
What are your restrictions on year other than it must be a positive integer number?
Regarding your month validation (and most probably your year one as well), you should be checking against a numeric range, eg
$m = ctype_digit($_GET['month']) ? (int) $_GET['month'] : 0;
if ($m >= 1 && $m <= 12) {
// month is valid
}
Yes, you can verify the month like this:
$month = intval($_GET['month']);
if ($month >= 1 && $month <= 12) {
// ...
}
You don't even need to verify the year; just clean it with intval()
http://php.net/intval
if (is_numeric($_GET['year']) && in_array($_GET['year'], range(1900,2100)))
also
if (is_numeric($_GET['month']) && in_array($_GET['month'], range(1,12)))
I'd do something like:
$m = intval($_GET['month']);
$y = intval($_GET['year']);
if($m < 1 || $m > 12 || $y < 1900 || $y > 2100) echo "bad input!";
2 things.
1st: you can use the pasre_url() method in php to ensure that there is no invalid formatting.
2nd: to match a year/month (since a year must be 4 numeric digits) they can be verified easily using regular expressions. Since I don't like to take credit for the sources I learned something ... look here to validate dates.
http://www.regular-expressions.info/dates.html
If you need I can write the .php for you, but it should be pretty easy from this point.
You can use this to check both ( month , year )
<?
// define vars
$months = array();
$years = array();
// create new array with months values
for($i=1;$i<=12;$i++)
array_push($months,$i);
// create new array with years values ex: begin with year 1930 to 2011
for($i=1930;$i<=2011;$i++)
array_push($years,$i);
// Check Values
if(in_array($_GET['m'],$months))
{ $m = $_GET['m']; }
else
{ $m = date("m"); }
if(in_array($_GET['y'],$years))
{ $y = $_GET['y']; }
else
{ $y = date("Y"); }
?>