I am writing a bot for a group in VK ...


How to implement a function in which when you receive the message "Subscription" and if its ID is not listed, it puts its ID in the file user_id.txt.


And when you receive the message "Unsubscribe" and if his ID is listed in this list, he removes the user ID from this list.


Ps. I will also be grateful if someone tells you how to enumerate variables (for example, hello, hi, hi, ku, etc.) and he will understand that he needs to respond to all these commands with one message.


Thank you in advance

if($user_msg == 'Подписка'){ if($user_id == "ID_USER"){ $v->msgSend("$user_name, ты уже подписан на рассылку!", $user_id, $access_token); } else { $v->msgSend("$user_name, спасибо что подписались на рассылку записей. Для отписки используй команду: Отписка.", $user_id, $access_token); } } if($user_msg == 'Отписка'){ if($user_id == "ID_USER"){ $v->msgSend("Вы успешно отписались от «Рассылки постов»!", $user_id, $access_token); } else { $v->msgSend("$user_name, вы не можете отписаться от рассылки, так как вы не были подписаны на неё.", $user_id, $access_token); } } 

    1 answer 1

    The text file may not be the best storage, but it will come down for learning.

    The first step is to come up with a format for storing data in a file. These may just be id separated by a character that will never appear in id. Let it be a newline character \n , for example.

    Further, to search in already recorded id, their values ​​must be read:

     $idsFile = __DIR__ . '/user_id.txt'; $idsStr = file_get_contents($idsFile); $ids = array_filter(explode("\n", $idsStr)); var_dump($ids); 

    Accordingly, it is possible to check that the id is already among the previously saved id using the array_search function. If the user is not yet in the list and Subscription, then add him to the $ids array, if the Unsubscribe and the user are in the array, then delete:

     $pos = array_search($user_id, $ids); switch ($user_msg) { case 'Подписка': if ($pos === false) { $ids[] = $user_id; $v->msgSend("$user_name, спасибо что подписались на рассылку записей. Для отписки используй команду: Отписка.", $user_id, $access_token); } else { $v->Send("$user_name, ты уже подписан на рассылку!", $user_id, $access_token); } break; case 'Отписка': if ($pos !== false) { unset($ids[$pos]); $v->msgSend("Вы успешно отписались от «Рассылки постов»!", $user_id, $access_token); } else { $v->msgSend("$user_name, вы не можете отписаться от рассылки, так как вы не были подписаны на неё.", $user_id, $access_token); } break; case 'привет': case 'хай': case 'ку': // break; } 

    Well, it remains to save the $ids array to the file:

     file_put_contents($idsFile, implode("\n", $ids)); 

    However, this method has many disadvantages.

    1. Multiple simultaneous requests can mismatch data in a file. For example, for one request, the script will read the file and add id 123, but will not have time to write the changes to the file. And at this time for the second request the file will be read (without 123) and id 456 will be added to it. Now the first handler will write the file with 123, and then the second handler with 456. Thus, there will not be a 123 record in the file (it will be overwritten by the second handler) .
    2. Reading and searching a large file can take considerable time.

    These problems are well known and solutions for them have long been invented. To ensure consistency of data, locks are used (while one is working with the file, the others are waiting). To speed up the search, indexes are used (this is like an alphabetical index in a book; it allows you not to scroll all over again, but to immediately open the necessary page).

    Implementing locks and indexes can be quite a challenge for a beginner and quite boring for a highly experienced developer, but there is a ready-made solution! This is a database. The easiest option could be SQLite , you need to master PDO to work with it. The ability to work with databases will not only help you in a task with a bot, but will also be very useful in the future.

    • I can’t understand how case works for passing more than one value. After going through your advice and reviewing the article came to this conclusion ( pp.userapi.com/c850324/v850324509/ca7f8/qtWb10xOU8I.jpg ) ( vk.com/wall-93782265_1154 ) (swears on the restriction on the code) ... As in this case assign additional values, so that he would understand, for example, not only Subscribe, but also subscribe, activate, run ... Thanks in advance =) - Timofey Kucherbaev
    • For the switch operator ( php.net/manual/ru/control-structures.switch.php ), one value is specified after the case, but if you specify several cases in a row without separating them with breaks, then for all these cases one piece of code will work. The same can be done with if; there you should use the logical operator || (or). - Yegor Banin
    • Returned to the original version, as you suggested. But there was a problem, the bot sends instead of one answer 2. That is, he answers two times to “You have already signed” with one “Subscription” message. And if you write "Subscription" and then after a couple of seconds "Unsubscribe" then he will start sending a lot of messages almost without stopping ... All code (from and to) with sending a message here vk.com/wall-93782265_1155 I can not even understand what is the re-sending of messages ... - Timofey Kucherbayev
    • @ TimofeyKucherbaev write in the ebanin cart, we will understand. - Yegor Banin