Типизация в php

Многие, наверное уже и не помнят какие холивары возникали по поводу недоООПешности php. Зачастую спорщики просто не знали о возможностях языка, другие судили по версии 3-4. Но вот уже появились нэймспэйсы, замыкания, лямбда функции кое как сделанные. Ещё одной проблемой виделась отсутствие строгой типизации. Особого смысла я в ней не вижу и, как показала практика, у не строго типизированных языков в вебе преимущества. Но всё же поговорим об этом. Самая большая проблема — то, что всё что нам приходит от пользователя представлено в протоколе http и в php сводится к строкам. Вводя в инпут строку html не даёт возможности сказать что в этом инпуте будет число, а в этом строка. Как вариант на этапе разгребания заголовков указать тип. Но удобства от этого не много, проще перевести к типу там, где это требуется, например (int)$_GET[‘var’] или intval($_GET[‘var’]).

Зачем же нам знать типы. Типизация позволит избегать неявных проблем с приведением типа, когда это не нужно, типизация позволит не заморачиваться обработкой ситуаций в коде, когда нам вместо интегера передали строку и не городить кучу ифов и бороться с помощью  паттернов типа Special Case, усложняя код. Хочется чтобы язык сам предотвращал такие evil-ситуации.

Очень хорошим шагом был ввод тайпхинтинга, позволяющий проверять тип объекта, переданный в функцию. function test(Mytype $var, TypeInt $varInt, array $varArray). К сожалению,  он работает только для объектов и массивов. Мне удалось нарыть информацию о патче, позволяющем осуществлять хинтинг других типов, таких как integer, string…. Счастье совсем рядом и мы сможем делать такие вкусности.

function test(integer $value) {
}

function (int) test($value) {
	return $value;
}

Указание типов входных и возвращаемых данных может быть очень и очень полезным для не совсем веб ориентированных приложений типа ERP и CRM систем на php.

Кроме это в pecl есть расширение SplTypes, которое позволяет при создании задавать класс переменной, а затем при изменении на неверный тип выбрасывает исключение

$int = new SplInt(94);

try {
 $int = 'Try to cast a string value for fun';
} catch (UnexpectedValueException $uve) {
 echo $uve->getMessage() . PHP_EOL;
}

Так что, формально и теоретически более строгая типизация в php может появиться, другое дело — насколько это поможет и будет полезным ли. Время покажет.

Типизация в php: 7 комментариев

  1. Nergal

    Имхо, динамическая типизация — ещё большее зло, нежели статическая. Самый лучший, на мой взгляд, подход — использование «утиной» типизации, применяемой в Python и JS — определение типа переменной допустимым набором операций над ней. Суть подхода наглядно можно показать на тривиальном делении строки на число: для кода «‘test’ / 2» Python выбросит TypeError, JS вернёт NaN, а вот PHP выполнит деление беспрекословно, вернув целое 0 (конечно, такого результата при нормальном делении не будет, но в данном случае речь не о математике, а с точки зрения семантики вызова возвращать int на такую операцию недопустимо).

    1. AmdY Автор записи

      но если нам в GET пришло ?id=10, то операция $_GET[‘id’]/2 = 5 может выполниться. фактически, вызывается оперция аналогичная parceInt

      точно так же если пользователь случайно добавил пробел
      ?id= 10 — что в адресной строке отразится как ?id=%2010, но даст опять же $_GET[‘id’]/2 = 5
      с точки зрения веба (http) — это стандартная ситуация и такое приведение очень удобно.
      с точки зрения семантики справедливо было бы, чтобы ‘test’ / 2 возвращала строку поделенную на две части, например, массив array(‘te’, ‘st’)
      динамическая типизация — страшный грех, но очень соблазнительный грех. и php придётся что-то делать с этим, если захочется выйти за пределы веба.
      здесь всё относительно, писать на кое как слепленном php — глупость, когда есть python, но в тоже время заумность python является излишней для ряда задач решаемых php и больше мешает, нежели помогает.

      1. fluid

        с точки зрения семантики справедливо было бы, чтобы ‘test’ / 2 возвращала строку поделенную на две части, например, массив array(‘te’, ’st’)

        \\
        «test» / 2 = array(‘te’,’st’); // так?)
        «test» / 5 = array(‘t’,’e’,’s’,’t’,null); // так?)
        и внимание (барабанная дробь)
        «test» / 0,5 = О_О
        думаю с точки зрения семантики лучше строки не делить на числа:)

        а по типизации… думаю нет, не быть этому… иначе придем к множественному наследованию, перегрузке операторов (о кстати тут я не против), указателям и ссылкам и еще тоне всякого нужного и не нужного, кстати к такому букету придет компилятор и именем ему быть gcc

        ps пойду искать табличку сарказмм;)

      2. AmdY Автор записи

        а как бы ты ответил, если бы тебе дали поделить слово из 4-х букв на пять частей? Сказал бы что не делится, а не null
        «test» / 0,5 = «test» / 1/2 = «test»*2 = array(«test», «test») ну или «testtest»

        типизация уже есть в php, как и многие другие вещи, которыми можно НЕ пользоваться.

        выбор — в этом и есть значение …..

  2. fluid

    Перегрузка операторов появилась? погнал смотреть.. ;)

    как я понимаю этого нет из-за явного объявления типов. то что есть это привести к типу или проверить на тип не более того.
    В ядре пхп осталась динамическая типизация+ предоставили какой-то контроль типов разработчикам больше похожий на проверку.

    ps какой будет логорифм от «test», думаю с точки зрения семантики не правильно производить математические операции со строками в стандартном понимании.

    1. AmdY Автор записи

      ещё не хватало перегрузки операторов, тьфу,тьфу….
      вообще-то нужно всегда рассуждать с точки здравого смысла и даже если есть возможность сделать define(‘true’, false); — то не делать этого. Типизация и проверка типов в НЕКОТОРЫХ местах помогут защитить код от криворуких разработчиков, это возможность прежде всего для тех, кто строит архитектуру приложения, кодерам — она не нужна и может даже быть вредной.

  3. fluid

    А :) я не про это вообще, кажись мы говорили о разных вещах)

    Кстати перегрузка операторов это отличная вещи, имхо, если смотреть со стороны сипп ;) А вот пхп без этого и так обходится..

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *