ресурс для начинающих веб-разработчиков
комплексные веб-услуги по созданию сайтов

Справочный материал по основным языкам программирования и верстки сайтов.

Готовая методика создания простых и сложных динамичных сайтов, с использованием PHP и MySQL.

Использование веб-редактора Adobe Dreamweaver в разработке сайтов.

Использование графических редакторов Adobe Flash, Adobe Photoshop, Adobe Fireworks в подготовке веб-графики.

Разработка веб-сайтов под "ключ".

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

Объекты в РНР5. Копирование, сравнение, клонирование объектов

Копирование

Копирование объектов

Так уж устроен 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. Модификатор 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;
?>

Методы не cозданных объектов

Чтобы обратиться к методу, константе или свойству класса, объект которого еще не создан, используется оператор : :

. имя_класса : : свойство()
имя_класса : : метод()
имя_класса : : константа

Пример:

<?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

Ключевое слово 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 в файл file.php. Подключение класса к объекту производим с помощью include:

<?php
include("file.php");
$object = new cheg;
$object->wedsum($sum);
?>

В РНР5 для загрузки классов, не подключенных к скрипту, используется глобальная функция __autoload. Эта функция принимает один параметр —имя класса. Действия, которые будут выполняться при вызове функции автозагрузки, придется определить.

Пример:

<?php
function __autoload($cheg){
include("file.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";
}
?>