Header Ads

PHP 5 - PHP 7 kod dönüştürücüsü oluşturma

 

PHP 5 - PHP 7 kod dönüştürücüsü oluşturma

Çoğunlukla, PHP 5.x kodu PHP 7'de değişmeden çalışabilir. Bununla birlikte, geriye dönük uyumsuz olarak sınıflandırılan birkaç değişiklik vardır. Bunun anlamı, PHP 5 kodunuz belirli bir şekilde yazılmışsa veya kaldırılmış işlevleri kullanıyorsa, kodunuzun kırılacağı ve elinizde kötü bir hata olacağıdır.

Hazırlanıyor

PHP 5 - PHP 7 Kod Dönüştürücü iki şey yapar:

  • Kod dosyanızı tarar ve kaldırılan PHP 5 işlevselliğini PHP 7'deki eşdeğerine dönüştürür
  • Dil kullanımında değişikliklerin meydana geldiği, ancak yeniden yazmanın mümkün olmadığı yerlerde açıklamalar ekler//WARNING

    NOT

    Dönüştürücüyü çalıştırdıktan sonra kodunuzun PHP 7'de çalışmasının garanti edilmediğini lütfen unutmayın. Yine de eklenen etiketleri gözden geçirmeniz gerekir. En azından, bu tarif PHP 5 kodunuzu PHP 7'de çalışacak şekilde dönüştürmeye iyi bir başlangıç sağlayacaktır.//WARNING

Bu tarifin özü yeni PHP 7 işlevidir. Bu şaşırtıcı işlevin yapmanıza izin verdiği şey, bağımsız bir geri aramayı temsil eden değerle birlikte bir dizi normal ifadeyi anahtar olarak sunmaktır. Daha sonra dizeyi bir dizi dönüşümden geçirebilirsiniz. Sadece bu değil, geri çağırma dizisinin konusu da bir dizi olabilir.preg_replace_callback_array()

