воскресенье, 3 февраля 2013 г.

Новый возможности PHP 5.4

Участвую в разработке одного сервиса построенного на Drupal 6 PHP 5.2.   Время идёт Drupal 6 становится deprecated. Кроме этого проект растёт, объём кода растёт появляется желание начать использовать новые возможности PHP 5.3, хотя бы На официальном сайте рекомендуемая версия PHP 5.3. Разработку провожу под PHP 5.4.Никаких проблем нет пока. Данная версия должна дать прирост по производительности, от чего бы мы не отказались.  Провожу исследования пытаюсь  выявить проблемы на раннем этапе, также, особенности которые бы помогли переубедить заказчика. Хотя чувствую что дело рисковое.

Усовершенствованы производительность, процессы использования памяти.

Количество внутренних структур стало меньше, они стали меньшими по размеру, или были удалены. Как результат – помогает большим проектом снизить использования памяти на 20-50%, увеличить производительность на 10-30%. Конечно, многое зависит от кода.

Ранние тесты показали, что Zend Framework на 21% работает быстрее и использует на 23% меньше памяти под PHP5.4. Также Drupal использует на 50% меньше памяти и работает на 7% быстрее.

Traits(переводиться как особенность). Примеси.

Данная возможность появилась в PHP 5.4. Данная технология очень похожа на "mixins" - примеси. Они расширяют объекты другими интерфейсами реализаций. Что-то похожее на наследования класса, но без выполнения конструктора, или склейку нескольких классов , шаблонизатор классов. PHP поддерживает только одинарное наследование. Данное свойство частично реализует множественное наследование. В данном примере показывается примесь синглентона, которая помогает другим классам вести себя как синглентоны. Через наследование этого бы не получилось.


trait Singleton {
    public static function getInstance() { ... }
}

class A {
    use Singleton;
    // ...
}

class B extends ArrayObject {
    use Singleton;
    // ...
}

// Singleton method is now available for both classes
A::getInstance();
B::getInstance(); 

Короткий синтаксис массивов.

$a = [1, 2, 3];
$b = ['foo' => 'orange', 'bar' => 'apple']; 

Функция массив пересылка.

Похож на паттерн “цепочка ответственности”. Это так и логично, и удобно. В примере вызывается функция, которая возвращает массив, сразу пытаемся получить значения массива.

function fruits() {
    return ['apple', 'banana', 'orange'];
}
echo fruits()[0]; // Outputs: apple

Вызов метода экземпляра класса.

Схожий на предыдущий вариант. Здесь работаем с объектами. Так мы составляем цепочку действий работы над возвращаемыми объектами:

class foo {
    public $x = 1;
 
    public function getX() {
        return $this->x;
    }
    public function setX($val) {
        $this->x = $val;
        return $this;
    }
}
 
$X = (new foo)->setX(20)->getX(); 
echo $X; // 20 

Присоединение замыкания(Closure).

Замыкание — это процедура или функция, которая ссылается на свободные переменные в своём лексическом контексте. Замыкание появились в PHP 5.3, но в 5.4 появилась возможность работы с объектами, точнее менять, перепривязывать замыкание к другому экземпляру класса. К примеру:

class Foo {
  private $prop;
  function __construct($prop) {
    $this->prop = $prop;
  }
  public function getPrinter() {
    return function() { echo ucfirst($this->prop); };
  }
}

$a = new Foo('bar');;
$func = $a->getPrinter();
$func(); // Outputs: Bar 

Заметьте, что замыкание имеет доступ к приватному полю объекта $this->prop. По умолчанию замыкания используют “ранее связывание”, это означает то, что переменные будут иметь значения те, которые были установлены при объявлении замыкания. Позднее связывание – это когда замыкание переподсоединяем к другому объекту с другими значениями.

$a = new Foo('bar');
$b = new Foo('pickle');
$func = $a->getPrinter();
$func(); // Outputs: Bar
$func = $func->bindTo($b);
$func(); // Outputs: Pickle 

Здесь мы переподсоединили замыкание от экземпляра объекта $a к экземпляру объекта $b. Эсли желаете сохранить доступ к экземпляру объекта, необходимо замыкание определить типа static:

