Перейти к содержимому


Помогите объяснить один момент в ООП на PHP новичку

новичок в ООП Свойство класса

Сообщений в теме: 31

#1 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 22 Октябрь 2019 - 20:42

Я пробовал менять свойство в классе, потом его и вовсе закоментил, но print_r($this->style); все равно выводится.

На скриншоте все отобразил и выделил.


Просто, хочу понять логику отработки скрипта.

Почему результат отработки foreach выводится правильно на экран через print_r($this->style); если нет самого свойства //protected $style; ? То есть для эксперимента я специально закоментил свойство //protected $style; но print_r все равно выводит заполненный массив:

Array ( [0] => /promenergo/template/default/style.css )

Прикрепленные файлы

  • Прикрепленный файл  123.jpg   107,94К   10 Количество загрузок:


#2 matroskin8

    Администратор

  • Администраторы
  • 12 415 сообщений
Репутация: 2 124

Отправлено 23 Октябрь 2019 - 06:04

Свойства не обязательно должны быть объявлены, их можно создавать на лету.
class Test
{
    public function __construct()
    {
	    $this->style = 'Hello'; // создаем свойство
    }
}
$a = new Test();
var_dump($a); // в распечатанном объекте будет присутствовать свойство


#3 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 23 Октябрь 2019 - 12:04

Да, интересно...

Минус тогда, что свойство не защищено protected, если это необходимо.

Или например, если я создам свойство с ошибкой proteced $stylerrr; в начале класса, а потом использую это свойство где-то в функции, например:

foreach($this->styles as $style){
$this->style[] = SITE_URL.VIEW.$style;
}

то все отработаем, и я даже могу не заметить ошибки.

Тогда для проверки всегда надо копировать само свойство $stylerrr; чтобы увидеть результат отработки метода.

#4 matroskin8

    Администратор

  • Администраторы
  • 12 415 сообщений
Репутация: 2 124

Отправлено 23 Октябрь 2019 - 12:31

Минус только в том, что Вы можете создать свойство с ошибкой. Но сделать это может тот, кто пользуется Вашим классом. Вы же, когда пишете код класса, сделать этого просто не вправе, поскольку должны протестировать работу написанного кода, чтобы избежать подобных опечаток.
Ну а запретить так делать на уровне языка - это было бы неправильно, поскольку в таком случае мы будем лишены возможности динамического создания свойств.

Просмотр сообщенияdim81 (23 Октябрь 2019 - 12:04) писал:

свойство не защищено protected, если это необходимо.
Задача модификаторов - ограничить доступ к объявленным свойствам, но не запретить создавать свойства, названия которых могут немного отличаться вследствие опечатки.

#5 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 23 Октябрь 2019 - 12:57

как разработчик я не в праве, но как мне отловить например эту ошибку, если код отрабатывается и все выводится на экран.

Пока я только пользуюсь проверками из уроков - это print_r(); и var_dump(); других пока не знаю, но видите не всегда они все показывают)). Как протестировать код, с помощью каких средств?

- по модификаторам согласен, я и написал о защите, а не о запрете.

#6 matroskin8

    Администратор

  • Администраторы
  • 12 415 сообщений
Репутация: 2 124

Отправлено 23 Октябрь 2019 - 15:59

Просмотр сообщенияdim81 (23 Октябрь 2019 - 12:57) писал:

как разработчик я не в праве, но как мне отловить например эту ошибку, если код отрабатывается и все выводится на экран.
Это не ошибка - это нормальное поведение языка.
Выложите мне пример кода, в котором можно допустить ошибку и не отловить ее при отладке. Вот честно, у меня такой ситуации в практике никогда не возникало. Если есть объявленное свойство в начале класса, которое затем заполняется значением и где-то я ошибусь и создам динамически другое свойство, тогда при вызове ожидаемого свойства в другом месте я не увижу ожидаемого значения в этом свойстве и найду ошибку.
Именно так и происходит процесс тестирования и отладки кода. Смотрите, можете даже отвлечься сейчас от классов. Аналогичная ситуация ведь может возникнуть и с переменными. Вы можете ожидать, что значение есть в переменной $test, но где-то в коде ошиблись и написали $tast. На этом основании ведь нельзя запретить на уровне языка создавать переменные, поскольку так нам просто негде будет хранить данные. При отладке такие ошибки достаточно легко найти.

