[Обновлено]: Внес некоторые изменения в код. Спасибо итилион И Одинокий кот Все уже знают, что в PHP 5 в аргументах функций можно указывать их тип, за исключением.
скалярных типов, т. е.
: целочисленного, строкового, логического, плавающего и т. д. Однако на страница руководства По поводу контроля типов в комментариях Дэниел Л.
Вуд предлагает довольно интересное решение этой проблемы с помощью класса-обработчика ошибок.
Единственным существенным недостатком этого решения является его производительность.
Ниже я постараюсь рассказать, как можно оптимизировать это решение и стоит ли его в принципе использовать в продакшен-релизах.
Итак, давайте посмотрим, что не так с приведенным выше решением:
Совершенно ненужные вызовы debug_backtrace. В принципе, анализа сообщения об ошибке достаточно для решения проблемы.Явная проверка аргументов попахивает паранойей.
Действительно, если мы поймали сообщение типа «Аргумент N, переданный в Class::function(), должен быть экземпляром строки, указана строка, .
» — это уже дает нам все основания сделать правильный выбор.
Примечание .
веревка, веревка .
В случае ошибки будет, например, .
целое число, строка.
Этого достаточно, чтобы определить, является ли данное сообщение на самом деле ошибкой или нет. В массиве типов опечатка.
ты сроу ce' => 'is_resource'.
Несколько неоптимальный код в некоторых местах.
Мы попробуем решить все эти проблемы, переписав класс следующим образом:
Давайте теперь проведем несколько тестов и посмотрим, что мы получим.<Эphp class Typehint { private static $_types = array( 'boolean,' => 'boolean', 'bool,' => 'boolean', 'integer,' => 'integer', 'int,' => 'integer', 'float,' => 'float', 'double,' => 'float', 'real,' => 'float', 'string,' => 'string', 'resource,' => 'resource' ); private function __construct() {} public static function init(){ set_error_handler('Typehint::handle'); return true; } public static function handle( $lvl, $msg) { if ($lvl == E_RECOVERABLE_ERROR && strstr($msg, 'must be an instance of') !== false) { $errmsg = explode(' ', $msg, 13); return isset( self::$_types[$errmsg[10]]) && self::$_types[$errmsg[10]] == $errmsg[11]; } return false; } } ?>
Вот что я получил: С Typehint: 0,0787329673767 сек.<Эphp require_once 'Typehint.php'; Typehint::init(); function teststring( string $string) { return $string; } function test( $var) { return $var; } function micro_time() { $timearray = explode(" ", microtime()); return ($timearray[1] + $timearray[0]); } $start = micro_time(); for ($i = 0; $i < 10000; $i++) { teststring( '123'); } $end = micro_time(); echo 'With Typehint: ' .($end-$start) .
' sec.'; echo "<br />\n"; $start = micro_time(); for ($i = 0; $i < 10000; $i++) { test( '123'); } $end = micro_time(); echo 'Without Typehint: ' .
($end-$start) .
' sec.'; ?>
Без Typehint: 0,00326299667358 сек.
Замечу, что для оригинального решения от Дэниела мой результат составил: 0,215523958206 сек.
Те.
мы выиграли почти в 2,7 раза в производительности.
Однако, как мы видим, без использования решения Typehint мы бы выиграли в производительности более чем в 24 раза.
Правильнее было бы сказать, что используя его, мы теряем 24 раза.
Это говорит о целесообразности его использования.
Посмотрите, 10 000 вызовов добавляют ко времени выполнения скрипта почти 0,1 секунды.
Здесь есть о чем подумать.
С другой стороны, использование Typehint повышает самодокументированность кода и позволяет в некоторых случаях, когда это особенно необходимо, контролировать тип передаваемых аргументов.
Однако следует учитывать, что повсеместная строгая типизация в PHP, по сути, не даст вам никаких преимуществ, т.к.
в языке нет механизма перегрузки; при объявленном типе возникнут проблемы со значениями аргументов по умолчанию.
Кроме того, никто не может гарантировать возвращаемые значения в конструкциях языка.
Поэтому вам следует несколько раз подумать, прежде чем использовать это решение или нет. Если вы все еще видите осуществимость и хотите использовать это в своем проекте, я предлагаю вам рассмотреть возможность/необходимость создания какого-то автоматического сборщика, который выпустит окончательный код для использования в производстве, очистив скалярные типы в определениях функций и методы класса.
В принципе, сделать это будет несложно, хотя бы с помощью того же PHP или Shell. Удачи вам в развитии! P.S. Кросс-пост из моего блога: mikhailstadnik.com/php5-types-control Теги: #php #php 5 #управление типами #ввод #решение #php
-
Все О Sony Vaio Vpc-F Серии 13Wfx/B
19 Oct, 24 -
Как Зарабатывать Деньги На Своем Блоге
19 Oct, 24 -
Пока, Майкрософт
19 Oct, 24 -
Маркетинг В Telegram На Узбекском Языке
19 Oct, 24 -
Глубокое Погружение В Систему Рендеринга Wpf
19 Oct, 24