【问题标题】:PHP - rendering templatePHP - 渲染模板
【发布时间】:2013-07-11 14:22:15
【问题描述】:

我有这段代码来渲染一个模板(我是 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));;
        }

    }

【问题讨论】:

  • 你能包含这些函数所属的整个类吗?您在一个类中拥有这些函数对吗?
  • @CaseyFlynn 我已经更新了整个班级
  • 尝试附加 var_dump($this->_template);分配后查看 new Template($controller,$action); 返回什么对象
  • @CaseyFlynn 不 new 总是要么返回一个对象,要么抛出一个异常?
  • 我们需要了解更多关于验证的信息

标签: php soap


【解决方案1】:

来自 PHP 文档:

一旦没有对特定对象的其他引用,或在关闭序列期间以任何顺序,将立即调用析构函数。

请注意,当析构函数由于脚本结束而运行时,它们可能会以任何顺序运行,这可能会给您留下对已经被析构的对象的引用。它没有明确记录,但这意味着您无法从析构函数安全地访问其他对象,因为它们可能不再存在。

这里可能发生的是 Template 对象首先被销毁,导致当您尝试从 Controller 析构函数访问它时出现错误。这也可以解释为什么它适用于某些机器而不适用于其他机器 - 因为销毁顺序是未定义的,并且在不同机器之间可能会有很大差异。

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

...或者当到达脚本末尾并且 PHP 结束请求时。后一种情况很微妙,因为您依赖于一些可能已经调用了析构函数并且不再可访问的对象。因此,请谨慎使用它,不要依赖析构函数中的其他对象。


解决这一切的真正方法是在你的析构函数中不包含这种类型的功能。在脚本末尾手动调用 renderHTML() 之类的方法会更简洁,而不是自动发生一些隐藏行为。

有关详细信息,请参阅这些其他问题:

如果您真的需要它自动发生,我建议您改为查看register_shutdown_function()。您可以将Controller 析构函数更改为名为@9​​87654331@ 之类的常规方法,并通过将此行放入构造函数中注册以使该方法在关闭时自动运行:

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

其中的array() 是在PHP 中指定callback method 的方法之一。

【讨论】:

  • 嗨,我已经添加了整个班级,有什么想法吗?
  • @jcansyi 有关如何解决此问题的任何想法?我不确定我是否遵循您的回答,因为我对 PHP 很陌生。
  • @germainelol 真正的解决方案是不要将析构函数用于这样的事情。我已经更新了答案的结尾,以扩展您的其他一些选项。
猜你喜欢
  • 2010-11-30
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 2017-03-24
  • 2012-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多