Семантика
В языках, где объекты выделяются динамически , как в Java или Python, фабрики семантически эквивалентны конструкторам. Однако в таких языках, как C ++, которые позволяют статически выделять некоторые объекты, фабрики отличаются от конструкторов для статически распределенных классов, поскольку у последних может быть выделение памяти, определяемое во время компиляции, в то время как распределение возвращаемых значений фабрик должно определяться в время выполнения. Если конструктор может быть передан в качестве аргумента функции, то вызов конструктора и выделение возвращаемого значения должны выполняться динамически во время выполнения и, таким образом, иметь аналогичную или идентичную семантику для вызова фабрики.
Что такое суперглобалы?
PHP имеет специальный набор предопределенных глобальных массивов, которые содержат различную информацию. Такие массивы называются суперглобалами, так как они доступны из любого места скрипта, включая внутреннее пространство функций, и их не надо определять с использованием ключевого слова .
Вот список суперглобалов, доступных в PHP версии 5.3:
- $GLOBALS — список всех глобальных переменных в скрипте (исключая суперглобалов)
- $_GET — содержит список всех полей формы, отправленной браузером с помощью запроса GET
- $_POST — содержит список всех полей формы отправленной браузером с помощью запроса POST
- $_COOKIE — содержит список всех куки, отправленных браузером
- $_REQUEST — содержит все сочетания ключ/значение, которые содержатся в массивах $_GET, $_POST, $_COOKIE
- $_FILES — содержит список всех файлов, загруженных браузером
- $_SESSION — позволяет хранить и использовать переменные сессии для текущего браузера
- $_SERVER — содержит информацию о сервере, такую как, имя файла выполняемого скрипта и IP адрес браузера.
- $_ENV — содержит список переменных среды, передаваемых PHP, например, CGI переменные.
<?php $yourName = $_GET; echo "Привет, $yourName!"; ?>
Если вы запустите выше приведенный скрипт с помощью строки URL , то он выведет:
Привет, Фред!
Предупреждение! В реальном скрипте никогда нельзя использовать подобную передачу данных по причине слабой безопасности. Нужно всегда осуществлять проверку или фильтрацию данных.
Суперглобал очень удобно использовать, так как он дает возможность организовать доступ к глобальным переменным в функции без необходимости использования ключевого слова . Например:
<?php $globalName = "Зоя"; function sayHello() { echo "Привет, " . $GLOBALS . "!<br>"; } sayHello(); // Выводит "Привет, Зоя!" ?>
Статические переменные: они находятся где-то рядом
Когда вы создаете локальную переменную внутри функции, она существует только пока работает функция. При завершении функции локальная переменная исчезает. Когда функция вызывается снова, создается новая локальная переменная.
В большинстве случаев это отлично работает. Таким образом функции самодостаточны и работают всегда одинаково при каждом вызове.
Однако, есть ситуации, когда было бы удобно создать локальную переменную, которая «помнит» свое значение между вызовами функции. Такая переменная называется статической.
Для создания статической переменной в функции нужно использовать ключевое слово перед именем переменной и обязательно задать ей начальное значение. Например:
function myFunction() { static $myVariable = 0; }
Рассмотрим ситуацию, когда удобно использовать статическую переменную. Допустим, вы создаете функцию, которая при вызове создает виджет и выводит количество уже созданных виджетов. Можно попробовать написать такой код с использованием локальной переменной:
<?php function createWidget() { $numWidgets = 0; return ++$numWidgets; } echo "Создаем некие виджеты...<br>"; echo createWidget() . " мы уже создали.<br>"; echo createWidget() . " мы уже создали.<br>"; echo createWidget() . " мы уже создали.><br>"; ?>
Но, так как переменная создается каждый раз при вызове функции, то мы получим следующий результат:
Создаем некие виджеты... 1 мы уже создали. 1 мы уже создали. 1 мы уже создали.
Но с использованием статической переменной, мы сможем сохранять значение от одного вызова функции к другому:
<?php function createWidget() { static $numWidgets = 0; return ++$numWidgets; } echo "Создаем некие виджеты...<br>"; echo createWidget() . " мы уже создали.<br>"; echo createWidget() . " мы уже создали.<br>"; echo createWidget() . " >мы уже создали.<br>"; ?>
Теперь скрипт выдаст ожидаемый результат:
Создаем некие виджеты... 1 мы уже создали. 2 мы уже создали. 3 мы уже создали.
Хотя статическая переменная сохраняет значение между вызовами функции, она действует только в момент выполнения скрипта. Как только скрипт завершает свое выполнение, все статические переменные уничтожаются, так же как и локальные и глобальные переменные.
Преимущества ООП
Основными преимуществами парадигмы разработчики считают следующие особенности:
-
Модульность: инкапсуляция объектов в себе упрощает разработку, уменьшает количество ошибок и ускоряет разработку при участии большого количества программистов, так как каждый может работать независимо друг от друга.
-
Реюзабельность кода: благодаря абстракциям, полиморфизму и наследованиям можно не писать один и тот же код много раз, что заметно ускоряет создание нового ПО.
-
Высокая скорость разработки: классы и интерфейсы в ООП могут легко трансформироваться в подобие полноценных библиотек, которые можно переиспользовать в новых проектах.
-
Расширяемость: ООП-код легче развивать, дополнять и менять. Этому способствует независимая модульная структура.
-
Простота восприятия: использование ООП упрощает понимание кода за счет взаимодействия с объектами, а не логикой. Не нужно углубляться в то, как построено ПО, чтобы модифицировать его.
-
Безопасность: инкапсулированный код недоступен извне, поэтому «поломать» ООП-программу сложнее.
-
Гибкость: полиморфизм позволяет быстро адаптировать ООП-код под свои нужды, не описывая новые функции и объекты.
Типы типов
Я уже упоминал, что типизированные свойства будут работать только в классах (пока), и что им нужен модификатор доступа или ключевое слово var перед ними.
Что касается доступных типов, то могут использоваться почти все типы, кроме void и callable.
Поскольку void означает отсутствие значения, имеет смысл, что его нельзя использовать для ввода значения. А вот с callable есть небольшой нюанс.
Callable в PHP может быть написан так:
Скажем, у вас будет следующий (неработающий) код:
В этом примере $callable относится к частному Bar::method, но вызывается в контексте Foo. Из-за этой проблемы и было решено не добавлять callable в список поддерживаемых типов.
Это не имеет большого значения, потому что замыкания (Closure) это допустимый тип, который будет помнить контекст $this, в котором он был создан.
С учетом всего написанного, вот список всех доступных типов:
- bool (логический)
- int (целый)
- float (вещественный)
- string (строковый)
- array (массив)
- iterable (псевдотип)
- object (объект)
- ? (nullable)
- self (объект того же тип)
- classes (классы)
Проблемы, которые решает компонентно-ориентированная парадигма.
COP — это очень мощная концепция, ибо она позволяет нам изолировать и инкапсулировать логику. Чем меньше наши файлы — тем более они поддерживаемы. Компании пришлось исправлять всем известную ошибку уведомлений. Где-то в 2014–15 гг. на персональной страничке пользователя показывало, что у него есть новые сообщения. Когда же пользователь нажимал на красный колокол(указания о новых сообщениях), никаких новых сообщений у пользователя не было. Это вызывало негодования пользователей по всему интернету. Причиной этого бага были огромные файлы с трудночитаемым и запутанным PHP кодом. Проблема была не в языке программирования, а в структуризации.
Онлайн-курс “Java Developer”
React был изобретен компанией именно для решения бага уведомлений. Релиз фреймворка React ознаменовал начало новой эры — эры компонентно-ориентированной парадигмы.Мой прогноз — будущее за нативными веб-компонентами. На данный момент каждая инфраструктура имеет свою собственную экосистему инструментов, компонентов, библиотек и т. д. Хотя удобно использовать оупенсорсный код, нехорошо то, что каждая экосистема является замкнутой. Если вы используете React, то вы должны ограничиваться только React. Вы не можете использовать инструменты Angular, Vue или Svelte. Нативные Веб Компоненты изменят все это.Подумайте только, как здорово, если бы мы могли использовать инструментарий различных библиотек одновременно.Допустим кто-то написал потрясающую библиотеку анимации, которая совместима со всеми фреймворками. Это именно то, к чему стремится API-интерфейс веб-компонентов. Если вы хотите узнать больше про API веб-компонентов — вот ссылка на статью.
Мотивация
В программировании на основе классов , завод является абстракцией из конструктора класса, в то время как в прототипе на базе программирования завода является абстракцией объекта прототипа. Конструктор конкретен в том смысле, что он создает объекты как экземпляры одного класса и с помощью указанного процесса (создание экземпляров класса), в то время как фабрика может создавать объекты, создавая экземпляры различных классов или используя другие схемы распределения, такие как пул объектов . Конкретный объект-прототип состоит в том, что он используется для создания объектов путем клонирования , в то время как фабрика может создавать объекты путем клонирования различных прототипов или с помощью других схем размещения.
Фабрика может быть реализована разными способами. Чаще всего он реализуется как метод, в этом случае он называется фабричным методом . Иногда она реализуется как функция, и в этом случае она называется заводской функцией . В некоторых языках конструкторы сами по себе являются фабриками. Однако в большинстве языков это не так, и конструкторы вызываются идиоматическим для языка способом, например, с помощью ключевого слова , в то время как фабрика не имеет особого статуса и вызывается через обычный вызов метода или вызов функции. В этих языках фабрика — это абстракция конструктора, но не строгое обобщение, поскольку конструкторы сами по себе не являются фабриками.
Объектно-ориентированное программирование: основы
Начнём с упрощённого высокоуровневого представления о том, что такое объектно-ориентированное программирование (ООП). Мы говорим упрощённого, потому что ООП может быстро стать очень сложным, и если сейчас дать полный курс, вероятно, можно запутать больше, чем помочь. Основная идея ООП заключается в том, что мы используем объекты для отображения моделей из реального мира в наших программах и/или упрощения доступа к функциям, которые в противном случае было бы трудно или невозможно использовать.
Объекты могут содержать данные и код, представляющие информацию о том, что вы пытаетесь смоделировать, а также о том, какие у этих объектов должны быть функциональные возможности или поведение. Данные объекта (а часто так же и функции) могут быть точно сохранены (официальный термин «инкапсулированы») внутри пакета объекта, упрощая структуру и доступ к ним. Пакету объекта может быть присвоено определённое имя, на которое можно сослаться и которое иногда называют пространством имён. Объекты также широко используются в качестве хранилищ данных, которые могут быть легко отправлены по сети.
Рассмотрим простую программу, которая отображает информацию об учениках и учителях в школе. Здесь мы рассмотрим теорию ООП в целом, а не в контексте какого-либо конкретного языка программирования.
Вернёмся к объекту Person из нашей статьи Основы объектов, который определяет общие сведения и функциональные возможности человека. Есть много вещей, которые вы можете узнать о человеке (его адрес, рост, размер обуви, профиль ДНК, номер паспорта, значимые черты личности …), но в данном случае нас интересует только имя, возраст, пол и интересы, а также мы хотим иметь возможность написать краткую информацию о нём, основываясь на этих данных, и сделать так, чтобы он поздоровался. Это известно как абстракция — создание простой модели более сложной сущности, которая представляет её наиболее важные аспекты таким образом, чтобы с ней было удобно работать для выполнения целей нашей программы.
В некоторых языках ООП, это общее определение типа объекта называется class (JavaScript использует другой механизм и терминологию, как вы увидите ниже) — это на самом деле не объект, а шаблон, который определяет, какие характеристики должен иметь объект.
Из нашего класса мы можем создать экземпляры объектов — объекты, содержащие данные и функциональные возможности, определённые в классе. Из нашего класса Person мы теперь можем создавать модели реальных людей:
Когда экземпляр объекта создаётся из класса, для его создания выполняется функция-конструктор класса. Этот процесс создания экземпляра объекта из класса называется создание экземпляра (instantiation) — из класса создаётся экземпляр объекта.
В нашем случае нам не нужны все люди — нам требуются учителя и ученики, которые являются более конкретными типами людей. В ООП мы можем создавать новые классы на основе других классов — эти новые дочерние классы могут быть созданы для наследования данных и характеристик родительского класса, так чтобы можно было использовать функциональные возможности, общие для всех типов объекта, вместо того чтобы дублировать их. Когда функциональность различается между классами, можно по мере необходимости определять специализированные функции непосредственно на них.
Это действительно полезно — преподаватели и студенты имеют много общих характеристик, таких как имя, пол и возраст, и удобно определить их только один раз. Вы можете также задать одну и ту же характеристику отдельно в разных классах, поскольку каждое определение этой характеристики будет находиться в отдельном пространстве имён. Например, приветствие студента может быть в форме «Yo, I’m » (например Yo, I’m Sam), в то время как учитель может использовать что-то более формальное, такое как «Hello, my name is , and I teach .» (например Hello, My name is Mr Griffiths, and I teach Chemistry).
Примечание: Если вам интересно, существует специальный термин Polymorphism (Полиморфизм) — это забавное слово, обозначающее реализацию той же функциональности для нескольких типов объекта.
Теперь вы можете создавать экземпляры объекта из дочерних классов. Например:
Далее мы рассмотрим, как ООП теорию можно применить на практике в JavaScript.
Работа с абстрактными классами
Абстрактный класс — это такой класс, который не может быть реализован, то есть, вы не сможете создать объект класса, если он абстрактный. Вместо этого вы создаете дочерние классы от него и спокойно создаете объекты от этих дочерних классов. Абстрактные классы представляют собой шаблоны для создания классов.
Абстрактный класс содержит один или несколько абстрактных методов. Когда вы создаете абстрактный метод в абстрактном классе, вы не добавляете в этот метод ничего. Вместо этого он должен быть описан в любом дочернем классе.
На заметку: как только вы создали хотя бы один абстрактный метод в классе, вы должны объявить этот класс как абстрактный.
Когда от абстрактного класса наследуется обычный класс, он должен реализовать все абстрактные методы класса-родителя. В противном случае, PHP сгенерирует ошибку. Так, абстрактный класс создает “правила поведения” для своих дочерних классов.
На заметку: вы можете добавлять в абстрактный класс и не абстрактные методы. Они будут обыкновенным образом наследоваться дочерними классами.
abstract class Person { private $firstName = ""; private $lastName = ""; public function setName( $firstName, $lastName ) { $this->firstName = $firstName; $this->lastName = $lastName; } public function getName() { return "$this->firstName $this->lastName"; } abstract public function showWelcomeMessage(); }
Как видите, мы создали абстрактный класс, добавив в его описание ключевое слово abstract. В этом классе есть несколько свойств, общих для всех людей, — $frstName и $lastName — а также методы для инициализации и чтения значений этих полей.
В классе также есть абстрактный метод showWelcomeMessage(). Этот метод выводит приветствие, когда пользователь входит на сайт. Опять же, мы добавляем ключевое слово abstract в описание данного метода, чтобы сделать его абстрактным. Так как он абстрактный, в нем нет ни строчки кода, это просто его объявление. Тем не менее, любой дочерний класс обязан добавить и описать метод showWelcomeMessage().
Теперь давайте создадим пару классов от абстрактного класса Person:
- класс Member для участников форума;
- класс Shopper для покупателей онлайн-магазина.
class Member extends Person { public function showWelcomeMessage() { echo "Hi " . $this->getName() . ", welcome to the forums!<br>"; } public function newTopic( $subject ) { echo "Creating new topic: $subject<br>"; } } class Shopper extends Person { public function showWelcomeMessage() { echo "Hi " . $this->getName() . ", welcome to our online store!<br>"; } public function addToCart( $item ) { echo "Adding $item to cart<br>"; } }
Как видите, каждый из них описывает метод showWelcomeMessage() из абстрактного супер-класса. Они имплементированы по-разному: в классе Member отображается сообщение «welcome to the forums», а в классе Shopper — «welcome to our online store», но это нормально. Главное то, что они оба описали данный метод.
Если бы один из них, например, Shopper, не описал метод, PHP выдал бы ошибку:
Class Shopper contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Person::showWelcomeMessage)
Наряду с имплементацией абстрактного метода, в каждом классе есть свои обычные методы. В Member есть метод newTopic() для создания новой темы в форуме, а в Shopper — метод addToCart() для добавления товаров в корзину.
Теперь мы можем создавать участников форума и покупателей на нашем сайте. Мы можем вызывать методы newTopic() и addToCart() от этих объектов, а также getName() и setName(), так как они наследуются от супер-класса Person.
Более того, зная, что классы Member и Shopper наследуются от Person, мы можем спокойно вызывать метод showWelcomeMessage() для обоих классов, так как он точно реализован и в том и в другом. Мы в этом уверены, так как знаем, что он был объявлен как абстрактный метод в классе Person.
Вот пример:
$aMember = new Member(); $aMember->setName( "John", "Smith" ); $aMember->showWelcomeMessage(); $aMember->newTopic( "Teddy bears are great" ); $aShopper = new Shopper(); $aShopper->setName( "Mary", "Jones" ); $aShopper->showWelcomeMessage(); $aShopper->addToCart( "Ornate Table Lamp" );
На странице отобразится:
Hi John Smith, welcome to the forums! Creating new topic: Teddy bears are great Hi Mary Jones, welcome to our online store! Adding Ornate Table Lamp to cart
Наследование классов
Вместо того, чтобы начинать с нуля, вы можете создать класс, выведя его из ранее существовавшего класса, перечислив родительский класс в скобках после имени нового класса.
Дочерний класс наследует атрибуты своего родительского класса, и вы можете использовать эти атрибуты, как если бы они были определены в дочернем классе. Дочерний класс также может переопределять элементы данных и методы родительского класса.
Синтаксис
Производные классы объявляются так же, как их родительский класс; однако список базовых классов для наследования дается после имени класса
class SubClassName (ParentClass1): 'Optional class documentation string' class_suite
Пример
#!/usr/bin/python class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor" def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method
Когда приведенный выше код выполняется, он дает следующий результат
Calling child constructor Calling child method Calling parent method Parent attribute : 200
Аналогичным образом вы можете управлять классом из нескольких родительских классов следующим образом:
class A: # define your class A ..... class B: # define your class B ..... class C(A, B): # subclass of A and B .....
Вы можете использовать функции issubclass () или isinstance (), чтобы проверить отношения двух классов и экземпляров.
- Issubclass ( к югу, вир) функция булева возвращает истину , если данный подкласс суб действительно подкласс суперкласса вир .
- Isinstance (объект, класс) Функция булева возвращает истину , если OBJ является экземпляром класса Class или является экземпляром подкласса класса
Объектно-ориентированное программирование
Основная задача ООП — сделать сложный код проще. Для этого программу разбивают на независимые блоки, которые мы называем объектами.
Объект — это не какая-то космическая сущность. Это всего лишь набор данных и функций — таких же, как в традиционном функциональном программировании. Можно представить, что просто взяли кусок программы и положили его в коробку и закрыли крышку. Вот эта коробка с крышками — это объект.
Программисты договорились, что данные внутри объекта будут называться свойствами, а функции — методами. Но это просто слова, по сути это те же переменные и функции.
Объект можно представить как независимый электроприбор у вас на кухне. Чайник кипятит воду, плита греет, блендер взбивает, мясорубка делает фарш. Внутри каждого устройства куча всего: моторы, контроллеры, кнопки, пружины, предохранители — но вы о них не думаете. Вы нажимаете кнопки на панели каждого прибора, и он делает то, что от него ожидается. И благодаря совместной работе этих приборов у вас получается ужин.
Объекты характеризуются четырьмя словами: инкапсуляция, абстракция, наследование и полиморфизм. Если интересно, что это такое, приглашаем в кат:
Инкапсуляция — объект независим: каждый объект устроен так, что нужные для него данные живут внутри этого объекта, а не где-то снаружи в программе. Например, если у меня есть объект «Пользователь», то у меня в нём будут все данные о пользователе: и имя, и адрес, и всё остальное. И в нём же будут методы «Проверить адрес» или «Подписать на рассылку».
Абстракция — у объекта есть «интерфейс»: у объекта есть методы и свойства, к которым мы можем обратиться извне этого объекта. Так же, как мы можем нажать кнопку на блендере. У блендера есть много всего внутри, что заставляет его работать, но на главной панели есть только кнопка. Вот эта кнопка и есть абстрактный интерфейс.
В программе мы можем сказать: «Удалить пользователя». На языке ООП это будет «пользователь.удалить()» — то есть мы обращаемся к объекту «пользователь» и вызываем метод «удалить»
Кайф в том, что нам не так важно, как именно будет происходить удаление: ООП позволяет нам не думать об этом в момент обращения
Например, над магазином работают два программиста: один пишет модуль заказа, а второй — модуль доставки. У первого в объекте «заказ» есть метод «отменить». И вот второму нужно из-за доставки отменить заказ. И он спокойно пишет: «заказ.отменить()»
Ему неважно, как другой программист будет реализовывать отмену: какие он отправит письма, что запишет в базу данных, какие выведет предупреждения
Наследование — способность к копированию. ООП позволяет создавать много объектов по образу и подобию другого объекта. Это позволяет не копипастить код по двести раз, а один раз нормально написать и потом много раз использовать.
Например, у вас может быть некий идеальный объект «Пользователь»: в нём вы прописываете всё, что может происходить с пользователем. У вас могут быть свойства: имя, возраст, адрес, номер карты. И могут быть методы «Дать скидку», «Проверить заказ», «Найти заказы», «Позвонить».
На основе этого идеального пользователя вы можете создать реального «Покупателя Ивана». У него при создании будут все свойства и методы, которые вы задали у идеального покупателя, плюс могут быть какие-то свои, если захотите.
Идеальные объекты программисты называют классами.
Полиморфизм — единый язык общения
В ООП важно, чтобы все объекты общались друг с другом на понятном им языке. И если у разных объектов есть метод «Удалить», то он должен делать именно это и писаться везде одинаково
Нельзя, чтобы у одного объекта это было «Удалить», а у другого «Стереть».
При этом внутри объекта методы могут быть реализованы по-разному. Например, удалить товар — это выдать предупреждение, а потом пометить товар в базе данных как удалённый. А удалить пользователя — это отменить его покупки, отписать от рассылки и заархивировать историю его покупок
События разные, но для программиста это неважно. У него просто есть метод «Удалить()», и он ему доверяет
Такой подход позволяет программировать каждый модуль независимо от остальных. Главное — заранее продумать, как модули будут общаться друг с другом и по каким правилам
При таком подходе вы можете улучшить работу одного модуля, не затрагивая остальные — для всей программы неважно, что внутри каждого блока, если правила работы с ним остались прежними
Перегрузка родительских методов
Как вы уже увидели, при создании дочернего класса, он наследует все поля и методы своего родительского класса. Тем не менее, может возникнуть необходимость изменить функциональность методов супер-класса в дочернем классе.
На примере с форумом: когда админ логинится, это происходит абсолютно так же, как и для обычного пользователя, но вы, возможно, захотите записывать логи в определенный файл, в целях безопасности.
Перегрузкой метода login() в дочернем классе, вы можете изменить данный метод по своему усмотрению.
Чтобы перегрузить метод супер-класса в дочернем классе, просто создайте в нем метод с таким же названием. Тогда при вызове метода для объектов дочернего класса, будет вызываться именно перегруженный метод, а не метод супер-класса:
class ParentClass { public function myMethod() { // (действия) } } class ChildClass extends ParentClass { public function myMethod() { // вызывется для объекта класса ChildClass // вместо метода супер-класса MyMethod() } }
Давайте перегрузим метод login() для класса Administrator так, чтобы в файл записывались логи:
class Member { public $username = ""; private $loggedIn = false; public function login() { $this->loggedIn = true; } public function logout() { $this->loggedIn = false; } } class Administrator extends Member { public function login() { $this->loggedIn = true; echo "Log entry: $this->username logged in<br>"; } } // создаем нового пользователя и логиним его $member = new Member(); $member->username = "Fred"; $member->login(); $member->logout(); // создаем нового администратора и логиним его $admin = new Administrator(); $admin->username = "Mary"; $admin->login(); // отобразит "Log entry: Mary logged in" $admin->logout();
Как видите, мы перегрузили метод login() класса Administrator, чтобы он отображал сообщения, как в файлах — логах.
Затем мы создали обычного пользователя (Fred) и администратора (Mary). При вызове метода login() от Фреда вызывается метод Member::login(). А когда мы вызываем метод от администратора Mary, вызовется метод Administrator::login(), так как PHP видит, что мы перегрузили этот метод для данного класса. На странице отобразится строка «Log entry: Mary logged in».
С другой стороны, мы не перегрузили метод logout() в дочернем классе, поэтому Member:logout() вызывается и для админов и для обычных пользователей.
5 последних уроков рубрики «PHP»
Когда речь идёт о безопасности веб-сайта, то фраза «фильтруйте всё, экранируйте всё» всегда будет актуальна. Сегодня поговорим о фильтрации данных.
Обеспечение безопасности веб-сайта — это не только защита от SQL инъекций, но и протекция от межсайтового скриптинга (XSS), межсайтовой подделки запросов (CSRF) и от других видов атак
В частности, вам нужно очень осторожно подходить к формированию HTML, CSS и JavaScript кода.
Expressive 2 поддерживает возможность подключения других ZF компонент по специальной схеме. Не всем нравится данное решение
В этой статье мы расскажем как улучшили процесс подключение нескольких модулей.
Предположим, что вам необходимо отправить какую-то информацию в Google Analytics из серверного скрипта. Как это сделать. Ответ в этой заметке.
Подборка PHP песочниц
Подборка из нескольких видов PHP песочниц. На некоторых вы в режиме online сможете потестить свой код, но есть так же решения, которые можно внедрить на свой сайт.