Так уж устроен PHP, что в нем все переменные, в том числе и объекты, всегда рассматриваются как простой набор значений и копируются целиком. Например, если у нас есть объект $a и мы выполняем оператор $b=$a, то все содержимое $a будет скопировано в $b один-в-один.
Пример:
<?php
class A {
// Создаем новый метод:
function Test() {
echo "<h1>Hello!</h1>";
}
}
// Создаем объект класса A:
$a=new A();
// Копируем объект $a:
$b=$a;
// Теперь работаем с новым объектом $b
$b->Test(); // Выводит 'Hello!'
?>
В окне веб-браузера это будет выглядеть ТАК.
Объекты сравниваются очень просто: по именам. Два объекта равны, если они имеют те же самые свойства и значения, а также являются экземплярами одного и того же класса. Сравнение двух объектов осуществляют, используя оператор сравнения (= =).
Пример:
<?php
class A{
// Создаем новый метод:
function test() {
echo "<h1>Hello!</h1>";
}
}
// Создаем объект класса A:
$a=new A();
// Создаем объект класса A:
$b=new A();
// Выводит 'Объекты равны':
if ($a==$b)
echo "<h3>Объекты равны</h2>";
?>
В окне веб-браузера это будет выглядеть ТАК.
PHP позволяет создавать ссылки на объекты.
Пример:
<?php
class A {
// Создаем новый метод:
function Test() {
echo "<h1>Hello!</h1>";
}
}
// Создаем объект класса A:
$a=new A();
// Ссылка на объект класса A:
$b=& new A();
$b->Test();
?>
В окне веб-браузера это будет выглядеть ТАК.
Видимость свойств и методов может быть определена ключевыми словами: public, private, protected. Модификатор public позволяет обращаться к свойствам и методам отовсюду. Модификатор private позволяет обращаться к свойствам и методам только внутри текущего класса. Модификатор protected позволяет обращаться к свойствам и методам только текущего класса и класса, который наследует свойства и методы текущего класса.
Пример:
<?php
//создаем новый класс MyClass
class MyClass
{
//определяем свойства класса
public $public = 'Public <br>';
protected $protected = 'Protected <br>';
private $private = 'Private';
//метод
function printHello() {
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj = new MyClass();
echo $obj->public; // выводит Public
echo $obj->protected; // выводит Fatal Error
echo $obj->private; // выводит Fatal Error
$obj->printHello(); // выводит Public, Protected and Private
//создаем класс-наследник MyClass2
class MyClass2 extends MyClass {
// определяем свойства класса-наследника
protected $protected = 'Protected2';
//создаем метод класса-наследника
function printHello(){
echo $this->public;
echo $this->protected;
echo $this->private;
}
}
$obj2 = new MyClass2();
echo $obj->public; // выводит Public
echo $obj2->private; // выводит Undefined
echo $obj2->protected; // выводит Fatal Error
$obj2->printHello(); // выводит Public, Protected2, not Private
?>
В окне веб-браузера это будет выглядеть ТАК.
Создание копии объекта с абсолютно идентичными свойствами не всегда является приемлемым вариантом. Например, когда ваш объект содержит ссылку на какой-либо другой используемый объект и, когда вы создаёте копию ссылающегося объекта, вам нужно также создать новый экземпляр содержащегося объекта, так, чтобы копия объекта содержала собственный отдельный экземпляр содержащегося объекта.
$объект_копия = clone $ исходный_объект;
Копия объекта создается с использованием вызова clone (который вызывает метод __clone() объекта, если это возможно). Вы можете объявить метод __clone(), который просто создаст объект со свойствами исходного.
Пример:
<?php
class MyClass {
function __clone() {
print "Объект был клонирован ";
}
}
$obj = new MyClass();
clone $obj;
?>
В окне веб-браузера это будет выглядеть ТАК.
Чтобы обратиться к методу, константе или свойству класса, объект которого еще не создан, используется оператор : :.
имя_класса : : свойство()
имя_класса : : метод()
имя_класса : : константа
Пример:
<?php
class cheg {
function myCheg(){
echo "Привет из класса cheg ";
}
}
cheg::myCheg();
?>
В окне веб-браузера это будет выглядеть ТАК.
В определения классов теперь можно включить константы, и ссылаться на них, используя объект. Константы также могут быть объявлены и в пределах одного класса. Отличие переменных и констант состоит в том, что при объявлении последних или при обращении к ним не используется символ $. Как и свойства и методы, значения констант, объявленных внутри класса, не могут быть получены через переменную, содержащую экземпляр этого класса.
Пример:
<?php
class myClass {
const SUCCESS = "Success";
const FAILURE = "Failure";
}
print myClass::SUCCESS;
?>
В окне веб-браузера это будет выглядеть ТАК.
Как видно из примера, использовать константу можно без создания объекта. Константы класса пригодятся нам для хранения параметров подключения к серверу баз данных или других данных, не подлежащих изменениям в ходе выполнения сценария.
В дальнейшем, изучая классы для работы с XML-документами, вы обнаружите в них статические свойства. Объявить статические свойства класса можно так, как показано в примере:
<?php
class cheg {
static $wsr= "Hello, world";
}
echo cheg::$wsr;
?>
Статические свойства едины для всего класса и не могут принадлежать ни одному из объектов класса. Кроме этого, можно обратиться к такому свойству, не создавая объекта:
echo cheg::$wsr;
В окне веб-браузера это будет выглядеть ТАК.
Аналогично можно определить статический метод и использовать его без создания объекта такого класса.
Пример:
<?php
class cheg {
static function mycheg() {
print "Hello, world";
}
}
cheg::mycheg();
?>
В окне веб-браузера это будет выглядеть ТАК.
В статическом методе становится невозможным использовать указатель $this, т.к. при вызове статического метода неизвестно, в контакте какого объекта он вызывается.
Абстрактным называется метод, который имеет только объявление, но не имеет реализации. Реализация же выполняется в классе-наследнике. Класс, который содержит абстрактный метод, объявляется как абстрактный. При этом в нем могут содержаться и обычные, неабстрактные, методы.
Создать объект, являющейся экземпляром абстрактного класса, невозможно. Но вот после того, как в классе-наследнике бывший абстрактный метод будет переопределен, можно уже создавать экземпляры этого класса-наследника.
Класс, может быть объявлен как абстрактный при помощи использования ключевого слова abstract.
Пример:
<?php
abstract class absClass {
/* Данный метод должен быть определён в дочернем классе */
abstract public function getCheg();
/* Общий метод */
public function myprint() {
print $this->getCheg();
}
}
class conClass1 extends absClass {
public function getCheg() {
return "Реализация метода conClass1<br>";
}
}
class conClass2 extends absClass {
public function getCheg() {
return "Реализация метода conClass2";
}
}
$class1 = new conClass1;
$class1->myprint();
$class2 = new conClass2;
$class2->myprint();
?>
В окне веб-браузера это будет выглядеть ТАК.
В РНР невозможно описать класс, являющейся наследником сразу двух классов, даже абстрактных. Для решения этой проблемы существуют интерфейсы, представляющие собой абстрактные классы, не содержащие ни одного неабстрактного метода. Класс можно наследовать двум интерфейсам одновременно, переопределяя их методы. Можно создавать объекты — экземпляры такого класса-наследника.
Интерфейсы объявляются так же, как и обычные классы, но с использованием ключевого слова interface; тела методов интерфейсов должны быть пустыми.
Для включения интерфейса в класс используется ключевое слово implements и описывается функционал методов, перечисленных во включаемом интерфейсе. Если это требуется, классы могут включать более одного интерфейса путём их перечисления через запятую.
Пример:
<?php
interface iCheg{
function mycheg();
}
interface isCheg {
function paint();
}
class cheg implements iCheg, isCheg {
public function mycheg() {
print "Hello, world! <br>";
}
public function paint() {
print "Привет, всем!";
}
}
$obj=new cheg;
$obj->mycheg();
$obj-> paint();
?>
В окне веб-браузера это будет выглядеть ТАК.
Ключевое слово instanceof позволяет определить, является ли объект экземпляром определенного класса (назовем его cheg) или экземпляром класса наследника (назовем его site) определенного класса.
Пример:
<?php
class cheg{}
$obj1=new cheg();
if($obj1 instanceof cheg) {
echo "\$obj1- объект класса cheg <br>";
}
class site extends cheg {}
$obj2=new site();
if($obj2 instanceof cheg){
echo "\$obj2 - объект класса, производного от cheg ";
}
?>
В окне веб-браузера это будет выглядеть ТАК.
Обработка ошибок в программах на языке РНР происходит на основе так называемого механизма исключительных ситуаций, который использует встроенный класс Exception (исключение). Вы можете определить некоторые нежелательные (исключительные) ситуации и обработать их по своему усмотрению. Если этого не делать, то при возникновении ошибок интерпретатор РНР обработает их некоторым стандартным образом с выводом соответствующих сообщений.
Пример:
<?php
class Exception
{
protected $message = 'Unknown exception'; // сообщение об исключении
protected $code = 0; // код исключения, определяемый пользователем
protected $file; // имя файла-источника исключения
protected $line; // строка, в которой произошло исключение
function __construct($message = null, $code = 0);
final function getMessage(); // сообщение об исключении
final function getCode(); // код исключения
final function getFile(); // файл источника
final function getLine(); // строка источника
final function getTrace(); // массив backtrace()
final function getTraceAsString();// форматированная строка трассировки
/* Overrideable — можно перегружать */
function __toString(); // Создание строки для отображения на экране
?>
Во многих объектно-ориентированных языках реализована схема обработки исключений с помощью конструкции try/catch/throw. Она позваляет весь код обработки ошибок локализовать в одном месте сценария.
Постараемся открыть несуществующий файл:
$fp=fopen("file.txt", "r");
Нельзя, получаем сообщение об ошибке. Скроем ее от пользователя.
@$fp=fopen("file.txt", "r");
Теперь напишем объектный код так, чтобы при возникновении ошибки, т.е. в случае, когда $fp получила значение false, создавался новый экземпляр $exception класса Exception. Создавать будем оператором new. Передадим для его создания в качестве значения свойства $message этого класса сообщение об исключении "Невозможно открыть файл!". Не будет ошибки — хорошо, запишем все, что нужно, в файл. Но если возникнет ошибка, то она будет перехвачена конструкцией catch, которая напечатает "Ошибка в строке", затем вызовет метод getLine() для нашего объекта и метод getMessage(). Эти методы вернут номер строки скрипта, в которой произошла ошибка, и значение свойства $message. Синтаксис обработки ошибок таков:
<?php
try
{
@$fp = fopen("file.txt", "w");
if (!$fp) throw new Exception("Невозможно открыть файл!");
// Запись данных в файл при отсутствии ошибок
fclose($fp);
}
catch (Exception $exception)
{
echo "Ошибка в строке ", $exception->getLine();
echo $exception->getMessage();
}
?>
Если у нас есть большой проект, при реализации которого мы решили использовать объектный подход, то нам не обойтись без создания файлов, в которых содержатся определения класса. Таким образом, мы можем соблюсти принцип модульности програмного обеспечения и сможем подключать обновления классов к любому скрипту, используя инструкцию include. Теперь каждый из описанных выше классов можно хранить в отлельных файлах. Поместим ранее созданный нами класс cheg в файл 220.php. Подключение класса к объекту производим с помощью include:
<?php
include("220.php");
$object = new cheg;
$object->wedsum($sum);
?>
В окне веб-браузера это будет выглядеть ТАК.
В РНР5 для загрузки классов, не подключенных к скрипту, используется глобальная функция __autoload. Эта функция принимает один параметр —имя класса. Действия, которые будут выполняться при вызове функции автозагрузки, придется определить.
Пример:
<?php
function __autoload($cheg){
include("220.php");
}
$object = new cheg;
$object->wedsum($sum);
?>
В окне веб-браузера это будет выглядеть ТАК.
При создании классов и файлов надо помнить о чувствительности к регистру и при необходимости выполнять соответствующие преобразования имен.
PHP 5 предоставляет механизм итераторов для получения списка всех свойств какого-либо объекта, например, для использования совместно с оператором цикла foreach(). По умолчанию, в итерации будут участвовать все свойства, объявленные как public.
Пример:
<?php
class MyClass {
public $var1 = 'value 1';
public $var2 = 'value 2';
public $var3 = 'value 3';
protected $protected = 'protected';
private $private = 'private';
}
$class = new MyClass();
foreach($class as $key => $value) {
print "<pre>$key => $value\n";
}
?>
В окне веб-браузера это будет выглядеть ТАК.
Похожие материалы по теме: Управление доступом с помощью модификаторов. Вызов операций класса
Реализация наследования в РНР
Реализация интерфейсов. Проектирование классов
Написание кода класса
Дополнительная объектно-ориентированная функциональность РНР