Câu hỏi Loại bỏ / lập bản đồ không gian tên PHP và các mã định danh viết lại


Tôi đang cố gắng để tự động hoá việc loại bỏ các không gian tên từ một bộ sưu tập lớp PHP để làm cho chúng tương thích với PHP 5.2. (Chia sẻ lưu trữ các nhà cung cấp không ưa thích rogue PHP 5.3 cài đặt. Không có ý tưởng tại sao. Ngoài ra mã trong câu hỏi không sử dụng bất kỳ bổ sung tính năng 5.3, chỉ là cú pháp. Autoconversion có vẻ dễ dàng hơn làm bằng tay hoặc reimplementing codebase.)

Để viết lại các kịch bản * .php, về cơ bản tôi đang chạy trên một người sửa lỗi danh sách. Số nhận dạng tìm kiếm + hợp nhất đã hoàn tất. Nhưng bây giờ tôi hơi bối rối làm thế nào để hoàn thành việc viết lại thực tế.

function rewrite($name, $namespace, $use) {

    global $identifiers2;            // list of known/existing classes

    /*
        bounty on missing code here
    */

    return strtr($name, "\\", "_");  // goal: backslash to underscore
}

Hàm đó sẽ được gọi trên mỗi số nhận dạng được tìm thấy (cho dù là lớp, hàm hay const). Nó sẽ nhận được một số thông tin ngữ cảnh để chuyển đổi một định danh địa phương thành một tên $ tuyệt đối / toàn cục:

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

Ở giai đoạn này tôi đã chuẩn bị một $identifiers2 danh sách. Nó chứa một danh sách tất cả các lớp, hàm và tên không đổi đã biết (được hợp nhất để đơn giản ở đây).

$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)

Các $name tham số khi nhận được bởi rewrite() chức năng có thể là một địa phương, không đủ điều kiện, \ tuyệt đối hoặc là tên \ khoảng cách số nhận dạng (nhưng chỉ là số nhận dạng, không có biểu thức). Các $identifiers2 danh sách là rất quan trọng để giải quyết không đủ điều kiện số nhận dạng, có thể tham chiếu đến mọi thứ trong không gian tên hiện tại hoặc nếu không tìm thấy ở đó, nội dung toàn cục.

Và nhiều use namespace bí danh phải được đưa vào tài khoản và thêm một số biến chứng bên cạnh các quy tắc phân giải không gian tên và ưu tiên.

Vì vậy, làm thế nào / trong đó thứ tự bạn sẽ cố gắng để chuyển đổi các biến thể của tên lớp / chức năng ở đây?

Tinh thần Laziness Bounty.

Để thực hiện điều này một câu hỏi plzsendtehcodez ít trắng trợn: một danh sách hướng dẫn giải thích hoặc câu trả lời giả mã sẽ đủ điều kiện. Và nếu cách tiếp cận khác phù hợp hơn với công việc, hãy giải thích điều đó. (Nhưng không, nâng cấp PHP hoặc thay đổi hoster không phải là một tùy chọn.)

Tôi nghĩ rằng tôi đã tìm ra nó trong khi đó, nhưng câu hỏi vẫn còn mở cho câu trả lời / đề xuất thực hiện. (Nếu không, tiền thưởng rõ ràng sẽ đi đến nikic.)


31
2018-05-23 23:49


gốc


Bộ chuyển đổi này có thể cực kỳ hữu ích cho nhiều người (kể cả tôi). Tôi rất thích xem kết quả! - jwueller
Oh, và điều này chứa một số thông tin về cách phân giải không gian tên. - jwueller
Tôi chắc chắn chuyển đổi này sẽ là lý do của rất nhiều lỗi. Và tôi nghĩ tốt hơn là thay đổi lưu trữ, hơn là thực hiện các hoạt động mạo hiểm với mã. Có lẽ nó là để phân phối một số thư viện, nhưng ngay cả trong trường hợp này, nó sẽ tốt hơn nếu thư viện này sẽ trở thành một lý do để cài đặt PHP 5.3. - OZ_
@ OZ_: Không có xung đột nếu mọi thứ được đặt tiền tố một cách nhất quán (đó là những gì công cụ này nên làm), vì vậy có thể có một vài trường hợp đặc biệt như chức năng / cuộc gọi phương thức động, nhưng có thể tránh được. Bạn không phải lúc nào cũng có lựa chọn để chọn chủ nhà. Một số khách hàng có thể muốn sử dụng nó trên máy tính của họ, vv Thật tuyệt vời khi có một công cụ như vậy cho những trường hợp đó. - jwueller
Bắt nó chạy trên php 5.2 là chủ đề câu hỏi và ràng buộc. - mario


Các câu trả lời:


Trong một câu hỏi hiện có về việc di chuyển các không gian tên thành mã không gian tên giả Tôi sẵn sàng giới thiệu công cụ chuyển đổi Tôi đã viết như là một phần của một dự án lớn hơn. Tôi đã không duy trì dự án này nữa kể từ thời điểm đó, nhưng theo như tôi nhớ các thay thế không gian tên đã làm việc. (Tôi có thể triển khai lại dự án này bằng cách sử dụng trình phân tích cú pháp thích hợp tại một số điểm. Làm việc với các thẻ thông thường đã được chứng minh là một công việc khá tẻ nhạt.)

Bạn sẽ thấy việc triển khai không gian tên của tôi -> độ phân giải không gian tên giả trong namespace.php. Tôi dựa trên việc triển khai trên quy tắc phân giải không gian tên, có lẽ cũng sẽ giúp ích cho bạn.

