LoginSignup
12
15

More than 5 years have passed since last update.

PHP7.2でFuelPHPがエラーになるのを何とかする

Posted at

PHP7.2では get_class 関数の仕様が変更されたため、FuelPHP最新版の1.8.xでもエラーを吐くようになりました。
1.8のPHP7.0対応以降ほぼ更新されていないので素直にLaravelなど他フレームワークへ移行するのがいいです。
リプレースまでのつなぎとしてPHP7.2対応させたときのメモです。

やったこと

コア拡張を利用して1.9devの修正を適用した。
https://github.com/fuel/core/commit/3dd5e70a57742c6148ef3c4cee4eb24eb9258832

作業

拡張クラスを作成

エラーを吐いている Fuel\Core\Security を拡張したクラスを fuel/app/classes/extend/security.php に用意
修正された htmlentities を張り付けて保存

fuel/app/classes/extend/security.php
<?php
class Security extends Fuel\Core\Security
{
  public static function htmlentities($value, $flags = null, $encoding = null, $double_encode = null)
  {
    static $already_cleaned = array();

    is_null($flags) and $flags = \Config::get('security.htmlentities_flags', ENT_QUOTES);
    is_null($encoding) and $encoding = \Fuel::$encoding;
    is_null($double_encode) and $double_encode = \Config::get('security.htmlentities_double_encode', false);

    // Nothing to escape for non-string scalars, or for already processed values
    if (is_null($value) or is_bool($value) or is_int($value) or is_float($value) or in_array($value, $already_cleaned, true))
    {
      return $value;
    }

    if (is_string($value))
    {
      $value = htmlentities($value, $flags, $encoding, $double_encode);
    }
    elseif (is_object($value) and $value instanceOf \Sanitization)
    {
      $value->sanitize();
      return $value;

    }
    elseif (is_array($value) or ($value instanceof \Iterator and $value instanceof \ArrayAccess))
    {
      // Add to $already_cleaned variable when object
      is_object($value) and $already_cleaned[] = $value;

      foreach ($value as $k => $v)
      {
        $value[$k] = static::htmlentities($v, $flags, $encoding, $double_encode);
      }
    }
    elseif ($value instanceof \Iterator or get_class($value) == 'stdClass')
    {
      // Add to $already_cleaned variable
      $already_cleaned[] = $value;

      foreach ($value as $k => $v)
      {
        $value->{$k} = static::htmlentities($v, $flags, $encoding, $double_encode);
      }
    }
    elseif (is_object($value))
    {
      // Check if the object is whitelisted and return when that's the case
      foreach (\Config::get('security.whitelisted_classes', array()) as $class)
      {
        if (is_a($value, $class))
        {
          // Add to $already_cleaned variable
          $already_cleaned[] = $value;

          return $value;
        }
      }

      // Throw exception when it wasn't whitelisted and can't be converted to String
      if ( ! method_exists($value, '__toString'))
      {
        throw new \RuntimeException('Object class "'.get_class($value).'" could not be converted to string or '.
          'sanitized as ArrayAccess. Whitelist it in security.whitelisted_classes in app/config/config.php '.
          'to allow it to be passed unchecked.');
      }

      $value = static::htmlentities((string) $value, $flags, $encoding, $double_encode);
    }

    return $value;
  }
}

拡張を有効化

'拡張したいクラス名' => '拡張したクラスのファイル名', で指定できる。

fuel/app/bootstrap.php
\Autoloader::add_classes(array(
  // Add classes you want to override here
  // Example: 'View' => APPPATH.'classes/view.php',
  'Security' => APPPATH.'classes/extend/security.php',
));

参考

12
15
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
15