PHP GET method in <a href> - php

I am creating a calendar function in php. Along with the function I need a "previous" and "next" link that show the previous or next month using the GET method. The links don't work the way I expect them to. From what I've found through debugging it doesn't look like it's actually adding or subtracting 1 from month.
This is currently what I have:
$month=$_GET["month"];//should initially set them to null?
$year=$_GET["year"];
//previous and next links
echo "<a href='calendar.php?month=<?php echo ($month-1)?>'>Previous</a>";
echo "<a href='calendar.php?month=<?php echo ($month+1)?>'>Next</a>";
//Calls calendar method that returns the calendar in a string
$calDisplay=calendar($month,$year);
echo $calDisplay;

PHP doesn't do calculations inside strings and doesn't parse PHP tags inside strings. You are already in 'PHP mode', and opening another PHP tag inside the string just outputs that tag as you may have noticed when you inspected the link in your browser.
Instead, try closing the string, concatenating the next/previous month (using the dot operator), and concatenating the last part of the link:
//previous and next links
echo "<a href='calendar.php?month=" . ($month-1) . "'>Previous</a>";
echo "<a href='calendar.php?month=" . ($month+1) . "'>Next</a>";
You can also calculate the values into variables first, because simple variables can be used inside double-quoted strings:
//previous and next links
$previousMonth = $month-1;
$nextMonth = $month+1;
echo "<a href='calendar.php?month=$previousMonth'>Previous</a>";
echo "<a href='calendar.php?month=$nextMonth'>Next</a>";
On the first request, you may not have a month at all, so you may want to check for that too, for instance using isset.
$month = 1;
if (isset($_GET['month'])) {
$month = (int)$_GET['month'];
}
As you can see, I already did an (int) typecast there too. Combining this with the variables version, allows you to make the code a little more solid by performing some checks on the input, and only output the previous/next links if they make sense.
$month = 1;
if (isset($_GET['month'])) {
$month = (int)$_GET['month'];
}
if ($month < 1 || $month > 12) {
// Invalid month. You can choose to throw an exception, or just
// ignore it and use a default, like this;
$month = 1;
}
//previous and next links, if necessary.
$previousMonth = $month-1;
$nextMonth = $month+1;
if ($previousMonth >= 0) {
echo "<a href='calendar.php?month=$previousMonth'>Previous</a>";
}
if ($nextMonth <= 12) {
echo "<a href='calendar.php?month=$nextMonth'>Next</a>";
}
Oh, and a minor detail. Personally I don't like to put 'big' chunks of HTML inside a string, so I'd rather use some template, or at least write it like this. As you can see, you can close and open PHP tags (just not inside strings), so you can output plain HTML from within your PHP code. The <?= $x ?> notation is a shorthand for <? echo $x; ?>.
//previous and next links, if necessary.
$previousMonth = $month-1;
$nextMonth = $month+1;
if ($previousMonth >= 0) {?>
<a href='calendar.php?month=<?=$previousMonth?>'>Previous</a>
<?php}
if ($nextMonth <= 12) {?>
<a href='calendar.php?month=<?=$nextMonth?>'>Next</a>
<?}

Try doing something like the following:
echo sprintf('Previous', http_build_query(array('month' => $month - 1)));
echo sprintf('Next', http_build_query(array('month' => $month + 1)));
While it seems more convoluted, it serves two purposes.
Its cleaner and less messing around with string concatination
You get to learn about sprintf and http_build_query functions which can be very useful in certain situations. sprintf is a string formatting function which basically takes a string as its first parameter and substitutes certain tokens with the next n parameters. In this example, %s is a token which means replace it with a string, which is passed as the second function. http_build_query takes an associative array and builds a http query from it. So in the code above, the http_build_query function will return month=11 (assuming the month was 12) for the Previous link. You can also add multiple array parameters and it will build the query string with the ampersands.
While the other answers do what you need, its always wise to look at and understand other PHP functions.

The $_SERVER REQUEST METHOD when you click on a link is 'GET'.
use the parse_str function and place your $_GET keys and variables into an array.
parse_str($_SERVER['QUERY_STRING'],$output);
print_r($output);
Maybe you can test for that. Is this what you are looking for?

Since everything you send via request is considered a String, try this casting integer.
HTML
<!-- previous and next links -->
<a href='calendar.php?month=<?php echo ((int)$month - 1)?>'>Previous</a>
<a href='calendar.php?month=<?php echo ((int)$month + 1)?>'>Next</a>

