[PHP] Типобезопасность констант
От: MaxSem  
Дата: 19.10.09 08:02
Оценка:
Дано: функция с переменным числом аргументов, при этом некоторые аргументы могут быть строками, а некоторые — константами, требующими особой обработки.

function foo() {
    $params = func_get_args();

    foreach( $params as $value) {
        if( $value === CONST_1 ) {
            ...
        } elseif( $value === CONST_2 ) {
            ...
        } else {
            ...
        }
    }
}


Проблема в том, что из-за утиной типизации PHP вместо строкового аргумента может быть передано что угодно, так что определения констант вроде define( 'CONST_1', 42 ) могут привести к непредсказуемым последствиям. define( 'CONST_1', 43490543235232.923724023553 ) более надёжно, но выглядит жутким хаком. Что-то вроде define( 'CONST_1', new stdClass() ) могло бы помочь, если бы язык такое позволял.

Можно тут ещё что-то придумать, или придётся прибегать к гораздо более корявым вещам вроде MyClass::const_1()?
Re: [PHP] Типобезопасность констант
От: piksel Россия  
Дата: 20.10.09 03:41
Оценка: +1
Здравствуйте, MaxSem, Вы писали:

MS>Дано: функция с переменным числом аргументов, при этом некоторые аргументы могут быть строками, а некоторые — константами, требующими особой обработки.


MS>
MS>function foo() {
MS>    $params = func_get_args();

MS>    foreach( $params as $value) {
MS>        if( $value === CONST_1 ) {
MS>            ...
MS>        } elseif( $value === CONST_2 ) {
MS>            ...
MS>        } else {
MS>            ...
MS>        }
MS>    }
MS>}
MS>


MS>Проблема в том, что из-за утиной типизации PHP вместо строкового аргумента может быть передано что угодно, так что определения констант вроде define( 'CONST_1', 42 ) могут привести к непредсказуемым последствиям. define( 'CONST_1', 43490543235232.923724023553 ) более надёжно, но выглядит жутким хаком. Что-то вроде define( 'CONST_1', new stdClass() ) могло бы помочь, если бы язык такое позволял.


MS>Можно тут ещё что-то придумать, или придётся прибегать к гораздо более корявым вещам вроде MyClass::const_1()?


Вот когда указано ===, то проверяется именно соответствие значения и типа, поэтому

define('CONST', 42); // int
define('CONST', 3.1415628); // double
define('CONST', '42'); // char*


и никак иначе.

"Утиная" типизация существует в также в Perl, Python и массе других языков, по-моему она называется динамической .
Re[2]: [PHP] Типобезопасность констант
От: MaxSem  
Дата: 25.10.09 11:23
Оценка:
Здравствуйте, piksel, Вы писали:

P>Вот когда указано ===, то проверяется именно соответствие значения и типа, поэтому


P>
P>define('CONST', 42); // int
P>define('CONST', 3.1415628); // double
P>define('CONST', '42'); // char*
P>


P>и никак иначе.


Проблема тут как раз в том, что из-за отстутствия чёткой типизации невозможно быть уверенным в том, что аргумент подали не строковой, а интовый. Да, не должны вроде — но и не такое может выйти если данные достаточно много крутить вертеть. А если тип совпал, то совпадение значения — уже вопрос времени. В общем, я решил сделать вот так.

P>"Утиная" типизация существует в также в Perl, Python и массе других языков, по-моему она называется динамической .


Не совсем, утиная — отдельная вещь, хотя я действительно не к месту применил этот термин
Re[3]: [PHP] Типобезопасность констант
От: piksel Россия  
Дата: 11.11.09 12:18
Оценка:
Здравствуйте, MaxSem, Вы писали:

MS>Проблема тут как раз в том, что из-за отстутствия чёткой типизации невозможно быть уверенным в том, что аргумент подали не строковой, а интовый. Да, не должны вроде — но и не такое может выйти если данные достаточно много крутить вертеть. А если тип совпал, то совпадение значения — уже вопрос времени. В общем, я решил сделать вот так.


Не стал разбираться, как-то всё там непонятно, что и где Но вот специально проверил:

define("BOOL", true);
define("INT", 22);
define("DOUBLE", 3.1415926);
define("STRING", "some chars");

$vars = array(false, 33, 0.98, "string");
$consts = array(BOOL, INT, DOUBLE, STRING);

$var = $vars[ mt_rand(0, 3) ];
echo "Variable $var is have type of ".gettype($var)."<br>\n";
foreach ($consts as $value) {
    $var = $value;
    echo "New type of \$var is a type of CONST: ".gettype($var)."<br>\n";
}

Т.е. тип констант всё-же зависит от того как она определена и является строго определенным. Поправьте меня...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.