#php #closures #anonymous-function
#php #замыкания #анонимная функция
Вопрос:
Я не уверен, как лучше всего это назвать, поэтому я подумал, что хотел бы опубликовать пример того, чего я пытаюсь достичь. На данный момент я очень упростил это.
Итак, сначала самый базовый класс, который будет выполнять действие.
abstract class AuditedSave extends AuditedSaveImplementation
{
public static function run($callback = null)
{
return new AuditedSaveImplementation($callback);
}
}
class AuditedSaveImplementation
{
public function __construct(Closure $closure)
{
echo ' - I ran before'; // point 1, $test = 0
$closure();
echo ' - i ran after!'; // point 2, $test = 1
}
}
Затем код, который его вызывает.
$test = 0;
AuditedSave::run(function() use ($test)
{
$test = 1;
});
Таким образом, между пунктами 1 и 2, как указано в комментариях, выполняется замыкание и устанавливает значение $test равным 1. Однако я хочу сохранить значение того, что передается в качестве первого параметра (в данном случае $test
), как копию того, что было во время вызова функции, которая всегда будет выполняться, затем закрытие изменяет его (это та часть, которая может быть переменной), а затем послевыполняется сравнение, и действия выполняются на основе различий, которые всегда будут выполняться.
Однако, чтобы сделать это, мне нужно иметь доступ к переменной $test в __construct()
методе AuditedSaveImplementation
, не зная, как она называется.
Возможно ли это вообще?
Комментарии:
1. Нет, область действия
$test
— это нечто совершенно иное, чемAuditedSaveImplementation::__construct
. Вам нужно переосмыслить все, что вы пытаетесь здесь сделать.2. Невозможно. Передать в другой класс с соответствующей логикой (например
getValue()
, и / илиgetOriginalValue()
) вместо простого замыкания. Также$test
всегда копируется в указанный вами код (ну, на самом деле это копирование при записи, но это не очень актуально). Его изменение не повлияет на исходную переменную.
Ответ №1:
Вы можете использовать метод класса ReflectionFunction getStaticVariables
, чтобы получить параметры, переданные closure via use
. Вот так:
class AuditedSaveImplementation
{
public function __construct(Closure $closure)
{
echo ' - I ran before'; // point 1, $test = 0
$closureReflection = new ReflectionFunction($closure);
$variables = $closureReflection->getStaticVariables();
var_dump($variables);
$closure();
echo ' - i ran after!'; // point 2, $test = 1
}
}
Но, как упоминалось в комментариях, вам следует переосмыслить, как вы это делаете.
Это не очень хороший подход. Попробуйте создать специальный класс, как было предложено в комментариях.
Комментарии:
1. Фу-у-у, это ужасное решение. Для этого должен быть разумный и простой интерфейс, а не перегибающее назад решение, которое зависит от деталей реализации. OP просто на неверном пути…
2. Я просто хотел показать, что это не невозможно. Что все, что передается в closure через
use
, будет преобразовано в статические переменные для замыкания и может быть извлечено с помощью отражения. Но я согласен, что автору нужно переосмыслить то, что он здесь делает.