web-dev-qa-db-ja.com

PHP 5.5で廃止された関数を使用したsymfony 1.4

私は最近PHPバージョン5.3.27から5.5.0にアップグレードしました。すべてのSymfony 2.3.2プロジェクトで問題なく動作し、最新のPHP =機能。

他のSymfony 1.4.16プロジェクトに戻ると、/ e修飾子を使用したpreg_replaceの非推奨に関するPHPエラーが表示されます。

フォーラムでこのエラーに関するリファレンスを見つけることができません。以前にこの問題が発生したことはありますか?すぐに適用できるパッチはありますか? Symfony 1.4.20へのアップグレードはこの問題を修正する予定ですか?

エラーメッセージは次のようになります。

非推奨:preg_replace():/ e修飾子は非推奨です。代わりに/myproject/lib/vendor/symfony/lib/response/sfWebResponse.class.phpの409行目でpreg_replace_callbackを使用してください

1つの方法は、メッセージおよび manual で推奨されているようにコードを変更することです。 preg_replace式をpreg_replace_callback呼び出しに変更するにはどうすればよいですか?

ヘルプ/ヒントは大歓迎です。

編集:

これまでのところ、これに対するパッチはありません(Symfony 1.4.20はこの問題に対処していません)。解決策は、ソースのpreg_replaceへの失敗した呼び出しをpreg_replace_callbackへの対応する呼び出しに置き換えることです。これはsfWebResponseクラスで簡単に実行されます(ヒントJonに感謝します)。今度は 次の失敗の発生 は少し複雑ですが、残念ながら、symfonyが壊れそうな場所を見つけるために、/ eオプションを使用してpreg_replaceをgrepする必要があるでしょう。 。かなりの数の結果が得られます:o

だから...私の結論は、Symfony 1.4ユーザーはいくつかの深刻なパッチが出るまでPHPをバージョン5.5にアップグレードしないほうがいいということです。あなたはどう思いますか?代替案はありますか?

18
mika

index.phpでデバッグを有効にしない限り、エラーは製品に表示されません。 settings.ymlでE_DEPRECATEDフラグの設定を解除することにより、それらをdevで削除することもできます。

dev:
  .settings:
    error_reporting:  <?php echo ((E_ALL | E_STRICT) ^ E_DEPRECATED)."\n" ?>
37
flm

基本的にあなたがしなければならないことは、preg_replace呼び出しから置換引数を取り、それを適切なPHP式に分解して、その式を、同等のpreg_replace_callback呼び出しへのコールバックとして使用されます。

あなたの場合 関連コード

return preg_replace('/\-(.)/e', "'-'.strtoupper('\\1')", /* input */)

だからあなたはそれを

$callback = function($matches) {
    return '-'.strtoupper($matches[1]);
};

return preg_replace_callback('/\-(.)/', $callback, /* input */)

コールバックコードは元の置換式と同じであることがわかりますが、\\1などの参照が$matches[1]などの配列アクセスに置き換えられている点が唯一の違いです。

13
Jon

/lib/vendor/symfony/lib/response/sfWebResponse.class.phpの407行目のnormalizeHeaderNameメソッドの修正

protected function normalizeHeaderName($name)
{
  //return preg_replace('/\-(.)/e', "'-'.strtoupper('\\1')", 
  strtr(ucfirst(strtolower($name)), '_', '-');
  return str_replace(array('\'$1$3\'','\'$2$4\'','\'$1\'', '\'$2\'', '$1', '$2'),array('$matches[1].$matches[3]','$matches[2].$matches[4]','$matches[1]','$matches[2]','$matches[1]','$matches[2]'),
$name);
}

/lib/vendor/symfony/lib/util/sfToolkit.class.phpの360行目のpregtrメソッドのFIX

public static function pregtr($search, $replacePairs){
  // return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
  foreach($replacePairs as $pattern => $replacement)
  {
    if (preg_match('/(.*)e$/', $pattern, $matches))
    {
      $pattern = $matches[1];
      $search = preg_replace_callback($pattern, function ($matches) use ($replacement) {
        preg_match("/('::'\.)?([a-z]*)\('\\\\([0-9]{1})'\)/", $replacement, $match);
        return ($match[1]==''?'':'::').call_user_func($match[2], $matches[$match[3]]);
      }, $search);
    }
    else
    {
      $search = preg_replace($pattern, $replacement, $search);
    }
  }
  return $search;
}
11
user2111395

