1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

PHP 7: Что нового

PHP 7: Что нового. часть 1

Релиз PHP 7 запланирован на конец ноября 2015 года.
В новой версии PHP появились интересные синтаксические плюшки, новые функции
а также самые долгожданные изменения коснулись ядра интерпретатора — проект phpng, увеличивает скорость
обработки скриптов практически вдвое по сравнению с PHP 5.x, плюс более эффективный менеджер памяти.

Итак, что изменилось?

Combined Comparison Operator

Объединенный оператор сравнения (spaceship operator — корабль) — шоткат для операция трехстороннего сравнения двух операндов.
Записывается в форме x = a b. Возвращает одно из трех значений:

Оператор имеет одинаковый приоритет с операциями сравнения (`==`, `!=`, `===`, `!==`) и работает также как и операторы (` =`, . ).
Также корабль не ассоциативен, то есть вы НЕ МОЖЕТЕ связать его с предыдущим вызовом (например `1 2 3`).

Объекты данным оператором сравнивать нельзя.

?? — Оператор объединения со значением NULL

Оператор является сокращенным вариантом вызова isset в тернарном операторе .

// до PHP7
$route = isset (
[H1toH2]
GET [ ‘route’ ] ) ?

GET [ ‘route’ ] : ‘index’ ;
// или
$route = @

GET [ ‘route’ ] ) ? : ‘index’ ;

// PHP 7+
$route =

GET [ ‘route’ ] ?? ‘index’ ;

Скалярные типы

Теперь в объявлениях переменных можно указывать их тип, даже если они являются скалярными (числа и строки).
По умолчанию используется кастинг для приведения к заданному типу, если вы хотите имееть более жесткий контроль,
можно включить strict режим, тогда при присвоении переменной значения, тип которого отличается от объявленного,
будет выброшено исключение TypeError.

строки ( `string` ) ,
целые ( `int` ) ,
числа ( `float` ) ,
бульки ( `bool` ) .

Типы аргументов , которые появились в php 5 . x

названия классов ,
интерфейсы ,
массив ` array `
и выполняемые `callable` аргументы .

// Coercive mode
function sumOfInts ( int . $ints )
<
return array_sum ( $ints ) ;
>

var_dump ( sumOfInts ( 2 , ‘3’ , 4.1 ) ) ; // int(9)

Чтобы включить строгий strict режим проверки, нужно в начале (каждого) файла, добавить вызов

Этот режим помимо обработки параметров влияет на возвращаемые значения!
В строгом режиме запрещен любой кастинг кроме конвертации int => float (но не наоборот)

declare ( strict_types = 1 ) ;

function multiply ( float $x , float $y )
<
return $x * $y ;
>

function add ( int $x , int $y )
<
return $x + $y ;
>

var_dump ( multiply ( 2 , 3.5 ) ) ; // float(7)
var_dump ( add ( ‘2’ , 3 ) ) ; // Fatal error: Uncaught TypeError: Argument 1 passed to add() must be of the type integer, string given.

Важно: Strict mode работает только по месту вызова функции, то есть если описание функции находится в файле с объявлением strict_types=1,
а вызывается она из другого файла без strict_types, то никакой строгой типизации не будет!

Необратимые изменения
Классы с именами `int`, `string`, `float`, and `bool` теперь запрещены.
Любое использование классов с этими названиями приведет к фатальным ошибкам.

Объявления возращаемых типов

Добавлена возможность указать тип переменной, возвращаемой функцией или методом или замыканием.

Следующие типы поддерживаются:

function arraysSum ( array . $arrays ) : array
<
return array_map ( function ( array $array ) : int <
return array_sum ( $array ) ;
> , $arrays ) ;
>

print_r ( arraysSum ( [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] , [ 7 , 8 , 9 ] ) ) ;

При использовании наследования в классах, дочерние методы должны соблюдать объявления возвращаемых типов
указанные в родительском классе / интерфейсе

class C
<
public function test ( ) : A
<
return new A ;
>
>

class D extends C
<
// overriding method C::test() : A
public function test ( ) : B // Fatal error due to variance mismatch
<
return new B ;
>
>

Читать еще:  На что обращать основное внимание?

Объявление метода `D::test() : B` вызовет `E_COMPILE_ERROR` потому что многовариантность не дозволена.
Для того чтобы метод `D::test()` заработал, нужно указать что он возвращает нечто типа `A`.

interface SomeInterface
<
public function test ( ) : A ;
>

