How to fix my PHP Code which return me "Invalid input" when I modify "input" variable value?

huangapple go评论52阅读模式
英文:

How to fix my PHP Code which return me "Invalid input" when I modify "input" variable value?

问题

这里是我的USSD个人代码:

    <?php
    class UssdNode {
        // ...(略)
    }

    class MyTree {
        // ...(略)
    }

    class MyUssdUserSession {
        // ...(略)
    }

    // 开始USSD会话
    session_start();

    // 创建USSD树
    $ussdTree = new MyTree();

    // 获取用户的地址(手机号码)
    $address = $_POST['address'] ?? '';

    // 创建或检索用户会话
    $userSessions = $_SESSION['userSessions'] ?? [];
    $userSession = $userSessions[$address] ?? null;
    if ($userSession === null) {
        $userSession = new MyUssdUserSession($address, $ussdTree);
        $userSessions[$address] = $userSession;
        $_SESSION['userSessions'] = $userSessions;
    }

    // 获取来自请求的USSD输入
    $input = $_POST['ussdInput'] ?? '';

    // 处理USSD输入并获取响应
    $response = $userSession->processUssdInput($input);

    // 将响应发送回USSD网关
    header('Content-type: text/plain');
    echo $response;
英文:

Here my USSD Personnal Code:

<?php
class UssdNode {
    private $name = '';
    private $parent = '';
    private $title = '';
    private $address = '';
    private $children = array();
    private $index = 0;

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

    function addChildNode(UssdNode $childNode) {
        $this->children[] = $childNode;
    }

    function setIndex($index) {
        $this->index = $index;
    }

    function hasChildren() {
        return count($this->children) > 0;
    }

    function setAddress($address) {
        $this->address = $address;
    }

    function getName() {
        return $this->name;
    }

    function getParent() {
        return $this->parent;
    }

    function getAddress() {
        return $this->address;
    }

    function getTitle() {
        return $this->title;
    }

    function getChildren() {
        return $this->children;
    }

    function getNameFromIndex($index) {
        return $this->children[$index - 1]->getName();
    }

    function toString() {
        $objectString = '';
        $items = $this->children;
        $bufferLimit = (count($items) == 0) ? 1 : $this->getBufferLimit() + 1;
        do {
            $bufferLimit -= 1;
            $objectString = $this->recurseMenu($items, $bufferLimit);
        } while (strlen($objectString) > 160);
        $this->index = $bufferLimit;
        return $objectString;
    }

    function getBufferLimit() {
        $len = count($this->children);
        $margin = $len - $this->index;
        if ($margin < 5)
            return $this->index + $margin;
        else
            return $this->index + 5;
    }

    function recurseMenu($items, $bufferLimit) {
        $objectString = $this->getTitle() . PHP_EOL;
        $lastMenu = false;
        if (count($items) > 0) {
            for ($i = $this->index; $i < $bufferLimit; $i++) {
                $item = $items[$i];
                $num = $i + 1;
                // get node by name
                $userSessions = $_SESSION['userSessions'];
                $currUserSession = $userSessions[$this->address];
                $node = $currUserSession->getNode($item->getName());
                $title = $node->getTitle();
                $objectString = $objectString . PHP_EOL . $num . '. ' . $title;
            }
        } else {
            $objectString = $objectString . PHP_EOL . 'NO DATA AVAILABLE, TRY AGAIN LATER';
        }
        $lastMenu = $bufferLimit == count($items);
        $objectString = $objectString . PHP_EOL . PHP_EOL . '0. Exit';
        if ($this->getParent() != '0') {
            $objectString = $objectString . PHP_EOL . '#. Back';

        }
        if ($lastMenu === false) {
            $rem = count($items) - $this->index;
            $objectString = $objectString . PHP_EOL . '77. Next (' . $rem . ')';
        }
        return $objectString;
    }
}

class MyTree {
    private $rootNode;

    function __construct() {
        $this->initTree();
    }

    function initTree() {
        $rootNode = new UssdNode('Welcome to Cheggen USSD Menu', 'root', '0');

        $childNode1 = new UssdNode('Option 1', 'option1', 'root');
        $childNode1->addChildNode(new UssdNode('Sub-option 1', 'suboption1', 'option1'));
        $childNode1->addChildNode(new UssdNode('Sub-option 2', 'suboption2', 'option1'));

        $childNode2 = new UssdNode('Option 2', 'option2', 'root');
        $childNode2->addChildNode(new UssdNode('Sub-option 3', 'suboption3', 'option2'));
        $childNode2->addChildNode(new UssdNode('Sub-option 4', 'suboption4', 'option2'));

        $rootNode->addChildNode($childNode1);
        $rootNode->addChildNode($childNode2);

        $this->rootNode = $rootNode;
    }

    function getRootNode() {
        return $this->rootNode;
    }
}

class MyUssdUserSession {
    private $ussdTree;
    private $currentNode;
    private $address;

