Прошу знающих в php помочь, изучаю php, для меня вообще первый язык программирования, поэтому в процессе постоянно возникают настолько тупые вопросы, что интернет словно даже не отвечает на них. Дошел до классов и попал в некий ступор. Помогите разобраться.
Есть вот такой пример из учебника:
<?php ## Использование статических членов класса.
class Counter
{
// Скрытый статический член класса - общий для всех объектов.
private static $count = 0;
// Конструктор увеличивает счетчик на 1. Обратите внимание
// на синтаксис доступа к статическим переменным класса!
public function __construct() { self::$count++; }
// Деструктор же - уменьшает.
public function __destruct() { self::$count--; }
// Статическая функция, возвращает счетчик объектов.
public static function getCount() { return self::$count; }
// Как видите, установить счетчик в произвольное значение
// извне нельзя, можно только получить его значение. Вот он,
// модификатор private "в действии".
}
// Создаем 6 объектов.
for ($objs = [], $i = 0; $i < 6; $i++)
$objs[] = new Counter();
// Статические функции можно вызывать точно так же, как будто
// бы это - обычный метод объекта. При этом $this все равно
// не передается, он просто игнорируется.
echo "Сейчас существует {$objs[0]->getCount()} объектов.<br />";
// Удаляем один объект.
$objs[5] = null;
// Счетчик объектов уменьшится!
echo "А теперь - {$objs[0]->getCount()} объектов.<br />";
// Удаляем все объекты.
$objs = [];
// Другой способ вызова статического метода - с указанием класса.
// Это очень похоже на вызов функции из библиотеки.
echo "Под конец осталось - ".Counter::getCount()." объектов.<br />";
?>
Начну с конца:
$objs[0]->getCount() - почему указан 0? Потому что при записи
$objs[]
В массив добавляется элемент. Если не указывать ключ, то он добавляется по порядку в виде числа. Так как эта операция была произведена один раз, то ключом ячейки будет "0", откуда и достается элемент.
заметка: однако такой вызов не совсем корректен, т.к. идет попытка вызова статического метода в нестатическом контексте. До PHP7 это прокатит, а в поздних версиях нет. потому что это неправильно.
$objs[5] = null; - я так понимаю, что присваивается значение null пятому элементу в массиве $objs, но по факту, весь массив вроде бы отчищается, как это работает?
Почему должен очиститься весь массив? Ведь тут же указана чётко ячейка с индексом 5.
$objs[] = new Counter(); - Я так понимаю создается массив $objs который использует класс Counter. Но что это значит? Как массив может быть равен классу, там же нет никакого точного значения. Только пара функций.
Когда пишется
new Counter()
то создается экземпляр класса и помещается в некую переменную. В данном случае экземпляры создаются в цикле и складываются в ячейки массива. Поэтому в каждой ячейке лежит по экземпляру класса Counter
public function __destruct() { self::$count--; } - как я понял, уменьшает $count на 1, но как он запускается?? Что приводит в действие эту функцию?
Например удаление объекта, как пример:
$objs[5] = null
или если данный объект больше не используется и GC решает его удалить как мусор. Например это может быть, если работа с объектом происходит в какой-нибудь функции/методе
function myMethod(){
$counter = new Counter();
}
После отработки метода myMethod
переменная $counter
нигде не используется и убивается. Что вызвает деструктор
public function __construct() { self::$count++; } - Тоже самое, только увеличивает счетчик на 1, вопрос тот же, что приводит в действие эту функцию?
Логично что создание объекта вызвает это, то есть вот эта строка:
new Counter()
Больше информации о магических методах, в которые входят __construct
и __destruct
написано в документации: http://php.net/manual/ru/language.oop5.magic.php
Честно говоря у вас очень плохо с теорией, а еще с выбором первого языка программирования(для примера я бы рекомендовал какой-нибудь Python).
Объясню "на пальцах":
null
- ключевое слово, которое занимается освобождением
памяти, тем самым уничтожая элемент/ы массива$objs[] = new Counter()
- в цикле добавляет к массиву
объект типа Counter
1) Вообще интересный способ вызова статической функции. Думаю при использовании где-то в реальных проектах будет создавать только непонятки (поскольку это функция класса и у объекта в реальности такого метода нету). Гораздо понятнее было бы делать вызов так Counter::getCount()
.
2) Во первых, в данном случае "убивается" 6-й элемент (нумерация массивов начинается с 0). Не совсем понятно, что вы имеете в виду под словом отчищается. Обычные массивы (а в php бывают еще и ассоциативные) визуально выглядят где-то так:
0 1 2 3 4 5 ---> индексы массивов
a b c d e f ---> значения массивов
т.е. Вы, при обращении к 5 элементу получаете букву f, при обращении ко 2 - c и т.д. Можете смотреть на них как на полочку с ящиками для инструментов, где каждый ящик на полке подписан.
3) ключевое слово new создает новый объект класса Counter, который умеет делать и использовать то, что вы объявили в классе Counter без модификатора static. В данном примере в классе Counter нету не статических пользовательских методов (конструктор и деструктор являются, как бы правильно назвать...встроенными методами что ли). Попробуйте объявить свой метод в Вашем классе, например:
public function sayHello(){
echo 'Hello!';
}
Тогда Вы сможете вызвать его на объекте (objs[0]->sayHello()
, но не сможете вызвать в статическом контексте (Counter::sayHello() //будет ошибка
).
4, 5) В данном месте используются операции инкрементации и декрементации. Почитать про данные операции можете, например, здесь.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
У меня есть массив в котором ключ - имя интерфейса, а значение - его реализация
Добрый деньЕсть код на PHP, который получает от пользователя необходимые данные и отвечает ему моментально
Как шифровать сообщения пользователей (чтобы они не были читабельны в базе данных mysql) которые переписываются между собой, и конечно же сделать...