Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP 5/6. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Календарь
 
 автор: kilogram   (31.05.2012 в 23:26)   письмо автору
 
 

В книге там прохожу немного даты и такой окд, вроде все верно написал, но он ругается на второй орич в конце кода непонятно почему.


<?php
//echo '<pre>'.print_r(getdate(),1).'</pre>';
function Calendar($year,$month){
$wday JDDayofWeek(GregorianToJD($month,1,$year),0);
if(
$wday == 0$wday 7;
$n = - ($wday 2);
$cal = array();
    for(
$j 0$j 6$j++){
        
$row = array();
        
$notEmpty false;
         for(
$x 0$x 7$x++,$n++){
        if(
checkdate($month,$n,$year)){
        
$row[] = $n;
        
$notEmpty true;        
            } else{ 
$row ''; }
        }
    if(!
$notEmpty) break;
    
$cal[] = $row;
    }
    return 
$cal;
}
//Формируем календарь на текущий месяц
$now getdate();
$cal Calendar($now['year'],$now['mon']-1);
?>
<!-- Шаблон вывода календаря -->
<table border="1">
    <tr>
        <td>Пн</td>
        <td>Вт</td>
        <td>Ср</td>
        <td>Чт</td>
        <td>Пт</td>
        <td>Сб</td>
        <td style="color:red">Вс</td>
    </tr>
    <? foreach ($cal as $row) {?>
    <tr>
    <? foreach ($row as $i=>$v){?>
    <td style="<?=$i==6?'color:red':''?>">
        <?=$v$v '&nbsp;'?>
    </td>
    <? ?>
    </tr>
    <? ?>
</table>




Warning: Invalid argument supplied for foreach() in C:\www\htdocs\test.ru\www\index.php on line 39

  Ответить  
 
 автор: kilogram   (31.05.2012 в 23:57)   письмо автору
 
   для: kilogram   (31.05.2012 в 23:26)
 

Я так понял из-за вот этого места может for($j = 0; $j < 6; $j++){
Если написать там for($j = 0; $j < 5; $j++){ тогда выведет без ошибки, но выведет не все рабочие дни этого месяца.

  Ответить  
 
 автор: Киналь   (01.06.2012 в 00:07)   письмо автору
 
   для: kilogram   (31.05.2012 в 23:26)
 

Ну как же непонятно. Он же вам пишет: "Invalid argument supplied for foreach()". Что это значит? Переведите, например, гугл-переводчиком.

  Ответить  
 
 автор: kilogram   (01.06.2012 в 00:08)   письмо автору
 
   для: Киналь   (01.06.2012 в 00:07)
 

Ну я переводу наверное так: Внимание: Ошибка аргумента поставляемого для форич. А как же ошибка, если вроде правильный аргумент поставляется, данный код из книги, не мой.

  Ответить  
 
 автор: kilogram   (01.06.2012 в 01:10)   письмо автору
 
   для: kilogram   (01.06.2012 в 00:08)
 

Вот взял исходник, нашел папку этого календаря и выдает что 1 июня это воскресенье, что за бред? Автор книги ошибся что ли?
Что может не правильно быть в коде, как-то странно. Вот оригинал автора с книги. Вот на сервер забросил результат http://santa.comoj.com/
<?php ## Календарь на текущий месяц.
// Функция формирует двумерный массив, представляющий собой
// календарь на указанный месяц и год. Массив состоит из строк,
// соответствующих неделям. Каждая строка - массив из семи 
// элементов, которые равны числам (или пустой строке, если
// данная клетка календаря пуста).
function makeCal($year$month) {
  
// Получаем номер дня недели для 1 числа месяца. Корректируем 
  // его, чтобы воскресенье соответствовало числу 7, а не числу 0.
  
$wday JDDayOfWeek(GregorianToJD($month1$year), 0);
  if (
$wday == 0$wday 7;
  
// Начинаем с этого числа в месяце (если меньше нуля 
  // или больше длины месяца, тогда в календаре будет пропуск).
  
$n = - ($wday 2);
  
$cal = array();
  
// Цикл по строкам.
  
for ($y=0$y<6$y++) {
    
// Будущая строка. Вначале пуста.
    
$row = array();
    
$notEmpty false;
    
// Цикл внутри строки по дням недели.
    
for ($x=0$x<7$x++, $n++) {
      
// Текущее число >0 и < длины месяца?
      
if (checkdate($month$n$year)) {
        
// Да. Заполняем клетку.
        
$row[] = $n;
        
$notEmpty true;
      } else {
        
// Нет. Клетка пуста.
        
$row[] = "";
      }
    }
    
// Если в данной строке нет ни одного непустого элемента,
    // значит, месяц кончился.
    
if (!$notEmpty) break;
    
// Добавляем строку в массив.
    
$cal[] = $row;
  }
  return 
$cal;
}

// Формируем календарь на текущий месяц.
$now getdate();
$cal makeCal($now['year'], $now['mon']-1);
?>
<!-- Шаблон вывода календаря. -->
<table border=1>
  <tr>
    <td>Пн</td>
    <td>Вт</td>
    <td>Ср</td>
    <td>Чт</td>
    <td>Пт</td>
    <td>Сб</td>
    <td style="color:red">Вс</td>
  </tr>
  <!-- цикл по строкам -->
  <?foreach ($cal as $row) {?>
    <tr>
      <!-- цикл по столбам -->
      <?foreach ($row as $i=>$v) {?>
        <!-- воскресенье - "красный" день -->
        <td style="<?=$i==6'color:red' ''?>">
          <?=$v$v "&nbsp;"?>
        </td>
      <?}?>
    </tr>
  <?}?>
</table>

  Ответить  
 
 автор: confirm   (01.06.2012 в 09:04)   письмо автору
 
   для: kilogram   (01.06.2012 в 01:10)
 

Выбросите вы этот календарь, практической пользы от него все равно никакой, да и написан он мягко сказать из рук вон.
function makeCal($year, $month)... это лишнее, так как вам нужен всего лишь день недели и количество дней в месяце, чтобы построить календарь. А далее просто вывод таблицы.

  Ответить  
 
 автор: kilogram   (01.06.2012 в 21:27)   письмо автору
 
   для: confirm   (01.06.2012 в 09:04)
 

Вроде работает, не совсем въехал в эту строку, объясните её если кто может.


 $wday = JDDayOfWeek(GregorianToJD($month, 1, $year), 0);

  Ответить  
 
 автор: kilogram   (02.06.2012 в 00:42)   письмо автору
 
   для: kilogram   (01.06.2012 в 21:27)
 

Вроде разобрался, возращается день недели, а вот здесь Не могу понять, почему здесь -2?
 $n = - ($wday - 2);

  Ответить  
 
 автор: confirm   (02.06.2012 в 05:25)   письмо автору
 
   для: kilogram   (02.06.2012 в 00:42)
 

Пишем календарь. Что нужно для этого:
1) день недели первого дня текущего месяца - определяет ячейку таблицы, с которой начинается вывод дней текущего месяца;
2) количество дней в текущем месяце - определяет последнюю ячейку в таблице, в которой заканчивается вывод дней текущего месяца.
Это все. Остальное нам известно - месяц начинается с 1 числа, неделя, это 7 дней.

Следовательно календарь, это счетчик итерации ЕДИНСТВЕННОГО цикла, в котором нужно проверять состояние этого счетчика, и корректируя его по дню недели, производить вывод таблицы.

Календарь можно выводить от первой недели, и заканчивать на последней. Но "хвост" календаря в этом случае будет прыгать в зависимости от количества дней в месяце и первого дня недели. Чтобы избавиться от этого на html-странице, что может портить дизайн расположенных рядом элементов, к примеру, будем выводить календарь в фиксированное число ячеек в таблице - 42 (без учета шапки календаря). 42 потому, что в 35 ячейках помещается максимум 31 день, с условием, если первый день недели не далее пятницы.

Пустые ячейки календаря будем использовать более рационально - выводить в них дни предыдущего и последующего месяцев. О последующем месяце нам все известно - начинается с 1 числа, а о предыдущем нужно узнать - количество дней в нем.
<?
//получаем день недели первого дня текущего месяца
//и количество дней в этом месяце,
//помещая эти данные в массив
$days explode('|'date('w|t'strtotime('2012/06/01')));
//строка '2012/06/01' содержит строковое значение даты
//запрашиваемой пользователем при навигацию по календарю,
//по который нужно его вывести

//получаем количество дней в предыдущем месяце
$prev date('t'strtotime('2012/05'));

//корректируем "буржуйский" день недели в "пролетарский" -
//если воскресенье, то у нас это будет день недели с номером 6, а не 0
$days[0] = !$days[0] ? $days[0]-1;
?>
<!-- стили календаря -->
<style>
table {
  font: 9pt arial; 
  color:#000;
}
td {
  text-align: right; 
  border: 1px solid #BFBFBF;
}
.prv {
  background: #F0F0F0; 
  color: #CECECE;
  border: 1px solid #E2E2E2;
}
.red {color:#f00;}
</style>
<!-- заголовок календаря -->
<table border="0" cellpadding="1" cellspacing="1"> 
  <tr> 
    <td>Пн</td> 
    <td>Вт</td> 
    <td>Ср</td> 
    <td>Чт</td> 
    <td>Пт</td> 
    <td>Сб</td> 
    <td class="red">Вс</td> 
  </tr>
  <tr>
<?
//ВЫВОД КАЛЕНДАРЯ
//Если первая неделя не с понедельника, и пока счетчик цикла не равен 
//дню недели первого дня месяца, то выводим дни предыдущего месяца, 
//получая их вычитанием из числа его дней номер дня недели 
//корректируемый по счетчику итераций цикла.
//Если счетчик цикла больше номера дня недели плюс количество дней месяца,
//то выводим дни следующего месяца, получая их вычитанием из итерации цикла 
//номера дня недели плюс количество дней текущего месяца.
//Иначе выводим дни текущего месяца, получая их
//вычитанием из итерации цикла номера дня недели.
//В цикле проверяем границы недели, закрывая и открывая строку таблицы,
//а также подсвечиваем красным воскресения

$cells '';
for(
$i=0$i<42$i++) { 
  if(!(
$i%7)) $cells .= '</tr><tr>'//если неделя заполнена
  
$cells .= $i >= $days[0] && $i <= array_sum($days)-
            
'<td'.(!(($i+1)%7)  //если воскресение
                     
' class=red' 
                     
'').'>'.($i+1-$days[0]).'</td>'  //текущее число
            
'<td class=prv>'.($i array_sum($days)-
                                
$i-array_sum($days)+//следующий месяц 
                                
$prev-($days[0]-($i+1))).'</td>'//предыдущий месяц
}
echo 
$cells;    
?>
<!-- закрываем последнюю строку и таблицу календаря -->
</tr></table>

Приведенный код подтверждает предположение выше, что для построение календаря необходимости писать функцию, которая делает бесполезную работу (как приведено ранее), нет. И требуется всего лишь один цикл.

Беда такого календаря в том, что в нем нет ничего практичного в веб среде. Чтобы придать календарю практичность, нужно сделать элементы календаря гиперссылками. В этом случае каждый день календаря, это может быть запрос новостей выбранного дня и месяца. Если добавляется такая возможность, значит нужна будет и навигация по календарю - выбор года/месяца, по которым можно получить предыдущие новости. Из этого следует - вывод календаря должен обеспечивать клиентский скрипт (javascript), а для того чтобы при навигации по календарю не происходила перезагрузка страницы, в данном случае ненужная, запросы за ссылками к календарю нужно производить ajax-методом. При этом ответ сервера не должен руководствоваться принципом - нет новости, значит отправляем для такого дня пустое сообщение. Сервер должен отдавать только имеющиеся ссылки, ключами которых является день, все остальное сделает клиентский скрипт.

Вы будете работать в необычной среде, не в рамках локальной машины, а значит работая над кодом чего либо конкретного, должны учитывать такую среду. Чтобы смоделировать взаимодействие клиент-сервер на примере календаря, не обязательно создавать базу с новостями, достаточно простого массива с примитивными данными, да и ajax не такой и страшный для понимания. Вот от этого будет польза, а муть с который вы разбираетесь не заслуживает траты времени на нее. Все что написано по принципу "в лоб", не только необдуманно по содержанию, но и не интересно, чтобы еще разбираться в глюках его.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования