Этот урок набрал набрал достаточно большое количество
комментариев и дальнейшее его комментирование отключено.
Если вы хотели убедиться в правильности выполнения ДЗ или у вас возник вопрос по уроку,
посмотрите ранее добавленные комментарии, кликнув по кнопке ниже. Скорее всего вы найдете там то, что искали.
Если это не помогло - задайте вопрос в чате в телеграме - https://t.me/php_zone
Всё норм, кроме, опять же, типов аргументов - их нужно указывать. Так не пишут уже пару лет.
И строки без переменных в них нужно писать в одинарных кавычках.
Не мог он такую подсказку дать, он говорит, что в Ваших настройках PHPStorm указана версия PHP < 7, а типы появились позже. Нужно зайти в настройки PHPStorm в пункт PHP и выбрать правильную версию.
Создайте ещё один класс, являющийся наследником класса Lesson - PaidLesson (платный урок).
Объявите в нем свойство price (цена), а также геттеры и сеттеры для этого свойства. Добавьте в конструкторе параметр, через который это свойство будет устанавливаться при создании объекта.
Создайте объект этого класса со следующими свойствами:
заголовок: Урок о наследовании в PHP
текст: Лол, кек, чебурек
домашка: Ложитесь спать, утро вечера мудренее
цена: 99.90
Выведите этот объект с помощью var_dump()
<?php
class Post
{
protected $title;
protected $text;
public function __construct(string $title, string $text)
{
$this->title = $title;
$this->text = $text;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title): void
{
$this->title = $title;
}
public function getText()
{
return $this->text;
}
public function setText($text): void
{
$this->text = $text;
}
}
class Lesson extends Post
{
protected $homework;
public function __construct(string $title, string $text, string $homework)
{
parent::__construct($title, $text);
$this->homework = $homework;
}
public function getHomework(): string
{
return $this->homework;
}
public function setHomework(string $homework): void
{
$this->homework = $homework;
}
}
class PaidLesson extends Lesson
{
protected $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function getPrice(): float
{
return $this->price;
}
public function setPrice(float $price): void
{
$this->price = $price;
}
}
$lesson = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек',
'Ложитесь спать, утро вечера мудренее', 99.90);
var_dump($lesson);
Это из-за опечатки в написании: __conctruct, а должно быть __construct.
И обратите внимание, что где-то в конструкторе вы задаете свойства через сеттеры, а где-то напрямую пишете в свойства. Как именно делать - решать вам, но делайте это одинаково.
class PaidLesson extends Lesson
{
private $price;
public function __construct($title, $text, $homework, $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function setPrice($price)
{
$this->price = $price;
}
public function getPrice()
{
return $this->price;
}
}
$plesson = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложитесь спать, утро вечера мудренее', 99.90);
var_dump($plesson);
P.S. Опять этот вопрос по поводу использования типов данных. Где-то в документации по PHP прочитал что добавлением псевдотипов данных используется с PHP 7.1 как подсказка для программистов.
Правда это? Или еще есть др. объяснение, в качестве доп. защиты данных?
К слову сказать в PhpStorme(установлена последняя версия) есть подсказки написания геттеров и сеттеров и там почему-то не добавляет эти доп. данные?
Объявите в нем свойство price (цена), а также геттеры и сеттеры для этого свойства. Добавьте в конструкторе параметр, через который это свойство будет устанавливаться при создании объекта.
<?php
include "Lesson.php";
class PaidLesson extends Lesson
{
private $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function setPrice(string $price): void
{
$this->price = $price;
}
public function getPrice()
{
return $this->price;
}
}
Создайте объект этого класса со следующими свойствами:
заголовок: Урок о наследовании в PHP
текст: Лол, кек, чебурек
домашка: Ложитесь спать, утро вечера мудренее
цена: 99.90
<?php
include "PaidLesson.php";
$paidLesson1 = new PaidLesson(
'Урок о наследовании в PHP',
'Лол, кек, чебурек',
'Ложитесь спать, утро вечера мудренее',
99.90);
Выведите этот объект с помощью var_dump()
var_dump($paidLesson1);
Большое спасибо за эти уроки, до этого изучал давненько Java, как бы ООП язык, но о ООП знал "слышу звон, не знаю где он", неуверенно себя чувствовал. НО сейчас очень много точек расставилось над i.
в Java вроде было правило, что файл должен иметь название идентичное названию класса, есть ли вообще такое правило, и применяется ли оно к РНР?. Спасибо
У меня у одного ошибка при выполнении метода класса Post:
public function setText($text):void
{
$this->text = $text;
}
когда пытаюсь использовать сеттер,
Fatal error: Uncaught TypeError: Return value of Post::setText() must be an instance of void, none returned in W:\domains\myproject.loc\www\index.php:26 Stack trace: #0 W:\domains\myproject.loc\www\index.php(51): Post->setText('\xD0\x98\xD0\xB2\xD0\xB5\xD0\xBD\xD0\xB5\xD1\x86\xD0\xBA\xD0...') #1 {main} thrown in W:\domains\myproject.loc\www\index.php on line 26.
Как я понял ожидается возврат любого значения, из-за void, но его не происходит, т.к. нам return не нужен.
Если при выполнении домашки в классе Lesson модификатор доступа оставить private $homework; то результат выдает вот такой, но это же неверно? Не совсем понимаю что должно сломаться в этом случае
Артем, спасибо за урок!
Есть вопрос:
В классе Lesson оставляю модификатор доступа к свойству 'homework' как 'private' и все выводится без ошибок, однако, судя по тексту урока, я не должен был получить доступ к этому свойству из наследуемого класса (т.к. 'private', а не 'protected'). Увидел комментарий выше о том, что через публичные геттеры и сеттеры можно достучаться до частных свойств родительского объекта. Это именно тот случай или у меня где-то закралась ошибка? Как делать правильнее и на что это влияет (скорость, безопасность, качество кода и т.д.)?
class Post
{
protected $title;
protected $text;
public function __construct(string $title, string $text)
{
$this->title = $title;
$this->text = $text;
}
public function getTitle()
{
return $this->titile;
}
public function setTitle($title): void
{
$this->$title;
}
public function getText()
{
return $this->text;
}
public function setText($text): void
{
$this->text=$text;
}
}
class Lesson extends Post
{
private $homework;
public function __construct(string $title, string $text, string $homework)
{
parent::__construct($title, $text);
$this->homework = $homework;
}
public function getHomework()
{
return $this->homework;
}
public function setHomework($homework): void
{
$this->homework=$homework;
}
}
class PaidLesson extends Lesson
{
private $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function getPrice()
{
return $this->price;
}
public function setPrice($price): float
{
$this->price=$price;
}
}
$paidlesson1 = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложитесь спать, утро вечера мудренее', 99.90);
var_dump($paidlesson1);
<?php
class Post
{
protected $title;
protected $text;
public function __construct(string $title, string $text)
{
$this->title = $title;
$this->text = $text;
}
public function setTitle($title): void
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setText($text): void
{
$this->text = $text;
}
public function getText()
{
return $this->text;
}
}
class Lesson extends Post
{
protected $homework;
public function __construct(string $title, string $text, string $homework)
{
parent::__construct($title, $text);
$this->homework = $homework;
}
public function setHomework($homework): void
{
$this->homework = $homework;
}
public function getHomework()
{
return $this->homework;
}
}
class PaidLesson extends Lesson
{
private $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function setPrice($price): void
{
$this->price = $price;
}
public function getPrice()
{
return $this->price;
}
}
$paidLesson = new PaidLesson('Урок о наследовании в PHP', 'Позновательные уроки о наследовании',
'Утро вечера мудренее',99.99);
var_dump($paidLesson );
Для чего сделали поля protected? В коде дочернего класса вы их не используете. А достучаться до них из унаследованных public-методов родительского класса вы можете.
1 ВПР. По уроку смотрел, но работает и с приватным модификатором также, а как правильно необходимо было сделать?
2 ВПР. Слетела лицензия на PHPStorm 2018.1; нашел новую скачал и установил PhpStorm 2019.2.1 Build #PS-192.6262.66. Так вот, а новая версия мне показывает все методы в данном домашнем задании(геттеры и сеттеры) с ошибкой: Unused elements: getTitle и так со всеми.
3 ВПР. Забегая немного в перед, это уже с 10-13 урока, при создании классов по уроку дает PHPStorm такое сообщение: 03.09.2019
17:19 Do you want to mark folder as PSR-0 root?
C:/OpenServer 5.3.0/OSPanel/domains/myproject.loc/src
Mark as PSR-0 root
Что мне с ним делать? Мы же вроде по уроку стандарт PSR-4 используем.
Вот когда надо будет, тогда и сделаешь. А по умолчанию всегда ставь private. Иначе непонятно будет, используется ли свойство только в этом классе или где-то ещё.
Fatal error: Class 'Post' not found in D:\OSPanel\domains\localhost\PHP.Zone\OOP\Blog\Lesson.php on line 9
Кто подскажет, что слетело в OpenServer или PHPShtorm
Не видит классы и все....устал бороться уже.
class PaidLesson extends Lesson
{
private $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function getPrice(): float
{
return $this->price;
}
public function setPrice(): void
{
$this->price = $price;
}
}
$paidLesson = new paidLesson(' Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложитесь спать, утро вечера мудренее', 99.90);
var_dump($paidLesson);
у класса Lesson у свойства $homework prived исправил на protected
В конструкторе надо тип поменять на float $price и в геттере тип возвращаемого значения :float выставить. О, Боже! Куда я вообще смотрел когда делал домашку?! :-0
Но в дочерних классах нет прямого обращения к этим свойствам. Они обращаются к ним через public-методы родителей, а так можно. Так что все свойства в вашем примере должны быть private.
<?php
class Post
{
protected $title;
protected $text;
public function __construct(string $title,string $text)
{
$this->title=$title;
$this->text=$text;
}
public function getTitle(){
return $this->title;
}
public function setTitle($title):void
{
$this->title=$title;
}
public function getText()
{
return $this->text;
}
public function setText($text) :void
{
$this->text=$text;
}
}
class Lesson extends Post
{
protected $homework;
public function __construct(string $title,string $text,string $homework){
parent::__construct($title,$text);
$this->homework=$homework;
}
public function getHomework():string
{
return $this->homework;
}
public function setHomework(string $homework): void
{
$this->homework=$homework;
}
}
class PaidLesson extends Lesson
{
private $price;
public function __construct(string $title,string $text, string $homework, string $price){
parent::__construct($title,$text,$homework);
$this->price=$price;
}
public function getPrice():string
{
return $this->price;
}
public function setPrice(double $price): void
{
$this->price=$price;
}
}
$lesson = new PaidLesson('Урок о наследовании в PHP','Лол, кек, чебурек','Ложитесь спать, утро вечера мудренее',99.90);
var_dump($lesson);
/*
Да, я вкурсе форматирования, обещаю, завтра я поставлю PHPStorm, и заморачиваться с форматированием)
Где тип аргумента? Почему скобка фигурная на той же строке, что и имя метода? Посмотрите в обязательном порядке урок по функциям из курса PHP для начинающих.
Коллеги писали его потому, что читали внимательно предыдущий урок, и знали, что свойство должно быть private.
Как вариант - сделать метод toArray(), который будет формировать массив вида ключ-значение. Но в этом методе конечно нужно будет описать весь маппинг. Вариант с var_dump для отладки - самое то!
Неправильный подход. Правильнее исходить из того, что нужно сейчас и по-максимуму делать все поля private. А уж если понадобится, то ослаблять доступность.
А в Post почему оставили protected?
<?php
class Post
{
private $title;
private $text;
public function __construct(string $title, string $text)
{
$this->title = $title;
$this->text = $text;
}
public function getTitle():string
{
return $this->title;
}
public function setTitle($newTitle): void
{
$this->title = $newTitle;
}
public function getText():string
{
return $this->text;
}
public function setText($newText): void
{
$this->text = $newText;
}
}
class Lesson extends Post
{
private $homework;
public function __construct(string $title, string $text, string $homework)
{
parent::__construct($title, $text);
$this->homework = $homework;
}
public function getHomework():string
{
return $this->homework;
}
public function setHomework(string $newHomework): void
{
$this->homework = $newHomework;
}
}
class PaidLesson extends Lesson
{
private $price;
public function __construct( string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function getPrice():float
{
return $this->price;
}
public function setPrice(float $newPrice):void
{
$this->price = $newPrice;
}
}
$paidLesson = new PaidLesson('Урок о наследование PHP', 'Лол,кек,чебурек',
'Ложитесь спать, утро вечера мудренее', 99.90);
var_dump($paidLesson);
Изначально код писал на компьютере, но видимо он у меня лаганул и показывал 2 момх комента. Зашёл с телефона и увидел, что кода моего нет.
Пришлось, используя чужой код, воссоздавать свой код с телефона, ибо с телефона форматировать код вообше неудобно.
P.S. мой код действительно так и выглядел, даже имена переменных на свои поменял ($newTitle, $newText, $newHomework, $newPrice)
Урок прочитал(я с других источников пришёл, но здесь я понял, что это рай для мозга), исправил имена переменных
убрал пробелы, по незнанию ставил пробелы, чтобы мне было понятно и приятно, перестал ставить. Придётся переделывать все свои коды :>
Благо, я недавно начал проходить ООП и много кода не создал. Ваши уроки помогают, начал проходить ООП на другом сайте и не понял тему интерфейсов, а здесь понял.
Вы правы, в уроке я допустил некоторую неточность. Дополнил урок, начиная со слов: "Обратите внимание, что если у родительского класса есть метод...". Изучите, пожалуйста, это дополнение.
<?php
class Post
{
private $title;
private $text;
public function __construct(string $title, string $text)
{
$this->title = $title;
$this->text = $text;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title): void
{
$this->title = $title;
}
public function getText()
{
return $this->text;
}
public function setText($text): void
{
$this->text = $text;
}
}
class Lesson extends Post
{
private $homework;
public function __construct(string $title, string $text, string $homework)
{
parent::__construct($title, $text);
$this->homework = $homework;
}
public function getHomework(): string
{
return $this->homework;
}
public function setHomework(string $homework): void
{
$this->homework = $homework;
}
}
class PaidLesson extends Lesson
{
private $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text, $homework);
$this->price = $price;
}
public function getPrice(): float
{
return $this->price;
}
public function setPrice(float $price): void
{
$this->price = $price;
}
}
$lesson = new Lesson('Заголовок', 'Текст', 'Домашка');
var_dump($lesson);
$paidLesson = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложитесь спать, утро вечера мудренее', '99.90');
var_dump($paidLesson);
Есть вопрос по сеттерах. Для чего мы указываем тип возвращаемого значения void у них? В мануале пишет, что такие функции не должны ничего возвращать. А вот для чего это нам я так и не понял.
Спасибо за интересное задание: выполнила с удовольствием! Намного понятнее излагаете основные принципы, чем в книжках или других ресурсах. Вопросик: Я использую св-во price типа string, поскольку решила, что нужно точно создать объект как в примере, однако, если опустить слова 'цена', то можно объявить тип float, поскольку значение 99.90, верно? ). Опустила в начале кода <?php - ведь это отрывок из программы с классами Post и Lesson
/*создаем класс PaidLesson (платный урок), являющийся наследником Leson*/
class PaidLesson extends Lesson
{
private $price; //объявляем свойство price (цена)
/*конструктор*/
public function __construct(string $title, string $text, string $homework, string $price)
{
parent :: __construct($title, $text, $homework);
$this->price = $price;
}
public function getPrice(): string //геттеры
{
return $this->price;
}
public function setPrice(string $price): void //сеттеры
{
$this->price = $price;
}
}
//создание объекта класса с требуемыми свойствами
$paidLesson = new PaidLesson(
'заголовок: Урок о наследовании в PHP',
'текст: Лол, кек, чебурек',
'домашка: Ложитесь спать, утро вечера мудренее',
'цена: 99.90'
);
var_dump($paidLesson); //вывод объекта через var_dump()
/*object(PaidLesson)[1]
private 'price' => string 'цена: 99.90' (length=15)
private 'homework' (Lesson) => string 'домашка: Ложитесь спать, утро вечера мудренее' (length=83)
private 'title' (Post) => string 'заголовок: Урок о наследовании в PHP' (length=63)
private 'text' (Post) => string 'текст: Лол, кек, чебурек' (length=42)*/
Мои рекомендации: по уроку Наследование в PHP.
Создать папку classes. В ней создать три файла с классами: два класса + один из домашки с названиями:
PaidLessonBlog
LessonBlog
PostBlog
Создать файл index.php или можете назвать Run.php. Который размещён выше на уровень папки classes, вообщем не в этой папке. И он служит для создания и вызовов методов:
<?php
error_reporting(-1); //Подключили отображение ошибок
require_once 'classes/PostBlog.php'; //Должен быть порядок, так как классы могут не увидеть друг друга.
require_once 'classes/LessonBlog.php';
require_once 'classes/PaidLessonBlog.php';
function debug($data){ //Чтобы было красиво
echo '<pre>' . print_r($data,1) . '</pre>';
}
/*$lesson = new LessonBlog('Заголовок', 'Текст', 'Домашка');
debug($lesson);*/
$PaidLesson = new PaidLessonBlog('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Домашка','99.90', 'Ложитесь спать, утро вечера мудренее');
debug($PaidLesson);
1) Каждый класс должен быть в отдельном файле.
2) Blog - так для меня более понятно, что эти классы относятся к Блогу.
3) Сначала, показать такой способ, потом в следующем уроке ещё лучше:
function autoloader1($class) {
$file = __DIR__ . "/classes/{$class}.php";
//Проверка: существует ли файл по указанному пути
if (file_exists($file)) {
require_once $file;
}
}
/*2) Для интерфейсов:*/
function autoloader2($class) {
$file = __DIR__ . "/classes/interfaces/{$class}.php";
//Проверка: существует ли файл по указанному пути
if (file_exists($file)) {
require_once $file;
}
}
spl_autoload_register('autoloader1');
spl_autoload_register('autoloader2');
А потом можно в следующем уроке показать ещё лучше с Компоузером.
4) Можно и так и так, но с кастомной будет красиво и с отступами.
5) По цене забыл, исправлю, кстати почему цену нельзя строкой передавать, забыл почему?
6) Это исправлю на какой-то из способов:
есть два способа именования переменных:
1) $paid_lesson
2) $paidLesson – первая с маленькой, каждое следующее с большой
1) Для чего?
2) Лучше положить их в соответствующий неймспейс
3) Всё будет дальше, не забегайте вперёд. В общем-то, это можно написать ко всем пунктам и на этом закончить)
4) Не поверите, но во встроенной еще и подсветка кода будет
5) Зачем строкой, если на входе ожидается float?
6) 2ой вариант единственно верный, соответствующий PSR
1) webformyself - курс про ООП, в первой части видео говориться:
Возьмите за привычку располагать один класс в одном файле. И там должно быть только описание класса. А если мы хотим использовать этот класс, то должны его подключить в тех местах, где мы это хотим сделать. Имя файла должно совпадать с именем класса для удобства в дальнейшем. Также имя класса идёт с большой буквы согласно требованиям PSR, но не обязательно. В имя класса могут входить все слова, кроме зарезервированных слов, которые входят в определённый список.
Если есть у Вас альтернатива вышесказанному, "что все классы лучше в одном файле", то аргументируйте ответ, отнесусь с пониманием. Да, нашёл и у Вас ответ на мой вопрос, в уроке про namespace: "В этом уроке мы затронем стандарт PSR-4. В нём говорится о том, что каждый класс должен храниться в отдельном файле и находиться в пространстве имён. Давайте обо всём по порядку."
Остальное - понятно.
Ну в общем-то главное чтобы было понимание для чего это делается. А делается это для того чтобы было возможно реализовать автозагрузку. Без раскладывания классов по одноименным файлам этого не добиться.
Нужно оформить код в комментарии (в редакторе комментариев самая первая кнопка).
Нажмите на карандашик и поправьте ваш комментарий, пожалуйста. А потом ответьте мне на этот комментарий. После этого проверю вашу домашнюю работу и отвечу на вопросы.
Я так понял, что родительский класс может быть только один, который самый первый, и все последующие дочерние классы наследуют его параметры, и тоже самое работает при вызове родительского конструктора? Я это к тому, что при создании объекта класса PaidLesson, у меня в геттер homework не возвращалось никаких значений, хотя я наследую свойства и методы родительского класса (Как я думал изначально именно класса Lesson), и мне пришлось добавить в в конструктор класса PaidLesson свойство $homework ,
$this->homework = $homework;
что бы Var_dump его видел, так как при наследовании родительского конструктора его не видно. Я все правильно сделал или нет ?)
Вот сама домашка
<?php
class Post
{
private $title;
private $text;
public function __construct(string $title, string $text)
{
$this->title = $title;
$this->text = $text;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title): void
{
$this->title = $title;
}
public function getText()
{
return $this->text;
}
public function setText($text): void
{
$this->text = $text;
}
}
class Lesson extends Post
{
private $homework;
public function __construct(string $title, string $text, string $homework)
{
parent::__construct($title, $text);
$this->homework = $homework;
}
public function getHomework(): string
{
return $this->homework;
}
public function setHomework(string $homework): void
{
$this->homework = $homework;
}
}
class PaidLesson extends Post
{
private $price;
public function __construct(string $title, string $text, string $homework, float $price)
{
parent::__construct($title, $text );
$this->homework = $homework;
$this->price = $price;
}
public function getPrice(float $price)
{
return $price->price;
}
public function setPrice(float $price): void
{
$this->price = $price;
}
}
$price1 = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложитесь спать, утро вечера мудренее', '99.90');
echo var_dump($price1);
Домашка:
UPD: что такое "void"? Мы вроде такого не проходили. Или дайте ссылку где прочитать
Отлично!
А void - значит что функция ничего не возвращает.
Отлично!
а разве setPrice - не должен принимать саму цену?
Всё норм, кроме, опять же, типов аргументов - их нужно указывать. Так не пишут уже пару лет.
И строки без переменных в них нужно писать в одинарных кавычках.
Я писал типов аргументов, но PHPStorm выдает подсказку, это устарело и его использовали ниже версии 7. Так писать или нет?)
Не мог он такую подсказку дать, он говорит, что в Ваших настройках PHPStorm указана версия PHP < 7, а типы появились позже. Нужно зайти в настройки PHPStorm в пункт PHP и выбрать правильную версию.
Извиняюсь, английский не очень у меня, не правильно понял))
Ничего страшного, главное чтобы Вы на новой версии учились =)
Отлично!
Отлично!
Всё супер!
Отлично!
Хорошо, только price через c.
Отличный курс, все доступно и понятно.
Отлично! И спасибо =)
Отлично!
Домашка:)
Отлично!
Хорошо, но переноси открывающие скобки { для классов и методов на новые строки.
Создайте ещё один класс, являющийся наследником класса Lesson - PaidLesson (платный урок).
Объявите в нем свойство price (цена), а также геттеры и сеттеры для этого свойства. Добавьте в конструкторе параметр, через который это свойство будет устанавливаться при создании объекта.
Создайте объект этого класса со следующими свойствами:
заголовок: Урок о наследовании в PHP
текст: Лол, кек, чебурек
домашка: Ложитесь спать, утро вечера мудренее
цена: 99.90
Выведите этот объект с помощью var_dump()
Отлично!
Отлично!
ошибка выходит Fatal error: Uncaught Error: Call to undefined method Lesson::__conctruct() in
Это из-за опечатки в написании: __conctruct, а должно быть __construct.
И обратите внимание, что где-то в конструкторе вы задаете свойства через сеттеры, а где-то напрямую пишете в свойства. Как именно делать - решать вам, но делайте это одинаково.
Супер!
Супер!
Решил в ОпенСервере сменить PHP с 7.0 на 7.2, и var_dump вывелся в сплошную строку:
object(PaidLesson)#1 (4) { ["price":"PaidLesson":private]=> float(99.9) ["homework":"Lesson":private]=> string(67) "Ложитесь спать, утро вечера мудренее" ["title":protected]=> string(43) "Урок о наследовании в PHP" ["text":protected]=> string(30) "Лол, кек, чебурек" }
В 7.2 у OpenServer отсутствует XDebug. Это именно он формирует красивый вывод var_dump.
Оберни var_dump в теги <pre>...</pre>
Спасибо за урок!
У меня есть вопрос: "var_dump();" у меня выводится строкой, а не акуратно столбиком как у вас, как это можно решить?
За это отвечает расширение xdebug. Инструкция тут
Совсем забыл настроить Xdebug поле того как скачал PHPstorm из телеграм чата. Огромное спасибо! А как само ДЗ?
Что-то не выводится цена.
Исправил
Другое дело :)
Супер!
Ок. Имена методов должны начинаться с маленькой буквы. Для цены указали тип float и явно передаёте строку - почему не число?
P.S. Опять этот вопрос по поводу использования типов данных. Где-то в документации по PHP прочитал что добавлением псевдотипов данных используется с PHP 7.1 как подсказка для программистов.
Правда это? Или еще есть др. объяснение, в качестве доп. защиты данных?
К слову сказать в PhpStorme(установлена последняя версия) есть подсказки написания геттеров и сеттеров и там почему-то не добавляет эти доп. данные?
Посмотри урок про функции из курса PHP для начинающих.
Объявите в нем свойство price (цена), а также геттеры и сеттеры для этого свойства. Добавьте в конструкторе параметр, через который это свойство будет устанавливаться при создании объекта.
Создайте объект этого класса со следующими свойствами:
заголовок: Урок о наследовании в PHP
текст: Лол, кек, чебурек
домашка: Ложитесь спать, утро вечера мудренее
цена: 99.90
Выведите этот объект с помощью var_dump()
По коду всё хорошо. По правилу именования - да, есть такое, дальше по курсу будет.
У меня у одного ошибка при выполнении метода класса Post:
когда пытаюсь использовать сеттер,
Fatal error: Uncaught TypeError: Return value of Post::setText() must be an instance of void, none returned in W:\domains\myproject.loc\www\index.php:26 Stack trace: #0 W:\domains\myproject.loc\www\index.php(51): Post->setText('\xD0\x98\xD0\xB2\xD0\xB5\xD0\xBD\xD0\xB5\xD1\x86\xD0\xBA\xD0...') #1 {main} thrown in W:\domains\myproject.loc\www\index.php on line 26.
Как я понял ожидается возврат любого значения, из-за void, но его не происходит, т.к. нам return не нужен.
Вопрос решен=) Переключился на версию PHP 7.1. Оставлю комент, вдруг кому понадобится!
ОК)
Отлично. А почему поле цены с типом protected?
Да, я тут ошибся, нужно было private.
Спасибо за урок!
Это задание понял вот так:
Цену всё-таки принято хранить в виде чисел, а не строк.
Теперь до конца понял как лучше применять строки, или числа. Спасибо!
Ок!
Ок. А почему в конструктор последний аргумент строкой передаешь?
Отлично!
Отлично
Если при выполнении домашки в классе Lesson модификатор доступа оставить private $homework; то результат выдает вот такой, но это же неверно? Не совсем понимаю что должно сломаться в этом случае
Нужно изменить на protected $homework; и тогда результат получится вот такой:
Через публичные геттеры и сеттеры родительского класса можно достучаться до его приватных свойств.
Хорошо. А почему в Post и Lesson свойства protected, а в PaidLesson private?
Потому что свойство price принадлежит классу PaidLesson, а от этого класса никто не наследует.правильно?
Верно =)
Отлично
Почему у вас цена - это строка? В сеттере тоже должен быть тип.
Ок
Если в родителях указаны типы переменных надо ли повторяться в наследниках или такая запись тоже верна?
Всё у вас верно. При вызове метода мы не указываем тип аргументов, тип указывается только в описании метода.
А вот price должен иметь тип float.
Разобрался, так правильнее
Отлично!
Образцовая домашка
Домашка "Наследование"
нужно указать возвращаемый тип.
Параметр float, а передаёте зачем-то строку.
Спасибо, поняла ошибку
Отлично
нужно указать возвращаемый тип.
Параметр float, а передаёте зачем-то строку.
Понял! поправил
Отлично
Артем, спасибо за урок!
Есть вопрос:
В классе Lesson оставляю модификатор доступа к свойству 'homework' как 'private' и все выводится без ошибок, однако, судя по тексту урока, я не должен был получить доступ к этому свойству из наследуемого класса (т.к. 'private', а не 'protected'). Увидел комментарий выше о том, что через публичные геттеры и сеттеры можно достучаться до частных свойств родительского объекта. Это именно тот случай или у меня где-то закралась ошибка? Как делать правильнее и на что это влияет (скорость, безопасность, качество кода и т.д.)?
Всё ты правильно понял про доступ через публичные методы. Ни на что это не влияет, это именно так и должно работать)
Для чего сделали поля protected? В коде дочернего класса вы их не используете. А достучаться до них из унаследованных public-методов родительского класса вы можете.
Отлично
Отлично.
Скобка, открывающая тело метода, в PHP ставится с новой строки.
Почему protected? Напрямую в дочерних классах не используются?
Нужно у геттеров тоже указать тип возвращаемого значения.
Тут чего это вообще public стало?
Имена переменных начинаются с маленькой буквы. Всегда.
ДЗ
Супер
Вот это всё должно быть private, так как в дочерних классах нет прямых обращений к этим свойствам.
getTitle(): string
Стоит везде указать типы возвращаемых значений.
Супер!!!
Отлично
Почему в сеттерах пишут void?
setTitle($title): void
Что здесь означает void?
Это означает, что метод ничего не возвращает (return отсутствует или используется без аргументов)
Отлично
Почему protected? Свойства ведь не используются в дочерних классах.
1 ВПР. По уроку смотрел, но работает и с приватным модификатором также, а как правильно необходимо было сделать?
2 ВПР. Слетела лицензия на PHPStorm 2018.1; нашел новую скачал и установил PhpStorm 2019.2.1 Build #PS-192.6262.66. Так вот, а новая версия мне показывает все методы в данном домашнем задании(геттеры и сеттеры) с ошибкой: Unused elements: getTitle и так со всеми.
3 ВПР. Забегая немного в перед, это уже с 10-13 урока, при создании классов по уроку дает PHPStorm такое сообщение: 03.09.2019
17:19 Do you want to mark folder as PSR-0 root?
C:/OpenServer 5.3.0/OSPanel/domains/myproject.loc/src
Mark as PSR-0 root
Что мне с ним делать? Мы же вроде по уроку стандарт PSR-4 используем.
Если напрямую не используются в дочерних, то всегда private.
Можно посетить как psr-0, чтобы штормик отстал.
Отлично
У сеттера тип аргумента потерялся
Вообще для денег не подходит флоат,но я пока не знаю,чем его заменить)
Почему все свойства protected? В дочерних классах ни одно из них не используется.
Ну,допустим мы не хотим изменения их напрямую,но в будущем мы может будем их использовать в дочерних классах,почему не поставить протектед?
Вот когда надо будет, тогда и сделаешь. А по умолчанию всегда ставь private. Иначе непонятно будет, используется ли свойство только в этом классе или где-то ещё.
Супер!
ничего не понял и ничего не получилось(
Зачем здесь повторяются свойства из Lesson? Где типы аргументов? Начинай с курса PHP для начинающих.
Почему protected а не private?
Почему в конструкторе есть тип аргумента, а здесь нет?
Имена переменных пишутся в camelCase. Не должно быть никаких подчеркиваний.
Принял, спасибо. Будем исправлять
Исправил.
Теперь отлично!
И почему цена то string, то float? Непорядок.
Упс...недоглядел. Исправил.
Теперь отлично
Домашка:
Еще насколько понимаю, в классе Lesson надо было поменять тип $homework с private на protected?
Нет. Модификатор доступа private правильный. Мы ведь в дочерних классах не используем это свойство.
Почему цена float, а в конструктор передаёте строку '99.90'?
В коде урока только заменил private $homework на protected, т.к. идет наследование свойства
Вывод:
private свойства наследуются! К ним просто нет доступа из методов, определенных в дочерних классах! protected здесь не нужен.
Fatal error: Class 'Post' not found in D:\OSPanel\domains\localhost\PHP.Zone\OOP\Blog\Lesson.php on line 9
Кто подскажет, что слетело в OpenServer или PHPShtorm
Не видит классы и все....устал бороться уже.
Файл с классом подключен через include?
Домашка была другой
Зачем?
И не prived а private
затем чтобы получить его в классе наследнике
В классе-наследнике не происходит обращения к этому свойству.
Выкладываю добавленную часть из домашки!
Слово class нужно писать с маленькой буквы.
Учту.
Спасибо за Уроки!
Супер!
Здрасьте приехали) А чего это мы цену строкой храним. Я сейчас отвернусь, а вы быстренько на float переделайте =)
OK!
А это что за рудимент?)
Не понял. Хост выдаёт:
Название урока: Заголовок
object(Lesson)#2 (3) { ["homework":"Lesson":private]=> string(14) "Домашка" ["title":protected]=> string(18) "Заголовок" ["text":protected]=> string(10) "Текст" } object(PaidLesson)#1 (4) { ["price":"PaidLesson":private]=> float(99.9) ["homework":"Lesson":private]=> string(69) "Ложитесь спать, утро вечера мудреннее" ["title":protected]=> string(43) "Урок о наследовании в PHP" ["text":protected]=> string(28) "лол,кек,чебурек" }
Ну конечно! Тип float, а передаёте строку. PHP, конечно, преобразует такое, но там где мы можем подставить сразу правильный тип, мы должны это делать.
Только вот с выводом через echo что-то не получилось.
Почему цена строкой-то? :)
Потому что не внимательный :)
Конечно, апострофы нужно убрать.
Кавычки, разумеется, нужно убрать. А еще что нужно сделать?
В конструкторе надо тип поменять на float $price и в геттере тип возвращаемого значения :float выставить. О, Боже! Куда я вообще смотрел когда делал домашку?! :-0
Верно
Домашка
Почему поля вдруг стали protected?
Чтобы был доступ к ним из дочерних классов
Но в дочерних классах нет прямого обращения к этим свойствам. Они обращаются к ним через public-методы родителей, а так можно. Так что все свойства в вашем примере должны быть private.
Отлично
Всё ок, только не указали типы аргументов для сеттеров.
И вот это не понял что такое
Это типа "to do", здесь должен быть размещен твой самый лучший код! :-), забыл удалить.
Насчет строгой типизации - спвсибо, забываю про 7 пхп.
Ок) На комментарии можно отвечать (кнопка справа со стрелочкой)
/*
Да, я вкурсе форматирования, обещаю, завтра я поставлю PHPStorm, и заморачиваться с форматированием)
*\
Должно быть private.
Отлично
А цена чего строкой? И фигурная скобка, открывающая тело функции, пишется на следующей строке.
Это еще зачем? Должно оставаться private.
Почему цена строкой? Это же числовое значение.
Нам же необходимо наследовать $homework.
Цену нужно float сделать
Ну так она наследуется, она просто недоступна для методов этого класса. Но при этом она доступна через публичные методы родительского класса.
Спасибо, теперь понял!
Доброго времени суток, сижу на самоизоляции, кусок кода к Вашему коду:
Почему public? И почему строка? И почему поехала первая строка конструктора?
ещё должен был добавить
но я так и не понял, почему этот код должен быть, и почему его писали коллеги по цэху?
Где тип аргумента? Почему скобка фигурная на той же строке, что и имя метода? Посмотрите в обязательном порядке урок по функциям из курса PHP для начинающих.
Коллеги писали его потому, что читали внимательно предыдущий урок, и знали, что свойство должно быть private.
И оформляйте код перед отправкой комментария (первая кнопка в редакторе).
Доброго времени суток, вроде всё исправил:
class PaidLesson extends Lesson
{
private $price;
}
$lesson = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложитесь спать, утро вечера мудренее', '99,90');
var_dump($lesson);
А код почему не оформили опять?
добрый день, я просто в нотепад++ всё делаю, там видеться всё вот так.
Я про комментарий. Перечитайте мои предыдущие сообщения. В редакторе комментариев есть специальная кнопка для оформления.
И почему не шторм? Дебаггером умеете пользоваться?
у меня win 7 x 32. на 64 не перешёл пока.
попробуй использовать клавишу Tab
я тоже пишу в Notepad++
привет, нотепад не так уж и плох. спасибо.
Еще хотел вывести не через var_dump, пока только так получилось ))
А как можно сразу все вывести, без отдельных гетеров ??
Отлично.
Как вариант - сделать метод toArray(), который будет формировать массив вида ключ-значение. Но в этом методе конечно нужно будет описать весь маппинг. Вариант с var_dump для отладки - самое то!
Вот что у меня получилось:
Почему все свойства стали protected? К ним ведь нет обращения в дочерних классах.
Я сделал чтобы можно было обращаться при необходимости, хотя в случае необходимости и private на protected не долго изменить)
Я исправил
вот здесь:
и тут:
Неправильный подход. Правильнее исходить из того, что нужно сейчас и по-максимуму делать все поля private. А уж если понадобится, то ослаблять доступность.
А в Post почему оставили protected?
тоже исправил:
Понял, большое спасибо, учту на будущее.
RESULT:
Почему свойства стали protected?
Изначально код писал на компьютере, но видимо он у меня лаганул и показывал 2 момх комента. Зашёл с телефона и увидел, что кода моего нет.
Пришлось, используя чужой код, воссоздавать свой код с телефона, ибо с телефона форматировать код вообше неудобно.
P.S. мой код действительно так и выглядел, даже имена переменных на свои поменял ($newTitle, $newText, $newHomework, $newPrice)
Нужно перечитать урок по переменным из курса для начинающих.
Не нужны пробелы слева и справа от этого оператора. Где вы их взяли?
Урок прочитал(я с других источников пришёл, но здесь я понял, что это рай для мозга), исправил имена переменных
убрал пробелы, по незнанию ставил пробелы, чтобы мне было понятно и приятно, перестал ставить. Придётся переделывать все свои коды :>
Благо, я недавно начал проходить ООП и много кода не создал. Ваши уроки помогают, начал проходить ООП на другом сайте и не понял тему интерфейсов, а здесь понял.
Ок, теперь отличная домашка
Отлично
Почему свойства стали protected?
Написала так же, как в примере кода, что получился в ходе урока.
Вы правы, в уроке я допустил некоторую неточность. Дополнил урок, начиная со слов: "Обратите внимание, что если у родительского класса есть метод...". Изучите, пожалуйста, это дополнение.
Хорошо, спасибо)
Вопрос, если не указать переменную $price в описании класса, но указать в конструкторе...это ошибка, но почему-то все работает, почему?
Потому что в PHP можно на лету создать свойство класса, будь он не ладен) Но делать так не стоит.
Супер!
Мой пример
Есть вопрос по сеттерах. Для чего мы указываем тип возвращаемого значения void у них? В мануале пишет, что такие функции не должны ничего возвращать. А вот для чего это нам я так и не понял.
Последний параметр float
Чтобы было понятно, что от этого метода не стоит ждать возвращаемого значения.
Понял свою ошибку. php "скушало" строку потому и не заметил ошибки)
Ага, можно юзать директиву strict_types дополнительно
Идеально
Почему protected?
А почему цена - это строка?)
блин) точно
А передаёте всё равно строку)
Ошибка
В конструкторе исправили, но передаётся туда всё равно строка. PHP конечно умный и всё исправит, но лучше делать это за него и явно.
Мне кажется я понял чего ты добиваешься ))
Теперь отлично
Чего?)
Спасибо за интересное задание: выполнила с удовольствием! Намного понятнее излагаете основные принципы, чем в книжках или других ресурсах.
Вопросик: Я использую св-во price типа string, поскольку решила, что нужно точно создать объект как в примере, однако, если опустить слова 'цена', то можно объявить тип float, поскольку значение 99.90, верно? ). Опустила в начале кода <?php - ведь это отрывок из программы с классами Post и Lesson
Не можно, а нужно. Как и во всех остальных случаях не нужно писать что это такое, просто данные передавайте.
Отлично. Только скобка, открывающая тело метода, пишется на новой строке.
Потеряли 90 центов =(
блин, точно! тип float, а не int!
Ага. Исправлять будем?)
Отлично
Добрый вечер,
Отлично!
Всё отлично, но проблема с форматированием. Делайте отступы и переносы как в уроках. Для этого в шторме можно нажать Ctrl+Alt+L
Почему строка?
Исправил.
Не вижу)
...
Ок. Если что - комменты можно редактировать.
Почему цена - строка?
Проблема с форматированием. Делайте отступы и переносы как в уроках. Для этого в шторме можно нажать Ctrl+Alt+L
Спасибо, исправила, да цена float
Кстати почему у меня var_dump в одну строку все выводит, а не как у других с форматированием?
https://php.zone/post/krasivyy-vyvod-var-dump-openserver
По домашке - всё отлично)
Почему в конструкторе класса не указан тип для аргумента цены?
Мои рекомендации: по уроку Наследование в PHP.
Создать папку classes. В ней создать три файла с классами: два класса + один из домашки с названиями:
Создать файл index.php или можете назвать Run.php. Который размещён выше на уровень папки classes, вообщем не в этой папке. И он служит для создания и вызовов методов:
Обосновать можете, почему нужно сделать так?
Для чего везде приписка Blog?
Что даст раскладывание по одноименным файлам без применения автозагрузки?
Вместо кастомной функции debug стоит использовать var_dump с соответствующей конфигурацией.
Почему цена передаётся строкой?
Почему имя переменной PaidLesson с большой буквы?
1) Каждый класс должен быть в отдельном файле.
2) Blog - так для меня более понятно, что эти классы относятся к Блогу.
3) Сначала, показать такой способ, потом в следующем уроке ещё лучше:
А потом можно в следующем уроке показать ещё лучше с Компоузером.
4) Можно и так и так, но с кастомной будет красиво и с отступами.
5) По цене забыл, исправлю, кстати почему цену нельзя строкой передавать, забыл почему?
6) Это исправлю на какой-то из способов:
есть два способа именования переменных:
1) $paid_lesson
2) $paidLesson – первая с маленькой, каждое следующее с большой
1) Для чего?
2) Лучше положить их в соответствующий неймспейс
3) Всё будет дальше, не забегайте вперёд. В общем-то, это можно написать ко всем пунктам и на этом закончить)
4) Не поверите, но во встроенной еще и подсветка кода будет
5) Зачем строкой, если на входе ожидается float?
6) 2ой вариант единственно верный, соответствующий PSR
1) webformyself - курс про ООП, в первой части видео говориться:
Возьмите за привычку располагать один класс в одном файле. И там должно быть только описание класса. А если мы хотим использовать этот класс, то должны его подключить в тех местах, где мы это хотим сделать. Имя файла должно совпадать с именем класса для удобства в дальнейшем. Также имя класса идёт с большой буквы согласно требованиям PSR, но не обязательно. В имя класса могут входить все слова, кроме зарезервированных слов, которые входят в определённый список.
Если есть у Вас альтернатива вышесказанному, "что все классы лучше в одном файле", то аргументируйте ответ, отнесусь с пониманием. Да, нашёл и у Вас ответ на мой вопрос, в уроке про namespace: "В этом уроке мы затронем стандарт PSR-4. В нём говорится о том, что каждый класс должен храниться в отдельном файле и находиться в пространстве имён. Давайте обо всём по порядку."
Остальное - понятно.
Ну в общем-то главное чтобы было понимание для чего это делается. А делается это для того чтобы было возможно реализовать автозагрузку. Без раскладывания классов по одноименным файлам этого не добиться.
Отлично
Добрый день!
В домашке добавил следующее
Получил:
C:\xampp\htdocs\ws_OOP\3post\index.php:76:
object(PaydLesson)[1]
private 'price' => float 99.9
private 'homework' (Lesson) => string 'Ложитесь спать, утро вечера мудренее' (length=67)
private 'title' (Post) => string 'Урок о наследовании в PHP' (length=43)
private 'text' (Post) => string 'Лол, кек, чебурек' (length=30)
Супер!
А почему в конструктор цену строкой передаете? Это же число
Поправила, спасибо!
Теперь отлично
Супер!
Отлично
Всё ок, только phpDoc не корректен. Должно быть float а не mixed.
class PaidLesson extends Lesson
{
private $price;
}
$lesson = new PaidLesson('Урок о наследовании в PHP', 'Лол, кек, чебурек', 'Ложись спать, утро вечера мудренее', '99.90');
var_dump($lesson);
Нужно оформить код в комментарии (в редакторе комментариев самая первая кнопка).
Нажмите на карандашик и поправьте ваш комментарий, пожалуйста. А потом ответьте мне на этот комментарий. После этого проверю вашу домашнюю работу и отвечу на вопросы.
Отлично объясняешь, просто сам в шоке что сначала было все непонятно, а потом прочел и все ок.
Спасибо.
Вот ДЗ.
Супер!
Я так понял, что родительский класс может быть только один, который самый первый, и все последующие дочерние классы наследуют его параметры, и тоже самое работает при вызове родительского конструктора? Я это к тому, что при создании объекта класса PaidLesson, у меня в геттер homework не возвращалось никаких значений, хотя я наследую свойства и методы родительского класса (Как я думал изначально именно класса Lesson), и мне пришлось добавить в в конструктор класса PaidLesson свойство $homework ,
что бы Var_dump его видел, так как при наследовании родительского конструктора его не видно. Я все правильно сделал или нет ?)
Вот сама домашка
Наследоваться надо от Lesson, а не от Post. У Post нет свойства homework.
Спасибо, как то упустил из виду, что он другому классу принадлежит)
Теперь верно?
Да, отлично)
Цена получается "99.9", вместо того как написано в задание "цена: 99.90".
Ну это же тоже самое