Làm cách nào để chuyển đổi mã php5 sang php7?

Trong thế giới JavaScript, việc chuyển đổi mã hiện đại sang cú pháp cũ hơn là khá phổ biến. Trong thế giới PHP, bạn không thấy điều đó xảy ra thường xuyên. Symfony cung cấp một số polyfill, nhưng không có chuyển đổi chính thức đầy đủ. Tại buổi họp mặt của nhóm người dùng PHP tại địa phương của chúng tôi, Jens Segers, Hannes Van de Vreken và tôi đã đùa giỡn với ý tưởng chuyển đổi mã PHP 7 thành mã PHP 5 tương đương một cách tự động

Hôm nay, dự án sở thích nhỏ của chúng tôi có tên là 7to5 đã được gắn thẻ 1. 0. 0. Bạn có thể xem repo trên GitHub

Nó làm gì?

Công cụ này sẽ chuyển đổi PHP 7 sang PHP 5 bằng cách
  • xóa gợi ý loại vô hướng
  • xóa gợi ý loại trả lại
  • xóa khai báo kiểu nghiêm ngặt
  • thay thế toán tử tàu vũ trụ bằng mã PHP 5 tương đương
  • thay thế các câu lệnh hợp nhất null bằng mã PHP 5 tương đương
  • thay thế khai báo sử dụng nhóm bằng mã PHP 5 tương đương
  • thay thế các mảng đã xác định bằng mã PHP 5 tương đương
  • chuyển đổi các lớp ẩn danh thành các lớp thông thường

Bởi vì có rất nhiều thứ nhỏ không thể được phát hiện và/hoặc chuyển đổi đúng cách nên không đảm bảo rằng mã được chuyển đổi sẽ hoạt động. Bạn nên chạy thử nghiệm tự động đối với mã đã chuyển đổi để xác định xem nó có hoạt động không

Sử dụng công cụ

7to5 có thể được cài đặt trên toàn cầu bằng cách chạy.
composer install global spatie/7to5

Khi đã xong, bạn có thể sử dụng

php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}
1 để chuyển đổi toàn bộ thư mục trong một lần

php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}

Đằng sau màn cửa

Loại bỏ một số tính năng của PHP 7 như gợi ý kiểu vô hướng và gợi ý kiểu trả về có vẻ khá dễ dàng. Thay thế các lớp ẩn danh, toán tử tàu vũ trụ và toán tử hợp nhất null khó hơn một chút

Hình ảnh làm thế nào bạn sẽ chuyển đổi này

class Test
{
    public function test()
    {
        $class = new class() {
            public function method(string $parameter = '') : string {
                return $parameter ?? 'no parameter set';
            }
        };
        
        $class->method();

        $anotherClass = new class() {
            public function anotherMethod(int $integer) : int {
                return $integer > 3;
            }
        };
    }
            
}

để này

class AnonymousClass0
{
    public function method($parameter = '')
    {
        return isset($parameter) ? $parameter : 'no parameter set';
    }
}

class AnonymousClass1
{
    public function anotherMethod($integer)
    {
        return $integer < 3 ? -1 : ($integer == 3 ? 0 : 1);
    }
}

class Test
{
    public function test()
    {
        $class = new AnonymousClass0();
        $class->method();
        $anotherClass = new AnonymousClass1();
    }
}

Sau cuộc gặp mặt của nhóm người dùng của chúng tôi, ý tưởng đã nằm im trong một thời gian, nhưng tại PHPUKConference năm nay, Hannes đã quyết định thực hiện nó ™. Tôi ngay lập tức bị kéo vào. Chúng tôi đã chạy qua một vài lựa chọn. Rõ ràng là việc sử dụng regex không còn là vấn đề nữa. Sử dụng một máy trạng thái cũng sẽ trở nên rất khó sử dụng. Chúng tôi quyết định sử dụng công cụ phân tích cú pháp PHP được tạo bởi Nikita Popov. Công cụ này có thể chuyển đổi mã PHP thành một cây cú pháp trừu tượng. Nó rất giống với một domtree cho mã html. Đây là một ví dụ (lấy từ tài liệu trình phân tích cú pháp php). mã này

echo 'Hi', 'World';
hello\world('foo', 'bar' . 'baz');

sẽ được chuyển đổi thành cây này

[
    0: Stmt_Echo(
        exprs: [
            0: Scalar_String(
                value: Hi
            )
            1: Scalar_String(
                value: World
            )
        ]
    )
    1: Expr_FuncCall(
        name: Name(
            parts: [
                0: hello
                1: world
            ]
        )
        args: [
            0: Arg(
                value: Scalar_String(
                    value: foo
                )
                byRef: false
            )
            1: Arg(
                value: Expr_Concat(
                    left: Scalar_String(
                        value: bar
                    )
                    right: Scalar_String(
                        value: baz
                    )
                )
                byRef: false
            )
        ]
    )
]

Đây là mã để tạo cây cú pháp trừu tượng

//create a parser
$parser = (new PhpParser\ParserFactory())->create(PhpParser\ParserFactory::PREFER_PHP7);

//feed it PHP 7 code
$php7code = file_get_contents($pathToPhp7File);

//this variable now contains the entire syntax tree
$syntaxTree = $parser->parse($php7code);

Bây giờ chúng ta đã tạo cây cú pháp trừu tượng, hãy thao tác với nó. Cây có thể được đi ngang qua một

