Тип PHP-намека на примитивные значения?

Я хотел бы знать, можно ли вводить тип-метод, чтобы ожидать примитивные типы?

Что-то вроде этого:

public function someMethod(string $str)
                         //^^^^^^

Или:

private function anotherMethod(int $num)
                             //^^^

так же, как и вы:

private function otherMethod(Person $rambo)
                           //^^^^^^

Возможно ли это в php?

Ответ 1

В PHP 7 они добавили следующее:

Объявления типа позволяют функциям требовать, чтобы во время разговора были заданы определенные типы. Если заданное значение имеет неправильный тип, генерируется ошибка: в PHP 5 это будет восстанавливаемой фатальной ошибкой, а PHP 7 будет генерировать исключение TypeError.

Ссылка: http://php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration


Когда этот ответ был задан, PHP 5 был последним и сказал следующее:

PHP 5 вводит намеки типов. Теперь функции могут заставить параметры быть объектами (указав имя класса в прототипе функции), интерфейсы, массивы (начиная с PHP 5.1) или вызываемые (начиная с PHP 5.4). Однако, если NULL используется как значение параметра по умолчанию, он будет разрешен в качестве аргумента для любого последующего вызова.

Если класс или интерфейс заданы как подсказка типа, тогда также разрешены все его дочерние элементы или реализации.

Типы подсказок нельзя использовать со скалярными типами, такими как int или string. Не разрешены и ресурсы и черты.

Ссылка: http://php.net/manual/en/language.oop5.typehinting.php

Ответ 2

Неа. Вы не можете вводить подсказки для примитивов, потому что PHP имеет автоматические преобразования для примитивов. См. http://bugs.php.net/bug.php?id=29508. Это никогда не изменится, если у команды PHP внезапная смена сердца (что сомнительно, они довольно упрямы).

Ответ 3

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

Подсказка типа Scalar состоит из объявления типов параметров функции и возвращаемых значений, которые могут быть типов int, float, string и bool. Это позволяет механизму выполнения PHP проверять, были ли типы значений переданы функции параметров и возвращены значения имеют ожидаемые типы, чтобы обнаружить возможные ошибки программирования. Тип намека на объекты, массивы и callables уже разрешен в прошлых версиях PHP. Текущая реализация вводит пять новых зарезервированных слов: int, float, bool, string и numeric. Они ранее не были зарезервированы, поскольку литье является особым случаем в лексере.

Example :
function test(float $a) {
    var_dump($a); 
}

test(1); // float(1)
test("1"); // float(1)
test(1.0); // float(1)
test("1a"); // E_RECOVERABLE_ERROR
test("a"); // E_RECOVERABLE_ERROR
test(""); // E_RECOVERABLE_ERROR
test(1.5); // float(1.5)
test(array()); // E_RECOVERABLE_ERROR
test(new StdClass); // E_RECOVERABLE_ERROR

У вас также есть возможность объявить в исходный файл, где вы можете разрешить использование типа Scaler. Он должен быть 1-й строкой вашей конфигурации script и не может быть объявлен в другом месте в том же файле.

Like : declare(strict_types=1);

Во время выполнения, когда PHP-движок пытается вернуть значение, он будет проверять, не соответствует ли ему, как объявлено, что он будет генерировать фатальную ошибку, например, Неустранимая ошибка: аргумент 1, переданный в increment(), должен быть типа integer, строка, заданная

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

Также возможны автоматические изменения типов. Например, типы int могут автоматически изменяться в параметрах типа float,

function test(float $x){
    var_dump($x);
}
test(10); // works fine

Объявление типа возврата

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

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

function mustReturnInt(): int { ... }
function mustReturnString(): string { ... }
function mustReturnBool(): bool { ... }
function mustReturnFloat(): float { ... }
function doesNotReturnAnything() { ... }

Немного более сложный пример

declare(strict_types=1);  
class StrictTypesTestingClass {  
public function returnSameInt(int $value): int {   return $value;  }   
public function returnSameFloat(float $value): float {   return $value;  }  
public function returnSameString(string $value): string {   return $value;  }   
public function returnSameBool(bool $value): bool {   return $value;  } }  
$check = new StrictTypesTestingClass();  // calls that work  print $check->returnSameInt(10); 
print $check->returnSameFloat(10.0); 
print $check->returnSameString("test"); 
print $check->returnSameBool(true) ? 'true' : 'false';  // calls that throw exceptions 
print $check->returnSameInt("10"); 
print $check->returnSameFloat("10.0"); 
print $check->returnSameString(10);
print $check->returnSameBool("true");

Поведение проверки слабых типов и преобразования типов: режим проверки слабых типов может использоваться с объявлением statement (strict_types = 0); или отсутствие объявления строгих типов. Необходимо учитывать несколько моментов: Слабые типы проверенных вызовов на расширение или встроенную функцию PHP имеют такое же поведение, что и в предыдущих версиях PHP Правила проверки слабых типов для новых деклараций скалярного типа в основном такие же, как и для функций расширения или встроенных функций PHP. NULL - это особый случай, чтобы соответствовать текущим объявлениям типов для классов, вызываемых и массивов. NULL не принимается по умолчанию, если только он не является параметром и явно задан значением по умолчанию NULL, например: function sample (int $a = NULL);

