Как использовать оператор переключателя PHP, чтобы проверить, содержит ли строка слово (но может также содержать другие)? - PullRequest
24 голосов
/ 14 ноября 2010

Я использую переключатель 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 case select (оператор switch)?

Спасибо.

Ответы [ 8 ]

35 голосов
/ 19 апреля 2013

Исходя из этого вопроса и этого ответа , решения, которые я придумал (, все еще используя вариант выбора ), приведены ниже.

Вы можете использовать stristr () или 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;
}
8 голосов
/ 14 ноября 2010

Поскольку в операторе 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;
    }
}
1 голос
/ 29 марта 2017

Вы также можете использовать регулярное выражение в 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;

    } 
?>
1 голос
/ 14 ноября 2010
$keywords = array('berlingo', 'c4');
foreach($keywords as $keyword)
  if(strpos($_GET['kw'], $keyword) !== FALSE)
    include("$keyword.php");

Я бы не рекомендовал включать php-файлы на основе пользовательского ввода.

1 голос
/ 14 ноября 2010

Вы можете использовать функцию strpos как:

if(strpos($_GET['kw'],'berlingo') !== false) {
 include 'berlingo.php';
}
if(strpos($_GET['kw'],'c4') !== false) {
 include 'c4.php';
}
0 голосов
/ 18 марта 2019

На мой взгляд, это запах кода , если вы включаете скрипты через переменные GET, но вы можете сделать это элегантно, используя класс значений с методами, логика которых возвращает сам объект значения, если он истинен.

Идея состоит в том, чтобы помнить, что оператор switch будет выполнять любой код, в котором $ switch == $ case (свободное совпадение). Так что просто создайте методы, которые либо возвращают $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';
}

Конечно, вы можете щедро украсить этот код печатными буквами. Если вы это делаете и не используете версию PHP, которая поддерживает типы возвращаемых значений, допускающие значение NULL (т. Е. Сигнатура метода public function contains(string $substring): ?Haystack), то ваш класс должен будет уточнить это, чтобы отразить это.

Пример:

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); имеет значение true, несоответствующее свойство "$ isMain" гарантирует, что они не будут оценены как равные.

Опять же, я бы еще раз рассмотрел, почему вы хотите сделать это в первую очередь для этой конкретной ситуации; Традиционно Composer - это инструмент управления зависимостями, который используется для включения различных скриптов, которые вам нужны, через стандарт автозагрузки PSR. Это в сочетании с библиотекой маршрутизатора, вероятно, будет наиболее полезным для удовлетворения ваших реальных потребностей.

0 голосов
/ 26 мая 2016

Я знаю, что это ПУТЬ после свершившегося факта, но, кроме того, всегда можно полностью избежать цикла, если ожидать отношения 1: 1.

Что-то вроде:

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

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

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

... просто делюсь информацией о себе как новичку.

0 голосов
/ 14 ноября 2010

strpos() - один для проверки, содержит ли строка другую строку.

Есть другие функции для проверки сходства строк и т.д.

A switch не подойдет, так как он сравнивает статические выражения с одним значением. Вам придется использовать if s.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...