Zend Framework — Изменилось ли поведение `$ this` в области видимости с PHP 5.3.29 на 5.5.24?

Короткий вопрос: повлияло ли поведение $this в области изменения с PHP 5.3.29 до 5.5.24? Я не мог найти какие-либо соответствующие изменения в PHP 5 Changelog.

Подробности:
В этот вопрос, Я думал, что у меня есть решение для моей проблемы (В PHPUnit ожидайте вызова метода с массивом в качестве аргумента). Это было мое решение

public function test_actionUpload_v10MasterdataFile()
{
/*
* Create a stub to disable the original constructor.
* Exposing data and rendering are stubbed.
* All other methods behave exactly the same as in the real Controller.
*/
$sut = $this->getMockBuilder('MasterdataController')
->setMethods(array('exposeAndSaveDataLines', 'render'))
->disableOriginalConstructor()
->getMock();

$sut->expects($this->once())
->method('exposeAndSaveDataLines')
->will($this->returnCallback(function($lines) {
$expectedLines = include ($this->dataDir() . 'ExpectedLines.php');
PHPUnit_Framework_Assert::assertTrue($this->similar_arrays($lines, $expectedLines));
}));

// Execute the test
$sut->actionUpload();
}

Он работает в моей локальной среде (PHP 5.5.24, Zend Engine v2.5.0), но когда я копирую код на наш тестовый сервер (PHP 5.3.29, Zend Engine v2.3.0), это не работает из-за эта строка:

$expectedLines = include ($this->dataDir() . 'ExpectedLines.php');

Ошибка:

Using $this when not in object context

Может ли это быть из-за версии PHP, или я должен искать в другом месте причину сбоя на одном сервере, а не на другом?

0

Решение

Причина в том, что в этот момент вы изменили рамки. Я не уверен, что изменилось, но ваш код должен не работать, по крайней мере, как правила области видимости PHP. Ниже ваш код вокруг проблемы:

$sut->expects($this->once())
->method('exposeAndSaveDataLines')
->will($this->returnCallback(function($lines) {
$expectedLines = include ($this->dataDir() . 'ExpectedLines.php');
PHPUnit_Framework_Assert::assertTrue($this->similar_arrays($lines, $expectedLines));
}));

Внутри returnCallback функционально, вы все еще технически «внутри» класса, но вам нужно Импортировать переменные из внешней области видимости (это поведение в PHP отличается от других языков, таких как Javascript, которые не требуют этого). Вот как это должно работать:

$self = $this; // Not necessary after PHP 5.4 where you can just use($this)
$sut->expects($this->once())
->method('exposeAndSaveDataLines')
->will($this->returnCallback(function($lines) use($self) {
$expectedLines = include ($self->dataDir() . 'ExpectedLines.php');
PHPUnit_Framework_Assert::assertTrue($self->similar_arrays($lines, $expectedLines));
}));
1

Другие решения

Да, в 5.4 есть важное различие:

  • Добавлено закрытие $ этой поддержки назад.

Значение в 5.3, $this внутри анонимной функции ничего не упоминалось, окружающий контекст не сохранялся. 5.4 добавлена ​​поддержка этого (назад), поэтому $this внутри анонимной функции относится к $this из окружающего контекста. Обходной путь раньше был:

$_this = $this;
function () use ($_this) {
$_this->foo();
};
2

По вопросам рекламы [email protected]