    function __construct($address, $ussdTree) {
        $this->address = $address;
        $this->ussdTree = $ussdTree;
        $this->currentNode = $ussdTree->getRootNode();
    }

    function getNode($name) {
        $children = $this->currentNode->getChildren();
        foreach ($children as $child) {
            if ($child->getName() === $name) {
                return $child;
            }
        }
        return null;
    }

    function processUssdInput($input) {
        if ($input === '') {
            // Initial menu
            return $this->currentNode->toString();
        } elseif ($input === '0') {
            // Exit
            return 'Thanks, end of session';
        } elseif ($input === '#') {
            // Back
            $parentName = $this->currentNode->getParent();
            $parentNode = $this->getNode($parentName);
            if ($parentNode !== null) {
                $this->currentNode = $parentNode;
                return $this->currentNode->toString();
            } else {
                return 'Invalid input';
            }
        } elseif ($input === '77') {
            // Next
            $index = $this->currentNode->getIndex() + 5;
            $this->currentNode->setIndex($index);
            return $this->currentNode->toString();
        } else {
            // Check if the input matches any child node
            $childNode = $this->getNode($input);
            if ($childNode !== null) {
                $this->currentNode = $childNode;
                return $this->currentNode->toString();
            } else {
                return 'Invalid input';
            }
        }
    }
}

// Start the USSD session
session_start();

// Create the USSD tree
$ussdTree = new MyTree();

// Get the user's address (phone number)
$address = $_POST['address'] ?? '';

// Create or retrieve the user session
$userSessions = $_SESSION['userSessions'] ?? [];
$userSession = $userSessions[$address] ?? null;
if ($userSession === null) {
    $userSession = new MyUssdUserSession($address, $ussdTree);
    $userSessions[$address] = $userSession;
    $_SESSION['userSessions'] = $userSessions;
}

// Get the USSD input from the request
$input = $_POST['ussdInput'] ?? '';

// Process the USSD input and get the response
$response = $userSession->processUssdInput($input);

// Send the response back to the USSD gateway
header('Content-type: text/plain');
echo $response;

The problem is when I try to start the first session (notice session_start at Line 194), USSD App is running well. But when I try to change in Line 212, $input = $_POST['ussdInput'] ?? ''; to $input = '1'; or to $input = 1; to access Sub-Menu of Option 1, I get This foolowing error: Invalid input.

Note that this $input variable is used to retrieve the value entered in the simulator by the user. And If, I put or give it 1 as value, normally it should return me the Sub-option 1 of the Option 1 as defined on my initTree() function from Line 115 to 130.

So How to fix my Code to browse (navigate) through Menus (Options) and their Sub-Menus (Sub-option) without getting Invalid input error ???

Thanks.

答案1

得分: 0

错误在于您将索引传递给一个按名称搜索节点的函数,而不是名称。如果我在您的代码中添加一些调试信息,例如

function getNode($name) {
    $children = $this->currentNode->getChildren();
    foreach ($children as $child) {
        echo var_dump([$child->getName(), $name]);
        if ($child->getName() === $name) {
            return $child;
        }
    }
    return null;
}

然后我可以看到循环正在检查匹配项:

How to fix my PHP Code which return me "Invalid input" when I modify "input" variable value?

如果您尝试将 'option1' 分配给 $input,那么它将起作用。如果您希望通过索引来搜索节点,那么您需要实现一个能够执行此操作的方法。

编辑

您可以更改 getNode 以检查输入的类型并根据情况返回索引或名称:

function getNode($input) {
    $children = $this->currentNode->getChildren();
    foreach ($children as $index => $child) {
        if ((is_int($input) ? $index : $child->getName()) == $input) {
            return $child;
        }
    }
    return null;
}

我已经删除了测试文件,所以上面的编辑未经测试,让我知道是否有效。

英文:

The mistake is that you pass the index rather than the name to a function that searches the nodes by name. If I add some debugging to your code, such as

    function getNode($name) {
        $children = $this->currentNode->getChildren();
        foreach ($children as $child) {
                echo var_dump([$child->getName(), $name]);
            if ($child->getName() === $name) {
                return $child;
            }
        }
        return null;
    }

then I see what the loop was checking for a match:

How to fix my PHP Code which return me "Invalid input" when I modify "input" variable value?

If you try assigning 'option1' to $input, then it works. If you want your node to be searched for by index, then you will need to implement a method that does that.

EDIT

You can change getNode to check for the type of the input and return the index if it's integer and name otherwise:

    function getNode($input) {
        $children = $this->currentNode->getChildren();
        foreach ($children as $index => $child) {
            if ((is_int($input) ? $index : $child->getName()) == $input) {
                return $child;
            }
        }
        return null;
    }

I already removed the test file, so the edit above is untested, let me know whether it works.

huangapple
  • 本文由 发表于 2023年6月11日 21:28:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76450692.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定