0

我正在开发一个 PHP 应用程序,该应用程序通过 Twilio 接收传入的 SMS 消息并根据主题标签和设置更改用户首选项。例如,如果用户想要禁用来自站点的 SMS 警报,他们会发短信#sms off.

下面是我为处理此任务而编写的代码,但我觉得它很臃肿,可以稍微清理一下。任何有关如何从另一个(希望更整洁)角度处理此任务的建议将不胜感激。

这很棘手,因为传入的主题标签可以是任何 cAsE - #SMS off#Sms Off等。我通过使命令和设置大写来处理这个问题。

这是我到目前为止所拥有的 -

<?php
$body = trim($_POST['Body']);
$pos = strripos($body, '#'); //Find position of hashtag in body
if ($pos != 0) {
    //Hashtag was not first, therefor this is a normal incoming SMS
    //without commands
    echo "Normal SMS message";
} else if ($pos == 0) {
    //This is a command SMS, we need to react to it
    preg_match_all('/#(\w+)/',$body,$matches); // Isolate the hashtag
    // Change hashtag, complete with #, to uppercase
    //This is to prevent case issues in the incoming SMS
    $command = strtoupper($matches[0][0]);
    //Remove the hashtag from the SMS, convert the remaining string to upper,
    //and trim it to isolate
    $setting = str_ireplace($command, '', $body);
    $setting = strtoupper(trim($setting));
    //Switch for available commands
    switch ($command) {
        case '#DISPATCH':
            if ($setting == 'ON') {
                echo 'Dispatch alert has been turned on';
            } else if ($setting == 'OFF') {
                echo 'Dispatch alert has been turned off';
            } else {
                'Missing setting. Please reply with #dispatch on or #dispatch off to set.';
            }
            break;
        case '#SMS':
            if ($setting == 'ON') {
                echo 'SMS alerts have been turned on';
            } else if ($setting == 'OFF') {
                echo 'SMS alerts have been turned off';
            } else {
                'Missing setting. Please reply with #sms on or #sms off to set.';
            }
            break;
        default:
            echo 'I do not recognize this command. Please enter either #dispatch or #sms followed by on or off to set.';
            break;
    }
}

谢谢!

4

2 回答 2

1

您可能会发现它explode()更易于使用。像这样的东西(未经测试):

$pos = strripos($body, '#'); //Find position of hashtag in body
if ($pos != 0) {
    echo "Normal SMS message";
} else {
    // The input needs to be all uppercase, and split apart by the space
    $pieces = explode(" ",strtoupper($body));

    // Our command will be the first item
    $command = array_shift($pieces);
    // The rest will be the setting
    $setting = trim(implode(" ",$pieces));

    switch($command) {

    ...
于 2013-03-29T16:58:59.860 回答
1

我会做一个更面向对象的方法。

例如,代码可能如下所示:

$sms = new SMS($_POST['Body']);

SMS 将负责解析所有内容并抽象出任何相关内容。

if ($sms->hasCommand()) {
    $commandDispatcher = new SMSCommandDispatcher($sms->getCommand(), $sms->getCommandArguments());
    $commandDispatcher->dispatch();
}

SMSCommandDispatcher 会知道存在哪些命令并执行它们:

它可能看起来像这样:

class SMSCommandDispatcher {
    protected $knownCommands = array(
        'dispatch' => 'DispatchCommand',
        'sms' => 'SMSCommand',
    );

    public function __construct($cmd, $args) {
        if (!isset($this->knownCommands[$cmd])) throw new InvalidArgumentException('Unknown command');
        $this->commandInstance = new $this->knownCommands[$cmd]($args);
    }

    public function dispatch() {
        $this->commandInstance->invoke();
    }
}

然后你当然有 SMSCommand 和 DispatchCommand 类......

抽象对于摆脱臃肿非常有帮助。希望这对您有所帮助。

于 2013-03-29T17:17:22.187 回答