2013-03-29 33 views
0

我的工作是通过Twilio接收传入的SMS消息并且基于哈希标签,并设置用户偏好的PHP应用程序。例如,如果用户想要禁用网站的短信提醒,他们会发送短信#sms off用#标签切换设置,PHP

下面是我已经把处理这个任务的代码,但我觉得这是臃肿,并且可以清理一下。将不胜感激任何关于如何从另一个(希望更加整洁)角度来处理这个任务的建议。

这很棘手,因为即将到来的hashtag可以在任何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; 
    } 
} 

谢谢!

回答

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) { 

    ... 
+0

我喜欢它除了一个缺点 - 如果有以下的井号标签多于一个的空间,设置不包含 – NightMICU

+0

好吧,我更新了答案。抓住第一个数组元素作为命令很容易,然后将它们拼接在一起。一般来说,我发现使用数组比字符串操作更容易。 – jszobody

+0

现在就来,谢谢!似乎是做工精细,部署:) – NightMICU

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 ...

抽象是非常有益的摆脱臃肿。希望这可以帮助你。

+0

谢谢,我正沿着同样的思路在OOP的思维 - 这实际上是现有课程的一部分,它会被分成不同的方法。发布在我的问题中的代码是一个更简单的版本的问题。核心问题是要找到在开始哈希标签(不会永远是主题标签)消息的最佳方式,然后拆分命令并设置 – NightMICU

+0

我认为你应该做的重构和抽象,然后再思考“好”解决低级问题的方法 - 当你有这样的抽象时,你可以通过只改变代码的很小部分来增加对各种方法和参数类型的支持,最好是即使你只需要为此添加类并且不必编辑现有的类。当然,我不知道你已经拥有了什么,所以我只能希望我能帮你:) – stefreak

+0

这是一个非常广阔的Laravel项目的一部分。有问题的班级确实是一团糟。我正在努力模块化它,并将重新审视。面向面向对象的方法 – NightMICU