Разыменование объектов, возвращаемых функциейВ PHP4 не было возможности разыменования (dereferencing) объектов, возвращаемых фунцией.
В PHP5 такая возможность введена, что позволяет вызывать методы возвращаемых объектов,
оперируя непосредственно с результатом выполнения функции:
class Circle { function draw() { print "Circle\n"; } } class Square { function draw() { print "Square\n"; } }
function ShapeFactoryMethod($shape) { switch ($shape) { case "Circle": return new Circle(); case "Square": return new Square(); } }
ShapeFactoryMethod("Circle")->draw(); ShapeFactoryMethod("Square")->draw(); ?> Инициализация статических переменных-элементов статических классовПример:class foo { static $my_static = 5; public $my_prop = 'bla'; }
print foo::$my_static; $obj = new foo; print $obj->my_prop; ?> Статические методыВ PHP5 ключевое слово "static" можно использовать для определения
статического метода, что позволяет вызывать метод вне контекста объекта.
Пример:class Foo { public static function aStaticMethod() { } }
Foo::aStaticMethod(); ?> Псевдо-переменная $this внутри метода, объявленного статическим, недоступна
(так как при вызове статического метода неизвестно, в контексте какого экземпляра класса
ее использовать, да и вполне возможно, что на момент вызова их не существует вообще - [fixxxer]).
Ключевое слово instanceof
В PHP5 введено ключевое слово instanceof, позволяющее определить,
является или не является объект экземпляром класса, экземпляром, производным от класса,
или же реализацией интерфейса.
Пример:class baseClass { }
$a = new baseClass;
if ($a instanceof basicClass) { echo "Hello World"; } ?> Статические переменные функцийСтатические переменные теперь обрабатываются на этапе компиляции,
что позволяет присваивать им значения по ссылке. Это изменение также
значительно повышает производительность, но означает, что косвенные ссылки
на статические переменные больше не будут работать.
Для параметров, передаваемых по ссылке, теперь можно указать значения по умолчанию.Пример:function my_function(&$var = null) { if ($var === null) { die("$var needs to have a value"); } } ?> __autoload()
Функция __autoload() вызывается автоматически в случае, когда происзодит попытка
создания неопределенного класса. Имя класса передается функции __autoload()
в качестве единственного аргумента.
Пример:function __autoload($className) { include_once $className . ".php"; }
$object = new ClassName; ?> Перегрузка вызовов метода и доступа к свойствам
Как вызовы методов, так и операции доступа к свойствам могут быть перегружены
с использованием методов __call(), __get() и __set().
Пример: __get() и __set()class Setter { public $n; public $x = array("a" => 1, "b" => 2, "c" => 3);
function __get($nm) { print "Getting [$nm]\n";
if (isset($this->x[$nm])) { $r = $this->x[$nm]; print "Returning: $r\n"; return $r; } else { print "Nothing!\n"; } }
function __set($nm, $val) { print "Setting [$nm] to $val\n";
if (isset($this->x[$nm])) { $this->x[$nm] = $val; print "OK!\n"; } else { print "Not OK!\n"; } } }
$foo = new Setter(); $foo->n = 1; $foo->a = 100; $foo->a++; $foo->z++; var_dump($foo); ?> Пример: __call()class Caller { var $x = array(1, 2, 3);
function __call($m, $a) { print "Method $m called:\n"; var_dump($a); return $this->x; } }
$foo = new Caller(); $a = $foo->test(1, "2", 3.4, true); var_dump($a); ?> ИтераторыДля объекта можно указать итератор, который будет использован при применении
класса в операторе foreach. По умолчанию итерация происходит путем перебора
всех свойств.
Пример:class Foo { var $x = 1; var $y = 2; }
$obj = new Foo;
foreach ($obj as $prp_name => $prop_value) { } ?> Каждый класс, экземпляры которого можно использовать с оператором foreach,
должен реализовывать пустой интерфейс Traversable. Другими словами, любой объект,
котороый реализует Traversable, можно использовать с foreach.
Интерфейсы IteratorAggregate и Iterator позволяют указать поведение класса
при его использовании с оператором foreach. Первый интерфейс предоставляет единственный
метод getIterator(), который должен возвращать массив или объект, который либо
реализует интерфейс Iterator, либо является объектом встроенного класса, имеющего
итератор.
Пример:class ObjectIterator implements Iterator {
private $obj; private $num;
function __construct($obj) { $this->obj = $obj; } function rewind() { $this->num = 0; } function hasMore() { return $this->num < $this->obj->max; } function key() { return $this->num; } function current() { switch($this->num) { case 0: return "1st"; case 1: return "2nd"; case 2: return "3rd"; default: return $this->num."th"; } } function next() { $this->num++; } }
class Object implements IteratorAggregate {
public $max = 3;
function getIterator() { return new ObjectIterator($this); } }
$obj = new Object;
foreach($obj as $key => $val) { echo "$key = $val\n"; }
$it = $obj->getIterator(); for($it->rewind(); $it->hasMore(); $it->next) { $key = $it->current(); $val = $it->key(); echo "$key = $val\n"; } unset($it); ?>
Данный пример весьма интерестен, так как демонстрирует использование всех
абстрактных методов, объявленных в интерфейсах Iterator и IteratorAggregate соответственно.
Новая константа __METHOD__Новая псевдо-константа __METHOD__ содержит текущие имена класса и метода,
если используется внутри метода, и имя функции, если используется вне класса.
Пример:
Example
class Foo { function Show() { echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__; } } function Test() { echo __FILE__ . '(' . __LINE__ . ')' . __METHOD__; } ?> Новый метод __toString()
Новый метод __toString() позволяет перегрузить преобразование типа "объект->строка".
Пример:class Foo { function __toString() { return "What ever"; } }
$obj = Foo;
$str = (string) $obj; echo $obj; ?> К сожалению, на данный момент метод _toString работает только при использовании в контексте оператора echo/print.
Reflection APIPHP5 включает в себя reflection API, предоставляющий возможность
реверс-инжиниринга классов, интерфейсов, функций, методов, а также
расширений (extensions).
Reflection API также предоставляет доступ к doc-комментариям
функций, классов и методов.
Практически все аспекты ОО-кода могут быть отражены с помощью reflection API.
Reflaction API документируется отдельно.
Пример:class Foo { public $prop; function Func($name) { echo "Hello $name"; } }
reflection_class::export('Foo'); reflection_object::export(new Foo); reflection_method::export('Foo', 'func'); reflection_property::export('Foo', 'prop'); reflection_extension::export('standard'); ?> Новый диспетчер памяти
В PHP5 используется новый диспетчер памяти, более эффективно работающий
в мультитрэдовой среде, так как он не использует мутексы (mutexes) для осуществления
блокирования/разблокирования (lock/unlock) при операциях выделения/освобождения памяти
(allocation/deallocation).
|