Related

regex match cond1 OR match cond2 in single command

I need to check if entered date is between 2019-09-01 - 2019-12-31
I can do this as follows: $koodi is user input
$pattern1 = "/^2019-(09|11)-([0-2][0-9]|30)$/";
$pattern2 = "/^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
if(preg_match($pattern1, $koodi) || preg_match($pattern2, $koodi)) {
echo "<code>$koodi</code> ok!<br>\n";
}
else {
echo ("<code>$koodi</code> NOT ok!<br>\n");
}
I was trying to make those two conditions into single regex statement, is that possible and if so how?
I tried:
$pattern = "/^2019-(09|11)-([0-2][0-9]|30)$ | ^2019-(10|12)-([0-2][0-9]|3[0-1])$/";
Did not work, neither the following where i tried to put parentheses around conditions:
$pattern = "/(^2019-(09|11)-([0-2][0-9]|30)$) | (^2019-(10|12)-([0-2][0-9]|3[0-1])$)/";
Please don't use a regex to do that, what if the dates change or what if the next developer has to come and work on this and figure out what your doing?
According to this article you can check if a date is between 2 dates by doing something like this.
<?php
$currentDate = date('Y-m-d');
$currentDate = date('Y-m-d', strtotime($currentDate));
$startDate = date('Y-m-d', strtotime("01/09/2019"));
$endDate = date('Y-m-d', strtotime("01/10/2019"));
if (($currentDate >= $startDate) && ($currentDate <= $endDate)){
echo "Current date is between two dates";
}else{
echo "Current date is not between two dates";
}
as for why your patterns didn't work its because you have a space around the pipe in the middle and you may possibly need to wrap the whole thing in brackets. You also have the $ half way through the regex which is matching the whole string, I would usually only have it at the end, like this: -
^(regex1|regex2)$
I haven't written the correct version in case your tempted to use it, (please use the date objects method)

Compare date to today does not work

