PHP7: scalar hinting

Продолжаю потихоньку наблюдать за развитием ПХП 7. Сегодня с утра выписывал из репозитория и компилировал новую версию, заметил, что в языке появилось указание типов для скаляров — поддерживаются int, float, string и bool.

Выглядит всё довольно естественно:
<?php
class Test
{
	public function __toString()
	{
		return "test";
	}
}

function len(string $a): int {
	return strlen($a);
}

echo len(new Test);
echo len(new stdClass); // Fatal error: Argument 1 passed to len() must be of the type string, object given
В данном случае первый вызов ошибку не вызовет (в отличие от второго), так как у объекта есть магический метод __toString, который вызывается, когда объект требуется привести к строке, так что всё логично. Возможные преобразования описаны в документации и ничего нового там нет, всё в соответствии с текущей логикой языка.

Есть и второй режим работы — строгий. Его можно включить при помощи конструкции declare, которая должна быть первой конструкцией языка (теперь у неё приоритет даже над namespace) в файле:
<?php
declare(strict_types=1);
namespace Test;

class Test
{
	public function __toString()
	{
		return "test";
	}
}

function len(string $a): int {
	return strlen($a);
}

echo len(new Test); // Fatal error: Argument 1 passed to Test\len() must be of the type string, object given
В этом случае все проверки на тип становятся строгими и никаких неявных преобразований не допускается.

По правде говоря, мне больше импонирует второй режим — несколько лет программирования на «Гоу» и «Пайтоне» позволили оценить все прелести строгой типизации, но существующий код большого продукта привести за приемлемое к строгому режиму будет часто невозможно, на мой взгляд. Видимо поэтому создатели языка ограничили действие строгого режима рамками файла — новые части можно писать, не затрагивая поведение старых, это удобно.
24 марта 2015 08:27

Олег Горбунов (инкогнито)
24 марта 2015, 09:19

Мне не нравится необходимость использовать declare() везде. Я бы предпочел, что бы определенное поведение можно было бы включить из php.ini, например.
Опять-таки, всплывает вопрос перегрузки методов, который есть в языках со строгой типизацией параметров.

bolknote.ru (bolknote.ru)
24 марта 2015, 09:39, ответ предназначен Олегу Горбунову

Мне не нравится необходимость использовать declare() везде. Я бы предпочел, что бы определенное поведение можно было бы включить из php.ini, например.
Возможно, ещё сделают это, сейчас сделано по RFC v0.5, а текущая — 0.5.3, он ещё развивается.
Опять-таки, всплывает вопрос перегрузки методов, который есть в языках со строгой типизацией параметров.
Такого, увы, нет. Но я бы предпочёл генерики, а не перегрузку.

alexei (инкогнито)
25 марта 2015, 11:45

Какой странный синакс у declare, нигде в языке больше такого нет. Больше ожидаемо было бы что то типа declare(['strict' => true])

bolknote.ru (bolknote.ru)
25 марта 2015, 13:35, ответ предназначен alexei

Почему ожидаемо? declare не функция, а конструкция. Причём древняя, примеры её использования:

declare(ticks=100);
declare(encoding='ISO-8859-1');

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

Олег Горбунов (инкогнито)
30 марта 2015, 19:27, ответ предназначен bolknote.ru:

Кое-кому еще тоже навеяло: https://github.com/ircmaxell/PhpGenerics =)

bolknote.ru (bolknote.ru)
30 марта 2015, 20:51, ответ предназначен Олегу Горбунову

Мать моя… :) Восхищён крутостью изврата! :)

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)