English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

PHP базовый курс

PHP продвинутый курс

PHP & MySQL

PHP справочник

Ориентированный на объекты PHP

В объектно-ориентированном программировании (OOP) объект - это целостный состав, состоящий из информации и описания обработки этой информации, это абстракция реального мира.

В реальном мире все, с чем мы сталкиваемся, - это объекты, такие как компьютеры, телевизоры, велосипеды и т.д.

Основные три характеристики объекта:

  • Действия объекта: можно применить к объекту те действия, такие как включение света, выключение света, это действия.

  • Форма объекта: когда применяются те методы, как объект реагирует, цвет, размер, форма.

  • Представление объекта: представление объекта подобно паспорту, конкретное различие заключается в том, что в одинаковых действиях и состояниях что-то отличается.

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

Содержание, связанное с объектно-ориентированным подходом

  • Класс − Определяет абстрактные характеристики某一事物. Определение класса включает форму данных и операции над данными.

  • Объект − Это пример класса.

  • Членские переменные − Определено в классе и является переменной, значение которой не видимо извне, но может быть доступно через членские функции. После того как класс будет примерен в объект, эта переменная может называться свойством объекта.

  • Членские функции − Определено в классе и может быть использовано для доступа к данным объекта.

  • наследование − Наследование — это механизм, при котором подкласс автоматически использует данные и методы родового класса, что является типом отношения между классами. При определении и реализации класса можно использовать уже существующий класс в качестве базового, добавляя к нему свои новые данные и методы.

  • Родовой класс − Если один класс наследуется из другого класса, то этот класс можно называть родовым классом, базовым классом или суперклассом.

  • Подкласс − Если один класс наследуется из другого класса, то его называют подклассом или производным классом.

  • Полиморфизм − Полиморфизм означает, что один и тот же функционал или метод может действовать на объекты различных типов и получать различные результаты. Разные объекты, получая одно и то же сообщение, могут дать различные результаты, что называется полиморфизмом.

  • Перегрузка − Простыми словами, это функция или метод с тем же именем, но с разным списком параметров. Функции или методы с одинаковыми именами и различными параметрами называют перегруженными функциями или методами.

  • Абстракция − Абстракция означает абстрагирование объектов с однородной структурой данных (свойства) и поведением (операции), которые представляют собой классы. Такой класс является абстракцией, которая отражает важные свойства, связанные с приложением, и忽略了 другие второстепенные детали. Любое разделение классов носит субъективный характер, но должно быть связано с конкретным приложением.

  • Encapsulation (объединение) − Encapsulation (объединение) означает привязку свойств и поведения некоторого объекта из реального мира к одному логическому блоку.

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

  • Деструктор − Деструктор (destructor) обратен конструктору, и когда объект заканчивает свою жизнь (например, когда функция, в которой находится объект, завершает свою работу), система автоматически выполняет деструктор. Деструктор часто используется для "очистки" (например, если при создании объекта с помощью new было выделено место в памяти, то перед выходом из объекта это место должно быть освобождено с помощью delete).

На следующем рисунке мы создали три объекта: Mercedes, Bmw и Audi, используя класс Car.

$mercedes = new Car();
$bmw = new Car();
$audi = new Car();

Определение класса PHP

Обычно синтаксис определения класса PHP выглядит следующим образом:

<?php
class phpClass {
  var $var1;
  var $var2 = "Константа строка";
  
  function myfunc($arg1, $arg2) {
     [..]
  }
  [..]
}
?>

Интерпретируется следующим образом:

  • Использование класса class После ключевого слова, добавленного именем класса.

  • Внутри фигурных скобок ({}) после имени класса можно определить переменные и методы.

  • Переменные класса используются var Для объявления, переменные также могут быть инициализированы значением.

  • Определение функции подобно определению функции в PHP, но функция может быть доступна только через этот класс и созданные из него объекты.

Пример

<?php
class Site {
  /* Членские переменные */
  var $url;
  var $title;
  
  /* Членские функции */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
?>

Переменная $this Представляет объект самого себя.

PHP_EOL Для перевода строки.

Создание объектов в PHP

После создания класса мы можем использовать new Оператором для создания объекта класса:

$w3codebox = new Site;
$taobao = new Site;
$google = new Site;

В этом коде мы создали три объекта, каждый из которых является независимым,接下来我们来看看如何访问 членские методы и переменные.

Вызов членских методов

После создания объекта мы можем использовать этот объект для вызова членских методов, членские методы могут изменять только членские переменные объекта:

// Вызов членских функций, настройка заголовка и URL
$w3codebox->setTitle('Основные курсы в Интернете');
$taobao->setTitle('Таobao');
$google->setTitle('Google поисковик');
$w3codebox->setUrl('ru.oldtoolbag.com');
$taobao->setUrl('www.taobao.com');
$google->setUrl('www.google.com');
// Вызов членских функций, получение заголовка и URL
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();

Полный код представлен ниже:

Онлайн пример

<?php
class Site {
  /* Членские переменные */
  var $url;
  var $title;
  
