Назад в будущее или как переносился проект на PHP 4
Казалось бы все давно перешли с уже почившего в прошлом PHP 4 на PHP 5, ан нет, не все.
Недавно пришлось переделывать проект написанный изначально под PHP 5.2+ чтобы он был совместим с web серверами где всё ещё стоит PHP 4. По ходу переделок нашел много приятностей PHP 5.2+, о которых думал как о должном, забыл что в "древние времена" было иначе:
1. Непосредственное использование объекта, полученного в результате вызова функции:
$template = $settings->getByName('default_template')->value;
2. Использование ссылки на элемент массива при переборе массива с помощью комманды foreach:
foreach($items as &$item) { ... обработка ...}
При использовании амперсанда перед переменной $item внутри блока обработки переменная $item является ссылкой на переменную хранящуюся в массиве, таким образом не создается лишних копий массива и можно менять данные в массиве явно оперируя его элементами, а не обращаясь к ним по индексу.
3. Нет функций str_ireplace(), htmlspecialchars_decode(). С первой я расстался легко, т. к. регистронезависимость была не особо критична, а вот для htmlspecialchars_decode пришлось найти подмену:
function htmlspecialchars_decode($string,$style=ENT_COMPAT) { if($style === ENT_QUOTES){ $translation['''] = '\''; } } }
4. В замечательной функции pathinfo в PHP 4 ещё не было константы PATHINFO_FILENAME, то есть получить имя файла без расширения с её помощью было нельзя. Заменить недостающий режим работы пришлось отдельной функцией:
function get_file_name($path) { if (!$ext) return $base; if (false === $pos) return $base; }
Это всё конечно мелочи, но все постепенные усовершенствования языка можно считать мелочью, к которой, тем не менее, быстро привыкаешь, если пользуешься.
5. Самым неприятным было отсутствие функции json_encode(). Эта проблема решается либо установкой PECL php_json, либо программными средствами. Вариант с установкой расширения не подходил, т.к. было несколько серверов куда нужно было установить разрабатываемую систему и для каждого перенастраивать PHP выходило неудобно. Основа была взята из примера с сайта http://kurapov.name/article/857/?&page=1 и немного исправлена:
// json_encode function recovering function json_encode($arr) { $is_list = false; //Find out if the given array is a numerical array if(($keys[0] == 0) and ($keys[$max_length] == $max_length)) {//See if the first key is 0 and last key is length - 1 $is_list = true; for($i=0; $i<count($keys); $i++) { //See if each key correspondes to its position if($i !== $keys[$i]) { //A key fails at position check. $is_list = false; //It is an associative array. break; } } } foreach($arr as $key=>$value) { if($is_list) $parts[] = json_encode($value); /* :RECURSION: */ else $parts[] = '"' . $key . '":' . json_encode($value); /* :RECURSION: */ } else { $str = ''; if(!$is_list) $str = '"' . $key . '":'; //Custom handling for multiple data types elseif($value === false) $str .= 'false'; //The booleans elseif($value === true) $str .= 'true'; // :TODO: Is there any more datatype we should be in the lookout for? (Object?) $parts[] = $str; } } if($is_list) return '[' . $json . ']';//Return numerical JSON return '{' . $json . '}';//Return associative JSON } }
В оригинальной функции были проблемы с многострочным текстом, для исправления была добавлена строка:
$str = str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $str);
PS: если наблюдаются проблемы с кириллицей - можно предварительно обрабатывать передаваемый в json_encode объект следующей функцией:
function json_fix_cyr($var) { foreach ($var as $k => $v) { $new[json_fix_cyr($k)] = json_fix_cyr($v); } $var = $new; foreach ($vars as $m => $v) { $var->$m = json_fix_cyr($v); } } return $var; }
Комментарии
Отправить комментарий