php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}
2. Thao tác có thể được thực hiện bởi một hoặc nhiều đối tượng
php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}
3. Hãy xem một số mã đi qua cây và chuyển đổi nó trở lại mã PHP thông thường

$traverser = new PhpParser\NodeTraverser();

$traverser->addVisitor(new NullCoalesceReplacer());

$manipulatedTree = $traverser->traverse($syntaxTree);

//convert the tree back to regular code
$code = (new \PhpParser\PrettyPrinter\Standard())->prettyPrintFile($manipulatedTree);

file_put_contents($pathToFileWithManipulatedPhpCode, $code);

Điều kỳ diệu thực sự xảy ra trong lớp

php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}
4. Nó sẽ chuyển đổi tất cả các tập quán của toán tử hợp nhất null, vốn chỉ dành riêng cho PHP 7, thành mã PHP 5 tương đương. Lớp này không phải là một phần của gói Nikita. Hannes và tôi đã tạo ra nó cùng với tất cả những du khách khác

Trước khi xem mã của lớp đó, trước tiên chúng ta sẽ kiểm tra cách chúng ta sẽ thay thế thủ công một toán tử hợp nhất null

//PHP 7 code
$result = $input ?? 'fixed-value';

//equivalent PHP 5 code
$result = isset($input) ? $input : 'fixed-value';

Hãy mô tả chuyển đổi cần thiết bằng tiếng Anh đơn giản. Chúng ta sẽ cần tạo một câu lệnh ternary. Phía bên trái của '??' . Nhánh đúng của câu lệnh bậc ba cần sử dụng vế trái của toán tử '??', nhánh sai cần vế phải

Đây là mã của khách truy cập

php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}
4

namespace Spatie\Php7to5\NodeVisitors;

use PhpParser\Node;
use PhpParser\Node\Expr\BinaryOp\Coalesce;
use PhpParser\NodeVisitorAbstract;

class NullCoalesceReplacer extends NodeVisitorAbstract
{
    public function leaveNode(Node $node)
    {
        //don't do at thing if the given node is not a Coalesce operator we
        if (!$node instanceof Coalesce) {
            return;
        }

        //create an isset functional call with the left side of '??' as the first parameter
        $issetCall = new Node\Expr\FuncCall(new Node\Name('isset'), [$node->left]);

        //replace the entire node by a ternary statement
        return new Node\Expr\Ternary($issetCall, $node->left, $node->right);
    }
}

Hãy xem xét một khách truy cập khác. Điều này sẽ loại bỏ tất cả các gợi ý loại vô hướng

php7to5 convert {$directoryWithPHP7Code} {$destinationWithPHP5Code}
0

Sử dụng một cây cú pháp trừu tượng chắc chắn làm cho mã thao tác khá dễ đọc. Có khá nhiều du khách khác. Bạn có thể xem chúng trên GitHub

kết thúc

Thành thật mà nói, tôi không nghĩ rằng bản thân mình sẽ sử dụng công cụ này. Tôi muốn nâng cấp máy chủ lên PHP 7 để chuyển đổi mã sang PHP 5. Điều đó đang được nói, đó là một dự án thú vị để làm việc trên. Nó có một yếu tố mát mẻ nhất định. Tôi đã học được rằng thao tác mã bằng trình phân tích cú pháp PHP không khó lắm. Có lẽ tôi có thể sử dụng kiến ​​thức đó vào một dự án khác vào một ngày nào đó

Trong khi đó, một dự án giàu tính năng hơn giúp chuyển đổi mã PHP 7 đã xuất hiện (vì vậy nếu bạn muốn chuyển đổi một số mã PHP 7, hãy xem qua dự án đó)

Làm cách nào để thay đổi PHP 5 thành PHP 7?

Tìm hiểu cách di chuyển ứng dụng PHP 5 sang PHP 7. Môi trường thiết lập và phát triển. .
Sao chép ứng dụng/cấu hình/tham số. yml. dist vào app/config/parameters. yml
Chạy cài đặt nhà soạn nhạc
Chạy cài đặt bower
Chạy tài sản bin/bảng điều khiển php. cài đặt --symlink --relative
Chạy docker-compose up -d

Mã PHP5 có chạy trên PHP7 không?

Phần lớn, PHP 5. Mã x có thể chạy không thay đổi trên PHP 7 . Tuy nhiên, có một vài thay đổi được phân loại là không tương thích ngược.

Làm cách nào để nâng cấp phiên bản PHP trong mã?

Nâng cấp hoặc hạ cấp phiên bản PHP .
Đảm bảo các gói php cho phiên bản bạn muốn đã được cài đặt
Cập nhật bất kỳ cấu hình nào cho phiên bản PHP đó
Cập nhật cấu hình máy chủ web của bạn để trỏ đến đúng phiên bản PHP
Trỏ PHP CLI đến đúng phiên bản PHP
Khởi động lại máy chủ web của bạn và php-fpm

Cách nâng cấp PHP 5. 6 đến 7 trong Ubuntu?

Cài đặt PHP (5. 6, 7. .
Trước tiên, hãy bắt đầu bằng cách thêm Ondřej Surý PPA để cài đặt các phiên bản PHP khác nhau – PHP 5. 6, PHP7. x và PHP 8. 0 trên hệ thống Ubuntu. .
Tiếp theo, cập nhật hệ thống như sau. $ sudo apt-get cập nhật
Bây giờ hãy cài đặt các phiên bản PHP được hỗ trợ khác nhau như sau