  /* Членские функции */
  function setUrl($par){
     $this->url = $par;
  }
  
  function getUrl(){
     echo $this->url . PHP_EOL;
  }
  
  function setTitle($par){
     $this->title = $par;
  }
  
  function getTitle(){
     echo $this->title . PHP_EOL;
  }
}
$w3codebox = new Site;
$taobao = new Site;
$google = new Site;
// Вызов членских функций, настройка заголовка и URL
$w3codebox->setTitle('Основные курсы в Интернете');
$taobao->setTitle('天猫商城');
$google->setTitle('Google поисковик');
$w3codebox->setUrl('ru.oldtoolbag.com');
$taobao->setUrl('www.tmall.com');
$google->setUrl('www.google.com');
// Вызов членских функций, получение заголовка и URL
$w3codebox->getTitle();
$taobao->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$taobao->getUrl();
$google->getUrl();
?>

Выполнение вышеуказанного кода приведет к выводу:

Сайт основы учебника
Taobao интернет-магазин
Google поисковая система
ru.oldtoolbag.com
www.tmall.com
www.google.com

Конструктор PHP

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

PHP 5 позволяет разработчику определить метод в классе в качестве конструктора, и его синтаксис выглядит следующим образом:

void __construct ([ mixed $args [, $... ]]]

В предыдущем примере мы можем初始化 переменные $url и $title через метод конструктора:

function __construct( $par1, $par2 ) {
   $this->url = $par1;
   $this->title = $par2;
}

Теперь нам больше не нужно вызывать методы setTitle и setUrl:

Онлайн пример

$w3codebox = new Site('ru.oldtoolbag.com', 'Сайт основы учебника');
$tmall = new Site('www.tmall.com', 'Taobao интернет-магазин');
$google = new Site('www.google.com', 'Google поисковая система');
// Вызов членских функций, получение заголовка и URL
$w3codebox->getTitle();
$tmall->getTitle();
$google->getTitle();
$w3codebox->getUrl();
$tmall->getUrl();
$google->getUrl();

Деструктор

Деструктор (деструктор) является обратным процессом по сравнению с конструктором, и когда объект заканчивает свою жизнь (например, когда функция, в которой находится объект, завершает свою работу), система автоматически выполняет деструктор.

PHP 5 ввел концепцию деструктора, которая аналогична другим языкам с поддержкой面向对象的 программирования, и ее синтаксис выглядит следующим образом:

void __destruct ( void )

Пример

<?php
class MyDestructableClass {
   function __construct() {
       print "Конструктор\n";
       $this->name = "MyDestructableClass";
   }
   function __destruct() {
       print "Уничтожение " . $this->name . "\n";
   }
}
$obj = new MyDestructableClass();
?>

Выполнение вышеуказанного кода приведет к выводу:

Конструктор
Уничтожение MyDestructableClass

наследование

PHP использует ключевое слово extends Для наследования класса PHP не поддерживает множественное наследование, формат следующий:

class Child extends Parent {
   // Часть кода
}

Пример

В примере класс Child_Site наследует класс Site и расширяет функциональность:

<?php 
// Расширение категории сайта подклассом
class Child_Site extends Site {
   var $category;
    function setCate($par){
        $this->category = $par;
    }
  
    function getCate(){
        echo $this->category . PHP_EOL;
    }
}

Методное перезапис

Если метод, наследованный из родительского класса, не удовлетворяет потребностям подкласса, его можно изменить,这个过程 называется методным перезаписом (override), также известным как перезапись метода.

В примере методы getUrl и getTitle были перезаписаны:

function getUrl() {
   echo $this->url . PHP_EOL;
   return $this->url;
}
   
function getTitle(){
   echo $this->title . PHP_EOL;
   return $this->title;
}

Контроль доступа

Контроль доступа к свойствам или методам в PHP реализуется добавлением ключевых слов public (общедоступные), protected (защищенные) или private (частные) перед ними.

  • public (общедоступные):Общедоступные члены класса могут быть доступны везде.

  • protected (защищенные):Защищенные члены класса могут быть доступны как самому классу, так и его подклассам и родительскому классу.

