PHP defines the scope for the included file

I have quite a few PHP view files that I used to include in my controllers using simple include statements. They all use the methods declared in the view class, which they get as $ view-> method (); However, I recently decided that it would be better if inclusion were also made by this class of views. This, however, changes the volume of the included file, so $ view is no longer defined. Here is a sample code:

in someViewFile.php (BOTH siuations) <html> <head><title><?php echo $view->getAppTitle(); ?></title> etc. OLD SITUATION in controller: $view = new view; include('someViewFile.php'); //$view is defined in someViewFile.php NEW SITUATION in controller: $view = new view; $view->show('someViewFile'); //$view is not defined in someViewFile.php 

Right now I have hacked my way around the problem using this in a view class:

 public function show($file){ $view = &$this; include($file.".php"); } 

Is it possible to declare a file attachment area or is this the best way to solve the problem?

These examples are not very simplified.

+4
source share
7 answers

You cannot change the scope of include (), no, so your method is probably as good as in the situation you are describing. Although I would have missed the ugly ampersand PHP4-compat myself.

+1
source

Here is a simplified but functional presentation class that I've seen quite a lot, and am using quite a lot.
As you can see in the code below: you create a view with the name of the template file.
Client code, possibly a controller, can send data to a view. This data can be of any type in which you need other types. Nested views will automatically be displayed when the parent is rendered.
Hope this helps.

 // simple view class class View { protected $filename; protected $data; function __construct( $filename ) { $this->filename = $filename; } function escape( $str ) { return htmlspecialchars( $str ); //for example } function __get( $name ) { if( isset( $this->data[$name] ) { return $this->data[$name]; } return false; } function __set( $name, $value ) { $this->data[$name] = $value; } function render( $print = true ) { ob_start(); include( $this->filename ); $rendered = ob_get_clean(); if( $print ) { echo $rendered; return; } return $rendered; } function __toString() { return $this->render(); } } 

Using

 // usage $view = new View( 'template.phtml' ); $view->title = 'My Title'; $view->text = 'Some text'; $nav = new View( 'nav.phtml' ); $nav->links = array( 'http://www.google.com' => 'Google', 'http://www.yahoo.com' => 'Yahoo' ); $view->nav = $nav; echo $view; 

Patterns

 //template.phtml <html> <head> <title><?php echo $this->title ?></title> </head> <body> <?php echo $this->nav ?> <?php echo $this->escape( $this->text ) ?> </body> </html> //nav.phtml <?php foreach( $this->links as $url => $link ): ?> <a href="<?php echo $url ?>"><?php echo $link ?></a> <?php endforeach ?> 
+11
source

What am I doing (I don’t know how good it is) just

 extract($GLOBALS); include $view.".php"; 

Of course hell

Hooray!

+1
source

An even more simplified version of the View class:

 Class View { protected $filename; function __construct($filename){ $this->filename = $filename; } function display(){ global $session; //put global variables here include Cfg::ROOT . '/views/' . $this->filename; } function assign($key, $val){ $this->$key = $val; } } 

In the controller:

 $view = new View('homepage.php'); $view->assign('page_title',$page_title); //assign all needed variables from controller $view->display(); 

In the template / view file:

 echo $this->page_title; 
+1
source

Perhaps this is due to my php settings or something, but if I include the file inside the function, the included file will have the scope of this function.

 $a = 1; // This variable isn't visible for the included file function render() { $b = 2; // This variable is include('template.php'); } // ---------------------------------------- // template.php <html> <body> <?=$a?> // wont show <?=$b?> // will show </body> </html> 

I think I would go with something like this:

 function render($template, $variables) { extract($variables); include($template); } 

Using:

 render('templates/mytemplate.php', array(a=>1, b=>2)); 
0
source

An extension of what Quano offers:

Take it one step further and include the variables in the global execution area (which otherwise would have to be called with global internal include elements). The idea is that you want the inclusion function to work as if it were included in your main application area or your definition area.

Consider this class:

 class PHPInclude { private static $globalsList = array( 'GLOBALS','_SERVER','_GET','_POST','_FILES', '_REQUEST','_SESSION','_ENV','_COOKIE' ); public static function phpInclude($file,$variables=array()) { if ( file_exists($file) ) { $globs = array(); foreach ( $GLOBALS as $key => $value ) { if ( !in_array($key,sefl::$globalsList) ) { array_push($globs,$key); } } foreach ( $globs as $key ) { global $$key; } foreach ( $variables as $variable ) { global $$variable; } unset($globs,$key,$value); ob_start(); include $file; return ob_get_clean(); } return ''; } } 

Use it as follows:

 $foo = 'bar'; function testScope() { $woo = 'sah'; PHPInclude::phpInclude('file.phtml',array($woo)); } 

In the example, $foo will be automatically turned on because it is in the global scope, and $woo added because it is in the local scope.

I have not tested $this as an arbitrary variable, but my spider feelings tell me it will not work (warning) .

0
source

You can send get_defined_vars () as a parameter to the view function. This creates an array containing all the defined variables in the current scope. In your "view" method, you will call PHP "extract" in the resulting array.

-1
source

All Articles