Последние пару часов я гуглил, пытаясь понять, как это сделать. Я просто хочу прояснить, что моя проблема не Эта проблема или же этот вопрос, потому что я не пытаюсь проверить внутри скрипт, если переменные установлены. Я пытаюсь проверить вне это, чтобы увидеть, если они установлены / переданы во включенный файл до они интерпретируются или, по крайней мере, содержательно интерпретируются до такой степени, что возникает ошибка. Позволь мне объяснить.
Я создаю пакет утилит для внутреннего пользования в компании, в которой я работаю. Я выбрал рендеринг шаблонов одним из двух способов: включить их или вывести выведенную строку.
public function render($context = array()) {
do_action(self::TAG_CLASS_NAME.'_render_view', $this, $context);
if ( empty( $this->html ) ) {
ob_start();
$this->checkContext($context);
extract( $context );
require_once $this->getFullPath();
$renderedView = ob_get_contents();
ob_end_clean();
$this->html = $renderedView;
return $renderedView;
} else {
return $this->html;
}
}
public function includeView($context = array()) {
do_action(self::TAG_CLASS_NAME.'_include_view', $this, $context);
extract( $context );
include $this->getFullPath();
}
Внутри render
метод, я начинаю некоторую буферизацию вывода. Это позволяет интерпретатору оценить код и вывести HTML в виде строки (без eval()
удар. В своих модульных тестах я экспериментировал с тем, что произойдет, если я пропущу context
это было внутри самого шаблона. Например: если у меня есть context
массив, который выглядит как:
$context = array(
'message' => 'Morning'
);
И связанный шаблон, который выглядит так:
<?php echo "Hello ".$name."! Good ".$message; ?>
Или это
<p>Hello <?php echo $name; ?>! Good <?php echo $message; ?></p>
Неважно, как это отформатировано, пока context
переменные передаются ему правильно. Во всяком случае, опуская $name
в context
приведет к "Undefined variable: $name"
E_NOTICE сообщение. Что имеет смысл. Как «захватить» эту неопределенную переменную до того, как она создаст уведомление?
Я пытался использовать:
$rh = fopen($this->getFullPath(), 'r');
$contents = fread($rh, filesize($this->getFullPath()));
fclose($rh);
куда $contents
выходы:
"<?php echo sprintf("Hello %s, Good %s.", $name, $greeting); ?>"
Следующий логический шаг (во всяком случае, для меня, таким образом, вопрос) состоит в извлечении переменных в этой строке. Поэтому я вкратце приступил к созданию регулярного выражения для сопоставления с этой строкой и захвата переменных, но в итоге оказался здесь, потому что чувствовал, что дублирую работу. Я имею в виду, что интерпретатор PHP уже делает это эффективно, поэтому должен быть способ использовать встроенную функциональность. Может быть?
Все это, чтобы сказать, я хочу сделать что-то похожее на этот код псевдо:
protected function checkContext($context) {
require $filename;
$availVars = get_defined_vars()
if ( $availVars !== $context ) {
setUnDefinedVar = null
}
}
Сказав это, это может даже не быть правильным способом сделать это, но что есть? Позволить ли интерпретатору завершиться с ошибкой для неопределенной переменной при включении файла? Если я позволю этому потерпеть неудачу, я подвергаю себя любым уязвимостям безопасности? Замечания: Я не устанавливаю никаких переменных в шаблонах через $_GET
или же $_POST
,
Любые ответы очень ценятся. Спасибо заранее
Я рекомендую использовать геттеры и сеттеры в вашем классе. Возможно, есть лучшее решение, но я так и делаю. Поскольку вы пытаетесь получить доступ к переменным в глобальной области видимости, вы должны добавить следующий метод в класс, вызывающий включенный файл:
public function __get($variable)
{
if (array_key_exists( $variable, $GLOBALS ))
return $GLOBALS[$variable];
return null;
}
Так что теперь во включенном файле вы будете обращаться к переменным с помощью
$ Это -> {$ имяПеременной}
В вашем конкретном случае это будет выглядеть так …
<?php echo "Hello ".$this->name."! Good ".$this->message; ?>
Тем не менее, обратите внимание: если запрашиваемая переменная определена в области видимости вызывающего класса, то эта конкретная переменная-член будет возвращена. Ни один не определен в глобальной области.
Лучшее объяснение этого оператора перегрузки можно найти здесь Магические методы PHP
Других решений пока нет …