PHP: Comment mettre en œuvre une méthode semblable à __get pour les variables de la fonction locale
Question
Je ne suis pas étranger à __get (), et ont utilisé pour faire des bibliothèques très pratique dans le passé. Cependant, je suis confronté à un nouveau défi (PHP 5.3, abrégé et simplifié mon code pour cette question):
<?php
namespace test;
class View {
function __construct($filename, $varArray) {
$this->filename = $filename;
$this->varArray = $varArray;
}
function display() {
include($this->filename);
}
function __get($varName) {
if (isset($this->varArray[$varName]))
return $this->varArray[$varName];
return "?? $varname ??";
}
}
?>
Au-dessus est un système très, très simplifié pour le chargement d'une vue. Ce code appellerait la vue et l'afficher:
<?php
require_once("View.php");
use test\View;
$view = new View("views/myview.php", array("user" => "Tom"));
$view->display();
?>
Mon objectif pour ce code est de permettre la vue « myview.php » pour contenir le code comme ceci:
<p>
Hello <?php echo $user; ?>! Your E-mail is <?php echo $email; ?>
</p>
Et, utilisé avec le code ci-dessus, ce serait sortie "Bonjour Tom! Votre adresse e-mail est ?? mail ??"
Cependant, cela ne fonctionnera pas. La vue est inclus dans une méthode de classe, alors quand il fait référence à $ utilisateur et $ email, il cherche des variables de fonction locales - pas des variables appartenant à la classe View. Pour cette raison, __get ne se déclenche.
Je pourrais changer toutes les variables de mon point de vue à des choses comme $ this-> utilisateur et $ this-> email, mais ce serait un désordre et d'une solution unintuitive. J'aimerais trouver un moyen où je peux faire référence à des variables directement, sans avoir PHP jeter une erreur quand une variable non définie est utilisée.
Pensées? Est-il un moyen propre à faire, ou suis-je obligé de recourir à des solutions aki?
La solution
Editing ma réponse . Abit d'un « hack autour », mais une solution potentielle. Peut vouloir « reset » error_handler à la fonctionnalité plus générique.
view.php
<?php
error_reporting(E_ALL);
ini_set("display_errors", 0);
class View {
function display($file, $values) {
set_error_handler(array($this, '__get'), E_NOTICE);
extract($values);
include($file);
}
function __get($vaule)
{
echo '<i>Unknown</i>';
}
}
$View = new View;
$values = array('user' => 'Tom',
'email' => 'email@host.com');
$View->display('/filename.php', $values);
?>
filename.php
Hello <?php echo $user; ?>, your email is <?php echo $email; ?> and your are <?php echo $age; ?> years old.
Sortie
Hello Tom, your email is email@host.com and your are
Unknown years old.
Autres conseils
Vous pouvez utiliser extrait pour tirer toutes les variables dans l'environnement local:
function display() {
extract($this->varArray);
include($this->filename);
}