Browse Source

Fixes #14178: Removed HHVM-specific code

tags/3.0.0-alpha1
Alexander Makarov 7 years ago committed by GitHub
parent
commit
85df384e8f
  1. 10
      .travis.yml
  2. 4
      docs/guide/start-installation.md
  3. 1
      framework/CHANGELOG.md
  4. 14
      framework/base/ErrorException.php
  5. 61
      framework/base/ErrorHandler.php
  6. 4
      framework/base/Security.php
  7. 5
      framework/i18n/MessageFormatter.php
  8. 3
      framework/rbac/PhpManager.php
  9. 52
      tests/framework/console/controllers/BaseMessageControllerTest.php
  10. 9
      tests/framework/console/controllers/PHPMessageControllerTest.php
  11. 8
      tests/framework/db/CommandTest.php
  12. 1
      tests/framework/db/mysql/connection/DeadLockTest.php
  13. 4
      tests/framework/db/pgsql/CommandTest.php
  14. 5
      tests/framework/helpers/FormatConverterTest.php
  15. 2
      tests/framework/mail/BaseMailerTest.php
  16. 3
      tests/framework/rbac/DbManagerTestCase.php
  17. 4
      tests/framework/rbac/PhpManagerTest.php
  18. 4
      tests/framework/requirements/YiiRequirementCheckerTest.php
  19. 4
      tests/framework/web/MultipartFormDataParserTest.php

10
.travis.yml

@ -73,18 +73,13 @@ matrix:
install:
- |
if [[ $TASK_TESTS_COVERAGE != 1 && $TRAVIS_PHP_VERSION != hhv* ]]; then
# disable xdebug for performance reasons when code coverage is not needed. note: xdebug on hhvm is disabled by default
# disable xdebug for performance reasons when code coverage is not needed
phpenv config-rm xdebug.ini || echo "xdebug is not installed"
fi
# install composer dependencies
- travis_retry composer self-update
- export PATH="$HOME/.composer/vendor/bin:$PATH"
- |
if [[ $TRAVIS_PHP_VERSION == "hhvm-3.12" ]]; then
# remove php-cs-fixer from composer dependencies on hhvm-3.12 - php-cs-fixer requires at least hhvm-3.18
composer remove friendsofphp/php-cs-fixer --dev
fi
- travis_retry composer install $DEFAULT_COMPOSER_FLAGS
# setup PHP extension
@ -102,9 +97,6 @@ install:
fi
before_script:
# Disable the HHVM JIT for faster Unit Testing
- if [[ $TRAVIS_PHP_VERSION = hhv* ]]; then echo 'hhvm.jit = 0' >> /etc/hhvm/php.ini; fi
# show some versions and env information
- php --version
- composer --version

4
docs/guide/start-installation.md

