32

我正在使用 PHP 开关来包含基于在页面 URL 参数中传递的传入关键字的某些文件。

例如,URL 可以是:...page.php?kw=citroen%20berlingo%20keywords

在页面内部,我想使用这样的东西:

<?
    switch($_GET['kw']){

        case "berlingo":     
            include 'berlingo.php'
            break;
        case "c4":
            include 'c4.php';
            break;

    } 
?>

berlingo.php在第一种情况下,如果关键字参数包含 ,我想做的是包含文件berlingo,但它不必完全是那个关键字。

例如,berlingo.php如果关键字是 ,我想包含文件berlingo,但如果它是citroen berlingo.

如何使用 PHP 案例选择(switch 语句)评估给定字符串是否包含值?

谢谢。

4

8 回答 8

47

基于这个问题这个答案,我提出的解决方案(同时仍然使用案例选择)如下。

您可以使用strstr( )strstr()。我选择stristr()在这种情况下使用的原因仅仅是因为它不区分大小写,因此更健壮。

例子:

$linkKW = $_GET['kw'];

switch (true){
   case stristr($linkKW,'berlingo'):
      include 'berlingo.php';
      break;
   case stristr($linkKW,'c4'):
      include 'c4.php';
      break;
}

如果您愿意,您也可以使用stripos()strpos() (感谢Fractaliste,尽管我个人觉得这更难阅读。与上述其他方法相同的交易;我走的是不区分大小写的路线。

例子:

$linkKW = $_GET['kw'];

switch (true){
   case stripos($linkKW,'berlingo') !== false:
      include 'berlingo.php';
      break;
   case stripos($linkKW,'c4') !== false:
      include 'c4.php';
      break;
}
于 2013-04-19T14:29:16.383 回答
8

因为在一个switch语句中只会执行一个简单的相等测试,它在这里对你没有多大帮助。您需要通过字符串匹配函数运行字符串,最适合的是strpos. 直接的答案是:

if (strpos($_GET['kw'], 'berlingo') !== false) {
    include 'berlingo.php';
} else if (strpos($_GET['kw'], 'c4') !== false) {
    include 'c4.php';
} … and so on …

更优雅的解决方案是这样的:

$map = array('berlingo' => 'berlingo.php', 'c4' => 'c4.php', …);
foreach ($map as $keyword => $file) {
    if (strpos($_GET['kw'], $keyword) !== false) {
        include $file;
        break;
    }
}

或者,如果关键字与文件的对应关系始终为 1:1:

$keywords = array('berlingo', 'c4', …);
foreach ($keywords as $keyword) {
    if (strpos($_GET['kw'], $keyword) !== false) {
        include "$keyword.php";
        break;
    }
}
于 2010-11-14T02:46:03.487 回答
1

您可以将strpos函数用作:

if(strpos($_GET['kw'],'berlingo') !== false) {
 include 'berlingo.php';
}
if(strpos($_GET['kw'],'c4') !== false) {
 include 'c4.php';
}
于 2010-11-14T02:43:27.990 回答
1
$keywords = array('berlingo', 'c4');
foreach($keywords as $keyword)
  if(strpos($_GET['kw'], $keyword) !== FALSE)
    include("$keyword.php");

不过,我不建议包含基于用户输入的 php 文件。

于 2010-11-14T02:49:20.353 回答
1

你也可以在 switch -> case 中使用正则表达式:

<?php

    $kw = filter_input(INPUT_GET, "kw");

    switch($kw){

        case (preg_match('/*berlingo*/', $kw) ? true : false):     
            include 'berlingo.php';
            break;

        case "c4":
            include 'c4.php';
            break;

    } 
?>
于 2017-03-29T07:40:17.003 回答
0

strpos()用于检查一个字符串是否包含另一个字符串。

还有其他功能可以检查字符串的相似性等。

但是, Aswitch不会这样做,因为它将静态表达式与单个值进行比较。你必须使用ifs.

于 2010-11-14T02:41:18.217 回答
0

在我看来,如果您通过 GET 变量包含脚本,这是一种代码异味,但是您可以使用带有方法的值类优雅地做到这一点,其逻辑如果为真,则返回值对象本身。

这个想法是要记住,switch语句将执行 $switch == $case (松散匹配)的任何代码。因此,只需创建 return$this或什么都没有的方法。

例子:

class Haystack {
    public $value;

    public function __construct($value)
    {
        $this->value = $value;
    }

    public function contains($needle):
    {
        if (strpos($this->value, $needle) !== false)
            return $this;
    }
}

$kw = new Haystack($_GET['kw']);

switch ($kw) {
    case $kw->contains('berlingo'):
        require_once 'berlingo.php';
    case $kw->contains('c4'):
        require_once 'c4.php';
}

当然,你可以慷慨地用 typehints 装饰这段代码。如果您这样做,并且没有使用支持可空返回类型(即 的方法签名public function contains(string $substring): ?Haystack)的 PHP 版本,那么您的类将不得不详细说明以反映这一点。

例子:

final class Haystack {
    private $value;
    private $isMain;

    public function __construct(string $value, bool $isMain = true)
    {
        $this->value = $value;
        $this->isMain = $isMain;
    }

    final public function contains($needle): Haystack
    {
        if (strpos($this->value, $needle) !== false)
            return $this;
        return new Haystack($needle, false);
    }
}

这样,如果您的显式匹配逻辑在方法内失败,如果由于某种原因new Haystack($_GET['kw']) == new Haystack($needle);为真,非匹配属性“$isMain”将确保它们不被评估为相等。

再一次,我会重新审视你为什么要首先针对这种特殊情况这样做;传统上,Composer是一个依赖管理工具,可用于通过 PSR 自动加载标准包含您需要的各种脚本。与路由器库结合使用可能对满足您的实际需求最有用。

于 2019-03-18T20:39:50.003 回答
0

我知道这是事后的方式,但顺便说一句,如果期望 1:1 的关系,人们总是可以完全避免循环。

类似于以下内容:

$map = array('berlingo' => 'berlingo.php', 'c4' => 'c4.php', …);

if( !isset( $map[$_GET['kw']] ))
    throw new Exception("Blah!!");

include $map[$_GET['kw']];

...只是分享给新手的仅供参考。

于 2016-05-26T19:43:46.433 回答