Что нас ожидает в Zend Framework 2 и Doctrine 2

// Июль 23rd, 2010 // Doctrine, Zend Framework, Веб-разработка

Я, как Zend Framework (PHP) программист работаю в основном с такими инструментами как ZF и Doctrine. Поэтому пристально слежу за выпуском их новых версий. Думаю к концу года (пока это есть в планах) завершится разработка второй ветки Zend Framework. Итак, что же нас ждет в новой версии?

Zend Framework 2.0

Использование пространств имен (namespaces)

Пространство имён — некоторое множество каким-либо образом взаимосвязанных имён или терминов. Во избежание путаницы, именам в одном пространстве имён не дают более одного значения. Например, в пространстве имён улиц любого города названия улиц, как правило, не повторяются. Пространство имён является важной частью контекста употребления имён, так как фактическое значение имени может меняться в зависимости от того, в какое пространстве имён оно входит.
Расширяя пространство имён, мы вынуждены расширять или усложнять имена. Пример — имя человека: в пространстве имён «Семья» одного имени как правило достаточно, чтобы обозначить конкретного человека, а в пространстве имён «Граждане страны N» — нет. Нужно добавить дополнительную информацию — фамилию, адрес и т. п.
В языках программирования и разметки данных пространства имён чётко формализуются и используются строго в соответствии с правилами соответствующего языка.

Пространство имён — некоторое множество каким-либо образом взаимосвязанных имён или терминов. Во избежание путаницы, именам в одном пространстве имён не дают более одного значения. Например, в пространстве имён улиц любого города названия улиц, как правило, не повторяются. Пространство имён является важной частью контекста употребления имён, так как фактическое значение имени может меняться в зависимости от того, в какое пространстве имён оно входит.Расширяя пространство имён, мы вынуждены расширять или усложнять имена. Пример — имя человека: в пространстве имён «Семья» одного имени как правило достаточно, чтобы обозначить конкретного человека, а в пространстве имён «Граждане страны N» — нет. Нужно добавить дополнительную информацию — фамилию, адрес и т. п.В языках программирования и разметки данных пространства имён чётко формализуются и используются строго в соответствии с правилами соответствующего языка.

Пространство имён (namespace/package) знакомо java и c# программистам, теперь доступно и в php. Нужно оно для того, что-бы не писать длинные перефиксы к названиям классов, как сейчас делается в Zend, PEAR и других библиотеках и платформах для совместимости.

Вместо этого классы, функции, интерфейсы (абстрактные классы) и константы могут быть объединены в одно пространство имён. Глобальные переменные в это пространство не входят.

Позднее статическое связывание (Last Static Binding)

Позднее Статическое Связывание (Late Static Binding, LSB) является бурно темой обсуждений последние три года в кругах разработчиков PHP (и наконец мы его получили в PHP 5.3). Но зачем оно нужно? В данной статье, как раз и будет рассматриваться, как позднее статическое связывание может значительно упростить ваш код. На встрече разработчиков PHP, которая проходила в Париже в ноябре 2005 года, тема позднего статического связывания официально обсуждалась основной командой разработчиков. Они согласились реализовать его, наряду со многими другими темами, которые стояли на повестке дня. Детали должны были быть согласованы в ходе открытых дискуссий.

С тех пор как позднее статическое связывание было объявлено как грядущая фишка, прошло два года. И вот наконец LSB стало доступно для использования в PHP 5.3. Но это событие прошло незаметно для разработчиков использующих PHP, из заметок только страничка в мануале.

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

class Beer {
const NAME = 'Beer!';
public function getName() {
return self::NAME;
}
}

class Ale extends Beer {
 const NAME = 'Ale!';
}
$beerDrink = new Beer;
$aleDrink = new Ale;

echo "Beer is: " . $beerDrink->getName() ."n";
echo "Ale is:  " . $aleDrink->getName()  ."n";

Этот код выдаст такой результат:

Beer is: Beer!
Ale is:  Beer!

Класс Ale унаследовал метод getName(), но при этом self все еще указывает на класс в котором оно используется (в данном случае это класс Beer). Это осталось и в PHP 5.3, но добавилось слово static. И снова рассмотрим пример:

class Beer {
const NAME = 'Beer!';
	public function getName() {
	  return self::NAME;
	}
	public function getStaticName() {
	  return static::NAME;
	}
}
class Ale extends Beer {
const NAME = 'Ale!';
}
$beerDrink = new Beer;
$aleDrink = new Ale;
echo "Beer is: " . $beerDrink->getName() ."n";
echo "Ale is:  " . $aleDrink->getName()  ."n";
echo "Beer is actually: " . $beerDrink->getStaticName() ."n";
echo "Ale is actually:  " . $aleDrink->getStaticName()  ."n";

Новое ключевое слово static указывает, что необходимо использовать константу унаследованного класса, вместо константы которая была определена в классе где объявлен метод getStaticName(). Слово static было добавлено, чтобы реализовать новый функционал, а для обратной совместимости self работает также как и в предыдущих версиях PHP.

Внутренне, основное отличие (и, собственно, причина почему связывание назвали поздним) между этими двумя способами доступа, в том, что PHP определят значение для self::NAME во время «компиляции» (когда симовлы PHP преобразуются в машинный код, который будет обрабатываться движком Zend), а для static::NAME значение будет определено в момент запуска (в тот момент, когда машинный код будет выполнятся в движке Zend).

Замыкания

В ZF’е будут использоваться замыкания(closure).

