I have a render function that looks like:
function render($template, $values = array()){
// if template exists, render it
if (file_exists("../views/$template")){
// extract variables into local scope
extract($values);
// render header_form
require("../views/header_form.php");
// render template
require("../views/$template");
// render footer
require("../views/footer_form.php");
}else{
// else err
trigger_error("Invalid template: $template", E_USER_ERROR);
}
}
Suppose I have a script crew.php that looks like this:
<?php
require('../includes/config.php');
$values=[];
$today = new DateTime();
render('crew_form.php',$values);
?>
Why don't I have access to $today in crew_form.php? For instance, if crew_form.php was:
<?php
echo $today;
?>
When you use require doesn't that just add the script to the existing code? Is it because of local scope of the function render()?
You don't have access to $today
because you're out of scope. The variable is defined outside a function, and is not available inside it -- and render()
is a function.
You can obviate the problem with the use
keyword, or by abusing the global
directive, but a better way to avoid polluting the scope would be passing the variables explicitly and reading them with extract().
Which is exactly what your code was attempting doing, using $values
. But you need to put $today
inside $values
and pass it to render()
:
$values['today'] = $today;
Now, a variable called $today
will be available in crew-form.php, but it will not be the same $today
even if it will start as a copy of the same value. You can see it better like this:
$values['today2'] = $today;
Inside crew-form.php, $today2
will exist, $today
will not, because the latter is "out of scope".
Changes to the extracted values will be lost upon exit from render
(you can use EXTR_REFS but that adds complications).