【问题标题】:PHP method get 2 types of objectsPHP方法获取2种对象
【发布时间】:2013-12-15 19:22:30
【问题描述】:

是否可以在方法函数中设置类似的东西

class myClass{

 public function myMethod($variable stdClass || otherClass){
 }

}

我想做一些类似的事情,在我的myMethod 中可以传递两种类型的对象,这在 PHP 中是可能的吗?

【问题讨论】:

  • PHP中不需要描述参数类型,为什么要这样做?
  • 据我了解,您不必将特定类型作为参数传递。
  • 因为我不想做类似 public function myMethod($variable){ if($variable instanceof stdClass){} if($variable instanceof otheClass){} } }

标签: php methods arguments


【解决方案1】:

您无需设置类型,PHP 允许您:

class myClass {
    public function myMethod($variable) {

    }
}

如果它必须是两种类型之一,你可以在方法内部检查它,并添加一个 PHPDoc 块告诉读者$variable 可能是什么类型:

class myClass {

    /**
     * @param stdClass|myClass $variable
     *
     * @throws InvalidArgumentException in case $variable is not one of the above classes.
     */
    public function myMethod($variable) {
        if (!($variable instanceof stdClass || $variable instanceof myClass)) {
            throw new InvalidArgumentException('$variable must be either an stdClass or myClass');
        }

    }

}

【讨论】:

    【解决方案2】:

    您不需要在方法定义中编写类型。您可以允许任何类型的参数在 PHP 中通过。如果你想检查,你可以稍后这样:

    public function myMethod($var) {
        if(class_name($var) == "MyClass1") { 
            // do something
        } 
        elseif(class_name($var) == "MyClass2") { 
            // do something elese
        } 
        else { 
            // Error
        }
    }
    

    【讨论】:

      【解决方案3】:

      您不必在 PHP 中精确的参数类型。这是一个名为Type Hinting 的新功能,无需使用。

      您唯一要做的就是处理您的参数可以是一个类或另一个类的实例这一事实。您可以使用instanceof 进行检查:

      class myClass {
          public function myMethod($param) {
              if($param instanceof MyClass1){
              }
              else if($param instanceof MyClass2){
              }
              ...
          }
      }
      

      【讨论】:

      • 是的,我知道,但我想避免 if $variable instanceof stdClass 和 if $variable instanceof otheClass 而不是做某事。当参数传递到方法体时,我想检查对象的类型。
      • 暂时没有办法。即使是 Type Hunting 也不允许两个方法同名,即使参数不同。
      • 你总是可以使用不同的设计模式来处理这种情况,但这总是一样的:打开参数类。最干净的方法是使用一个接口,让你的两个类实现它,并通过声明你的参数是这个接口的一个实例来使用类型提示。但这是同一个 IMO,我没有这种模式,两个类之间除了被同一个方法作为参数之外没有其他联系。
      【解决方案4】:

      这不可能!您可以传递实现一个interface 的对象或尝试使用模式factory method 或简单地传递变量

       public function myMethod($var) {
          if($var instanceof MyClass) {
      
          }
       }
      

      【讨论】:

        【解决方案5】:

        如果您想控制输入参数,请改用接口或抽象类:

        class MyClass {
        
            public function doSomething(IExpectedObject $input)
            {
                ...
            }
        
        }
        
        interface IExpectedObject{}
        
        class A implements IExpectedObject {}
        class B implements IExpectedObject {}
        class C {}
        

        在这种情况下,A 类和 B 类将通过而 C 类将失败,如果您的方法期望某种类型的对象以相同的方式处理它们而不关心它是 A 还是 B 对象,这将很有用。

        这也可以通过继承来完成,具体取决于您的需要。

        【讨论】:

        • 这真的是一个好习惯吗?创建一个接口只是为了使用它来声明一个参数类型对我来说似乎有点矫枉过正。特别是如果两个类之间绝对没有功能联系。你会为你得到的这种类型的每个方法创建一个接口吗?
        • 就像我在回答中所说的那样,当方法处理它们而不关心它们的类时,使用接口是一种很好的做法。由于他在示例中使用了“stdClass”,我推测后面的对象需要特定的处理。 IMO我看不到一个方法应该能够接受和处理给它的任何对象的情况,当您使用相同的方法处理多个对象类型时,不是对它们都应用相同的操作吗? “两个类之间没有功能联系”所以在这种情况下为什么使用相同的处理方法(请原谅我的英语)
        • 是的,我同意你的看法,这种问题来自受孕问题。如果相同的方法适用于两个类,则这些类应该通过继承共享一些方法和属性。但是我仍然认为只为这个用途创建一个接口是矫枉过正的。他将以class MyClass implements InterfaceForMethod1, InterfaceForMethod2, InterfaceForMethod3... 之类的东西结束,如此松散的OOP 最好的方面之一:代码清晰。
        • 仅基于它的示例无法说,但我同意你的观点,如果仅用于允许方法接受多种类型,那么接口是一种矫枉过正,那不是它们的用途。这更像是一个概念问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-30
        • 2023-03-22
        相关资源
        最近更新 更多