Using for each I am dismantling a series of dates.
foreach( $ds as $d){
echo '<div class="bkback" onclick="bkdates(this);">'.date('M', strtotime("today + $d day")).'<br /><span class="bknum">'.date('d', strtotime("today + $d day")).'</span><br />
'.date('D', strtotime("today + $d day")).'</div>';
}
What I want to do is every put a marker <div class="marker"></div> after post 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, and 85 for the purposes of a jumping Jquery scroller.
So I need away of identifying which post we are at so far.
Any ideas?
Marvellous
Increment a variable each time through the loop - something like:
$i = 0;
foreach( $ds as $d) {
if ($i++ % 5 == 0) {
echo '<div class="marker"></div>';
}
}
I would just increment a counter and then check to see if it's divisible by 5.
$acounter = 0;
foreach( $ds as $d){
$acounter++;
if ( $acounter % 5 == 0 ) echo '<div class="marker"></div>';
echo '<div class="bkback" onclick="bkdates(this);">'.date('M', strtotime("today + $d day")).'<br /><span class="bknum">'.date('d', strtotime("today + $d day")).'</span><br />'.date('D', strtotime("today + $d day")).'</div>';
}
$counter = 0;
foreach( $ds as $d){
echo '<div class="bkback" onclick="bkdates(this);">'.date('M', strtotime("today + $d day")).'<br /><span class="bknum">'.date('d', strtotime("today + $d day")).'</span><br />
'.date('D', strtotime("today + $d day")).'</div>';
$counter++;
if ($counter % 5 == 0) { echo '<div class="marker"></div>'; }
}
Related
I am showing images in php in ul list. I want to show 5 li in my ul then 2 li and after that again 5 li.I am using this code but it is showing 5 li every row.
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$break_after = 5;
$counter = 0;
$totalNumber = count($data);
foreach ($data as $item)
{
if ($counter % $break_after == 0)
{
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after == ($break_after-1) || $counter == $totalNumber-1) {
echo '</ul>';
}
++$counter;
}
dfff
fdfddf
fdfd
ffd
fdfd
fddf
dfdf
fddf
dfdf
dfdf
fddf
fddf
fdfd
fddf
fddf
fdfd
fddf
Hope this solution might help you :
When you want a break after 5,2,5 Y not take that an array array(5,2,5) instead of just break_after=5. break_after=5 will breake the ul at every 5 intervals. I have some change in logic for you :
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$break_after = array(5,2,5);
$counter = 0;
$break_key=0;
$totalNumber = count($data);
foreach ($data as $item){
if ($counter % $break_after[$break_key] == 0){
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after[$break_key] == ($break_after[$break_key]-1) || $counter == $totalNumber-1) {
echo '</ul>';
++$break_key;
$counter = 0;
}else{
++$counter;
}
}
Output for same is :
<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>
<ul><li>6</li><li>7</li></ul>
<ul><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li></ul>
To achieve what you want use the following:
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22);
$total = count($data);
foreach ($data as $index => $item)
{
if ($index == 0 || $index == 5 || $index == 7 || ($index > 8 && ($index - 2) % 5 == 0))
{
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($index == 4 || $index == 6 || $index == $total - 1 || ($index > 6 && ($index - 2) % 5 == 4)) {
echo '</ul>';
}
}
Pretty much the same answer as varunsinghal and Vivek Tankaria, but refactored to separate the logic and the view:
<?php
$pattern = [5, 2, 5, 5];
$data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
if (count($data) < array_sum($pattern)) {
throw new Exception('Please provide at least the same amount of data as lines required in the pattern');
}
?>
<?php foreach ($pattern as $limit): ?>
<ul>
<?php for ($i = 0; $i < $limit; $i++): ?>
<li><?= $data[$i]; ?></li>
<?php endfor; ?>
</ul>
<?php endforeach; ?>
For multiple values in array.
$data = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36);
$break_after = array(5,2,5);
$counter = 0;
$break_key=0;
$totalNumber = count($data);
foreach ($data as $item){
if ($counter % $break_after[$break_key] == 0){
echo '<ul>';
}
echo '<li>'.$item.'</li>';
if ($counter % $break_after[$break_key] == ($break_after[$break_key]-1)) {
echo '</ul>';
++$break_key;
if(count($break_after)==($break_key)){
$break_key=0;
}
$counter = 0;
}else{
++$counter;
}
}
?>
You can try this logic
<?php
$data = array(1,2,3,4,5,6,7,8,9,10,11,12);
$breakPoint=4;
$ct=1;
echo '<ul>';
foreach($data as $k=>$v){
echo '<li>'.$v.'</li>';
if($breakPoint == $k && $ct==1){
$breakPoint=$breakPoint+2;
$ct=2;
echo '</ul><br/><ul>';
}elseIf($breakPoint == $k && $ct==2){
$breakPoint=$breakPoint+5;
$ct=1;
echo '</ul><br/><ul>';
}
}
echo '</ul>';
?>
Output:
1
2
3
4
5
6
7
8
9
10
11
12
First break is at 5 so $i will be 4 then 2 elements more so $i will be 6. After this the break is required after every 5 elements, so we have 5+2+5 = 12 elements which gives $i=11 So similarly other break points will be 11 16 21 26 31 36 and so on.
<ul>
<?php
$i=0;
foreach($data as $item){
echo '<li>'.$item.'</li>';
if($i==4 || $i==6 || $i==11 || $i==16 || $i==21 || $i==26){
echo '</ul><ul>';
}
$i++;
}
?>
</ul>
There's an array of pages,
$pages = array(
1,
2,
3,
...
100,
101
);
And there's a variable $current_page. All I'm trying to do is pagination in digg-like style, so that it would look like this,
< 4 5 6 7 .... 15 16 17 18 >
The first thing that comes to mind is to get last and previous array values from specific position that equals to $current_page.
So I started with a basic for loop, but the problem is that amount of pages could be very large, so I don't think that's an efficient thing to do. Is there any another proper way of doing this? (maybe via native array_* functions)?
The following function builds StackOverflow like pagination. The objectives are:
First and last links must be visible always
Previous and next links must be visible always
At most 4 links before/after the current page should be visible
While the following function displays the complete pager, we are primarily interested in how to calculate the surrounding pages a and b as a function of current page, pager size and page count.
function so_like_pager($current_page, $page_count, $pager_size = 4) {
if ($current_page <= $pager_size) {
// the pager for first 4 pages starts from 1
$a = 1;
$b = min(1 + $pager_size, $page_count);
} else {
// the pager for remaining pages ends at current page + 2
// and starts so that 4 links are shown
$b = min($current_page + ($pager_size >> 1), $page_count);
$a = $b - $pager_size;
}
// return array("show_from" => $a, "show_upto" => $b);
echo '<p>';
if ($current_page !== 1) {
echo '' . 1 . ' ';
} else {
echo '<b>' . 1 . '</b> ';
}
if ($a > 1 + 1) {
echo '<span>...</span> ';
}
for ($i = $a; $i <= $b; $i++) {
if ($i !== 1 && $i !== $page_count) {
if ($current_page !== $i) {
echo '' . $i . ' ';
} else {
echo '<b>' . $i . '</b> ';
}
}
}
if ($b < $page_count - 1) {
echo '<span>...</span> ';
}
if ($current_page !== $page_count) {
echo '' . $page_count . ' ';
} else {
echo '<b>' . $page_count . '</b> ';
}
echo '</p>';
}
function so_like_pager_page($page) {
return 'page-' . $page . '/';
}
Tests:
so_like_pager(1, 100);
so_like_pager(2, 100);
so_like_pager(3, 100);
so_like_pager(4, 100);
so_like_pager(5, 100);
so_like_pager(6, 100);
so_like_pager(50, 100);
so_like_pager(99, 100);
so_like_pager(100, 100);
Output:
PS: Note: I ported this function from ASP classic to PHP in a hurry and did not test against edge cases.
function get_surrounding_pages(array $pages, $current, $amount = 2) {
$pages_idx = array_flip($pages);
if (!isset($pages_idx[$current])) {
return false;
}
$offset = max(0, $pages_idx[$current] - $amount);
$limit = $amount + 1 + ($pages_idx[$current] - $offset);
return array_slice($pages, $offset, $limit);
}
$pages = range(1, 1000);
$current = 42;
get_surrounding_pages($pages, $current, 4);
// array(38, 39, 40, 41, 42, 43, 44, 45, 46)
// this will work even if your number of pages is not continuous (eg: 1, 2, 6).
$pages = array(1, 2, 5, 6, 42, 234, 1048);
$current = 6;
get_surrounding_pages($pages, $current, 2);
// array(2, 5, 6, 42, 234)
// also works if you reach the boundaries
$pages = range(1, 10);
$current = 2;
get_surrounding_pages($pages, $current, 2);
// array(1, 2, 3, 4)
$current = 9;
get_surrounding_pages($pages, $current, 2);
// array(7, 8, 9, 10)
// returns false if you ask a page that doesn't exists
$pages = range(1, 10);
$current = 42;
get_surrounding_pages($pages, $current, 2);
// false
You can use PHP's end function to get the last entry of an array.
<?php
$a = array( 1, 2, 3, 4, 5, 10 );
echo end($a);
You can also use array_slice, or array_splice to cut an array, or array_pop, which removes the last element and returns what was removed.
Maybe you can try end. Should be more efficient than looping.
Im trying to create a calendar in php and want the selected month to display a picture (e.g. one for january, another for february and so on). I want the pictures to be extracted from a folder called 'months'. How do I do that?
This is my code:
<?php
class Calendar
{
var $events;
function Calendar($date)
{
if(empty($date)) $date = time();
define('NUM_OF_DAYS', date('t',$date));
define('CURRENT_DAY', date('j',$date));
define('CURRENT_MONTH_A', date('F',$date));
define('CURRENT_MONTH_N', date('n',$date));
define('CURRENT_YEAR', date('Y',$date));
define('START_DAY', (int) date('N', mktime(0,0,0,CURRENT_MONTH_N,1, CURRENT_YEAR)) - 1);
define('COLUMNS', 7);
define('PREV_MONTH', $this->prev_month());
define('NEXT_MONTH', $this->next_month());
$this->events = array();
}
function prev_month()
{
return mktime(0,0,0,
(CURRENT_MONTH_N == 1 ? 12 : CURRENT_MONTH_N - 1),
(checkdate((CURRENT_MONTH_N == 1 ? 12 : CURRENT_MONTH_N - 1), CURRENT_DAY, (CURRENT_MONTH_N == 1 ? CURRENT_YEAR - 1 : CURRENT_YEAR)) ? CURRENT_DAY : 1),
(CURRENT_MONTH_N == 1 ? CURRENT_YEAR - 1 : CURRENT_YEAR));
}
function next_month()
{
return mktime(0,0,0,
(CURRENT_MONTH_N == 12 ? 1 : CURRENT_MONTH_N + 1),
(checkdate((CURRENT_MONTH_N == 12 ? 1 : CURRENT_MONTH_N + 1) , CURRENT_DAY ,(CURRENT_MONTH_N == 12 ? CURRENT_YEAR + 1 : CURRENT_YEAR)) ? CURRENT_DAY : 1),
(CURRENT_MONTH_N == 12 ? CURRENT_YEAR + 1 : CURRENT_YEAR));
}
function getEvent($timestamp)
{
$event = NULL;
if(array_key_exists($timestamp, $this->events))
$event = $this->events[$timestamp];
return $event;
}
function addEvent($event, $day = CURRENT_DAY, $month = CURRENT_MONTH_N, $year = CURRENT_YEAR)
{
$timestamp = mktime(0, 0, 0, $month, $day, $year);
if(array_key_exists($timestamp, $this->events))
array_push($this->events[$timestamp], $event);
else
$this->events[$timestamp] = array($event);
}
function makeEvents()
{
if($events = $this->getEvent(mktime(0, 0, 0, CURRENT_MONTH_N, CURRENT_DAY, CURRENT_YEAR)))
foreach($events as $event) echo $event.'<br />';
}
function makeCalendar()
{
echo '<table border="1" cellspacing="4"><tr>';
echo '<td colspan="7" style="text-align:center"> <img src= \"img/months/$month.jpg\" > </td>';
echo '</tr><tr>';
echo '<td width="30"><<</td>';
echo '<td colspan="5" style="text-align:center">'.CURRENT_MONTH_A .' - '. CURRENT_YEAR.'</td>';
echo '<td width="30">>></td>';
echo '</tr><tr>';
echo '<td width="30">Mon</td>';
echo '<td width="30">Tue</td>';
echo '<td width="30">Wed</td>';
echo '<td width="30">Thu</td>';
echo '<td width="30">Fri</td>';
echo '<td width="30">Sat</td>';
echo '<td width="30">Sun</td>';
echo '</tr><tr>';
echo str_repeat('<td> </td>', START_DAY);
$rows = 1;
for($i = 1; $i <= NUM_OF_DAYS; $i++)
{
if($i == CURRENT_DAY)
echo '<td style="background-color: #C0C0C0"><strong>'.$i.'</strong></td>';
else if($event = $this->getEvent(mktime(0, 0, 0, CURRENT_MONTH_N, $i, CURRENT_YEAR)))
echo '<td style="background-color: #99CCFF">'.$i.'</td>';
else
echo '<td>'.$i.'</td>';
if((($i + START_DAY) % COLUMNS) == 0 && $i != NUM_OF_DAYS)
{
echo '</tr><tr>';
$rows++;
}
}
echo str_repeat('<td> </td>', (COLUMNS * $rows) - (NUM_OF_DAYS + START_DAY)).'</tr></table>';
}
}
$epcMonthPic = date("m", mktime(0,0,0,$mo)); //change the "F" for "m" if you want to use numbers
$epcImagePath = "/img/"; // the path to your monthly images (keep the trailing slash)
$epcImageExt = "jpg"; // the extension you'll be using for your images
echo "<img src=\"$epcImagePath$epcMonthPic.$epcImageExt\">";
$month = $_REQUEST["month"];
$cal = new Calendar($_GET['date']);
$cal->makeCalendar();
?>
In the method makeCalendar() fix line:
echo '<td colspan="7" style="text-align:center"> <img src= \"img/months/$month.jpg\" > </td>';
with:
echo '<td colspan="7" style="text-align:center"> <img src="img/months/' . CURRENT_MONTH_N . '.jpg" > </td>';
and make sure that images exists:
img/months/1.jpg
img/months/2.jpg
...
img/months/12.jpg
I want to generate alphanumeric unique numbers but the format should be like this
that should be starts from AA001 to AA999 after that AB001 to AB999 .... BA001 to BA999 end with ZZ999. if i give the input is
1 = result AA001
999 = result AA999
1000 = result AB001
any one can help this ?
Complete solution (see it running):
function formatNum1000($num) {
$tail = $num % 1000;
$head = (int)($num / 1000);
$char1 = chr(ord('A') + (int)($head / 26));
$char2 = chr(ord('A') + ($head % 26));
return sprintf('%s%s%03d', $char1, $char2, $tail);
}
function formatNum999($num) {
$tail = (($num - 1 ) % 999) + 1;
$head = (int)(($num - $tail) / 999);
$char1 = chr(ord('A') + (int)($head / 26));
$char2 = chr(ord('A') + ($head % 26));
return sprintf('%s%s%03d', $char1, $char2, $tail);
}
$ns = array(1, 500, 999, 1000, 1998, 1999, 2000, 25974, 25975, 25999, 26000, 675324, 675999);
foreach($ns as $n) {
$formatted1000 = formatNum1000($n);
$formatted999 = formatNum999 ($n);
echo "Num: $n => $formatted1000 / $formatted999\n";
}
Note: you need to make sure that the input number is within the valid range (0...675999 when including 000-numbers, 1...675324 otherwise)
Note: answer revised, missed the point earlier that 000 is not allowed
How about:
$start = 'AA997';
for($i = 0; $i < 5; $i++) {
$start++;
if (substr($start, 2) == '000') continue;
echo $start,"\n";
}
output:
AA998
AA999
AB001
AB002
Here is my function,
It is meant to get the user level an the amount of xp needed until the next level, it works but only through levels 1 to 2, then if the required xp for level 3 is entered it fails.
The XP doubles per level, so from level 1 to 2 is 10, 2 to 3 is 20, 3 to 4 is 40 etc;
$user['xp'] is an int to explain better, here are some examples of what the function returns with different values.
$user['xp'] == 1, level 1, xpGot 1, xpNeeded 9, 10%
$user['xp'] == 5, level 1, xpGot 5, xpNeeded 5, 50%
$user['xp'] == 9, level 1, xpGot 9, xpNeeded 1, 90%
$user['xp'] == 10, level 2, xpGot 0, xpNeeded 20, 0%
$user['xp'] == 15, level 2, xpGot 5, xpNeeded 15, 25%
$user['xp'] == 29, level 2, xpGot 19, xpNeeded 1, 95%
7. $user['xp'] == 30, level 2, xpGot 0, xpNeeded 0, 0%
It fails there on after.
function calculateLevel($xpGot) {
$level = 1;
$xpNeeded = 10;
while ($xpGot >= $xpNeeded) {
$level++;
$xpGot %= $xpNeeded;
$xpNeeded *= 2;
}
if ($xpGot < $xpNeeded) {
$xp = $xpGot / $xpNeeded * 100;
echo '<p>Level: ' . $level . '</p>';
echo '<div class="displayBarWrap" title="' . $xpGot . '/' . $xpNeeded . ' XP (' . $xp . '%)">
<p>XP:</p>
<div class="displayBar"><div style="width: ' . $xp . '%;"></div></div></div>';
}
}
calculateLevel($user['xp']);
I think you want following: replace %= with -=:
$xpGot -= $xpNeeded;
Take this line
$xpGot %= $xpNeeded;
There is no difference if the $xpGot is 15 or 45, % 10 will still return 5. The modulus operator divides the left operand by the right and returns the remainder.
Changing it to -= as #scessor suggested is probably what you're looking for.
With the fix the others mentioned and a possible mistake in the echo, this works for me:
<?php
function calculateLevel($xpGot) {
$level = 1;
$xpNeeded = 10;
if ($xpGot < $xpNeeded) /* NEW! */
return;
while ($xpGot >= $xpNeeded) {
$level++;
$xpGot -= $xpNeeded; /* FIXED (other answers!) */
$xpNeeded *= 2;
}
if ($xpGot < $xpNeeded) {
$xp = $xpGot / $xpNeeded * 100;
echo '<p>Level: ' . $level . '</p>';
/* FIXED ? */
echo '<div class="displayBarWrap" title="' . $xpGot . '/' . $xpNeeded . ' XP (' . $xp . '%)"> <p>XP:</p> <div class="displayBar"><div style="width: ' . $xp . '%;"></div></div></div>';
}
}
calculateLevel($user['xp']);
?>