Просмотр сообщенияdim81 (23 Октябрь 2019 - 12:57) писал:

Пока я только пользуюсь проверками из уроков - это print_r(); и var_dump(); других пока не знаю, но видите не всегда они все показывают)). Как протестировать код, с помощью каких средств?
Этих двух функций вполне достаточно и они всегда покажут значение переменной, если таковое есть. Если переменной нет, тогда Вы увидите NULL. Собственно, так и было в Вашем случае, функция print_r() распечатала свойство и это как раз дало понять, что такое свойство есть, у него есть значение, которое где-то присваивается.

#7 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 23 Октябрь 2019 - 20:41

Добрый вечер!

Не могу найти свою ошибку, буду Вам признателен за помощь.

- в файле 11.jpg показал стрелочками какие не выводятся данные.

- в файле 12_ishodnic_skrin.jpg - это скрин 9 урока "Создание класса для вывода статических блоков сайта" - видно, что есть блоки с новостями, каталог и О компании.

Не могу понять почему у меня не выводятся данные согласно файлу 12_ishodnic_skrin.jpg - это новости, каталог и некоторые разделы.

В файле Base.php есть массив $page, но насколько я понимаю это структура, а не сам вывод данных. Есть папка Дефолт, но я опять же пока ни как не разберусь, там ли нужно искать и как подобраться print_r();

Помогите найти ошибку.

Исходники прилагаю.

Заранее Вам благодарен.

Прикрепленные файлы

  • Прикрепленный файл  promenergo.rar   1,33МБ   1 Количество загрузок:
  • Прикрепленный файл  22_ishodnic_skrin.jpg   112,33К   8 Количество загрузок:
  • Прикрепленный файл  11.jpg   89,68К   8 Количество загрузок:


#8 Meits

    Продвинутый пользователь

  • Администраторы
  • 3 092 сообщений
Репутация: 284

Отправлено 24 Октябрь 2019 - 18:40

Здравствуйте!
Новости в правой колонке не отображаются, так как Вы их не выбираете из базы данных. В шаблоне right_bar.php Вы используете переменную $news , но ее значение не определено, а значит данные не отображаются.
Собственно эта переменная формируется в классе Base.php
protected function input() {
 
  $this->title = "Промстрой энерго | ";
 
  foreach($this->styles as $style) {
   $this->style[] = SITE_URL.VIEW.$style;
  }
 
  foreach($this->scripts as $script) {
   $this->script[] = SITE_URL.VIEW.$script;
  }
 
  //object Model
  $this->ob_m = Model::get_instance();
 
  $this->news = $this->ob_m->get_news();
 
  $this->pages = $this->ob_m->get_pages();
 
  $this->catalog_type = $this->ob_m->get_catalog_type();
 
  $this->catalog_brands = $this->ob_m->get_catalog_brands();
 
  $this->header_menu = $this->ob_m->get_header_menu();
 
}

protected function output() {
 
  $this->left_bar = $this->render(VIEW.'left_bar',array(
			  'pages'=>$this->pages,
			  'types' => $this->catalog_type,
			  'brands' => $this->catalog_brands
			  ));
 
  if($this->need_right_side) {
   $this->right_bar = $this->render(VIEW.'right_bar',array(
			    'news' => $this->news
			    ));
  }
 
 
  $this->footer = $this->render(VIEW.'footer', array(
			 'pages' => $this->pages
			 ));
  $this->header = $this->render(VIEW.'header',array(
			   'styles' => $this->style,
			   'scripts' => $this->script,
			   'header_menu' => $this->header_menu,
			   'title' => $this->title,
			   'keywords' => $this->keywords,
			   'discription' => $this->discription
			  
			   ));		  
 
  $page = $this->render(VIEW.'index',
		  array(
		   'header'=>$this->header,
		   'left_bar' =>$this->left_bar,
		   'content' => $this->content,
		   'right_bar' => $this->right_bar,
		   'footer' => $this->footer
		   ));
  return $page;		
}

Я ьы Вам порекомендовал, заново начать смотреть практическую часть кусра, то есть заново с нуля начинать создавать сайт. В первых уроках я показывал и довольно подробно рассказывал о общей логике работы всего движка и даже приводил схему.
По исходникам есть только определенные части кода, но они не полные и соответственно сайт работает только частично.