Để làm cho câu trả lời readmycodez ít trắng trợn hơn, ở đây các bước cơ bản mà mã này thực hiện:

  1. Nhận định danh để được giải quyết và đảm bảo rằng nó không phải là một lớp, giao diện, chức năng hoặc khai báo liên tục (chúng được giải quyết trong registerClass và registerOther đơn giản bằng cách thêm vào không gian tên hiện tại với các dấu tách ns được thay thế bằng dấu gạch dưới).
  2. Xác định loại định danh đó là: Lớp, hàm hoặc hằng số. (Vì chúng cần độ phân giải khác nhau.)
  3. Đảm bảo chúng tôi không giải quyết self và parent các lớp học, cũng không phải true, false và null hằng số.
  4. Giải quyết bí danh (use danh sách):
    1. Nếu số nhận dạng đủ điều kiện, hãy lấy phần trước dấu tách vùng tên đầu tiên và kiểm tra xem có tồn tại bí danh với tên đó hay không. Nếu có, thay thế phần đầu tiên bằng không gian tên bí danh (bây giờ mã định danh sẽ hoàn toàn đủ điều kiện). Nếu không, hãy thêm vào không gian tên hiện tại.
    2. Nếu số nhận dạng không đủ điều kiện và loại số nhận dạng là class, kiểm tra xem số nhận dạng có phải là bí danh hay không và nếu có, hãy thay thế bằng bí danh.
  5. Nếu số nhận dạng đủ điều kiện hiện nay, hãy bỏ dấu phân tách không gian tên hàng đầu và thay thế tất cả các dấu phân tách không gian tên khác bằng dấu gạch dưới và kết thúc thuật toán này.
  6. Nếu không thì:
    1. Nếu chúng ta đang ở trong không gian tên chung thì không cần độ phân giải cao hơn, do đó kết thúc thuật toán này.
    2. Nếu loại số nhận dạng là class thêm vào không gian tên hiện tại, thay thế tất cả các dấu phân cách NS bằng dấu gạch dưới và kết thúc thuật toán này.
    3. Nếu không thì:
      1. Nếu hàm / hằng số được xác định trên toàn cầu, hãy để định danh như là và kết thúc thuật toán này. (Điều này giả định rằng không có chức năng toàn cầu nào được định nghĩa lại trong một không gian tên! Trong mã của tôi, tôi không đưa ra giả định này, do đó tôi chèn mã độ phân giải động.)
      2. Nếu không, hãy thêm vào không gian tên hiện tại và thay thế tất cả các dấu phân tách không gian tên bằng dấu gạch dưới. (Có vẻ như tôi có lỗi trong mã của tôi ở đây: Tôi không làm điều này ngay cả khi assumeGlobal cờ được đặt. Thay vào đó, tôi luôn chèn mã công văn động.)

Lưu ý bổ sung: Đừng quên rằng người ta cũng có thể viết namespace\some\ns. Tôi giải quyết các cấu trúc này trong các NS chức năng (cũng chịu trách nhiệm tìm kiếm các khai báo không gian tên).


18
2018-05-27 13:20



Khá thú vị. Có vẻ như đây gần như là một nhiệm vụ được giải quyết rồi. Kể từ khi thực hiện của bạn là sạch hơn đáng kể, tôi sẽ sử dụng nếu tôi không thể làm cho tôi để làm việc. Và bạn đã giải quyết vấn đề chức năng lambda giữa những người khác. (Làm việc trên một danh sách mã thông báo thực sự chỉ làm phức tạp vấn đề, nhưng ít nhất là nó hoàn toàn khả thi với một số nhượng bộ.) - Tính toàn cầu / lớp mơ hồ có thể là một vấn đề, đó cũng là lý do tại sao tôi đã thử $ identifiers2 list workaround. - mario
@mario: Tôi đã thêm mô tả về chức năng giải quyết trong trường hợp bạn muốn triển khai phiên bản của riêng mình (và đó có thể không phải là không hợp lý, vì mã của tôi có ý nghĩa hơn để được sử dụng để chuyển đổi chung 5.3 -> 5.2 và không chuyển trong các trường hợp sau, bạn có thể kết hợp kiến ​​thức của riêng bạn về dự án để làm cho việc chuyển đổi trở nên tốt đẹp hơn). - NikiC
Giải quyết không gian tên \ tiền tố với một bí danh tiềm ẩn $use["namespace"] = $namespace;, và một số gotchas khác bạn đã đề cập (cha mẹ, tự) do tai nạn. Trong khi tôi đã tách lớp, func, khai báo const, tôi không thực sự phân biệt chúng theo ngữ cảnh trong luồng mã thông báo (để đơn giản). Nhưng tôi nghĩ rằng nó không tạo ra sự khác biệt đủ nếu tôi biết các mã nhận diện được khai báo. - Tôi không chắc chắn về điểm đầu tiên của bạn: không bạn viết lại các tuyên bố tên cuối cùng quá? (Tôi sẽ đọc kỹ mã người nghe kỹ hơn ..) - mario
@mario: Tôi rephrased điểm đầu tiên của tôi. Các khai báo được viết lại riêng biệt, không phải trong hàm này, đơn giản bằng cách thêm vào vùng tên hiện tại (và thay thế dấu gạch dưới). Đó là những gì tôi có ý nghĩa với điểm này;) - NikiC