Алгоритм для приложения USSD (конечный автомат)

Я создал USSD-приложение в PHP. Поскольку USSD-запросы уникальны (новый запрос для каждого выбора), мне нужен способ их отслеживать. Отслеживать в том смысле, что мне нужен способ сохранить поток приложения. В моем USSD-приложении есть есть статические меню, а также динамические меню (полученные из базы данных). Моя проблема в том, что я создал приложение с большим количеством операторов if, else и switch, и очень сложно обновить пункты меню. Так может ли кто-нибудь предложить мне хороший алгоритм для создания этого приложения USSD? Я имею в виду эффективный способ решения проблемы, мне нужен способ, с помощью которого я мог бы добавлять и удалять меню в соответствии с запросом клиента. Когда я это делаю, мой код не должен ломаться. Может ли кто-нибудь помочь мне в этом?

-С уважением

PS: я прочитал это и это, и на самом деле это не отвечает на мой вопрос.


person Fawzan    schedule 22.12.2013    source источник
comment
Можете уточнить, что такое USSD и в чем именно заключается ваш вопрос? Добавлять и удалять меню к чему, где? Каков ваш код на данный момент и где/как он не работает?   -  person Pekka    schedule 22.12.2013
comment
@pekka (USSD) Unstructured Supplementary Service Data — это протокол, используемый сотовыми телефонами GSM для связи с компьютерами поставщика услуг, например. когда мы делаем что-то вроде #111# на мобильном телефоне, вы получаете меню, верно? В котором вы можете перейти к большему количеству меню. Ясно?   -  person Fawzan    schedule 22.12.2013
comment
Это делает эту часть более ясной. Но не могли бы вы уточнить, в чем заключается ваш вопрос? Может быть, показать какой-нибудь код?   -  person Pekka    schedule 22.12.2013
comment
@pekka здесь я вставил статический код приложения ussd. pastebin.com/76bqvAV5   -  person Fawzan    schedule 22.12.2013
comment
вы можете легко превратить это в приложение, управляемое базой данных, вместо того, чтобы переключаться, вы в основном запускаете запрос, и если строка возвращается, вы что-то делаете, если это не так, вы не   -  person cmorrissey    schedule 22.12.2013
comment
@Christopher, не могли бы вы быть более конкретными и дать мне немного больше информации, я бы очень признателен.   -  person Fawzan    schedule 22.12.2013
comment
Вы должны отредактировать свой вопрос, чтобы включить пример взаимодействия между вашими системами. Каковы начальные условия, какие сообщения передаются между конечными точками и каковы конечные условия. Понятно, что, хотя вы очень хорошо знакомы с USSD и его особенностями, не многие другие. Кроме того, срок действия вашего pastebin истек ...   -  person Speed8ump    schedule 14.01.2014


Ответы (3)


Лучший способ работы с USSD — сделать каждый command отдельным классом. Таким образом, вы можете работать, отлаживать и поддерживать большое USSD приложение.

Пример

$ussd = new USSDMessage(); // USSD Class 

$main = new Command("menu"); // Starting Command 

// Register multiple command 
$main->register(new Command("help"));
$main->register(new Command("account"));
$main->register(new Command("transfer"));
$main->register( new Recharge("reacharge"));

$main->run($ussd); // Run Request 

Базовая структура класса

// Class To receve message from USSD
class USSDMessage {
    function next();
    function saveSession();
}

// Basic Command  Class 
class Command {
    private $name;
    private $cmd = array();

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

    function register(Command $menu) {
        $this->cmd[$menu->getName] = $menu;
    }

    function run(USSDMessage $ussd) {
        $key = $ussd->next(); // get next inpur from ussd

        if (isset($this->cmd[$key])){
            $ussd->run($ussd);
        }
    }
}

// Recharge Command Example 
class Recharge extends Command {

    function run(USSDMessage $ussd) {
        $key = $ussd->next();

        switch ($key){
            case "1":
                // Proccess card recharge
                // Do Somthing 
                $ussd->saveSession(); // End Session 
                break;
            case "2":
                // Process direct deposit
                // Do Somthing
                $ussd->saveSession(); // End Session
                break;
            default:
                // Format Not supported
                // Do Somthing
                $ussd->saveSession(); // End Session
                break;
        }
    }
}
person Baba    schedule 17.01.2014

Основываясь на том, что я получил от вопроса OP, вот некоторая подсказка:

Эта проблема связана с обходом дерева. Каждое состояние меню будет храниться в одном узле дерева.

Если вы ничего не знаете о дереве/дереве суффиксов, прочитайте здесь. Идея проста, так как у пользователя есть ограниченные возможности ввода: 0,1,2,3,4,5,6...9,#,*, мы можем представить все состояния в одном дереве.

Каждый узел дерева будет выглядеть примерно так:

Node{        
    Node [] next = new Node[12];//All options from 0 to *
    Menu menu;
}

Таким образом, вместо if и switch мы можем легко найти и сохранить все состояния, используя и проходя по дереву от корня к листу. А для обращения ко всем состояниям нам нужно хранить только одну переменную: Node root

Например, если у нас есть ряд действий #111#. (Предположим, что # находится в индексе 10, а * в индексе 11). Мы всегда будем начинать с root -> переходить к узлу с индексом 10-> переходить к узлу с индексом 1... и, наконец, возвращаться в меню.

Псевдокод:

Menu traverse(String input){
    Node cur = root;
    for(int index in input){
        cur = cur.next[index];
    }
    return cur.menu;
}

Для удаления состояния/ветви просто перейдите от корня к этому листу и замените этот конечный узел в родительском массиве next на null.

Примечание. Вы можете еще проще управлять списком меню, если будете хранить все меню в массиве Menu[]menu, и для каждого узла вместо возврата меню вы будете возвращать целое число указывает индекс желаемого меню в массиве menu.

person Pham Trung    schedule 16.01.2014

Вы должны попытаться использовать свои запросы к БД для поддержания состояния приложения, использование запросов к БД поможет вам отслеживать прогресс пользователей, а также переводить их на более высокие уровни и понижать их до более низких уровней, таким образом, вы можете сделать свою жизнь легче поддерживать код. Взгляните на приведенный ниже фрагмент кода, который поможет вам понять прогресс USSD на основе сеанса с использованием платформы AfricasTalking.

if($userResponse==""){
        // this is when you receive nothing from the user. serve them the registration menu
        switch ($level) {
            case 0:
                //. Graduate the user to the next level, so you dont serve them the same menu
                 $sql1 = "INSERT INTO `some_seesion_name`(`session_id`, `yourIdentifier`,`level`) VALUES('".$sessionId."','".$yourIdentifier."', 1)";
                 $db->query($sql1);

                 // Insert the Identifier, since it comes with the first POST
                 $sql1a = "INSERT INTO YourDB(`yourIdentifier`) VALUES ('".$yourIdentifier."')";
                 $db->query($sql1a);

                 // Serve the menu request for name
                 $response = "CON Please enter your name";

                // Print the response onto the page so that our gateway can read it
                header('Content-type: text/plain');
                echo $response; 
                break;

     // continue the flow of the app ...... 
person Muazu Musa Muhd    schedule 13.05.2018