  • private (частные):Частные члены класса могут быть доступны только в классе, в котором они определены.

Контроль доступа к свойствам

Классовые свойства должны быть определены как общедоступные, защищенные или частные. Если использовать var, то оно будет считаться общедоступным.

<?php
/**
 * Определение MyClass
 */
class MyClass
{
    public $public = 'Public';
    protected $protected = 'Protected';
    private $private = 'Private';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj = new MyClass();
echo $obj->public; // Это может быть выполнено normally
echo $obj->protected; // Это вызывает фатальную ошибку
echo $obj->private; // Это также вызывает фатальную ошибку
$obj->printHello(); // Вывод Public、Protected и Private
/**
 *Определение MyClass2
 */
class MyClass2 extends MyClass
{
    // Можете переопределять public и protected, но не private
    protected $protected = 'Protected2';
    function printHello()
    {
        echo $this->public;
        echo $this->protected;
        echo $this->private;
    }
}
$obj2 = new MyClass2();
echo $obj2->public; // Это может быть выполнено normally
echo $obj2->private; // Неопределено private
echo $obj2->protected; // Это вызывает фатальную ошибку
$obj2->printHello(); // Вывод Public、Protected2 и Undefined
?>

Уровень доступа к методам

Методы в классе могут быть определены как公有ные, частные или защищенные. Если эти ключевые слова не установлены, то метод по умолчанию является публичным.

<?php
/**
 * Определение MyClass
 */
class MyClass
{
    // Объявление публичного конструктора
    public function __construct() { }
    // Объявление публичной функции
    public function MyPublic() { }
    // Объявление защищенной функции
    protected function MyProtected() { }
    // Объявление частной функции
    private function MyPrivate() { }
    // Этот метод является общедоступным
    function Foo()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate();
    }
}
$myclass = new MyClass;
$myclass->MyPublic(); // Это может быть выполнено normally
$myclass->MyProtected(); // Это вызывает фатальную ошибку
$myclass->MyPrivate(); // Это вызывает фатальную ошибку
$myclass->Foo(); // Общедоступные, защищенные и private методы могут выполняться
/**
 * Определение MyClass2
 */
class MyClass2 extends MyClass
{
    // Этот метод является общедоступным
    function Foo2()
    {
        $this->MyPublic();
        $this->MyProtected();
        $this->MyPrivate(); // Эта строка вызовет фатальную ошибку
    }
}
$myclass2 = new MyClass2;
$myclass2->MyPublic(); // Эта строка будет выполнена normalmente
$myclass2->Foo2(); // Общедоступные и защищенные методы можно выполнять, ноprivate нет
class Bar 
{
    public function test() {
        $this->testPrivate();
        $this->testPublic();
    }
    public function testPublic() {
        echo "Bar::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Bar::testPrivate\n";
    }
}
class Foo extends Bar 
{
    public function testPublic() {
        echo "Foo::testPublic\n";
    }
    
    private function testPrivate() {
        echo "Foo::testPrivate\n";
    }
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate 
                // Foo::testPublic
?>

Интерфейс

Использование интерфейса (interface) позволяет определить, какие методы должен реализовать класс, но не требует определения конкретного содержимого этих методов.

Интерфейс определяется через interface ключевым словом, как определение стандартного класса, но все методы в нем пусты.

Все методы в интерфейсе должны быть общедоступными, это свойство интерфейса.

Чтобы реализовать интерфейс, использовать implements Класс должен реализовать все методы, определенные в интерфейсе, в противном случае будет выведена фатальная ошибка. Класс может реализовывать несколько интерфейсов, и имена интерфейсов можно разделить запятыми.

<?php
// Указание интерфейса 'iTemplate'
interface iTemplate
{
    public function setVariable($name, $var);
    public function getHtml($template);
}
// Реализация интерфейса
class Template implements iTemplate
{
    private $vars = array();
  
    public function setVariable($name, $var)
    {
        $this->vars[$name] = $var;
    }
  