@ -161,9 +161,7 @@ Configuring Web Servers <span id="configuring-web-servers"></span>
The application installed according to the above instructions should work out of box with either
an [Apache HTTP server](http://httpd.apache.org/) or an [Nginx HTTP server](http://nginx.org/), on
Windows, Mac OS X, or Linux running PHP 5.4 or higher. Yii 2.0 is also compatible with facebook's
[HHVM](http://hhvm.com/). However, there are some edge cases where HHVM behaves different than native
PHP, so you have to take some extra care when using HHVM.
Windows, Mac OS X, or Linux running PHP 5.4 or higher.
On a production server, you may want to configure your Web server so that the application can be accessed
via the URL `http://www.example.com/index.php` instead of `http://www.example.com/basic/web/index.php`. Such configuration

1
framework/CHANGELOG.md

@ -20,6 +20,7 @@ Yii Framework 2 Change Log
- Enh #2990: `yii\widgets\ActiveField::hiddenInput()` no longer renders label by default (lennartvdd)
- Chg: Moved masked input field widget into separate extension https://github.com/yiisoft/yii2-maskedinput (samdark)
- Chg #12089: Behavior of `yii\grid\DataColumn::$filterInputOptions` changed when default value is overwritten (bvanleeuwen, cebe)
- Chg #14178: Removed HHVM-specific code (samdark)
2.0.13 under development
------------------------

14
framework/base/ErrorException.php

@ -20,17 +20,6 @@ use Yii;
class ErrorException extends \ErrorException
{
/**
* This constant represents a fatal error in the HHVM engine.
*
* PHP Zend runtime won't call the error handler on fatals, HHVM will, with an error code of 16777217
* We will handle fatal error a bit different on HHVM.
* @see https://github.com/facebook/hhvm/blob/master/hphp/runtime/base/runtime-error.h#L62
* @since 2.0.6
*/
const E_HHVM_FATAL_ERROR = 16777217; // E_ERROR | (1 << 24)
/**
* Constructs the exception.
* @link http://php.net/manual/en/errorexception.construct.php
* @param $message [optional]
@ -82,7 +71,7 @@ class ErrorException extends \ErrorException
*/
public static function isFatalError($error)
{
return isset($error['type']) && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, self::E_HHVM_FATAL_ERROR]);
return isset($error['type']) && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING]);
}
/**
@ -106,7 +95,6 @@ class ErrorException extends \ErrorException
E_USER_NOTICE => 'PHP User Notice',
E_USER_WARNING => 'PHP User Warning',
E_WARNING => 'PHP Warning',
self::E_HHVM_FATAL_ERROR => 'HHVM Fatal Error',
];
return isset($names[$this->getCode()]) ? $names[$this->getCode()] : 'Error';

61
framework/base/ErrorHandler.php

@ -46,10 +46,6 @@ abstract class ErrorHandler extends Component
* @var string Used to reserve memory for fatal error handler.
*/
private $_memoryReserve;
/**
* @var \Exception from HHVM error that stores backtrace
*/
private $_hhvmException;
/**
@ -59,11 +55,8 @@ abstract class ErrorHandler extends Component
{
ini_set('display_errors', false);
set_exception_handler([$this, 'handleException']);
if (defined('HHVM_VERSION')) {
set_error_handler([$this, 'handleHhvmError']);
} else {
set_error_handler([$this, 'handleError']);
}
set_error_handler([$this, 'handleError']);
if ($this->memoryReserveSize > 0) {
$this->_memoryReserve = str_repeat('x', $this->memoryReserveSize);
}
@ -111,9 +104,6 @@ abstract class ErrorHandler extends Component
$this->renderException($exception);
if (!YII_ENV_TEST) {
\Yii::getLogger()->flush(true);
if (defined('HHVM_VERSION')) {
flush();
}
exit(1);
}
} catch (\Throwable $e) {
@ -147,45 +137,10 @@ abstract class ErrorHandler extends Component
}
$msg .= "\n\$_SERVER = " . VarDumper::export($_SERVER);
error_log($msg);
if (defined('HHVM_VERSION')) {
flush();
}
exit(1);
}
/**
* Handles HHVM execution errors such as warnings and notices.
*
* This method is used as a HHVM error handler. It will store exception that will
* be used in fatal error handler
*
* @param int $code the level of the error raised.
* @param string $message the error message.
* @param string $file the filename that the error was raised in.
* @param int $line the line number the error was raised at.
* @param mixed $context
* @param mixed $backtrace trace of error
* @return bool whether the normal error handler continues.
*
* @throws ErrorException
* @since 2.0.6
*/
public function handleHhvmError($code, $message, $file, $line, $context, $backtrace)
{
if ($this->handleError($code, $message, $file, $line)) {
return true;
}
if (E_ERROR & $code) {
$exception = new ErrorException($message, $code, $code, $file, $line);
$ref = new \ReflectionProperty('\Exception', 'trace');
$ref->setAccessible(true);
$ref->setValue($exception, $backtrace);
$this->_hhvmException = $exception;
}
return false;
}
/**
* Handles PHP execution errors such as warnings and notices.
*
* This method is used as a PHP error handler. It will simply raise an [[ErrorException]].
@ -214,9 +169,6 @@ abstract class ErrorHandler extends Component
foreach ($trace as $frame) {
if ($frame['function'] === '__toString') {
$this->handleException($exception);
if (defined('HHVM_VERSION')) {
flush();
}
exit(1);
}
}
@ -242,11 +194,7 @@ abstract class ErrorHandler extends Component
$error = error_get_last();
if (ErrorException::isFatalError($error)) {
if (!empty($this->_hhvmException)) {
$exception = $this->_hhvmException;
} else {
$exception = new ErrorException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']);
}
$exception = new ErrorException($error['message'], $error['type'], $error['type'], $error['file'], $error['line']);
$this->exception = $exception;
$this->logException($exception);
@ -258,9 +206,6 @@ abstract class ErrorHandler extends Component
// need to explicitly flush logs because exit() next will terminate the app immediately
Yii::getLogger()->flush(true);
if (defined('HHVM_VERSION')) {
flush();
}
exit(1);
}
}

4
framework/base/Security.php

@ -518,10 +518,6 @@ class Security extends Component
if (function_exists('stream_set_read_buffer')) {
stream_set_read_buffer($this->_randomFile, $bufferSize);
}
// stream_set_read_buffer() isn't implemented on HHVM
if (function_exists('stream_set_chunk_size')) {
stream_set_chunk_size($this->_randomFile, $bufferSize);
}
}
}
}

5
framework/i18n/MessageFormatter.php

@ -113,11 +113,6 @@ class MessageFormatter extends Component
$this->_errorCode = $e->getCode();
$this->_errorMessage = 'Message pattern is invalid: ' . $e->getMessage();
return false;
} catch (\Exception $e) {
// Exception is thrown by HHVM
$this->_errorCode = $e->getCode();
$this->_errorMessage = 'Message pattern is invalid: ' . $e->getMessage();
return false;
}
$result = $formatter->format($params);

3
framework/rbac/PhpManager.php

@ -23,9 +23,6 @@ use yii\helpers\VarDumper;
* (for example, the authorization data for a personal blog system).
* Use [[DbManager]] for more complex authorization data.
*
* Note that PhpManager is not compatible with facebooks [HHVM](http://hhvm.com/) because
* it relies on writing php files and including them afterwards which is not supported by HHVM.
*
* For more details and usage information on PhpManager, see the [guide article on security authorization](guide:security-authorization).
*
* @author Qiang Xue <qiang.xue@gmail.com>

52
tests/framework/console/controllers/BaseMessageControllerTest.php

@ -1,17 +1,12 @@
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yiiunit\framework\console\controllers;
use Yii;
use yii\console\controllers\MessageController;
use yii\base\Module;
use yii\helpers\FileHelper;
use yii\helpers\VarDumper;
use yiiunit\TestCase;
use yii\console\controllers\MessageController;
/**
* Base for [[\yii\console\controllers\MessageController]] unit tests.
@ -31,20 +26,7 @@ abstract class BaseMessageControllerTest extends TestCase
if (!file_exists($this->sourcePath)) {
$this->markTestIncomplete('Unit tests runtime directory should have writable permissions!');
}
$this->configFileName = $this->generateConfigFileName();
}
/**
* Generate random config name.
*
* @return string
*/
protected function generateConfigFileName()
{
$this->configFileName = Yii::getAlias('@yiiunit/runtime')
. DIRECTORY_SEPARATOR . 'message_controller_test_config-' . md5(uniqid()) . '.php';
return $this->configFileName;
$this->configFileName = Yii::getAlias('@yiiunit/runtime/message_controller_test_config.php');
}
public function tearDown()
@ -61,7 +43,7 @@ abstract class BaseMessageControllerTest extends TestCase
*/
protected function createMessageController()
{
$module = $this->getMockBuilder('yii\\base\\Module')
$module = $this->getMockBuilder(Module::class)
->setMethods(['fake'])
->setConstructorArgs(['console'])
->getMock();
@ -94,9 +76,7 @@ abstract class BaseMessageControllerTest extends TestCase
unlink($this->configFileName);
}
$fileContent = '<?php return ' . VarDumper::export($config) . ';';
// save new config on random name to bypass HHVM cache
// https://github.com/facebook/hhvm/issues/1447
file_put_contents($this->generateConfigFileName(), $fileContent);
file_put_contents($this->configFileName, $fileContent);
}
/**
@ -155,7 +135,7 @@ abstract class BaseMessageControllerTest extends TestCase
public function testConfigFileNotExist()
{
$this->expectException('yii\\console\\Exception');
$this->expectException(\yii\console\Exception::class);
$this->runMessageControllerAction('extract', ['not_existing_file.php']);
}
@ -458,26 +438,6 @@ abstract class BaseMessageControllerTest extends TestCase
$this->language = $firstLanguage;
$this->assertArrayHasKey($mainMessage, $messages, "\"$mainMessage\" for language \"$secondLanguage\" is missing in translation file. Command output:\n\n" . $out);
}
/**
* @depends testCreateTranslation
*
* @see https://github.com/yiisoft/yii2/issues/13824
*/
public function testCreateTranslationFromConcatenatedString()
{
$category = 'test.category1';
$mainMessage = 'main message second message third message';
$sourceFileContent = "Yii::t('{$category}', 'main message' . \" second message\".' third message');";
$this->createSourceFile($sourceFileContent);
$this->saveConfigFile($this->getConfig());
$out = $this->runMessageControllerAction('extract', [$this->configFileName]);
$messages = $this->loadMessages($category);
$this->assertArrayHasKey($mainMessage, $messages,
"\"$mainMessage\" is missing in translation file. Command output:\n\n" . $out);
}
}
class MessageControllerMock extends MessageController

