2013-07-12 243 views
1

我有这样的代码来渲染一个模板(我是新来的PHP所以多多包涵)PHP - 渲染模板

function __destruct() 
    { 
     /* 
     * It's render the template 
     * 
     */ 
      $this->_template->render(); 
    } 

与此错误:

Fatal error: Call to a member function render() on a non-object in /opt/lampp/htdocs/soap/php/library/controller.class.php on line 73

这是构建

function __construct($model, $controller, $action) 
    { 
     /* 
     * A default constructor which creates objects of the template and model 
     * @param string model, controller and action. 
     * @return 
     */ 

     $this->_controller = $controller; 
     $this->_action = $action; 
     $this->_model = $model; 

     $this->$model = new $model; 
     $this->_template = new Template($controller,$action); 

    } 

让我知道你是否认为我应该增加更多。我是PHP的新手,并试图让这个应用程序工作。任何想法欢迎!

更新:全班

<?php 
/* 
* 
* controller.class.php - Controller class will be used as the base class 
*      for all our controllers 
* 
* 
* The above class is used for all the communication between the controller, 
* the model and the view (template class). It creates an object for the 
* model class and an object for template class. The object for model class 
* has the same name as the model itself 
* 
* 
* We are not including the ?\> to avoid injection of any extra whitespaces in our output. 
* 
* 
*/ 
class Controller extends Validation 
{ 

    protected $_model; 
    protected $_controller; 
    protected $_action; 
    protected $_template; 


// ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* 


    function __construct($model, $controller, $action) 
    { 
     /* 
     * A default constructor which creates objects of the template and model 
     * @param string model, controller and action. 
     * @return 
     */ 

     $this->_controller = $controller; 
     $this->_action = $action; 
     $this->_model = $model; 

     $this->$model = new $model; 
     $this->_template = new Template($controller,$action); 

    } 


// ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* 


    function set($name,$value) 
    { 
     /* 
     * Set the variables from the controller to the template as a variables. 
     * @param string name,value 
     * @return 
     */ 
     $this->_template->set($name,$value); 
    } 


// ~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~*~* 


    function __destruct() 
    { 
     /* 
     * It's render the template 
     * 
     */ 
      $this->_template->render(); 
    } 


} 

验证类:

<?php 
/* 
* 
* pdoconnectionclass.php - Validation is used to validate any input data to the website 
* 
* 
* The above class is used for checking every data that are the user wrote it and are going 
* to be stored in the database. For each type of input there is an appropriate function 
* to check it before is going to be store in the database. 
* 
* 
* We are not including the ?\> to avoid injection of any extra whitespaces in our output. 
* 
* 
*/ 

    class Validation 
    { 

     public function isEmpty($check_var) 
     { 
     /** Check if the input value is empty or not 
     * If is empty then return true back on the main program 
     * else return false 
     */ 

      if (empty($check_var)){ 
       return true; 
      } 
      else 
      { 
       return false; 

      } 

     } 


     public function isInt($check_var) 
     { 
     /** Check if the input value is integer 
     * and if Yes then return false else if not and is not int return false 
     */ 
      if (is_int($check_var)) { 
       return true; 
      } 
      else 
      { 
       return false; 

      } 

     } 

     public function isPositive($check_var) 
     { 
     /** Check if the input value is positive 
     * and if Yes then return false else if not and is not int return false 
     */ 
      if ($check_var > 0) 
      { 
       return true; 
      } 
      else 
      { 
       return false; 

      } 

     } 

     public function checking_phone($check_var) 
     { 
     /** Check if the input value is a phone 
      Check if the if the characters of $check_var 
      are equal to 14 if the value has 0044 or if are 11 
      if they start from 07. Then check if is positive 
      and then removes the 0 from 07 and adds 44 at the beginning 
     */ 
      if (strlen($check_var) == 11) 
      { 
       if ($this->isPositive($check_var) == true) 
       { 
        if (($check_var >= '07000000000') && ($check_var <= '07999999999')) 
        { 
         $temp_phone = "44"; 
         $temp_phone .= substr($check_var, 1); 
         return $temp_phone; 
        } 
        else 
        { 
         return false; 
        } 
       } 
       else 
       { 
        return false; 
       } 
      } 
      else if (strlen($check_var) == 14) 
      { 
       if ($this->isPositive($check_var) == true) 
       { 
        if (($check_var >= '00447000000000') && ($check_var <= '00447999999999')) 
        { 
         $temp_phone = substr($check_var, 2); 
         return $temp_phone; 
        } 
        else 
        { 
         return false; 
        } 
       } 
       else 
       { 
        return false; 
       } 

      } 
      else if (strlen($check_var) == 12) 
      { 
       if ($this->isPositive($check_var) == true) 
       { 
        if (($check_var >= '447000000000') && ($check_var <= '447999999999')) 
        { 
         return $check_var; 
        } 
        else 
        { 
         return false; 
        } 
       } 
       else 
       { 
        return false; 
       } 

      } 
      else 
      { 
       return false; 
      } 

     } 


     public function checkforXSS($check_var) 
     { 
     /** Gets the input value and prevents HTML from being embedded, 
      and therefore prevents JavaScript embedding as well. 
      Return a safe versions of the input.  
      The htmlentities() function converts both double and single 
      quotation marks to entities and the text to ASCII compatible multi-byte 8-bit Unicode. 
     */ 
      htmlentities($check_var, ENT_QUOTES, 'utf-8'); 
      return $check_var; 
     } 



     public function filter_var_int($var) 
     { 
     /** Filters a variable with the specified filter. 
     */ 
      return filter_var($var, FILTER_SANITIZE_NUMBER_INT); 
     } 


     public function filter_var_string($var) 
     { 
     /** Filters a variable with the specified filter. 
     */ 
      return filter_var($var, FILTER_SANITIZE_STRING); 
     } 


     public function filter_var_email($var) 
     { 
     /** Filters a variable with the specified filter. 
     */ 
      $temp = ''; 
      $temp = filter_var($var, FILTER_SANITIZE_EMAIL); 
      $temp = filter_var($temp, FILTER_VALIDATE_EMAIL); 
      return $temp; 
     }  

     public function create_salt_password($username) 
     { 
     /** Creates a hash value for the password using 
      a prefixed random unique identifier value with a static characters and the username 
     */ 
      $salt = hash('sha256', uniqid(mt_rand(), true) .AUTH_SALT .strtolower($username)); 
      return $salt; 
     } 

     public function get_activation_code() 
     { 
     /** Creates an activation code for the user 
     */ 
      return md5(uniqid(rand(), true));; 
     } 

    } 
+0

你能否包括这些功能所属的全部类?你在班上有这些功能吧? –

+0

@CaseyFlynn我已经更新了整个类 – germainelol

+0

尝试追加var_dump($ this - > _ template);分配给它以查看新模板返回的对象($ controller,$ action); –

回答

0

从PHP文件:

The destructor method will be called as soon as there are no other references to a particular object, or in any order during the shutdown sequence.

注意,当析构函数运行的结果你脚本结尾,它们可以以任何顺序运行,这可能会让您引用已经存在的对象被破坏了。它没有清楚的记录,但这意味着你不能安全地从析构函数中访问其他对象,因为它们可能不再存在。

这里可能发生的情况是,Template对象首先被破坏,导致出现错误,然后尝试从您的Controller析构函数访问它。这也解释了为什么它可以在一些机器上运行,而不是其他机器 - 因为销毁顺序是不确定的,并且可能在不同的机器之间有很大差异。

这个问题似乎并没有明确记载,但根据this random page,你不是第一人遇到这样的问题:

...or when the end of the script is reached and PHP ends the request. The latter situation is delicate because you are relying on some objects that might already have had their destructors called and are not accessible anymore. So, use it with care, and don’t rely on other objects in your destructors.


真正解决这一切都是为了在你的析构函数中没有这种类型的功能。如果您在脚本结尾处手动调用renderHTML()方法,而不是自动发生某些隐藏行为,那么这种方法会更清晰。

看到这些其他问题的更多细节:

如果你真的需要它自动发生,我建议你寻找到register_shutdown_function()代替。您可以通过把这个线在构造函数中Controller析构函数改为名字类似renderHTML一个普通的方法,并注册自动拥有该方法运行在关机:

register_shutdown_function(array($this, 'renderHTML')); 

array()中存在的方式,以一个在PHP中指定一个callback method

+0

嗨我已经添加了整个班级,有什么想法? – germainelol

+0

@jcansyi关于如何解决这个问题的任何想法?因为我对PHP很陌生,所以我不确定是否遵循了您的答案。 – germainelol

+0

@germainelol真正的解决方案是不使用这样的析构函数。我已经更新了我的答案的结尾,以扩展一些其他选项。 – jcsanyi