Замыкание — это особый вид функции. Она определена в теле другой функции и создаётся каждый раз во время её выполнения. В записи это выглядит как функция, находящаяся целиком в теле другой функции. При этом вложенная внутренняя функция содержит ссылки на локальные переменные внешней функции. Каждый раз при выполнении внешней функции происходит создание нового экземпляра внутренней функции, с новыми ссылками на переменные внешней функции.

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

Нотация:

function ($var) use ($outerVar1, $outerVar2, ...) { }

Пример использования:

function outer($x) // Определение внешней функции
{
	$y = 2; // Локальная переменная внешней функции
	$inner = function($a) use ($x, $y) // Определение внутренней функции
	{
		$b = 4; // Локальная переменная внутренней функции
		$res = $x + $y + $a + $b;
		echo $res; // Результат будет равен 10
	};
	$inner(3); // Вызов внутренней функции
}
$outer(1); // вызов внешней функции

__invoke()

Теперь класс можно вызвать как функцию, и в ZF’е,  я думаю, это будет использоваться на всю катушку.

class Example {
public function __invoke() {
echo "Hello World! \n";
}
}
$foo = new Example();
$foo();

Оператор GOTO

Тут вообще ходит много разговоров. В стиле, что goto пережиток прошлого и использовать его — моветон. Однако в некоторых случая его использование черезвычайно эффективно. Например, в случае различного рода парсеров, конечных автоматов, различного рода синтаксических и лексических анализаторов. А вот в ZF 2.0 он будет использоваться в следующих классах:

  • Zend_Controller_Front
  • Zend_Lcal
  • Zend_Search_Lucene
  • Zend_Markup

и в других классах.

Ближе к стандартам

Также нас ждет много архитектурных отличий. Прежде всего это касается стандартизации. Например вызов метода непосредственно го функционала (основного метода сущности) в плагинах, хелперах вида и хелперах контроллера происходит совершенно по-разному. Для Action helpers это метод _direct(), для view helpers formSelect() (имя класса), для валидаторов — isValid() для фильтров — filter(). Из за этого снижается производительность, PluginLoader производит лишние операции при каждом поиске, да и нет единой парадигмы по передаче параметров тем же фабрикам. Так вот в ZF 2.0 такого не будет. И это хорошо, не придется каждый раз вспоминать, как происходит вызов, да и отладка будет проще.

Тестирование

Тестирование упроститься благодаря стандартизации. Также для тестирования в Zend Framework будет выделено отдельное пространство имен Zend/Test, Test/Zend или ZendTest.

Будет стандартизован массив options, что в сочетании с предыдущим пунктом позволит стандартизировать и упростить вызовы разных частей приложения. То что мне изначально понравилось во фреймворке, это то что он дисциплинирует, во второй ветке, это видно еще больше.

Уменьшение количества синглтонов

Также идет тенденция на уменьшение количества сингтонов. Они понижают тестируемость приложения, т.к. зависимость от синглтона не видна в публичном контракте класса.

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

Изменения в плагинах

Теперь плагины будут делиться на три типа:

  • Цепочки (chails): валидаторы, фильтры, декораторы
  • Помошники (helpers): action helpers, view helpers.
  • Адаптеры (adapters): form display groups, subforms, database adapters, translation adapters

Doctrine 2.0

В новой доктрине на всю катушку будет использоваться рефлексия, которая доступна в принципе и в php 5.2.

В информатике, отражение или рефлексия (синоним интроспекция, англ. reflection) означает процесс, во время которого программа может отслеживать и модифицировать собственную структуру и поведение. Парадигма программирования, положенная в основу отражения, называется рефлексивным программированием. Это один из видов метапрограммирования. Доктрина будет использовать рефлексивно-ориентированное программирование, т.е. читать комментарии к самой себе и использовать их как код (интерпретировать). Думаю в этой связи надо учитывать работы PHP Reflection с eAccelerator.

Doctrine 2.0 на php5.3 кушает на 31% меньше памяти и выполняется на 17% быстрее, чем Doctrine 1.0 на PHP 5.2.8

Вот тизер от новой доктрины:

namespace Doctrine\Tests\Models\CMS;

/**
* @DoctrineEntity(tableName="cms_articles")
*/
class CmsArticle
{
   /**
    * @DoctrineId
    * @DoctrineColumn(type="integer")
    * @DoctrineIdGenerator("auto")
    */
   public $id;

   /**
    * @DoctrineColumn(type="varchar", length=255)
    */
   public $topic;

   /**
    * @DoctrineColumn(type="varchar")
    */
   public $text;

   /**
    * @DoctrineManyToOne(targetEntity="Doctrine\Tests\Models\CMS\CmsUser",
           joinColumns={"user_id" = "id"})
    */
   public $user;

   /**
    * @DoctrineOneToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsComment", mappedBy="article")
    */
   public $comments;
}

Даты выхода

Zend Framework 2.0:  конец 2010 года

Doctrine 2.0: 11 декабря 2010 будет еще один альфа-релиз, а 8-го января выйдет уже первая бета.

Материалы и полезные ссылки

http://www.zfconf.ru/2010/topics/what-news-zend-framework-2-0-brings-to-us/

http://habrahabr.ru/blogs/php/27791/

Share

Спасибо!


Если вам помогла статья, или вы хотите поддержать мои исследования и блог - вот лучший способ сделать это:


3 Responses to “Что нас ожидает в Zend Framework 2 и Doctrine 2”

  1. Мда стільки змін, а я вже думав переходити на рубі, а тут стільки інтересного нового в пхп.
    Думаю це буде інтересно :)

  2. qasa:

    Обесните пожалуйста следуюшее:
    Какая разница между созданием модела вот так:
    Application_Model_DbTable_Model extends Zend_Db_Table_Abstract

    и вот так просто:
    Model extends Zend_Db_Table_Abstract

Комментировать