PHP函数里面包含一个类函数

时间:2012-09-06 01:50:53

标签: php class function

我需要一些柠檬水-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

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

但是,当我尝试在fullwidth函数中运行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

这是我的全班syscore

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());
        }
    }

}

1 个答案:

答案 0 :(得分: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为静态,并始终返回SAME mongodb实例(单例模式)。您绝对不希望为每个Mongo实例创建1000个syscore个实例。

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

  3. fullwidth.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.    
    }
    

    看第二种方式是完全破解,编写这样的代码可能意味着你不会被提升。但它应该有用。

    但是,假设你想要升职,那么你就可以制作出优秀而有光泽的代码。

    //注意:大写的类名 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.   
    }