class Foo {
  private $prop;
  function __construct($prop) {
    $this->prop = $prop;
  }
  public function getPrinter() {
    return static function() { echo ucfirst($this->prop); };
  }
}

$a = new Foo('bar');;
$func = $a->getPrinter(); 
$func(); // Fatal error: Using $this when not in object context

Объекты как функции.

Появилась возможность вызова экземпляра объекта как функцию. Добавили магическую функцию “__invoke”, которая используется при данной попытке.

class MoneyObject {
    private $value;
    function __construct($val) {
        $this->value = $val;
    }
    function __invoke() {
        return sprintf('$%.2f',$this->value); 
    }
}
$Money = new MoneyObject(11.02/5*13);
echo $Money(); // Outputs: $28.65

Встроенный Web сервер.(CLI)

CLI сервер очень маленькая часть реализация полного Web сервера, который возможно запустить с командной строки:

% php -S localhost:8000
PHP 5.4.0 Development Server started at Sun Mar 11 13:27:09 2012
Listening on localhost:8080
Document root is /home/rasmus
Press Ctrl-C to quit.


Для более сложных приложений необходимо, при использовании mod_rewrite пересылки запросов на front-controller, или router, использовать скрипт-обёртку, которая будет выполнять некоторую логику. Также необходимо запустить скрипт с этой обёрткой.

% php -S localhost:8080 /path/to/router.php
PHP 5.4.0 Development Server started at Sun Mar 11 13:28:01 2012
Listening on localhost:8080
Document root is /tmp/web
Press Ctrl-C to quit.

router.php скрипт-обёртка должена выглядеть так:

Эта захватывает все прямые запросы к .php, передаёт их дальше на обработку, пропуская остальные, как статические файлы. Таким способом возможно запустить Drupal и Symphony, как было показано выше.

Родной Интерфейс Сессии.

Как маленькая особенность существует интерфейс сессии, который возможно реализовать. Возможно передать экземпляр объекта, который реализует данный интерфейс в session_set_save_handler() вместо того, чтобы передавать имена 6-ти ужасных функций:

SessionHandler implements SessionHandlerInterface {
  public int close ( void )
  public int destroy ( string $sessionid )
  public int gc ( int $maxlifetime )
  public int open ( string $save_path , string $sessionid )
  public string read ( string $sessionid )
  public int write ( string $sessionid , string $sessiondata )
}
session_set_save_handler(new MySessionHandler); 
JsonSerializable Интерфейс

Появилась возможность контролировать json_encode(), передавая экземпляр объекта, реализующий интерфейс JsonSerializable:

class Foo implements JsonSerializable {
    private $data = 'Bar';
    public function jsonSerialize() {
        return array('data'=>$this->data);
    }
}
echo json_encode(new Foo); // Outputs: {"data":"Bar"}

Бинарное представление значения.

PHP поддерживало шестнадцатеричное, десятеричное, а теперь и двоичное представление данных:

$mask = 0b010101;

Усовершенствованы сообщения об ошибках.

До этого:
% php -r 'class abc foo' 
Parse error: syntax error, unexpected T_STRING, expecting '{' 
in Command line code on line 1
Теперь:
% php -r 'class abc foo'
Parse error: syntax error, unexpected 'foo' (T_STRING), expecting '{' 
in Command line code on line
Добавили уточнения об ошибке.

Уведомление о попытке конвертации массива в строку.

До этого, когда вы пытались работать с массивом, как со строкой, вы получали cтроку Array(). Теперь это считается неполадкой и получите уведомление:
$a = [1,2,3];
echo $a; 
Note: Array to string conversion in example.php onlLine 2

Удалённые особенности.

Были удалены особенности, которые были некоторые особености, как устаревшие ещё в предыдущих версиях. Использовались для поддержания совместимости. Список: allow_call_time_pass_reference, define_syslog_variables, highlight.bg, register_globals, register_long_arrays, magic_quotes, safe_mode, zend.ze1_compatibility_mode, session.bug_compat42, session.bug_compat_warn and y2k_compliance.

magic_quotes – серъёзное изменение, которое может повлиять на безопасность некоторых ресурсов, которые полагались на эту особенность и не предпринимали собственных мер защиты.

Большинство материало взято, как перевод с этого сайта.

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

Отправить комментарий