Для такого подхода есть много преимуществ. Вы получаете безопасность типа. Это означает, что вы можете, наконец, статически анализировать код! Вы можете обнаружить ошибки, когда вы случайно берете строку из одной функции и передаете ее как целое число в другую. Для меня, разработчика, который ежедневно использует PHP и видит Java в качестве ссылки для языков ООП, это большой прогресс для PHP.

Ответ 4

Все уже сказали это, вы не можете использовать тип подсказки для примитивов, потому что PHP doest не поддерживает его. Причина этого связана не только с автоматическими преобразованиями, но и с реакцией сообщества.

До сих пор я помню, что в мае 2010 года поддержка сущности скалярного типа была добавлена ​​в ствол PHP. Но из-за реакции сообщества эта функция не попала в выпуск 5.4.

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

ИМХО: Ключевой тип намека должен быть добавлен в PHP ASAP, это функция, в которой мы все нуждаемся, я действительно уважаю, что PHP - это слабый типизированный язык, но для разработки и производства высокого уровня, особенно для OO контексты, подсказка скалярного типа - обязательная. Мы можем иметь как альтернативы в PHP, так и процедурные и OO.

Ответ 5

Да, это возможно.

http://ru2.php.net/manual/ru/language.oop5.typehinting.php#83442

Предупреждение: в оригинальном руководстве есть опечатка: res ro uce вместо res ou rce

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

Примечание. Вы должны включить этот код выше всего другого кода в заголовки include и если вы используете функцию set_error_handler(), вы должны знать, что это также использует его. Возможно, вам понадобится связать set_error_handlers()

Почему?

  • Потому что люди устали от использования функций is_ * для проверки параметров.
  • Сокращение избыточного кодирования защитных кодеров.
  • Функции/Методы - это самоопределение/документация относительно требуемого ввода.

также.. Следуйте дискуссиям по типам в PHP 6.0 на внутренних досках PHP.

<?php

define('TYPEHINT_PCRE', '/^Argument (\d)+ passed to (?:(\w+)::)?(\w+)\(\) must be an instance of (\w+), (\w+) given/');

class Typehint
{

    private static $Typehints = array(
        'boolean'   => 'is_bool',
        'integer'   => 'is_int',
        'float'     => 'is_float',
        'string'    => 'is_string',
        'resource'  => 'is_resource'
    );

    private function __Constrct() {}

    public static function initializeHandler()
    {

        set_error_handler('Typehint::handleTypehint');

        return TRUE;
    }

    private static function getTypehintedArgument($ThBackTrace, $ThFunction, $ThArgIndex, &$ThArgValue)
    {

        foreach ($ThBackTrace as $ThTrace)
        {

            // Match the function; Note we could do more defensive error checking.
            if (isset($ThTrace['function']) && $ThTrace['function'] == $ThFunction)
            {

                $ThArgValue = $ThTrace['args'][$ThArgIndex - 1];

                return TRUE;
            }
        }

        return FALSE;
    }

    public static function handleTypehint($ErrLevel, $ErrMessage)
    {

        if ($ErrLevel == E_RECOVERABLE_ERROR)
        {

            if (preg_match(TYPEHINT_PCRE, $ErrMessage, $ErrMatches))
            {

                list($ErrMatch, $ThArgIndex, $ThClass, $ThFunction, $ThHint, $ThType) = $ErrMatches;

                if (isset(self::$Typehints[$ThHint]))
                {

                    $ThBacktrace = debug_backtrace();
                    $ThArgValue  = NULL;

                    if (self::getTypehintedArgument($ThBacktrace, $ThFunction, $ThArgIndex, $ThArgValue))
                    {

                        if (call_user_func(self::$Typehints[$ThHint], $ThArgValue))
                        {

                            return TRUE;
                        }
                    }
                }
            }
        }

        return FALSE;
    }
}

Typehint::initializeHandler();

?>

An are some examples of the class in use:

<?php

function teststring(string $string) { echo $string; }
function testinteger(integer $integer) { echo $integer; }
function testfloat(float $float) { echo $float; }

// This will work for class methods as well.

?>

Вы получаете изображение.

Ответ 6

Accordind to PHP documentation тип подсказки не поддерживается для примитивных типов.

Он поддерживается для классов и интерфейсов.

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

Ответ 7

Вот короткий синтаксис для принудительного вывода логического значения из переданного параметра. Если $state истинно, то $this->is_active установлено значение true. Для всех других типов значений установлено значение false.

function set_active ( $state ) {
    $this->is_active = true === $state;
}

Ответ 8

Я думаю, вам не нужно вводить намеки на PHP, потому что вам предоставляются функции проверки типов, такие как is_bool(), is_string() и т.д. и т.д., поэтому вы можете проверить, что вы пытаетесь внести в аргумент против этих функций до фактически делая это аргументом, хотя метод, который они используют для проверки массива и типов объектов, будет намного более чистым.