全体として、最善の解決策は、Symfony 1.4との互換性がなくなったため、PHPをバージョン5.5にアップグレードしないことです。

Symfony 2と1.4の両方のバージョンが開発環境にある場合は、PHPのように、適切に記述された here のようにバージョンを切り替えることができます)。

本当に必要な場合は、2つの異なるバージョンのPHPを同じApacheサーバーで同時に実行するようにセットアップすることができます。これには、さらに設定が必要になります。上記のリンクでも説明されています。

代替ホットフィックス:

Symfonyコードにいくつかの更新を加えることで、ほとんどのWebページをdevで実行できます。もちろん、別のSymfonyライブラリが原因で「非推奨」エラーがいつでも発生する可能性があるため、これを本番環境に適用するのは危険です。

Myproject/lib/vendor/symfony/lib/response/sfWebResponse.class.phpの409行目にあります(コメント付きのコードは元のSymfonyコードです):

  protected function normalizeHeaderName($name)
  {
    // return preg_replace('/\-(.)/e', "'-'.strtoupper('\\1')", strtr(ucfirst(strtolower($name)), '_', '-'));    

    return preg_replace_callback(
                  '/\-(.)/', 
                  function ($matches) {
                    return '-'.strtoupper($matches[1]);
                  }, 
                  strtr(ucfirst(strtolower($name)), '_', '-')
        );
  }

そして、myproject/lib/vendor/symfony/lib/util/sfToolkit.class.phpの362行目で、次のようになります。

  public static function pregtr($search, $replacePairs)
  {
    // return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
    foreach($replacePairs as $pattern => $replacement)
        $search = preg_replace_callback(
                    $pattern, 
                    function ($matches) use ($replacement){
                        if(array_key_exists(1, $matches)){ $replacement = str_replace("\\1", $matches[1], $replacement);}
                        if(array_key_exists(2, $matches)){ $replacement = str_replace("\\2", $matches[2], $replacement);}
                        return $replacement;
                    }, 
                    $search
                );
    return $search;
  }

自己責任で使用してください:)

11
mika

古いコードを維持してパッチを当てるSymfonyのコミュニティバージョンがあります。

https://github.com/LExpress/symfony1

8
Kevin

360の/lib/vendor/symfony/lib/util/sfToolkit.class.phppregtrメソッドの代替FIX

public static function pregtr($search, $replacePairs)
{
  // return preg_replace(array_keys($replacePairs), array_values($replacePairs), $search);
  foreach($replacePairs as $pattern => $replacement)
  {
    if (preg_match('/(.*)e$/', $pattern, $matches))
    {
      $pattern = $matches[1];
      $search = preg_replace_callback($pattern, function ($matches) use ($replacement) {
        preg_match("/('::'\.)?([a-z]*)\('\\\\([0-9]{1})'\)/", $replacement, $match);
        return ($match[1]==''?'':'::').call_user_func($match[2], $matches[$match[3]]);
      }, $search);
    }
    else
    {
      $search = preg_replace($pattern, $replacement, $search);
    }
  }
  return $search;
}
5
sadikoff
Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in lib/vendor/symfony/…This changelog will solve the problem for all symfony 1.4.x. Tested on Symfony 1.4.20
---
 lib/vendor/symfony/lib/command/sfCommandManager.class.php     |  4 +++-
 lib/vendor/symfony/lib/form/addon/sfFormObject.class.php      |  2 +-
 lib/vendor/symfony/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php  |  2 +-
 lib/vendor/symfony/plugins/sfPropelPlugin/lib/form/sfFormFilterPropel.class.php      |  2 +-
 lib/vendor/symfony/lib/response/sfWebResponse.class.php       |  2 +-
 lib/vendor/symfony/lib/util/sfInflector.class.php             |  5 +----
 lib/vendor/symfony/lib/util/sfToolkit.class.php               | 11 +++++++++++
 7 files changed, 19 insertions(+), 9 deletions(-)

