【问题标题】:Is it incorrect to create a new instance of a class with a static method on it? [closed]使用静态方法创建类的新实例是否不正确? [关闭]
【发布时间】:2013-05-31 08:02:20
【问题描述】:

我只是想知道在 PHP 中使用静态方法。我有一个具有公共静态方法的类。

class Dog{
  public static function sound(){
     $bark = "WOOF!";
     return $bark;
  }
}

$new = new Dog(); 
$new->sound();

它返回一个致命错误。 所以当我打电话给这堂课时。我创建了一个新实例,然后调用它,但它给了我一个错误。它所指的对象是什么?什么是非对象?

谢谢。

更新: 致命错误:调用非对象上的成员函数

【问题讨论】:

  • return 中没有s
  • 你得到什么错误?
  • 据我所知,您的代码触发的唯一错误应该是“Parse error: syntax error, unexpected '$bark' (T_VARIABLE)”,它与 OOP 无关。您能澄清一下您在修复错字时遇到的错误吗?
  • Cannot reproduce。关于$new 不是对象的错误投诉!
  • 这是整个代码吗?我也无法重现您的错误。

标签: php function static


【解决方案1】:

您将访问您的静态方法:

Dog::sound();

如果您没有将 sound() 方法设为静态,那么它将是:

$dog = new Dog();
$dog->sound();

所以你的代码可能是:

class Dog{
    public static function staticSound(){
        $bark = "WOOF!";
        return $bark;
    }

    public function objectSound(){
        $bark = 'Woof';
        return $bark;
    }
}

$dog = new dog(); 
echo $dog->objectSound();
echo Dog::staticSound();

【讨论】:

  • 可悲的是,只要对象被实例化,PHP 不关心是否使用 -> 调用静态方法,在 PHP 5.4 版本之前,此外,在 5.4 中,它只会产生严格的警告,不是致命错误。
  • @MészárosLajos +1,这是真的,这确实有时会让我感到困惑!
  • @Phil Cross:非常感谢。为此,我应该使用 (::)。
  • @MészárosLajos - 你能提供触发你所说的严格警告的代码吗?我一直无法收到任何错误、警告或通知。
  • 抱歉,您的代码工作正常,刚刚在 PHP 5.4 下测试过,当您将非静态方法作为实例化对象中的静态方法调用时,我正在混合它。 ini_set('display_errors', 1); error_reporting(E_ALL); class Dog{ public function sound(){ $bark = "WOOF!"; return $bark; } } $new = new Dog(); echo $new::sound(); 严格标准:非静态方法 Dog::sound() 不应静态调用
【解决方案2】:

PHP 中的静态方法是这样调用的:

Dog::sound();

静态方法和非静态方法的区别在于静态方法不能访问 $this 变量。此外,静态方法在 上调用,而不是在该类的 实例 上调用。

注意:您只会收到一个致命错误,因为您在 return 语句中有错字 - 您的语法会正常工作,因为 PHP 是非常容易原谅的,并且会 允许 在非静态方式。

【讨论】:

  • 我明白了。这更有意义。 :)
  • 静态方法也可以在类实例上调用。没有什么可以阻止它发挥作用。
【解决方案3】:

如果$new->sound(); 触发对非对象的成员函数的调用,这意味着您正试图在非对象(@ 987654325@)。这是真正的问题,它不能由您发布的代码触发。我很确定您在真实代码中遇到了该错误,但您发布了一个不会重现该问题的简化版本。

您发布的简化代码应该可以正常工作,除了它当然不打印或使用返回值。稍微修正一下,我们可以看到调用静态方法的两种方式都是有效的:

<?php

error_reporting(-1);

class Dog{
  public static function sound(){
     $bark = "WOOF!";
     return $bark;
  }
}

$new = new Dog();
echo Dog::sound();
echo $new->sound();

in action

The manual 可能没有明确说出来,但隐含地确认可以做到:

将类属性或方法声明为静态使它们可以访问 无需需要类的实例化。
[...]
因为静态方法可以在没有实例的情况下调用 对象创建后,伪变量 $this 在 方法声明为静态。

不强制不等于被禁止。

静态属性不能通过对象使用 箭头运算符-&gt;.

属性,而不是方法。

调用 非静态 方法静态生成 E_STRICT 级别 警告。

这是相反的事情,它被明确记录为不允许

【讨论】:

  • G.维卡里奥:哇,谢谢!
【解决方案4】:

在 PHP 中,您必须在类上调用静态方法,而不是在实例上。这实际上因 OOP 语言而异 - 有些确实允许这样做,因此混淆是可以理解的,但 PHP 之所以不这样做的原因仅仅是因为它没有强类型,因此不允许编译器安全地确定 @987654321 的类型@ 在调用期间。

正确的语法是Dog::sound()

【讨论】:

  • 你必须?手册上没有这样说,如果你使用它,它就可以工作。
【解决方案5】:

您可以像这样从实例调用静态方法:

$dog = new Dog();
$dog::sound();

但是你应该像这样调用静态方法

Dog::sound();

见:http://www.php.net/manual/en/language.oop5.static.php

【讨论】:

  • $new-&gt;sound() 工作得很好。试试看!
  • 是的,它似乎从 PHP 5.0.0 开始工作。但我不认为它可以被认为是好的编程风格。此外,它不向后兼容低于 5.0.0 的 PHP 版本。
  • 如果我没记错的话,方法不能明确定义为静态before PHP/5。所以我想说$new-&gt;sound() 自 OOP 达到 PHP 以来一直有效;-)
  • 是的,你是对的。我的错。
【解决方案6】:

创建实现静态方法的类的实例是可以的。

静态调用该方法是非法的。

调用你将使用的静态方法

Dog::sound();

Dog::sound $this 中将不可用,因为您是在类而不是实例上调用它。

另外,静态方法也可以通过以下方式调用:

从类中作为

self::sound();
static::sound();

从扩展类作为

static::sound();

从任何地方作为

$a = array("Dog","sound");
$a();

call_user_func($a);

$d= "Dog"; $s = "Sound";
$d::$s();

$d = new Dog();
$d->sound();

【讨论】:

  • 究竟是什么让$new-&gt;sound() 非法?
  • 在 php 5.4 中它会生成一个警告
  • 你能在你选择的 PHP 小提琴中重现它吗?
  • 我错了...我想到的警告是如果您在静态上下文中调用非静态函数。
【解决方案7】:

您不能在实例化对象上调用静态方法,而必须像这样在示例中调用它:

Dog.sound();

这是大多数语言中使用静态方法的方式

【讨论】:

  • @user2417992:嗨,它指的是什么对象?我是新手,仅此而已。谢谢。
  • @mishu:这就是我的想法,你们中的一些人会将我推荐给 php.net。我在这里问它是因为答案更简单。
  • 它不引用对象...它对类来说是静态的,这意味着它无权访问任何实例方法或属性。
  • @ladybug 我没有把你介绍给php.net,我发帖说因为答案是错误的,所以使用范围解析运算符( :: )调用静态方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多