Błąd PHP 5.5 - przestarzała funkcjonalność: preg_replace ()

16

Po aktualizacji do PHP 5.5 pojawia się następujący błąd podczas dodawania witryny, sklepu lub widoku sklepu. Ten błąd jest nadal obecny w Magento 1.9.0.1

Exception message: Deprecated functionality: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in app/code/core/Mage/Core/Helper/Abstract.php on line 238
Trace: #0 [internal function]: mageCoreErrorHandler(8192, 'preg_replace():...', 'app...', 238, Array)
#1 app/code/core/Mage/Core/Helper/Abstract.php(238): preg_replace('# <(?![/a-z]) |...', 'htmlentities('$...', 'New Store Name')
#2 app/code/core/Mage/Adminhtml/controllers/System/StoreController.php(175): Mage_Core_Helper_Abstract->removeTags('New Store Name')
#3 app/code/core/Mage/Core/Controller/Varien/Action.php(418): Mage_Adminhtml_System_StoreController->saveAction()
#4 app/code/core/Mage/Core/Controller/Varien/Router/Standard.php(250): Mage_Core_Controller_Varien_Action->dispatch('save')
#5 app/code/core/Mage/Core/Controller/Varien/Front.php(172): Mage_Core_Controller_Varien_Router_Standard->match(Object(Mage_Core_Controller_Request_Http))
#6 app/code/core/Mage/Core/Model/App.php(354): Mage_Core_Controller_Varien_Front->dispatch()
#7 app/Mage.php(686): Mage_Core_Model_App->run(Array)
#8 index.php(87): Mage::run('', 'store')
#9 {main}

To jest kod, który powoduje błąd

Kod można znaleźć w Mage_Core_Helper_Abstract

/**
 * Remove html tags, but leave "<" and ">" signs
 *
 * @param   string $html
 * @return  string
 */
public function removeTags($html)
{
    $html = preg_replace("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #exi", "htmlentities('$0')", $html);
    $html =  strip_tags($html);
    return htmlspecialchars_decode($html);
}

To, moim zdaniem, najłatwiejsza łatka dla tej metody:

/**
 * Remove html tags, but leave "<" and ">" signs
 *
 * @param   string $html
 * @return  string
 */
public function removeTags($html)
{
    $html = preg_replace_callback("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #xi",
        create_function('$matches', 'return htmlentities($matches);'),
        $html
    );
    $html =  strip_tags($html);
    return htmlspecialchars_decode($html);
}

Ta metoda jest używana tylko przez Mage_Adminhtml_System_StoreController::storeAction().

Istnieją trzy możliwe miejsca, aby to naprawić:

  1. Mage_Core_Helper_Abstract => to gdzie znajduje się metoda, ale jest do bani, ponieważ dotyka pliku podstawowego.
  2. Przepisz Mage_Core_Helper_Abstract => jest to klasa abstrakcyjna, więc nie powinna / nie może być przepisana.
  3. Przepisz Mage_Adminhtml_Helper_Data i dodaj tam metodę. => Myślę, że to jest właściwa droga.

Co myślicie?

  1. Czy opcja nr 3 jest właściwym sposobem na rozwiązanie tego problemu.
  2. Czy kod w mojej łatce jest poprawny?
RobM84
źródło
Problem nadal występuje w

Odpowiedzi:

13

Tak masz rację. Napraw pomocnika adminhtml. To jest różnica dla poprawki, której używam:

--- app/code/core/Mage/Core/Helper/Abstract.php.orig 2014-09-25 15:32:56.000000000 +0200
+++ app/code/core/Mage/Core/Helper/Abstract.php 2014-09-25 15:34:42.000000000 +0200
@@ -235,7 +235,9 @@
  */
 public function removeTags($html)
 {
-        $html = preg_replace("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #exi", "htmlentities('$0')", $html);
+        $html = preg_replace_callback("# <(?![/a-z]) | (?<=\s)>(?![a-z]) #xi", function($matches) {
+            return htmlentities($matches[0]);
+        }, $html);
         $html =  strip_tags($html);
         return htmlspecialchars_decode($html);
 }

Jest to test potwierdzający, że zachowanie jest takie samo jak w przypadku php 5.4:

<?php

namespace Vinai\Kopp\Magento\Tests;

class MageAdminhtmlHelperDataTest extends \PHPUnit_Framework_TestCase
{
    /**
     * @var \Mage_Adminhtml_Helper_Data
     */
    private $helper;

    static public function setUpBeforeClass()
    {
        ini_set('display_errors', 1);
        umask(0);
        error_reporting(E_ALL);
        require_once 'app/Mage.php';
        \Mage::setIsDeveloperMode(true);
    }

    public function setUp()
    {
        $this->helper = new \Mage_Adminhtml_Helper_Data();
    }

    /**
     * @covers \Mage_Core_Helper_Abstract::removeTags
     * @dataProvider removeTagsDataProvider
     */
    public function testRemoveTags($inputHtml, $expected)
    {
        $result = $this->helper->removeTags($inputHtml);
        $this->assertEquals($expected, $result);
    }

    public function removeTagsDataProvider()
    {
        return array(
            array('<b>', ''),
            array('<b> >', ' >'),
            array('<b> <', ' <'),
            array('<b/> </', ' '),
            array('< <b/>', '< '),
            array('> <b/>', '> '),
            array('</ <b/>', ''),
            array('x />', 'x />'),
            array('> <', '> <'),
            array('>>', '>>'),
            array('<<', '<<'),
            array('<>', '<>'),
        );
    }
} 
Vinai
źródło
4

Zostało to teraz naprawione w Magento EE 1.14.1 i 1.9.1. Dodatkową niezgodnością są zmiany pack () / unpack (), które wpływają na Kopię zapasową / przywracanie i niektóre rozszerzenia podczas instalacji - wszystko, co dotyczy plików tar. Zakładam, że każdy, kto korzysta z Magento w produkcji, nie korzysta z nich.

Piotr Kamiński
źródło
Kiedy zostanie wydana łatka na wcześniejsze wersje;)
Ben Lessani - Sonassi,
nie wiem jeszcze czy / kiedy
Piotr Kamiński
3

Krótka odpowiedź: Magento nie jest kompatybilny z PHP 5.5, nie aktualizuj swojego serwera do wersji 5.5.

Dłuższa odpowiedź: Zakładam, że Magento naprawia ten błąd w następnej wersji, więc po prostu zrobię podstawowy hack i mam nadzieję, że będzie najlepszy. Przepraszam, nie wiem, czy kod jest poprawny.

Fabian Blechschmidt
źródło
Cześć Fabian, od dłuższego czasu obsługujemy wszystkie nasze serwery na PHP 5.5. To pierwszy problem, jaki kiedykolwiek spotkałem. Jakie inne znane niezgodności istnieją lub skąd pochodzą te informacje?
RobM84,
1
Nie mam pojęcia. Możesz po prostu sprawdzić dziennik zmian php.net/manual/en/migration54.php i grep dla metod i ustawień ini
Fabian Blechschmidt
1
to właściwie jedyny problem z PHP 5.5 w Magento CE, nie trafiliśmy na inny w ciągu ostatniego półrocza
Flyingmana
2
jest to również bardzo zła rada, ponieważ 5.3 jest zdecydowanie przestarzały, php 5.4 nigdy nie osiąga prawdziwego stabilnego stanu, ponieważ większość ludzi używa go z APC, 5.5 jest obecnie jedyną dostępną minimalną stabilną obsługiwaną wersją PHP, nie wspominając o wszystkich poprawkach bezpieczeństwa, które nie są zawarte w starszych wersjach PHP
Flyingmana