PHP dahil dosyanın kapsamını tanımlamak

5 Cevap php

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

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

Şu anda ben görünümü sınıfında bu kullanarak soruna yolumu kesmek:

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

Inluded dosyanın kapsamını beyan için yine de var mı yoksa bu sorunu çözmenin en iyi yolu nedir?

Bu örnekler kapalı kaba basitleştirilmiş.

5 Cevap

Sen değiştiremezsiniz include () kapsam, hayır, bu yüzden yöntem muhtemelen sizin tarif ettiğiniz durum alır gibi yaklaşık olarak iyidir. Ben çirkin PHP4-compat imi, kendimi atlamak istiyorum ama.

Here' a simplified but functional view class that I've seen around quite a lot and use quite a lot.
As you can see in the code below: you instantiate a view with the filename of the template file.
The client code, probably a controller, can send data into the view. This data can be of any type you need even other views.
Nested views will be automatically rendered 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();
    }
}

Kullanım

// 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;

Şablonları

//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 ?>

I ne (i ne kadar tamam bilmiyorum) basitçe

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

Tabii cehennem işleri gibi

Şerefe!

Belki de bu benim php-ayarlarıyla falan ile ilgisi var, ama ben dosyayı dahil bir fonksiyonu içinde bir dosya eklerseniz, yalnızca bu işlevin değişkenlerinin kapsamını sahip olacak.

$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>

Ben böyle bir şey ile gitmek istiyorum düşünüyorum:

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

Kullanımı:

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

Quano sunabileceği ne genişletilmesi:

Bir adım daha ileri götürün ve (aksi takdirde include internals küresel ile çağrılacak olurdu) yürütme genel kapsam değişkenleri dahil. Fikir o ana uygulama kapsamında, ya da bir tanım kapsamına sanki çalışmak dahil istiyor.

Bu sınıf düşünün:

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 '';
    }
}

Aşağıdaki gibi kullanın:

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

Küresel kapsam içinde olan ve yerel kapsamında olduğundan $woo eklenir beri örnek otomatik olarak $foo içerecektir.

I $this rasgele değişken olarak test etmedim, ama benim örümcek hislerim it won't work (warning) söyle.