    public function getHtml($template)
    {
        foreach($this->vars as $name => $value) {
            $template = str_replace('{ $name }', $value, $template);
        }
 
        return $template;
    }
}

Константы

Значения, которые всегда остаются постоянными в классе, можно определить как константы. При определении и использовании констант символ $ не используется.

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

С PHP 5.3.0 можно динамически вызывать классы с помощью переменных, но значение переменной не может быть ключевыми словами (например, self, parent или static).

Пример

<?php
class MyClass
{
    const constant = 'Значение константы';
    function showConstant() {
        echo self::constant . PHP_EOL;
    }
}
echo MyClass::constant . PHP_EOL;
$classname = "MyClass";
echo $classname::constant . PHP_EOL; // c 5.3.0
$class = new MyClass();
$class->showConstant();
echo $class::constant . PHP_EOL; // c PHP 5.3.0
?>

Абстрактный класс

Любой класс, у которого хотя бы один метод объявлен как абстрактный, должен быть объявлен как абстрактный.

Классы, определенные как абстрактные, не могут быть примерены.

Абстрактные методы определяют только способ их вызова (параметры), но не определяют их конкретное функциональное выполнение.

Когда наследуется абстрактный класс, подкласс обязан определить все абстрактные методы родительского класса; кроме того, уровень доступа этих методов должен быть таким же, как и в родительском классе (или более свободным). Например, если абстрактный метод объявлен как защищенный, то метод, реализованный в подклассе, должен быть объявлен как защищенный или公有ный, но не как частный.

<?php
abstract class AbstractClass
{
 // Обязательное требование к подклассам определять эти методы
    abstract protected function getValue();
    abstract protected function prefixValue($prefix);
    // Обычный метод (не абстрактный метод)
    public function printOut() {
        print $this->getValue() . PHP_EOL;
    }
}
class ConcreteClass1 extends AbstractClass
{
    protected function getValue() {
        return "ConcreteClass1";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass1";
    }
}
class ConcreteClass2 extends AbstractClass
{
    public function getValue() {
        return "ConcreteClass2";
    }
    public function prefixValue($prefix) {
        return "{$prefix}ConcreteClass2";
    }
}
$class1 = new ConcreteClass1;
$class1->printOut();
echo $class1->prefixValue('FOO_') . PHP_EOL;
$class2 = new ConcreteClass2;
$class2->printOut();
echo $class2->prefixValue('FOO_') . PHP_EOL;
?>

Выполнение вышеуказанного кода приведет к выводу:

ConcreteClass1
FOO_ConcreteClass1
ConcreteClass2
FOO_ConcreteClass2

Кроме того, метод подкласса может содержать опциональные параметры, которые отсутствуют в абстрактном методе родительского класса.

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

<?php
abstract class AbstractClass
{
    // Наше абстрактное метод требует только определить необходимые параметры
    class ConcreteClass extends AbstractClass
}
abstract protected function prefixName($name);
{
    // Наша подкласс может определить опциональные параметры, которые отсутствуют в подписи родительского класса
    public function prefixName($name, $separator = ".") {
        if ($name == "Pacman") {
            elseif ($name == "Pacwoman") {
        }
            $prefix = "Mrs";
        }
            $prefix = "";
        }
        return "{$prefix}{$separator} {$name}";
    }
}
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
?>

Результат вывода:

Mr. Pacman
Mrs. Pacwoman

Ключевое слово static

Если объявить классовое свойство или метод как static (статический), то их можно будет получить без инстанцирования класса.

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

Поскольку статические методы могут быть вызываться без объекта, переменная-псевдоним $this недоступна в статических методах.

Статические свойства не могут быть доступными через объект с помощью оператора ->.

С PHP 5.3.0 можно динамически вызывать класс с помощью переменной, но значение этой переменной не может быть ключевыми словами self, parent или static.

<?php
class Foo {
  public static $my_static = 'foo';
  
  public function staticValue() {
     return self::$my_static;
  }
}
print Foo::$my_static . PHP_EOL;
$foo = new Foo();
print $foo->staticValue() . PHP_EOL;
?>

При выполнении следующего кода, результат вывода будет:

foo
foo

Ключевое слово final

PHP 5 добавил ключевое слово final. Если метод в родительском классе объявлен как final, то подкласс не можетoverride этот метод. Если класс объявлен как final, то его нельзя наследовать.

Следующий код выполнения вызовет ошибку:

<?php
class BaseClass {
   public function test() {
       echo "BaseClass::test() called" . PHP_EOL;
   }
   
   final public function moreTesting() {
       echo "BaseClass::moreTesting() called" . PHP_EOL;
   }
}
class ChildClass extends BaseClass {
   public function moreTesting() {
       echo "ChildClass::moreTesting() called" . PHP_EOL;
   }
}
// Сообщение об ошибке Fatal error: Cannot override final method BaseClass::moreTesting()
?>

Вызов метода конструктора родительского класса

PHP не вызывается автоматически метод конструктора родительского класса в методе конструктора подкласса. Чтобы вызвать метод конструктора родительского класса, необходимо вызвать его в методе конструктора подкласса parent::__construct() .

<?php
class BaseClass {
   function __construct() {
       print "Класс BaseClass: метод конструктора" . PHP_EOL;
   }
}
class SubClass extends BaseClass {
   function __construct() {
       parent::__construct(); // Метод конструктора подкласса не может автоматически вызывать метод конструктора родительского класса
       print "Класс SubClass: метод конструктора" . PHP_EOL;
   }
}
class OtherSubClass extends BaseClass {
    // Наследование метода конструктора BaseClass
}
// Вызов метода конструктора BaseClass
$obj = new BaseClass();
// Вызов методов конструктора BaseClass и SubClass
$obj = new SubClass();
// Вызов метода конструктора BaseClass
$obj = new OtherSubClass();
?>

При выполнении следующего кода, результат вывода будет:

Класс BaseClass: метод конструктора
Класс BaseClass: метод конструктора
Класс SubClass: метод конструктора
Класс BaseClass: метод конструктора