【问题标题】:php calling a non static method from a static methodphp从静态方法调用非静态方法
【发布时间】:2015-01-16 01:46:52
【问题描述】:

我在 Java 中阅读了一些关于此的问题,但我在 PHP 中找不到我正在寻找的内容 - 尽管这些问题非常接近: php static methods question
Call method non-static with static in PHP

是否可以从静态中调用非静态方法?

我有一个如下的会话类(由 session::init() 调用),但我不知道如何避免收到错误消息。

<?php 
class session {

    public static function init(){
    if (**QUERY HERE**_is_session_started() === FALSE ) {
//      if (session_status() == PHP_SESSION_NONE) {
            @session_start();   
        }   else {
            echo "Session already started<br/>";
        }
    }   


private function _is_session_started() {
    if ( php_sapi_name() !== 'cli' ) {
        if ( version_compare(phpversion(), '5.4.0', '>=') ) {
            return session_status() === PHP_SESSION_ACTIVE ? TRUE : FALSE;
        } else {
            return session_id() === '' ? FALSE : TRUE;
        }
    }
    return FALSE;
}

}

我只希望 _is_session_started 函数被 init() 函数调用 - 所以它不需要是静态的或公共的 - 但我不确定如何引用它。

如果我将 QUERY HERE 替换为 'self::' 页面加载,但我收到此错误:

 PHP Strict Standards:  Non-static method session::_is_session_started() should not be called statically in /Applications/MAMP/htdocs/mvc/libs/session.php on line 5

但如果我尝试使用 $this->_is_session_started() 非静态地引用该方法,则会收到致命错误,因为静态 init() 函数尚未实例化会话类。

所以我认为必须有另一种方法来做到这一点。我可以将 _is_session_started 方法设为静态,或者只是让我的 init 函数更长,但我很想知道为什么会这样。

谢谢

【问题讨论】:

标签: php oop static


【解决方案1】:

想要从静态方法调用非静态方法没有任何意义。要调用非静态方法,您需要一个对象实例。当您静态调用方法时,您没有对象实例。我希望差异很明显。

非静态方法的关键在于它们可以访问特定于实例的数据:

class Foo {

    public $bar;

    public function baz() {
        echo $this->bar;
    }

}

$a = new Foo;
$b = new Foo;

$a->bar = 'Hello';
$b->bar = 'World';

$a->baz();
$b->baz();

$this 关键字是这里的特殊调味料。由于静态方法中没有对象实例,即没有$this,因此不能调用非静态方法:

Foo::baz();  // now what?

如果你的函数使用$this 并且需要一个对象实例,你不能静态调用它。如果您的函数不使用 $this 并且不需要对象实例,请将其设为 static 并静态调用它。

【讨论】:

  • 听起来答案是不可能的。这很有趣,而且我理解其中的逻辑。如果可能的话,我本来想分解我的静态方法,但我不得不接受将它们全部合并到一个方法中。
  • 我不是这么说的。如果您的方法是静态的(即它不使用$this),则静态调用它(即self::foo()并用static 关键字标记它。
【解决方案2】:

您必须将方法_is_session_started 声明为静态。

private static function _is_session_started() {

然后调用它

self::_is_session_started();

【讨论】:

  • 静态函数不必公开。如果静态函数只应该由类本身(从其他公共静态函数)内部调用,它们不应该是公共的。
  • 谢谢,但我提到我可以更改它以在原始帖子中静态声明它 - 我正在查询,因为我只想从 init 方法中调用第二个方法(我永远不会做 session::_is_session_started) 所以我试图找到最好的方法。
  • 对不起,我没有读到。正如 dceze 提到的,您还可以将静态方法声明为私有。所以你可以用self::_is_session_started来调用它。
  • 这给了我一个严格的错误,即不应该静态调用非静态方法......
  • 你必须声明它static private
猜你喜欢
  • 1970-01-01
  • 2016-10-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多