I want to display a text if the date in the database matches today's date.
$userdate = date("m/d/Y", strtotime($rr['last_login']));
$today = date("m/d/Y");
if ($userdate==$today){
echo "<test>";
}
Even if it is today's date, the records never echo out the string.
Interestingly, if I change it to
if ($userdate!=$today){
it also does not display the <test>.
My bad! I was not trying to echo out any html thing. The < brackets were just random characters. I changed it to "test" and now it works. Sorry for the < > characters causing confusion!
Since this is PHP, one would assume you're looking at the result in a browser, which will interpret the "<test>" as an HTML tag, and thus it will ignore it. Try changing the "echo" to simply echo "test<br>";
Also, if you are always dealing with a database, you could also use this:
if (substr($rr['last_login'], 0, 10) == date('Y-m-d'))
echo "test<br />\n";

Check whether day is specified in a date string

Test case scenario - User clicks on one of two links: 2012/10, or 2012/10/15.
I need to know whether the DAY is specified within the link. I am already stripping the rest of the link (except above) out of my URL, am I am passing the value to an AJAX request to change days on an archive page.
I can do this in either JS or PHP - is checking against the regex /\d{4}\/\d{2}\/\d{2}/ the only approach to seeing if the day was specified or not?
You can also do this if you always get this format: 2012/10 or 2012/10/15
if( str.split("/").length == 3 ) { }
But than there is no guaranty it will be numbers. If you want to be sure they are numbers you do need that kind of regex to match the String.
You could explode the date by the "/" delimiter, then count the items:
$str = "2012/10";
$str2 = "2012/10/5";
echo count(explode("/", $str)); // 2
echo count(explode("/", $str2)); // 3
Or, turn it into a function:
<?php
function getDateParts($date) {
$date = explode("/", $date);
$y = !empty($date[0]) ? $date[0] : date("Y");
$m = !empty($date[1]) ? $date[1] : date("m");
$d = !empty($date[2]) ? $date[2] : date("d");
return array($y, $m, $d);
}
?>
I would personally use a regex, it is a great way of testing this sort of thing. Alternatively, you can split/implode the string on /, you will have an array of 3 strings (hopefully) which you can then test. I'd probably use that technique if I was going to do work with it later.
The easiest and fastest way is to check the length of the string!
In fact, you need to distinguish between: yyyy/mm/dd (which is 10 characters long) and yyyy/mm (which is 7 characters).
if(strlen($str) > 7) {
// Contains day
}
else {
// Does not contain day
}
This will work EVEN if you do not use leading zeros!
In fact:
2013/7/6 -> 8 characters (> 7 -> success)
2013/7 -> 6 characters (< 7 -> success)
This is certainly the fastest code too, as it does not require PHP to iterate over the whole string (as using explode() does).

echo php variable between php scripts

I was given a script with different variables that are based on date and time on the top of XHTML Strict page.
<?php
date_default_timezone_set('America/Los_Angeles');
$time = new DateTime();
if($time < new DateTime('2011-10-31 18:00')){
$title="Before Halloween";
$cb1="2011,10,31,18,0";
}else if
...
?>
Halfway through the HTML code I have a second PHP script:
<?php
date_default_timezone_set('America/Los_Angeles');
countdown(2011,10,31,18,0);
function countdown($year, $month, $day, $hour, $minute)
{
...
?>
How can I echo $cb1 from the upper script into the second script so the third line looks something like countdown(echo $cb1); and updates automatically based on the upper script?
Since it is a string you will need to explode (take apart) at the comma, to create 5 variables. To do this you would use:
$cbarray = explode(",",$cb1);
countdown($cbarray[0],$cbarray[1],$cbarray[2],$cbarray[3],$cbarray[4]);
Or something simalar by putting each one in a named variable.
You could try to set $cb1 as a session variable instead so you can access it from anywhere in the file.
Maybe replace:
$cb1="2011,10,31,18,0";
with
$_SESSION['cb1']="2011,10,31,18,0";
And then your code in the second script would be: countdown($_SESSION['cb1']);

PHP while loop for HTML Generation: Should I Check Array values at each While Loop Iteration or use Post-Loop String Processing?

I'm working on a PHP-written html calendar that writes each day of the month inside a while loop.
Each day of the month is inside a pair of tags and certain days need a title attribute in the tag. Those days will be obtained from the MySQL db and stored in an array like this: $array($day_number=>$quantity).
An example array might be: (3=>5, 12=>4, 15=>6, 22=>10, 27=>2, 31=>4). The array would only contain keys for days where the quantity is not zero.
I can think of two ways to do this. I'm wondering which one is more efficient, or if there is another, best way.
Option 1.) Check the array at each iteration of the html-creating loop to see if it contains the corresponding day. If so, add the appropriate title attribute to the tag. So I would be using something like:
$day = 1;
while($day < 31) {
if(array_key_exists($day,$array)) {
echo "<td title=\"$array['$day'] spots available\">$day</td>";
}
else echo "<td title\"No spots available for this date\">$day</td>";
$day++;
}
2.) Use loop to put entire calendar into a string variable, then use string functions to insert special title attributes.
$day = 1;
while($day < 31) {
$month .= "<td>$day</td>";
$day++;
}
foreach($array as $day_number=>$quantity) {
$month = str_replace("<td>$day_number</td>","<td title=\"$quantity spots available\">$day_number</td>",$month)
}
In this application, either method will be done very quickly but my question is more general. Is it better to use string functions after the loop that creates the basic html, or to checking/processing at each iteration? Or is there a third, best way?
I have learned PHP entirely by myself using internet resources so I have no idea how bad my coding may be. Any help is appreciated.
Thank you.
Here's another solution:
$day = 1;
$strings = array();
while($day < 31) {
if (array_key_exists($day, $array)) {
$strings[$day] = $array['$day'] . " spots available";
} else {
$strings[$day] = "No spots available for this date";
}
$day += 1;
}
foreach ($strings as $day => $string) {
echo '<td title="' . $string . '">' . $day . '</td>';
}
What is so different about it? Well, fist of all, it's likely going to be slower than your solution since I'm looping 31 times, twice! But this example is so trivial that performance is not your main concern.
Your main concern is writing code that is so simple anyone can understand it.
PHP code gets very complicated if you have lots of HTML printing going on. Generally what you want to do is make some sort of model (adhoc or systematic) that collects all your data, and only prints it to HTML as the very last step.
Learn to separate the data-collection and model generation step from the HTML printing step. This may seem like overkill and a waste of CPU power and memory and what not, but what is more expensive: your time and sanity or some server in a hot room somewhere? ;)
Your choice to have a sparse array of only the days that have spots available is already an optimization. And premature optimization is the mother of all evil. Think about the easiest way to solve your problem, build that, it's likely going to be fast enough anyway.

Categories