class B implements SomeInterface
<
public function test ( ) : A // Окей
<
return null ; // Fatal error: Uncaught TypeError: Return value of B::test() must be an instance of A, null returned.
>
>

В этот раз выполнение закончится эксепшном `TypeError`, потому что `null` не валидный возвратный тип, валидацию пройдет только экземпляр клааса `A`.

Анонимные классы. Да!

Аноимные классы подходят для небольших задач. Из часто используют в языках например C# или Java для выполнения колбэков.

// до PHP 7
class Logger
<
public function log ( $msg )
<
echo $msg ;
>
>

$util -> setLogger ( new Logger ( ) ) ;

// PHP 7+
$util -> setLogger ( new class <
public function log ( $msg )
<
echo $msg ;
>
> ) ;

Анонимные классы позволяют делать тоже самое что и обычные классы: передавать данные в конструктор, наследовать другие классы, использовать трейты и т.п.

var_dump ( new class ( 10 ) extends SomeClass implements SomeInterface <
private $num ;

public function __construct ( $num )
<
$this -> num = $num ;
>

object ( class @ anonymous ) #1 (1) <
[ «Command line code0x104c5b612» : «class@anonymous» : private ] =>
int ( 10 )
>

Анонимные классы поддерживают вложенность. Вложенные классы не будут иметь доступа к private/protected свойствам внешнего класса.
Если такое необходимо, то нужно передать эти данные через конструктор вложенного класса.

class Outer
<
private $prop = 1 ;
protected $prop2 = 2 ;

protected function func1 ( )
<
return 3 ;
>

public function func2 ( )
<
return new class ( $this -> prop ) extends Outer <
private $prop3 ;

public function __construct ( $prop )
<
$this -> prop3 = $prop ;
>

public function func3 ( )
<
return $this -> prop2 + $this -> prop3 + $this -> func1 ( ) ;
>
> ;
>
>

echo ( new Outer ) -> func2 ( ) -> func3 ( ) ; // 6

Поддержка юникод управляющих (escape-) последовательностей

Теперь в «строках» и объявлениях heredoc можно использовать uXXXX последовательности для описания символов юникод

Метод call() у замыканий

Новый метод `call()` — шоткат для выполнения лямбды с прикрепленным объектом выполнения.

// до PHP 7
$getXCB = function ( ) < return $this ->x ; > ;
$getX = $getXCB -> bindTo ( new A , ‘A’ ) ; // биндим А к лямбде
echo $getX ( ) ; // 1

// PHP 7+
$getX = function ( ) < return $this ->x ; > ;
echo $getX -> call ( new A ) ; // 1

Фильтрация `unserialize()`

Новый функционал направлен на обеспечение безопасности сериализации объектов, предотвращает возможные code injection атаки,
давая возможность разработчику указать какие классы могут обрабатываться, а какие игнорироваться.

// конвертирует все объекты в __PHP_Incomplete_Class
$data = unserialize ( $foo , [ «allowed_classes» => false ] ) ;

// конвертирует все объекты в __PHP_Incomplete_Class object исключая MyClass и MyClass2
$data = unserialize ( $foo , [ «allowed_classes» => [ «MyClass» , «MyClass2» ] ) ;

// поведение по-умолчанию, разрешает все классы
$data = unserialize ( $foo , [ «allowed_classes» => true ] ) ;

Класс IntlChar

Новый класс IntlChar расширяет функциональность ICU (библиотека для локализации приложений International Components for Unicode)
Класс содержит статические методы и константы для работы с юникодом.

Для использования должно быть установлено расширение Intl.

Необратимые изменения
Классы в глобальном пространстве не могут называться IntlChar.

Ожидания — Expectations

Обратно совместимое расширение для классической функции `утверждения` (assert).

Если первый параметр функции равен false, то бросается исключение / выводится ошибка с AssertionError (второй параметр).

Assert позволяет отлаживать скрипты, при этом в продакш окружении вызовы будут игнорировать интерпритатором, т.е. ничего не стоить в плане ресурсов.

ini_set ( ‘assert.exception’ , 1 ) ;

class CustomError extends AssertionError

assert ( false , new CustomError ( ‘Что-то пошло не так’ ) ) ;

Добавлены две настройки PHP.ini, по-умолчанию:

— zend . assertions = 1
— assert . exception = 0

#zend.assertions может быть равен:
1 = обрабатывать утверждения assert ( режим разработки | development mode )
0 = генерировать код , но не выполнять
— 1 = игнорировать код ( 0 — стоимость , production mode )

#assert.exception
Включает возможность генерирования исключения вместо вывода ошибки и остановки скрипта ,
выключена для обратной совместимости со старым ` assert ( ) `

Читать еще:  Чистка наушников перекисью водорода

Группировка объявлений `use`

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

// до PHP 7
use somenamespaceClassA ;
use somenamespaceClassB ;
use somenamespaceClassC as C ;

use function somenamespacefn_a ;
use function somenamespacefn_b ;
use function somenamespacefn_c ;

use const somenamespaceConstA ;
use const somenamespaceConstB ;
use const somenamespaceConstC ;

Возврат выражений в генераторах

Generator Return Expressions
Позволяет использовать `return (expression)` в генераторах.
Значение может быть получено вызовом метода `Generator::getReturn()`, только по завершении работы генератора.

$gen = ( function ( ) <
yield 1 ;
yield 2 ;

foreach ( $gen as $val ) <
echo $val , PHP_EOL ;
>

echo $gen -> getReturn ( ) , PHP_EOL ;

Возможность явно вернуть последнее значение — хорошая возможность, которая упрощает работу с генераторами.
Теперь не нужно проверять является ли значение последним. просто вызываем getReturn.

Делегирование генераторов

Generator Delegation
Построено на основе возможности возврата выражений из генератора.
Используется новый синтаксис:

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

function gen ( )
<
yield 1 ;
yield 2 ;

return yield from gen2 ( ) ;
>

function gen2 ( )
<
yield 3 ;

foreach ( $gen as $val )
<
echo $val , PHP_EOL ;
>

echo $gen -> getReturn ( ) ;

Целочисленное деление intdiv()

Функция intdiv() позволяет делить числа на выходе получая целые числа.

Необратимые изменения
Ключевое слово `intdiv` зарезервировано для глобального контекста.

Параметры session_start()

Теперь возможно передавать параметры функции session_start().
Опции — стандартные настройки сессий из php.ini.

Добавился новая настройка для сессий `session.lazy_write`, по-умолчанию включена.

Функция preg_replace_callback_array()

Альтернатива preg_replace_callback, когда требуется обработать несколько условий в коллбеке.
Позволяет передать в качестве обратной функции — массив [‘/regex’/ => callback, . ].

$tokenStream = [ ] ; // [tokenName, lexeme] pairs

// до PHP 7
preg_replace_callback (
[


] ,
function ( $match ) use ( & $tokenStream ) <
if ( strpos ( $match [ 0 ] , ‘[/H1toH2]
) === 0 ) <
$tokenStream [ ] = [ ‘T_VARIABLE’ , $match [ 0 ] ] ;
> elseif ( strpos ( $match [ 0 ] , ‘=’ ) === 0 ) <
$tokenStream [ ] = [ ‘T_ASSIGN’ , $match [ 0 ] ] ;
> elseif ( ctype_digit ( $match [ 0 ] ) ) <
$tokenStream [ ] = [ ‘T_NUM’ , $match [ 0 ] ] ;
> elseif ( strpos ( $match [ 0 ] , ‘;’ ) === 0 ) <
$tokenStream [ ] = [ ‘T_TERMINATE_STMT’ , $match [ 0 ] ] ;
> elseif ( strpos ( $match [ 0 ] , ‘//’ ) === 0 ) <
$tokenStream [ ] = [ ‘T_COMMENT’ , $match [ 0 ] ] ;
>
> ,
$input
) ;

// PHP 7+
preg_replace_callback_array (
[

Необратимые изменения
Имя `preg_replace_callback_array` зарезервировано.

[/H1toH2]

А теперь давайте рассмотрим разные типы операторов

Арифметические операторы

Тут нас ждут знакомые со школьной скамьи операторы:

Многие впадают в ступор от оператора остатка от деления. Тут всё просто. В нашем случае мы вычисляем остаток от деления 6 на 4. Нацело не делится, целая часть – 1, и 2 в остатке. Ещё несколько аналогичных примеров для понимания:

Думаю, арифметические операторы больше не требуют дополнительных разъяснений.

Оператор присваивания

С ним мы уже работали. Используется для присваивания какого-либо значения в переменную.
Классический пример:

Ок, тут всё просто. А как на счёт такого:

Здесь переменной $x присвоили значение 5, а затем умножили на 2 и положили результат выражения в переменную $result. Да, в PHP так тоже можно, хоть и не приветствуется, так как код выглядит довольно запутанно.

Помимо этого есть так называемые сокращенные, комбинированные операторы присваивания.
Например, в комбинации с оператором сложения:

можно было бы записать как

Таким образом, если что-то совершается с левым операндом в исходном виде, то можно использовать эти сокращённые варианты. И да, это применяется и выглядит весьма элегантно, стоит к ним привыкать уже сейчас. Давайте рассмотрим ещё несколько примеров:

И с конкатенацией строк:

Операторы сравнения

Ну тут из названия понятно, что это за операторы и для чего они предназначены. Результатом их работы всегда будет булево значение (true или false).

Начнём с операторов равенства/неравенства:

boolean true
boolean false
boolean false
boolean true

Давайте поясню. Оператор == приводит операнды к одному типу и после сравнивает их значения. Так строка ‘2’ была преобразована к числу и значения оказались равными.
Оператор тождественного равенства === не выполняет приведения типов и сравнивает сначала то, что типы значений идентичны, например, целые числа, а затем сравнивает их значения. И если они одинаковы, то только в таком случае возвращает true.

Читать еще:  Так почему же компьютер шумит?

Оператор неравенства != приводит типы к одному и сравнивает значения. Если они не равны, вернёт true, иначе – false.
Оператор тождественного неравенства !== сначала сравнивает типы, если они не идентичны, например, строка и число, то вернёт true, иначе сравнит их значения. Если они не равны, вернёт true, иначе – false.

Также к операторам сравнения относятся:

boolean false
boolean true
boolean false
boolean true

Тут всё очевидно, не будем задерживаться.

Spaceship

А теперь рассмотрим оператор сравнения, который появился в PHP7. Это спейсшип (или космический корабль) . Похож на корабль штурмовиков из звёздных войн, не так ли?

Логика у этого оператора следующая:
$a $b
Если $a > $b, вернёт 1
Если $a == $b, вернёт 0
Если $a 22.05.2017 в 05:48

Активировать объектно-ориентированный режим Python

Python, как объектно-ориентированный язык программирования, имеет следующие концепции: классы и объекты.

Класс — это чертёж, модель для его объектов.

Ещё раз, класс — это просто модель, или способ для определения атрибутов и поведения(о которых мы говорили в теории выше). Например, класс машины будет иметь свои собственные атрибуты, которые определяют какие объекты являются машинами. Количество колёс, тип топлива, количество сидячих мест и максимальная скорость — всё это является атрибутами машин.

Держа это в уме, давайте посмотрим на синтаксис Python для классов:

Мы определяем классы class-блоком и на этом всё. Легко, не так ли?

Объекты это экземпляры классов. Мы создаём экземпляр тогда, когда даём классу имя.

Здесь car это объект(экземпляр) класса Vehicle.

Помните, что наш класс машин имеет следующие атрибуты: количество колёс, тип топлива, количество сидячих мест и максимальная скорость. Мы задаём все атрибуты когда создаём объект машины. В коде ниже, мы описываем наш класс таким образом, чтобы он принимал данные в тот момент, когда его инициализируют:

Мы используем метод init. Мы называем этот конструктор-методом. Таким образом, когда мы создаём объект машины, мы можем ещё и определить его атрибуты. Представьте, что нам нравится модель Tesla S и мы хотим создать её как наш объект. У неё есть четыре колеса, она работает на электрической энергии, есть пять сидячих мест и максимальная скорость составляет 250 км/ч. Давайте создадим такой объект:

Четыре колеса + электрический “вид топлива” + пять сидений + 250 км/ч как максимальная скорость.

Все атрибуты заданы. Но как нам теперь получить доступ к значениям этих атрибутов? Мы посылаем объекту сообщению с запросом атрибутов. Мы называем это метод. Это поведение объекта. Давайте воплотим эту идею:

Это реализация двух методов: number_of_wheels и set_number_of_wheels. Мы называем их получатель и установщик. Потому что получатель принимает значение атрибута, а установщик задаёт ему новое значение.

В Python мы можем реализовать это используя @property для описания получателя и установщика. Посмотрим на это в коде:

Далее мы можем использовать методы как атрибуты:

Это немного отличается от описания методов. Эти методы работают как атрибуты. Например, когда мы задаём количество колёс, то не применяем два как параметр, а устанавливаем значение двойки для number_of_wheels. Это один из способ написать получать и установщик в Python.

Ещё мы можем использовать методы для других вещей, например создать метод “make_noise”(пошуметь).

Когда мы вызовем этот метод, он просто вернётся строку “VRRRRUUUUM”.

Ссылка на основную публикацию
Статьи c упоминанием слов:
Adblock
detector