Nasıl yapılır...

  1. Yeni bir sınıfta , bir dosya adını bağımsız değişken olarak kabul eden bir yöntemle başlıyoruz. Dosyanın var olup olmadığını denetler. Öyleyse, dosyayı bir diziye yükleyen PHP işlevini çağırır ve her dizi öğesi bir satırı temsil eder:Application\Parse\Convertscan()file()
    public function scan($filename)
    {
    if (!file_exists($filename)) {
    throw new Exception(
    self::EXCEPTION_FILE_NOT_EXISTS);
    }
    $contents = file($filename);
    echo 'Processing: ' . $filename . PHP_EOL;

    $result = preg_replace_callback_array( [
  2. Ardından, bir dizi anahtar/değer çiftini geçirmeye başlıyoruz. Anahtar, dizeye karşı işlenen normal bir ifadedir. Tüm eşleşmeler, anahtar/değer çiftinin değer parçası olarak temsil edilen geri aramaya geçirilir. PHP 7'den kaldırılan etiketleri açıp kapatmadığını kontrol ediyoruz:
        // replace no-longer-supported opening tags
    '!^\<\%(\n| )!' =>
    function ($match) {
    return '<?php' . $match[1];
    },

    // replace no-longer-supported opening tags
    '!^\<\%=(\n| )!' =>
    function ($match) {
    return '<?php echo ' . $match[1];
    },

    // replace no-longer-supported closing tag
    '!\%\>!' =>
    function ($match) {
    return '?>';
    },
  3. Ardından, belirli işlemler algılandığında bir dizi uyarı vardır ve PHP 5 ile PHP 7'de nasıl işlendikleri arasında potansiyel bir kod kırılması vardır. Tüm bu durumlarda, kod yeniden yazılmaz. Bunun yerine, kelimeyi içeren satır içi bir yorum eklenir:WARNING
        // changes in how $$xxx interpretation is handled
    '!(.*?)\$\$!' =>
    function ($match) {
    return '// WARNING: variable interpolation
    . ' now occurs left-to-right' . PHP_EOL
    . '// see: http://php.net/manual/en/'
    . '// migration70.incompatible.php'
    . $match[0];
    },

    // changes in how the list() operator is handled
    '!(.*?)list(\s*?)?\(!' =>
    function ($match) {
    return '// WARNING: changes have been made '
    . 'in list() operator handling.'
    . 'See: http://php.net/manual/en/'
    . 'migration70.incompatible.php'
    . $match[0];
    },

    // instances of \u{
    '!(.*?)\\\u\{!' =>
    function ($match) {
    return '// WARNING: \\u{xxx} is now considered '
    . 'unicode escape syntax' . PHP_EOL
    . '// see: http://php.net/manual/en/'
    . 'migration70.new-features.php'
    . '#migration70.new-features.unicode-'
    . 'codepoint-escape-syntax' . PHP_EOL
    . $match[0];
    },

    // relying upon set_error_handler()
    '!(.*?)set_error_handler(\s*?)?.*\(!' =>
    function ($match) {
    return '// WARNING: might not '
    . 'catch all errors'
    . '// see: http://php.net/manual/en/'
    . '// language.errors.php7.php'
    . $match[0];
    },

    // session_set_save_handler(xxx)
    '!(.*?)session_set_save_handler(\s*?)?\((.*?)\)!' =>
    function ($match) {
    if (isset($match[3])) {
    return '// WARNING: a bug introduced in'
    . 'PHP 5.4 which '
    . 'affects the handler assigned by '
    . 'session_set_save_handler() and '
    . 'where ignore_user_abort() is TRUE
    . 'has been fixed in PHP 7.'
    . 'This could potentially break '
    . 'your code under '
    . 'certain circumstances.' . PHP_EOL
    . 'See: http://php.net/manual/en/'
    . 'migration70.incompatible.php'
    . $match[0];
    } else {
    return $match[0];
    }
    },
  4. Negatif bir işleç veya 64'ün ötesinde herhangi bir kullanım girişimi, atılacak bir şey arayan bir bloğa sarılır:<<>>try { xxx } catch() { xxx }ArithmeticError
        // wraps bit shift operations in try / catch
    '!^(.*?)(\d+\s*(\<\<|\>\>)\s*-?\d+)(.*?)$!' =>
    function ($match) {
    return '// WARNING: negative and '
    . 'out-of-range bitwise '
    . 'shift operations will now
    . 'throw an ArithmeticError' . PHP_EOL
    . 'See: http://php.net/manual/en/'
    . 'migration70.incompatible.php'
    . 'try {' . PHP_EOL
    . "\t" . $match[0] . PHP_EOL
    . '} catch (\\ArithmeticError $e) {'
    . "\t" . 'error_log("File:"
    . $e->getFile()
    . " Message:" . $e->getMessage());'
    . '}' . PHP_EOL;
    },

    NOT

    PHP 7, hataların ele alınma şeklini değiştirdi. Bazı durumlarda, hatalar istisnalarla benzer bir sınıflandırmaya taşınır ve yakalanabilir! Hem sınıf hem de sınıf arabirimi uygular. Bir veya bir yakalamak istiyorsanız, yakalayın .ErrorExceptionThrowableErrorExceptionThrowable

  5. Ardından, dönüştürücü PHP 7'de kaldırılan , 'nin herhangi bir kullanımını yeniden yazar. Bunlar, aşağıdakileri kullanarak eşdeğeri ile değiştirilir:call_user_method*()call_user_func*()
        // replaces "call_user_method()" with
    // "call_user_func()"
    '!call_user_method\((.*?),(.*?)(,.*?)\)(\b|;)!' =>
    function ($match) {
    $params = $match[3] ?? '';
    return '// WARNING: call_user_method() has '
    . 'been removed from PHP 7' . PHP_EOL
    . 'call_user_func(['. trim($match[2]) . ','
    . trim($match[1]) . ']' . $params . ');';
    },

    // replaces "call_user_method_array()"
    // with "call_user_func_array()"
    '!call_user_method_array\((.*?),(.*?),(.*?)\)(\b|;)!' =>
    function ($match) {
    return '// WARNING: call_user_method_array()'
    . 'has been removed from PHP 7'
    . PHP_EOL
    . 'call_user_func_array(['
    . trim($match[2]) . ','
    . trim($match[1]) . '], '
    . $match[3] . ');';
    },
  6. Son olarak, değiştirici ile kullanmaya yönelik herhangi bir girişim bir :preg_replace()/epreg_replace_callback()
         '!^(.*?)preg_replace.*?/e(.*?)$!' =>
    function ($match) {
    $last = strrchr($match[2], ',');
    $arg2 = substr($match[2], 2, -1 * (strlen($last)));
    $arg1 = substr($match[0],
    strlen($match[1]) + 12,
    -1 * (strlen($arg2) + strlen($last)));
    $arg1 = trim($arg1, '(');
    $arg1 = str_replace('/e', '/', $arg1);
    $arg3 = '// WARNING: preg_replace() "/e" modifier
    . 'has been removed from PHP 7'
    . PHP_EOL
    . $match[1]
    . 'preg_replace_callback('
    . $arg1
    . 'function ($m) { return '
    . str_replace('$1','$m', $match[1])
    . trim($arg2, '"\'') . '; }, '
    . trim($last, ',');
    return str_replace('$1', '$m', $arg3);
    },

    // end array
    ],

    // this is the target of the transformations
    $contents
    );
    // return the result as a string
    return implode('', $result);
    }

Nasıl çalışır...

Dönüştürücüyü kullanmak için, komut satırından aşağıdaki kodu çalıştırın. Bağımsız değişken olarak taranacak PHP 5 kodunun dosya adını sağlamanız gerekir.

Komut satırından çalıştırılan bu kod bloğu, dönüştürücüyü çağırır:chap_01_php5_to_php7_code_converter.php

<?php
// get filename to scan from command line
$filename = $argv[1] ?? '';

if (!$filename) {
echo 'No filename provided' . PHP_EOL;
echo 'Usage: ' . PHP_EOL;
echo __FILE__ . ' <filename>' . PHP_EOL;
exit;
}

// setup class autoloading
require __DIR__ . '/../Application/Autoload/Loader.php';

// add current directory to the path
Application\Autoload\Loader::init(__DIR__ . '/..');

// get "deep scan" class
$convert = new Application\Parse\Convert();
echo $convert->scan($filename);
echo PHP_EOL;

Ayrıca bakınız

Geriye dönük uyumsuz değişiklikler hakkında daha fazla bilgi için lütfen http://php.net/manual/en/migration70.incompatible.php bakın.

Hiç yorum yok

Blogger tarafından desteklenmektedir.