0

我正在使用柠檬水-php。我的代码位于https://github.com/sofadesign/limonade

我遇到的问题是当我尝试运行时

class syscore {

    public function hello(){
        set('post_url',  params(0));
        include("./templates/{$this->temp}/fullwidth.tpl"); 
        return render('fullwidth');

    }

}

然后加载 fullwidth.tpl 并运行函数 fullwidth

全宽.tpl

<?php

global $post;
function fullwidth($vars){ 
    extract($vars);
    $post = h($post_url);

}

    print_r($this->post($post));    

?>

它似乎通过了,$post_url但我不能再次将它传递给print_r($this->post($post));

但是,当我尝试print_r($this->post($post))在全角函数中运行时,它说找不到该post()函数

我已经尝试了很多类似下面的东西

function fullwidth($vars){ 
        extract($vars);
        $post = h($post_url);
    print_r(post($post));
}

我尝试通过重新连接到 syscore

$redi = new syscore();
$redi->connection() <-- this works
$redi->post($post) <-- this does not

这是我的全班系统核心

class syscore {

    // connect
    public function connect($siteDBUserName,$siteDBPass,$siteDBURL,$siteDBPort, $siteDB,$siteTemp){
        for ($i=0; $i<1000; $i++) {
         $m = new Mongo("mongodb://{$siteDBUserName}:{$siteDBPass}@{$siteDBURL}:{$siteDBPort}", array("persist" => "x", "db"=>$siteDB));
        }

        // select a database
       $this->db = $m->$siteDB;
       $this->temp = $siteTemp;
    }

    public function hello(){
        set('post_url',  params(0));
        include("./templates/{$this->temp}/fullwidth.tpl"); 
        return render('fullwidth');

    }

    public function menu($data)
    {

        $this->data = $data;
        $collection = $this->db->redi_link;
        // find everything in the collection
        //print $PASSWORD;
        $cursor = $collection->find(array("link_active"=> "1"));

        if ($cursor->count() > 0)
        {
            $fetchmenu = array();
            // iterate through the results
            while( $cursor->hasNext() ) {   
                $fetchmenu[] = ($cursor->getNext());
            }
            return $fetchmenu;
        }
        else
        {
            var_dump($this->db->lastError());
        }
    }

    public function post($data)
    {

        $this->data = $data;
        $collection = $this->db->redi_posts;
        // find everything in the collection
        //print $PASSWORD;
        $cursor = $collection->find(array("post_link"=> $data));

        if ($cursor->count() > 0)
        {
            $posts = array();
            // iterate through the results
            while( $cursor->hasNext() ) {   
                $posts[] = ($cursor->getNext());
            }
            return $posts;
        }
        else
        {
            var_dump($this->db->lastError());
        }
    }

}
4

1 回答 1

0

看起来您在理解 PHP 在尝试呈现模板时所采用的执行路径时遇到了一些问题。让我们更深入地看看,好吗?

// We're going to call "syscore::hello" which will include a template and try to render it
public function hello(){
    set('post_url',  params(0));  // set locals for template
    include("./templates/{$this->temp}/fullwidth.tpl");  // include the template
    return render('fullwidth'); // Call fullwidth(array('post_url' => 'http://example.com/path'))
}

解决这个问题的诀窍是了解 PHP 包含是如何工作的。当你调用你include("./templates/{$this->temp}/fullwidth.tpl")的一些代码在 syscore 对象的范围内执行时,即:

global $post;

print_r($this->post($post));

fullwidth此时在全局范围内创建,但尚未调用。当render调用fullwidth时你不再在syscore范围内,这就是为什么你不能$this->post($post)在不触发错误的情况下放入。

好的,那我们怎么解决呢?很高兴你问。

  1. 我们可能会重构syscore::post为静态方法,但这需要syscore::db是静态的,并且总是返回相同的 mongodb 实例(单例模式)。您绝对不想Mongo为每个实例创建 1000 个syscore实例。

  2. 我们可以滥用框架。一个更糟糕的解决方案,但它会完成工作。

全宽.tpl

<?php

function fullwidth($vars){ 
    $post_url = ''; // put the variables you expect into the symbol table
    extract($vars, EXTR_IF_EXISTS); // set EXTR_IF_EXISTS so you control what is added.
    $syscore_inst = new syscore; 
    $post = h($post_url);
    print_r($syscore->post($post)); // I think a puppy just died.    
}

看第二种方式是一个完整的黑客,编写这样的代码可能意味着你不会得到提升。但它应该工作。

但是假设你想得到提升,你会写出好的、闪亮的代码。

// Note: Capitalized class name
class Syscore {
protected static $_db;

public static function db () {
    if (! static::$_db) {
        static::$_db = new Mongo(...);
    }
    return static::$_db;
}

// @FIXME rename to something more useful like "find_posts_with_link"
public static post($url) {
    $collection = static::db()->redi_posts;
    // find everything in the collection
    $cursor = $collection->find(array("post_link"=> $url));

    // Changed to a try-catch, since we shouldn't presume an empty find is
    // an error.
    try {
        $posts = array();
        // iterate through the results
        while( $cursor->hasNext() ) {   
            $posts[] = ($cursor->getNext());
        }
        return $posts;
    } catch (Exception $e) {
        var_dump($this->db->lastError());
    }
}

}

然后在您的全角函数中,我们不必做任何愚蠢的废话,将实例方法视为静态方法。

function fullwidth($vars){ 
    $post_url = ''; // put the variables you expect into the symbol table
    extract($vars, EXTR_IF_EXISTS); // set EXTR_IF_EXISTS so you control what is added.
    $post = h($post_url);
    print_r(Syscore::post($post)); // static method. \O/ Rainbows and unicorns.   
}
于 2012-09-06T06:56:03.130 回答