#php #oop #recursion
#php #ооп #рекурсия
Вопрос:
Итак, в моей PHP-программе я создаю функцию календаря, и одним из классов является «CalendarDay». Что я хочу сделать, так это иметь возможность создавать новый день для каждого количества дней, так что, например new CalendarDay (22)
, это означает новую дату 22-го числа месяца. Существует также show()
функция, используемая для отображения каждого дня. Сам класс функционирует нормально, но когда я пытаюсь создать экземпляр new days с помощью рекурсии, кажется, что он больше не работает, поскольку все, что связано с созданным объектом, исчезает с веб-страницы.
class CalendarDay{
private $current_month;
private $current_year;
private $current_date;
public $reminderSet;
public $reminders;
public function __construct($current_day_of_month){
$current_year = date("Y");
$current_month = date("m");
$this->days_in_month = cal_days_in_month(CAL_GREGORIAN, $current_month, $current_year);
$this->current_date = date("d");
$this->current_day_of_month = $current_day_of_month;
}
public function show(){
$output = '<div class = "generator>"';
//$output .= $this->current_date;
//$output .= '<h1>' . $this->current_date . '</h1>';
$output .= '</div>';
$output .= $this->current_day_of_month;
echo $output;
}
}
Моя неудачная попытка рекурсии:
for ($countTo31 == 0; $countTo31 == 31; $countTo31 ){
$holder = $countTo31;
$date = new CalendarDay ($holder);
$date->show();
}
Для справки, этот исходный блок кода без рекурсии работает нормально:
$holder = $countTo31;
$date = new CalendarDay ($holder);
$date->show();
Комментарии:
1. Что вы ожидаете здесь произойти? Если вы собираетесь иметь 31
CalendarDay
объект, то этот метод (и те, что указаны в ответах) не будет работать, поскольку вы перезаписываете объект с каждой итерацией и, следовательно, получаете только последний созданный объект!
Ответ №1:
Я очень смущен тем, чего вы пытаетесь достичь…
У вас есть класс «day», который принимает входные данные для инициализации определенного дня, но вместо этого фактически вычисляет текущий день на основе date("Y-m-d");
?.. А потом все равно выводит входной день?
Честно говоря, это больше похоже на то, что вам нужен объект «месяц»
Начальные проблемы
- Вы используете
==
для определения своей отправной точки==
это не оператор присваивания, это сравнение.- Это эффективно добавляет дополнительную итерацию цикла в начале цикла
for($i == 1; $i < 5; $i ){ echo $i; } // Loop 1: // --> Notice on $i == 1 // --> Notice on $i < 5 // --> Notice on echo $i // --> Notice on $i // Loop 2: --> $i = 1 BECAUSE of the previous $i so the intended loop starts...
- Кроме того, цикл, в этом случае, должен начинаться с 1, а не с 0 (!)
- Вы используете
==
для определения своего состоянияfor
циклы, подобные вашему, эффективно работают как:for ( A ; B ; C ){ // Do something... } // Loop works as: // Check A against B // If TRUE then "Do something..." // and then do C // IF FALSE then break
- Однако, даже если ваше назначение (
A
) было правильным (т. Е.$countTo31 = 1
), Оно все равно не будет работать, потому1 !== 31
что и поэтому циклbreaks
с самого начала - Это должно быть
$countTo31 <= 31
- Зацикливание на объекте, перезапись переменной
- В данный момент ваш код переписывает переменную, которая содержит объект date, с каждым циклом
- Фактически вы создаете объект для вывода дня, выводите эти данные и мгновенно удаляете объект, чтобы его нельзя было использовать ни для чего другого…
- Ваш HTML-вывод содержит a
"
в неправильном месте:$output = '<div class = "generator>"'; //Should be... $output = '<div class = "generator">';
- Некоторые переменные в вашем классе не назначены или не объявлены должным образом
$current_month
объявляется, но никогда не назначается$current_year
объявляется, но никогда не назначается$current_day_of_month
назначается, но не объявляется$days_in_month
назначается, но не объявляется
Промежуточное решение
Без дополнительной информации о том, что вы собираетесь делать, невозможно дать хорошее / точное руководство, поэтому я оставлю рабочий пример, который должен показать вам, что делать:
$days_in_month = cal_days_in_month(
CAL_GREGORIAN,
date("m"),
date("Y")
);
for ($day = 1; $day <= $days_in_month; $day ){
echo "Day {$day}<br>";
}
Предлагаемые изменения
Не похоже, что вам действительно нужен класс «day» для функций, которые вы пытаетесь реализовать. Итак, на мой взгляд, было бы лучше сначала создать объект «месяц» со всеми днями месяца, а затем заставить его генерировать объект «день» для каждого дня месяца, который затем может собирать информацию для каждого дня, например, напоминания.
Делая это таким образом, вы можете затем обновлять каждый день по мере использования, например, данных пользовательского ввода или базы данных.
class Month
{
private $month;
private $year;
private $days = [];
public function __construct($month, $year)
{
$this->month = $month;
$this->year = $year;
$number_of_days = cal_days_in_month(
CAL_GREGORIAN,
$month,
$year
);
for ($i = 1; $i <= $number_of_days; $i ){
$date = "{$this->year}-{$this->month}-{$i}";
// $days[] = new Day($date);
$this->days[$i] = new Day($date);
}
}
public function getDay($day)
{
return $this->days[$day];
}
public function getNumberOfDays()
{
return count($this->days);
}
}
class Day
{
private $date;
private $reminders = [];
public function __construct($date)
{
$this->date = $date;
// Initialise day...
# Get reminders
# Get meetings
# Get bills to pay
}
public function getReminders()
{
return $this->reminders;
}
public function setReminder($content, $time)
{
// Set reminders
$this->reminders[] = [
"content" => $content,
"time" => $time
];
}
public function show()
{
return date("d / m / Y", strtotime($this->date));
}
}
$month = new Month(12, 2020);
for ($i = 1; $i <= $month->getNumberOfDays(); $i ){
echo $month->getDay($i)->show()."<br>";
}