Если переменые используются в шаблонах, они должны туда передаваться, то есть переменную нужно создать, сохранить в нее определенное значение и только потом передать в шаблон.
Переменная $page, которую Вы указываете, хранит в себе все содержимое, которое выводится на экран.

#9 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 24 Октябрь 2019 - 20:00

Виктор, добрый вечер!

Очень здорово, что сам автор дает разъяснение, спасибо Вам большое!

То есть получается, что в 9 уроке выводятся не новости из БД а обычный HTML код как заглушка - там, где новости и каталог (скриншот ishodnic_skrin) - скрин сделал в самом конце 9 урока. Ведь с БД мы начинаем работать аж в 11 уроке, а в 10 идет лишь формирование запросов к БД, правильно?

Тогда я мог не те HTML шаблоны c заглушкой использовал и надо посмотреть, есть ли они вообще, поскольку в них, то есть шаблонах папки темплейт/дефолт уже прописан местами php.

По логике как раз все понятно:

Есть основной абстрактный класс Base_controller, у него есть как бы вспомогательный класс Base,

у Вase есть классы-контроллеры Главная, Новости, Каталог и т.д.

Распаршивает контроллеры и параметры Route_Controller, который реализован очень наглядно и доступно на мой взгляд.

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

#10 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 24 Октябрь 2019 - 20:03

да, спасибо, что прикрепили код, но это уже после 9 урока идет реализация методов и описание модели.

#11 Meits

    Продвинутый пользователь

  • Администраторы
  • 3 092 сообщений
Репутация: 284

Отправлено 25 Октябрь 2019 - 05:53

Просмотр сообщенияdim81 (24 Октябрь 2019 - 20:03) писал:

да, спасибо, что прикрепили код, но это уже после 9 урока идет реализация методов и описание модели.
Пожалуйста!

#12 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 27 Октябрь 2019 - 20:20

Виктор, добрый вечер!

В файле Base_Controller вы показываете сначала как вывести страницу в методе Route 2 строчками:

$obj = new $this->controller;
$obj->request($this->params);

Но говорите, что это не красиво и предлагаете внутри Route использовать метод ReflectionClass.

Мне как новичку пока тяжело-то вникнуть в ReflectionClass, и на этапе освоения php хотелось бы, что-то полегче.

ReflectionClass я может быть оставил на закуску или вовсе отказаться.


Скажите, можно ли все-таки использовать данное обращение:


$obj = new $this->controller;
$obj->request($this->params);

Это рабочее решение, или так действительно не красиво или не правильно?

Или есть какой-то другой рабочий промежуточный способ, не такой громоздкий как ReflectionClass - в методе Route он занимает 8 строчек.

Большое спасибо!

#13 Meits

    Продвинутый пользователь

  • Администраторы
  • 3 092 сообщений
Репутация: 284

Отправлено 28 Октябрь 2019 - 07:26

Доброе утро!
Отражения дают возможность получить информацию о классе и по сути все. Их можно не использовать и применять первый способ - стандартное создание объекта класса

#14 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 28 Октябрь 2019 - 07:36

Спасибо за разъяснение.
Я вижу возможность использования отражения например в изучении различный CMS - например как устроена их логика.

#15 Meits

    Продвинутый пользователь

  • Администраторы
  • 3 092 сообщений
Репутация: 284

Отправлено 28 Октябрь 2019 - 07:38

Просмотр сообщенияdim81 (28 Октябрь 2019 - 07:36) писал:

Спасибо за разъяснение.
Я вижу возможность использования отражения например в изучении различный CMS - например как устроена их логика.
Пожалуйста!

#16 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 29 Октябрь 2019 - 17:56

Здравствуйте, уважаемые Виктор!

Подскажите, пожалуйста, по файлу Base, - мы в методе input через foreach вызываем $this->styles as $style

$this->styles (в нем мы храним 'style.css' ) если я правильно понимаю мы берем из файла Base_Controller ???

То есть мы получаем доступ к этому свойству , через наследование классов? - Abstract class Base extends Base_Controller - Правильно ли я понимаю?

на всякий случай прикрепил 2 скрина.



Спасибо большое!