9
tests/framework/console/controllers/PHPMessageControllerTest.php

@ -85,13 +85,6 @@ class PHPMessageControllerTest extends BaseMessageControllerTest
return [];
}
if (defined('HHVM_VERSION')) {
// use eval() to bypass HHVM content cache
// https://github.com/facebook/hhvm/issues/1447
$content = file_get_contents($messageFilePath);
return eval(substr($content, strpos($content, 'return ')));
}
return require $messageFilePath;
}
@ -120,6 +113,6 @@ class PHPMessageControllerTest extends BaseMessageControllerTest
$content = file_get_contents($messageFilePath);
$head = substr($content, 0, strpos($content, 'return '));
$expected = "<?php\n/*file header*/\n/*doc block*/\n";
$this->assertSame($expected, $head);
$this->assertEqualsWithoutLE($expected, $head);
}
}

8
tests/framework/db/CommandTest.php

@ -143,10 +143,6 @@ abstract class CommandTest extends DatabaseTestCase
public function testBindParamValue()
{
if (defined('HHVM_VERSION') && $this->driverName === 'pgsql') {
$this->markTestSkipped('HHVMs PgSQL implementation has some specific behavior that breaks some parts of this test.');
}
$db = $this->getConnection();
// bindParam
@ -204,14 +200,12 @@ SQL;
$this->assertEquals($floatCol, $row['float_col']);
if ($this->driverName === 'mysql' || $this->driverName === 'sqlite' || $this->driverName === 'oci') {
$this->assertEquals($blobCol, $row['blob_col']);
} elseif (defined('HHVM_VERSION') && $this->driverName === 'pgsql') {
// HHVMs pgsql implementation does not seem to support blob columns correctly.
} else {
$this->assertInternalType('resource', $row['blob_col']);
$this->assertEquals($blobCol, stream_get_contents($row['blob_col']));
}
$this->assertEquals($numericCol, $row['numeric_col']);
if ($this->driverName === 'mysql' || $this->driverName === 'oci' || (defined('HHVM_VERSION') && in_array($this->driverName, ['sqlite', 'pgsql']))) {
if ($this->driverName === 'mysql' || $this->driverName === 'oci') {
$this->assertEquals($boolCol, (int) $row['bool_col']);
} else {
$this->assertEquals($boolCol, $row['bool_col']);

1
tests/framework/db/mysql/connection/DeadLockTest.php

@ -41,7 +41,6 @@ class DeadLockTest extends \yiiunit\framework\db\mysql\ConnectionTest
if (!function_exists('posix_kill')) {
$this->markTestSkipped('posix_kill() is not available');
}
// HHVM does not support this (?)
if (!function_exists('pcntl_sigtimedwait')) {
$this->markTestSkipped('pcntl_sigtimedwait() is not available');
}

4
tests/framework/db/pgsql/CommandTest.php

@ -79,10 +79,6 @@ class CommandTest extends \yiiunit\framework\db\CommandTest
*/
public function testSaveSerializedObject()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('HHVMs PgSQL implementation does not seem to support blob colums in the way they are used here.');
}
$db = $this->getConnection();
$command = $db->createCommand()->insert('type', [

5
tests/framework/helpers/FormatConverterTest.php

@ -45,11 +45,6 @@ class FormatConverterTest extends TestCase
*/
public function testPHPDefaultFormat()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('Can not test on HHVM because HHVM returns inconsistend with PHP date format patterns.');
}
foreach (FormatConverter::$phpFallbackDatePatterns as $format => $formats) {
foreach ($formats as $name => $expected) {
$expected = FormatConverter::convertDatePhpToIcu($expected);

2
tests/framework/mail/BaseMailerTest.php

@ -260,7 +260,7 @@ TEXT
$mailer->htmlLayout = false;
$mailer->textLayout = false;
$htmlViewName = 'test_html_view' . $i; // $i is needed to generate different view files to ensure it works on HHVM
$htmlViewName = 'test_html_view';
$htmlViewFileName = $this->getTestFilePath() . DIRECTORY_SEPARATOR . $htmlViewName . '.php';
file_put_contents($htmlViewFileName, $htmlViewFileContent);

3
tests/framework/rbac/DbManagerTestCase.php

@ -79,9 +79,6 @@ abstract class DbManagerTestCase extends ManagerTestCase
protected function setUp()
{
if (defined('HHVM_VERSION') && static::$driverName === 'pgsql') {
static::markTestSkipped('HHVM PDO for pgsql does not work with binary columns, which are essential for rbac schema. See https://github.com/yiisoft/yii2/issues/14244');
}
parent::setUp();
$this->auth = $this->createManager();
}

4
tests/framework/rbac/PhpManagerTest.php

@ -79,10 +79,6 @@ class PhpManagerTest extends ManagerTestCase
static::$time = null;
parent::setUp();
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('PhpManager is not compatible with HHVM.');
}
$this->mockApplication();
$this->removeDataFiles();
$this->auth = $this->createManager();

4
tests/framework/requirements/YiiRequirementCheckerTest.php

@ -134,10 +134,6 @@ class YiiRequirementCheckerTest extends TestCase
public function testCheckPhpExtensionVersion()
{
if (defined('HHVM_VERSION')) {
$this->markTestSkipped('Can not test this on HHVM.');
}
$requirementsChecker = new YiiRequirementChecker();
$this->assertFalse($requirementsChecker->checkPhpExtensionVersion('some_unexisting_php_extension', '0.1'), 'No fail while checking unexisting extension!');

4
tests/framework/web/MultipartFormDataParserTest.php

@ -14,10 +14,6 @@ class MultipartFormDataParserTest extends TestCase
{
public function testParse()
{
if (defined('HHVM_VERSION')) {
static::markTestSkipped('Can not test on HHVM because it does not support proper handling of the temporary files.');
}
$parser = new MultipartFormDataParser();
$boundary = '---------------------------22472926011618';

Loading…
Cancel
Save