PHP/FI
На ПХП я начинал программировать с третьей версии, предыдущую, вторую, никогда в глаза не видел. Занялся сегодня археологией, что интересно, интерпретатор собрался под «Мак» без каких-либо проблем, а я уже настроился его патчить.
По описанию, вторая версия — удивительно бедный язык, я попытался написать подобие функции var_dump (которой тогда в языке не было), описал в комментариях с чем столкнулся. Надо сказать, некоторые вещи очень сильно удивили.
Вообще, я хотел написать одну функцию, а отступ для вывода скаляра передавать вторым параметром, но оказалось, во-первых, что не указанный параметр при первом вызове сохраняет своё состояние — в каждый следующий вывод он попадает через какую-то магию (причём это работает не всегда), а во-вторых, если не указать второй параметр, то он получит значение первого, а первый станет не заданным (isset вернёт «ноль», булевского типа нет, поэтому «ноль»).
В общем, пришлось сделать две разные функции.
#!php.cgi -q
<?
# однострочные комментарии только такие, два слеша не работают
/* так описываются функции */
function var_dump_scalar $var, $indent (
if ($indent) {
/* вот так выглядит конкатенация строки — плюс, а не точка */
/* интерполяции нет, а одинарные кавычки вернут код символа в них */
$indent = strtr(sprintf("%' '" + $indent + "d", 0), "0", " ");
/* функции str_repeat тоже нет, приходится вот так выкручиваться */
} else {
$indent = "";
}
/* всего три типа данных, нет булевого типа, нет ресурсов — fopen вернёт число */
/* объектов тоже нет, конечно же */
switch (gettype($var)) {
case "integer"; /* после case точка с запятой, а не двоеточие */
echo "%sint(%d)\n" $indent, $var;
break;
case "string";
echo "%sstring(%d) \"%s\"\n" $indent, strlen($var), $var;
break;
case "double";
echo "%sfloat(%f)\n" $indent, $var;
break;
}
/* можно было бы вернуть всё через return, но мне не удалось бы продемонстрировать несколько вещей */
);
function var_dump $var (
/* смотрим — передан ли параметр */
if (isset($var)) {
/* пытаемся определить — не массив ли это, отдельного типа нет */
$cnt = count($var);
if ($cnt > 1 || key($var) != "0") {
reset($var);
/* echo умеет принимать форматирующую строку */
echo "array(%d) {\n" $cnt;
/* других способов проверять конец массива нет — только итерировать по длине */
/* цикла for в языке тоже нет */
while ($cnt > 0) {
$key = key($var);
echo " [\"%s\"]=>\n" $key;
next($var);
/* тут только скаляры, так как массивов, кроме одномерных не бывает */
var_dump_scalar($var[$key], 2);
$cnt--;
}
echo "}\n";
} else {
var_dump_scalar($var, 0);
}
} else {
echo "Warning: var_dump() expects exactly 1 parameter, 0 given\n";
}
);
/* ассоциативный массив */
$b["aaa"] = "aaa";
/* числовой массив, отдельного типа массива нет, любой тип является нулевым элементом массива */
/* конструкции array(...) тоже нет, массивы задаются только так — в строку */
$a = 1;
$a[1] = 2;
/* двухмерных массивов у нас нет, это просто операция слияния массивов */
$a[] = $b;
var_dump($a);
/* Результат работы:
array(3) {
["0"]=>
int(1)
["1"]=>
int(2)
["2"]=>
string(3) "aaa"
}
*/
/* вот так заканчиваются PHP-скрипты, знака вопроса у закрывающего тега нет */
>
Но самый сок, конечно, это две функции — ClearStack и SecureVar. Их я не использовал, просто не придумал как. Первая является костылём к парсеру (почитайте описание, у меня нет сил это описывать), вторая — фильтрует переменные из ГЕТ- (но почему-то не из ПОСТ-) запроса через маску. Секюрити!
Комментарий для pavelpat:
Речь о PHP/FI