Прикрепленные файлы

  • Прикрепленный файл  Base_Controller.jpg   113,17К   4 Количество загрузок:
  • Прикрепленный файл  Base.jpg   121,53К   7 Количество загрузок:


#17 Meits

    Продвинутый пользователь

  • Администраторы
  • 3 092 сообщений
Репутация: 284

Отправлено 30 Октябрь 2019 - 07:09

Просмотр сообщенияdim81 (29 Октябрь 2019 - 17:56) писал:

Здравствуйте, уважаемые Виктор!

Подскажите, пожалуйста, по файлу Base, - мы в методе input через foreach вызываем $this->styles as $style

$this->styles (в нем мы храним 'style.css' ) если я правильно понимаю мы берем из файла Base_Controller ???

То есть мы получаем доступ к этому свойству , через наследование классов? - Abstract class Base extends Base_Controller - Правильно ли я понимаю?

на всякий случай прикрепил 2 скрина.



Спасибо большое!
Здравствуйте!
Да все верно, в классе родителе мы определяем значения свойства, а в дочернем классе, мы получаем доступ к нему.

#18 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 04 Ноябрь 2019 - 13:58

Здравствуйте, Виктор!

Буду признателен Вам за разъяснение.

Мое понимание по ООП было следующим:

1. Мы создаем абстрактный класс, какой-то вспомогательный класс - пишем в них как бы чертеж, какие-то методы, делаем перезагрузки методов и т.д.

2. Далее мы создаем объект класса(то есть это уже как бы сущность) и далее мы у этого объекта вызываем какой-то метод на исполнение.

Отлично, все здорово.

Но вот эта запись меня немного сбила с толку:

$obj = new $this->controller;
$obj->request($this->params);

То есть мы создаем объект не у класса, а у свойства(оно заполнено), далее мы у заполненного свойства вызываем метод request.

Нет, не так. Мы в объект поместили заполненное свойство, а уже у этого объекта вызвали главный метод request класса Base_Controller.

То есть в зависимости от задачи мы можем вызывать объект как у класса, так и у отдельного свойства или метода???

Поскольку до этого случая я думал, что только у класса может быть объект, и далее мы можем обращаться к какому-то его методу или методам.

Спасибо!

#19 Meits

    Продвинутый пользователь

  • Администраторы
  • 3 092 сообщений
Репутация: 284

Отправлено 05 Ноябрь 2019 - 07:15

Просмотр сообщенияdim81 (04 Ноябрь 2019 - 13:58) писал:

Здравствуйте, Виктор!

Буду признателен Вам за разъяснение.

Мое понимание по ООП было следующим:

1. Мы создаем абстрактный класс, какой-то вспомогательный класс - пишем в них как бы чертеж, какие-то методы, делаем перезагрузки методов и т.д.

2. Далее мы создаем объект класса(то есть это уже как бы сущность) и далее мы у этого объекта вызываем какой-то метод на исполнение.

Отлично, все здорово.

Но вот эта запись меня немного сбила с толку:

$obj = new $this->controller;
$obj->request($this->params);

То есть мы создаем объект не у класса, а у свойства(оно заполнено), далее мы у заполненного свойства вызываем метод request.

Нет, не так. Мы в объект поместили заполненное свойство, а уже у этого объекта вызвали главный метод request класса Base_Controller.

То есть в зависимости от задачи мы можем вызывать объект как у класса, так и у отдельного свойства или метода???

Поскольку до этого случая я думал, что только у класса может быть объект, и далее мы можем обращаться к какому-то его методу или методам.

Спасибо!
Здравствуйте!
Объект класса создается исключительно у класса, но имя этого класса может быть написано как вручную, так и хранится в переменной, или в свойстве другого класса. К примеру $this->controller, хранится имя класса, для которого нужно создать объект.

#20 dim81

    Пользователь

  • Пользователи
  • PipPip
  • 26 сообщений
Репутация: 0

Отправлено 05 Ноябрь 2019 - 09:15

Спасибо большое, Вот это место:
if(!empty($url[0])){
$this->controller = ucfirst($url[0]).'_Controller';
}
else{
$this->controller = "Index_Controller";
}
...Ну а метод request у страниц мы вызываем через класс Base, а тот в свою очередь получает его из основного абстрактного класса Base_Controller





Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных