PHP namespace removal / mapping and rewriting identifiers

前端 未结 1 678
眼角桃花
眼角桃花 2020-12-24 12:19

I\'m attempting to automate the removal of namespaces from a PHP class collection to make them PHP 5.2 compatible. (Shared hosting providers do not fancy rogue PHP 5.3 insta

相关标签:
1条回答
  • 2020-12-24 12:23

    In an existing question on migration of namespaces to pseudo namespaced code I already introduced a conversion tool I have written as part of a larger project. I haven't maintained this project anymore since that point, but as far as I remember the namespace replacements did work. (I may reimplement this project using a proper parser at some point. Working with plain tokens has proven to be quite a tedious task.)

    You will find my implementation of namespace -> pseudo-namespace resolution in the namespace.php. I based the implementation on the namespace resolution rules, which will probably be of help for you, too.

    To make this a less blatant readmycodez answer, here the basic steps the code does:

    1. Get the identifier to be resolved and ensure that it is not a class, interface, function or constant declaration (these are resolved in registerClass and registerOther by simply prepending the current namespace with ns separators replaced by underscores).
    2. Determine what type of identifier it is: A class, a function or a constant. (As these need different resolution.)
    3. Make sure we do not resolve the self and parent classes, nor the true, false and null constants.
    4. Resolve aliases (use list):
      1. If the identifier is qualified get the part before the first namespace separator and check whether there exists an alias with that name. If it does, replace the first part with the aliased namespace (now the identifier will be fully qualified). Otherwise prepend the current namespace.
      2. If identifier is unqualified and the identifier type is class, check whether the identifier is an alias and if it is, replace it with the aliased class.
    5. If the identifier is fully qualified now drop the leading namespace separator and replace all other namespace separators with underscores and end this algorithm.
    6. Otherwise:
      1. If we are in the global namespace no further resolution required, thus end this algorithm.
      2. If the identifier type is class prepend the current namespace, replace all NS separators with underscores and end this algorithm.
      3. Otherwise:
        1. If the function / constant is defined globally leave the identifier as is and end this algorithm. (This assumes that no global functions are redefined in a namespace! In my code I don't make this assumption, thus I insert dynamic resolution code.)
        2. Otherwise prepend the current namespace and replace all namespace separators with underscores. (Seems like I got a fault in my code here: I don't do this even if the assumeGlobal flag is set. Instead I always insert the dynamic dispatch code.)

    Additional note: Don't forget that one can also write namespace\some\ns. I resolve these constructs in the NS function (which is also responsible for finding namespace declarations).

    0 讨论(0)
提交回复
热议问题