Идентификация / сопоставление и переписывание имен пространства имен PHP

Я пытаюсь автоматизировать удаление пространств имен из коллекции классов PHP, чтобы сделать их совместимыми с PHP 5.2. (Shared хостинг-провайдерам не нравятся мошеннические установки PHP 5.3.Не думайте, почему. Также этот код не использует никаких добавлений к функциям 5.3, просто этот синтаксис. Autoconversion кажется проще, чем делать это вручную или переопределять кодовую базу.)

Для переписывания скриптов * .php я в основном запускаю список токенов . Идентификатор поиска + слияние уже завершен. Но я немного запутался, как выполнить фактическое переписывание.

function rewrite($name, $namespace, $use) { global $identifiers2; // list of known/existing classes /* bounty on missing code here */ return strtr($name, "\\", "_"); // goal: backslash to underscore } 

Эта функция будет вызываться для каждого найденного идентификатора (будь то класс, функция или константа). Он получит некоторую контекстную информацию для преобразования локального идентификатора в абсолютное / глобальное $ name:

 $name = rewrite( "classfuncconst", # <-- foreach ($names as $name) "current\name\space", array( 'namespc' => 'use\this\namespc', 'alias' => 'from\name\too', ... ) ); 

На этом этапе я уже подготовил список $identifiers2 . Он содержит список всех известных классов, функций и имен констант (для удобства здесь объединены).

 $identifiers2 = array( // Alternative suggestions welcome. "name\space\Class" => "Class", // - list structure usable for task? "other\ns\func1" => "func1", // - local name aliases helpful? "blip\CONST" => "CONST", // - (ignore case-insensitivity) 

Параметр $name полученный функцией rewrite() может быть локальным , неквалифицированным , абсолютным или именным rewrite() идентификаторами, без выражений). Список $identifiers2 имеет решающее значение для разрешения неквалифицированных идентификаторов, которые могут ссылаться на вещи в текущем пространстве имен или если они не найдены там, глобальные вещи.

    И различные псевдонимы use namespace должны быть приняты во внимание и добавить некоторые сложности, кроме правил разрешения имен и правил приоритета.

    Итак, как / в каком порядке вы попытаетесь преобразовать вариации имен классов / функций здесь?

    Умственная щедрость.

    Чтобы сделать это менее вопиющим вопросом plzsendtehcodez: список объясняющих инструкций или ответ на псевдокод тоже будут иметь право. И если другой подход будет более подходящим для этой задачи, пожалуйста, уточните это. (Но нет, обновление PHP или изменение хостера не является вариантом.)

    Я думаю, что я понял это тем временем, но вопрос по-прежнему открыт для ответов / предложений по внедрению. (В противном случае щедрость, очевидно, пойдет на никич.)

    Related of "Идентификация / сопоставление и переписывание имен пространства имен PHP"

    В существующем вопросе о переносе пространств имен на псевдо-именный код я уже представил инструмент преобразования, который я написал как часть более крупного проекта. С тех пор я не поддерживал этот проект, но, насколько я помню, замена пространства имен действительно сработала. (Я могу переопределить этот проект, используя подходящий парсер в какой-то момент. Работа с простыми токенами оказалась довольно утомительной задачей.)

    Вы найдете мою реализацию пространства имен -> разрешение псевдопространства в namespace.php . Я основывал реализацию на правилах разрешения пространства имен , которые, вероятно, также помогут вам.

    Чтобы сделать это менее вопиющим ответом readmycodez, вот основные шаги, которые выполняет код:

    1. Получите идентификатор, который будет разрешен, и убедитесь, что он не является объявлением класса, интерфейса, функции или константы (они разрешены в registerClass и registerOther , просто добавляя текущее пространство имен с заменой ns-разделителями на символы подчеркивания).
    2. Определите тип идентификатора: класс, функция или константа. (Поскольку они нуждаются в разной разрешающей способности.)
    3. Убедитесь, что мы не разрешаем классы self и parent , а также true , false и null константы.
    4. Разрешить псевдонимы (список use ):
      1. Если идентификатор является квалифицированным, получите часть перед первым разделителем пространства имен и проверьте, существует ли псевдоним с этим именем. Если это так, замените первую часть на псевдонимы (теперь идентификатор будет полностью квалифицирован). В противном случае добавьте текущее пространство имен.
      2. Если идентификатор неквалифицирован и тип идентификатора является class , проверьте, является ли идентификатор псевдонимом, а если он есть, замените его на класс с псевдонимом.
    5. Если идентификатор полностью квалифицирован, отбросьте ведущий разделитель пространства имен и замените все остальные разделители пространства имен на символы подчеркивания и завершите этот алгоритм.
    6. В противном случае:
      1. Если мы находимся в глобальном пространстве имен, дальнейшее разрешение не требуется, таким образом, заканчивается этот алгоритм.
      2. Если тип идентификатора является class preend текущего пространства имен, замените все разделители NS на символы подчеркивания и завершите этот алгоритм.
      3. В противном случае:
        1. Если функция / константа определена глобально, оставите идентификатор как есть и закончите этот алгоритм. (Это предполагает, что глобальные функции не переопределены в пространстве имен! В моем коде я не делаю этого предположения, поэтому я вставляю динамический код разрешения.)
        2. В противном случае добавьте текущее пространство имен и замените все разделители пространств имен символами подчеркивания. (Похоже, что я получил ошибку в моем коде здесь: я не делаю этого, даже если флаг assumeGlobal установлен. Вместо этого я всегда вставляю динамический код отправки.)

    Примечание. Не забывайте, что можно также написать namespace\some\ns . Я разрешаю эти конструкции в функции NS (которая также отвечает за поиск деклараций пространства имен).