【问题标题】:What is the best way to achieve the same behaviour of method overloading in PHP?在 PHP 中实现相同的方法重载行为的最佳方法是什么?
【发布时间】:2020-03-08 15:38:45
【问题描述】:

假设我有两个名为UserProduct 的类。 这两个都需要保存在数据库中。

名为PersistencyHandler 的第三个类处理所有数据库交互(为了同时遵守单一职责原则和依赖倒置)。 这是这个类的样子:

<?php
/**
 * Class PersistencyHandler
 * Handles database using PDO API
 */
class PersistencyHandler{

    /**
     * PDO connection used to save objects into.
     * @var $conn PDO
     */
    private $conn;

    /**
     * PDODatabaseSaver constructor.
     * @param $conn PDO
     */
    public function __construct($conn){
        $this->pdo = $conn;
    }

    /**
     * Saves the given object in the database
     * @param $object mixed
     */
    public function save($object){

        // as PHP does not support classic method overloading for different
        // types of objects, this is the cleanest solution I've been able to find.
        // And it's still pretty dirty...

        if($object instanceof Product) {
            $this->saveProduct($object);
        } else if($object instanceof User) {
            $this->saveUser($object);
        } else {
            throw new UnsupportedOperationException("Cannot save object, unsupported type."); // custom class
        }
    }


    private function saveProduct(Product $object){
        // save Product into database
    }

    private function saveUser(User $object){
        // save User into database
    }

}
?>

我有 Java 经验,我确信使用 instanceof 是一种非常糟糕的做法(至少在 Java 中是这样)。例如,在 Java 中,我曾经使用重载方法来解决此类问题。

我检查了php.net 和其他网站(包括这个),但我没有找到一个很好的答案:

以正确的方式实现上述代码的相同行为的更好方法是什么?

请注意,我有一个带有 单个参数单个方法,并且调用的方法由参数的类型决定。 p>

【问题讨论】:

  • 策略模式。
  • @AnuragSrivastava 这不是我的用例。这个问题是关于使用不同数量的参数进行重载。我总是有一个参数传递给我的方法。
  • @u_mulder 这种模式在这种情况下似乎很有趣,谢谢!
  • @Z.Alessandro 您可能错过了已接受答案中的第一行。 You cannot overload PHP functions.

标签: php overloading


【解决方案1】:

一种解决方案是使用动态调用(类似于Java中的反射):

public function save($object)
{
    $mtd = 'save'.get_class($object);
    if(method_exists($this, $mtd))
        call_user_func(array($this, $mtd), $object);
    else
        throw new UnsupportedOperationException("Cannot save object, unsupported type.");
}

注意:如果使用命名空间,则需要修改代码(get_class() 返回限定名称)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    相关资源
    最近更新 更多