Или, скорее, «Исправить строки без кавычек, используемые в качестве ключей массива PHP», но это было немного длинно для заголовка.
Я унаследовал довольно большую кодовую базу, где массивы пишутся так:
$array[id] = 0;
$array[value] = "test"
Хотя этот код на самом деле работает, он бросает много Use of undefined constant
обратите внимание, поэтому эти строки действительно должны стать:
$array['id'] = 0;
$array['value'] = "test"
Речь идет о сотнях тысяч строк кодов, разбросанных по паре тысяч файлов.
Есть также такие случаи:
$_SESSION[user_information][access_bit][ACCESS_NULL] = 1;
куда user_information
а также access_bit
предназначены для строк и ACCESS_NULL
является определенной константой. Хорошо, что константы определены только в верхнем регистре.
И чтобы сделать вещи более интересными, у нас также есть javascript в тех же файлах php, где код array[id] = 0;
отлично в порядке.
Я хочу эффективно убрать этот беспорядок и обернуть все эти неопределенные константы в одинарные кавычки, но я не уверен, что простой поиск / замена (даже с регулярным выражением) сделает это. Какие-нибудь мысли?
Это оказалось проще, чем я думал.
function fix_unquoted_array_keys($filename){
if(!is_file($filename)){
return "File not found!";
}
$content = file_get_contents($filename);
$content = preg_replace('/^!|\$([a-zA-Z_]+)\[([a-z_]+)\]/','\$$1[\'$2\']',$content);
$content = preg_replace('/\]\[([a-z_]+)\]/','][\'$1\']',$content);
file_put_contents($filename,$content);
// Check the file just in case we break something.
@exec("php -l ".$filename." 2>&1",$syntax);
if($syntax[0] && strpos($syntax[0],"No syntax errors") === false){
return $syntax[0];
}
return "OK";
}
Первый preg_replace
заменяет все простые массивы, такие как $user[id]
в $user['id']
, Это оставляет многомерные массивы, такие как $user[data][id]
в $user['data'][id]
, Я намеренно не сопоставляю ключи в верхнем регистре, потому что они, скорее всего, определены константы.
Второй preg_replace
работает со всеми последующими ключами, просто сопоставляя закрывающую скобку предыдущего ключа.
Возможно, это не самое элегантное решение, но кажется, что оно сделало свою работу. Сейчас я проверяю различия за последний час, и я не могу найти ни одного места, где это не удалось.
Постскриптум PHP токенизатор не справляется с этой задачей, потому что она также, кажется, преобразует неопределенную константу как строки, и они маркируются как T_STRING
,
Других решений пока нет …