Php 方法/函数中需要2个参数中的1个(两个参数中的一个可选)

Php 方法/函数中需要2个参数中的1个(两个参数中的一个可选),php,methods,arguments,Php,Methods,Arguments,我有一个我正在调用的方法/函数(在类中),我想传递和id或url。然后,该方法在mysql WHERE查询中使用这些参数之一。它只能使用其中一个 我怎么能要求两个参数中的一个?或者换言之,我怎么能只选择两个参数中的一个 有没有比两个参数都可选并使用几个if-else语句更好的方法呢?如果您确实需要一个参数: public function fetchRow($where) { if (empty($where['id']) && empty($where['url']))

我有一个我正在调用的方法/函数(在类中),我想传递和id或url。然后,该方法在mysql WHERE查询中使用这些参数之一。它只能使用其中一个

我怎么能要求两个参数中的一个?或者换言之,我怎么能只选择两个参数中的一个

有没有比两个参数都可选并使用几个if-else语句更好的方法呢?

如果您确实需要一个参数:

public function fetchRow($where)
{
    if (empty($where['id']) && empty($where['url'])) {
        throw new Exception('WHERE clause must be supplied');
    }

    // proxy to specific method
    if (!empty($where['id'])) {
        return $this->fetchById((int) $where['id']);
    } elseif (!empty($url)) {
        return $this->fetchByUrl((string) $where['url']);
    }
}

public function fetchById($id) 
{
    if ($stmt = $mysqli->prepare('SELECT * FROM table WHERE id = ?')) {
        $stmt->bind_param('i', $id);
        // ...
    }
}

// ...
$object = new MyClass();
try {
    $object->fetchRow(); // would throw exception
    $object->fetchRow(array('id' => 10)); // would work
} catch (Exception $ex) {
    // do something, for example:
    echo $ex->getMessage(); // echoes 'at least one argument must be supplied'
}

如果它只能使用一个或另一个,那么您有状态。如果您有状态,您需要多态性,或者在这个非常小的用例中,需要两种不同的方法

public function getById($id) {}
public function getByUrl($url) {}
到此为止。这是你能为自己做的最好的了


如果且仅当您事先不知道传入的是哪种类型(如用户输入),您可以使用第三种方法来解析和验证输入字符串,确定它是哪种类型,并调用适当的方法。

最后,我使用了一个非常简单的方法,该方法不会导致代码重复,并且实际上允许将来在需要时传递更多参数,而无需更改该方法

public function getMovie($argType, $arg) {
    $movieQuery =  "SELECT 
        id, rt_id, imdb_id, url, rt_url, type, adult, 
        DATE_FORMAT(release_date, '%Y') AS year, date_added,
        title, runtime, budget, revenue, homepage, rating,
        tagline, overview, popularity, image, backdrop, trailer
        FROM movies
        WHERE " . $argType . " =  ?";

    $movieResult = $this->_query($movieQuery, $arg);
    $movies      = array();

    if ($movieResult->fetch_array(MYSQLI_ASSOC)) {
        while ($m = $movieResult->fetch_array(MYSQLI_ASSOC)) {
            $movies[] = array(
                'title'        => $m['title'],
                'duplicate'    => $m['duplicate'],
                'url'          => $m['url'],
                'rt_url'       => $m['rt_url'],
                'release_date' => $m['release_date'],
                'date_added'   => $m['date_added'],
                'type'         => 'movie',
                'adult'        => $m['adult'],
                'id'           => $id,
                'rt_id'        => $m['rt_id'],
                'imdb_id'      => $m['imdb_id'],
                'rating'       => $m['rating'],
                'tagline'      => $m['tagline'],
                'overview'     => $m['overview'],
                'popularity'   => $m['popularity'],
                'runtime'      => $m['runtime'],
                'budget'       => $m['budget'],
                'revenue'      => $m['revenue'],
                'homepage'     => $m['homepage'],
                'image'        => $m['image'],
                'backdrop'     => $m['backdrop'],
                'trailer'      => $m['trailer'] 
            );
        }
        return $movies;
    } else {
        return false;
    }
}


模拟命名参数(将关联数组作为param)怎么样?函数x($param1,$param2=null){if($param2!=null){…}else{…}如果我理解正确,数组方法仍然需要if-else语句。@Seth此方法不允许只传递$param2。@DominicM如果您仔细想想,在您的情况下,一个方法无法知道您传递给它的哪个参数(如果两者都是可选的,但同时是一个必需的),调用
$object->myFunction(false)
也会抛出一个异常。@MadaraUchiha我认为你在吹毛求疵,这是一个简单的例子。还是你希望我写下他的整个申请?GeezWell,同样在您的情况下,$arg1和$arg2都是必需的。而且,最重要的是,这甚至不能回答问题的要求,因为他想要一个或另一个。如果我的投票结果仍然有效,请原谅我。我不完全理解这个例子(我是oop新手),但我不明白这是怎么回事。我仍然只能通过requiredArg或两者中的任何一个,但不能通过optionalArg。@MadaraUchiha当时在wikipedia上讨论过这一点,这不是我的定义。我知道什么是例外,我同意你的解释。我只是不明白我提供的定义是怎么说的,我的例子也是如此。为了方便起见,请删除我的答案。我对此感到厌烦。getById的一部分目的是验证$id是否为id。如果将这两种方法混合在一起,你就无法合理地做到这一点……我没有挑剔,你的方法从根本上说是有缺陷的,这不是一些可以忽略的小错误,你完全忽略了这个问题,完全基于(有点误导)标题!不完全是,但我知道你是怎么想的。我还是编辑了我的答案。上帝,我非常讨厌火影忍者,但这次我必须同意他$Madara Uchiha多想一想这似乎不再是一个好的解决方案,我怎么能避免代码重复?因为这两种方法和一种方法中只有一个参数是不同的所有代码都完全相同……您的解决方案很好,因为它可以正常工作,但您确实应该在准备好的语句中使用
bind_param
。:)什么是bind param?/准备好的声明?我计划将来使用数据库类,这样查询就不会出现在这个方法中。为了简单起见,我的示例假设了一个db类,并使用了
bind\u param
函数。但是这里有一个很好的学习预处理语句的来源(它们是存储过程之外最安全的)。链接被书签,直到性能成为一个问题(现在我有点头晕)。除了例外,绑定参数在你的回答中的用法我的方法是好的,对吗?我的意思是,它在某种程度上更简单,因为我不需要在调用时将$where参数传递给方法之前创建它。。。与传递2个参数而不是$where数组相比,您的方法似乎有更多的if/else语句。下面是另一篇关于预处理语句的精彩文章: