Error de PHP 5.5 - Funcionalidad obsoleta: preg_replace ()

16

Después de actualizar a PHP 5.5, obtenemos el siguiente error al agregar un sitio web, tienda o vista de tienda. Este error todavía está presente en 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}

Este es el código que produce el error.

El código se puede encontrar en 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);
}

Este es, en mi opinión, el parche más fácil para el método:

/**
 * 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);
}

El método solo lo utiliza el Mage_Adminhtml_System_StoreController::storeAction().

Hay tres lugares posibles para solucionarlo:

  1. Mage_Core_Helper_Abstract => es donde se encuentra el método, pero apesta porque toca un archivo central.
  2. Reescribir Mage_Core_Helper_Abstract => es una clase abstracta, por lo que no debe / no puede reescribirse.
  3. Reescribe Mage_Adminhtml_Helper_Data y agrega el método allí. => Creo que este es el camino a seguir.

¿Qué piensan ustedes?

  1. ¿Es la opción 3 la forma correcta de solucionar el problema?
  2. ¿Es correcto el código en mi parche?
RobM84
fuente
El problema aún existe en 1.9.1 CE y 1.14.1 EE

Respuestas:

13

Sí, tiene usted razón. Repara el ayudante adminhtml. Esta es la diferencia para la solución que uso:

--- 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);
 }

Esta es una prueba para confirmar que el comportamiento es el mismo que con 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('<>', '<>'),
        );
    }
} 
Vinaí
fuente
4

Esto ahora está arreglado en Magento EE 1.14.1 y 1.9.1. Una incompatibilidad adicional son los cambios de paquete () / desempaquetado () que afectan a la Copia de seguridad / Reversión y algunas extensiones durante la instalación, cualquier cosa que toque archivos tar. Supongo que cualquiera que esté ejecutando Magento en producción no los está usando.

Piotr Kaminski
fuente
¿Cuándo se lanzará el parche para versiones anteriores?)
Ben Lessani - Sonassi
no sé aún si / cuándo
Piotr Kaminski
3

Respuesta corta: Magento no es compatible con PHP 5.5, no actualice su servidor web a 5.5.

Respuesta más larga: supongo que Magento corrige este error con la próxima versión, por lo que simplemente haría un truco central y esperaría lo mejor. No sé si el código es correcto, lo siento.

Fabian Blechschmidt
fuente
Hola Fabian, ejecutamos todos nuestros servidores en PHP 5.5 desde hace bastante tiempo. Este es el primer problema que he encontrado. ¿Qué otras incompatibilidades conocidas existen o de dónde proviene esta información?
RobM84
1
tbh no tengo idea. Puede consultar el registro de cambios php.net/manual/en/migration54.php y grep para conocer los métodos y la configuración de ini
Fabian Blechschmidt
1
de hecho, este es el único problema de PHP 5.5 en magento CE, no encontramos otro en el último medio año en ejecución
Flyingmana
2
También es un consejo realmente malo, ya que 5.3 está desactualizado, php 5.4 nunca alcanzó un estado estable real ya que la mayoría de las personas lo usa con APC, 5.5 es actualmente la única versión mínima estable de PHP compatible disponible, sin mencionar todas las correcciones de seguridad que no son incluido en versiones anteriores de PHP
Flyingmana