lib/vendor/symfony/lib/command/sfCommandManager.class.php
@@ -108,7 +108,9 @@ class sfCommandManager
     else if (!is_array($arguments))
     {
       // hack to split arguments with spaces : --test="with some spaces"
-      $arguments = preg_replace('/(\'|")(.+?)\\1/e', "str_replace(' ', '=PLACEHOLDER=', '\\2')", $arguments);
+      $arguments = preg_replace_callback('/(\'|")(.+?)\\1/', function($matches) {
+         return str_replace(' ', '=PLACEHOLDER=', $matches[2]);
+     }, $arguments);
       $arguments = preg_split('/\s+/', $arguments);
       $arguments = str_replace('=PLACEHOLDER=', ' ', $arguments);
     }

lib/vendor/symfony/lib/form/addon/sfFormObject.class.php
@@ -278,6 +278,6 @@ abstract class sfFormObject extends BaseForm

   protected function camelize($text)
   {
-    return preg_replace(array('#/(.?)#e', '/(^|_|-)+(.)/e'), array("'::'.strtoupper('\\1')", "strtoupper('\\2')"), $text);
+    return sfToolkit::camelize($text);
   }
 }

lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/form/sfFormFilterDoctrine.class.php
@@ -323,7 +323,7 @@ abstract class sfFormFilterDoctrine extends sfFormFilter

   protected function camelize($text)
   {
-    return sfToolkit::pregtr($text, array('#/(.?)#e' => "'::'.strtoupper('\\1')", '/(^|_|-)+(.)/e' => "strtoupper('\\2')"));
+    return sfToolkit::camelize($text);
   }

   protected function getTable()

lib/vendor/symfony/lib/plugins/sfPropelPlugin/lib/form/sfFormFilterPropel.class.php
@@ -263,6 +263,6 @@ abstract class sfFormFilterPropel extends sfFormFilter

   protected function camelize($text)
   {
-    return sfToolkit::pregtr($text, array('#/(.?)#e' => "'::'.strtoupper('\\1')", '/(^|_|-)+(.)/e' => "strtoupper('\\2')"));
+       return sfToolkit::camelize($text);
   }
 }

lib/vendor/symfony/lib/response/sfWebResponse.class.php
@@ -406,7 +406,7 @@ class sfWebResponse extends sfResponse
    */
   protected function normalizeHeaderName($name)
   {
-    return preg_replace('/\-(.)/e', "'-'.strtoupper('\\1')", strtr(ucfirst(strtolower($name)), '_', '-'));
+    return preg_replace_callback('/\-(.)/', function ($matches) { return '-'.strtoupper($matches[1]); }, strtr(ucfirst(strtolower($name)), '_', '-'));
   }

   /**

lib/vendor/symfony/lib/util/sfInflector.class.php
@@ -28,10 +28,7 @@ class sfInflector
   public static function camelize($lower_case_and_underscored_Word)
   {
     $tmp = $lower_case_and_underscored_Word;
-    $tmp = sfToolkit::pregtr($tmp, array('#/(.?)#e'    => "'::'.strtoupper('\\1')",
-                                         '/(^|_|-)+(.)/e' => "strtoupper('\\2')"));
-
-    return $tmp;
+    return sfToolkit::camelize($tmp);;
   }

   /**

lib/vendor/symfony/lib/util/sfToolkit.class.php
@@ -608,4 +608,15 @@ class sfToolkit

     return set_include_path(join(PATH_SEPARATOR, $paths));
   }
+
+   public static function camelize($text)
+   {
+       if (preg_match('#/(.?)#', $text, $matches)) {
+           $text = str_replace($matches[0], '::'.strtoupper($matches[1]), $text);
+       }
+       if (preg_match('/(^|_|-)+(.)/', $text, $matches)) {
+           $text = str_replace($matches[0], strtoupper($matches[2]), $text);
+       }
+       return $text;
+   }
 }
--
0
ImLeo