Изчисляване на математически формули в PHP и Javascript - блог Kosmom
Здравейте всички. Днес ще говорим за задачата за изчисляване на определена от потребителя функция. Например, ние правим услуга за изграждане на диаграми с възможност за задаване на функция или правим някакъв аналог на Excel, в който е необходимо да се извършват изчисления по зададени формули.
Ще търсим решение в най-простите сървърни и клиентски езици - PHP и Javascript.
И така - трябва по някакъв начин да анализираме низа, въведен от потребителя. Това ще гарантира, че низът е истинска формула. Можем с помощта на сложни манипулации да разделим низа на операции, функции, да се опитаме да изчислим влагането, да намерим сравнение с вече създадени математически функции и да намерим отговора. Всичко това е твърде сложно. За тези езици има зъл операторeval().
Eval - позволява ви да изпълните произволен низ. Лошото на тази функция е, че потребителят може да посочи много злонамерен код като низ и по този начин да получи достъп или да срине нещо на сървъра. Следователно - ако решите проблема чрез eval - просто трябва да се уверите, че потребителят е въвел валиден низ.
Между другото, можем също така да позволим на потребителя да се позовава във формулата на валидни специфични за кода променливи, както и на свои собствени дефинирани от потребителя функции. Необходимо е само първо да се декларира обхватът на тези променливи и предварително да се опишат функциите.
Примерна формула може да изглежда така
Във формулата - ние казваме на потребителя предварително, че променливата може да се използва само чрез кавички. Това ще ни позволи да избегнем грешки, свързани със сливането на променливи с функции или действия.
Делението на нула е законно в PHP, то просто ще върне 0. Останалите оператори ще бъдат сумирани отделно. НаJavascript - разделянето на 0 ще даде безкрайност, но случаят е специален и не носи никакво семантично натоварване, основното е, че програмата не се спъва, а продължава изпълнението си.
За да извършим проверка - можем да прибегнем до регулярни изрази, за да разберем дали формулата съдържа само валидни символи или нещо друго. Но е дълго като изчисления. Можем да вървим спокойно. Можем да заменим всички позволени конструкции с празни и да сравним низа с празнота в края. Ако знаците останат, това е грешка, въведени са забранени знаци. Можем също да проверим броя на отворените и затворените скоби. Можем да извършим още няколко проверки, но за безопасност това е достатъчно. Ако нещо във формулата не е зададено, ще се покаже празен резултат.
За да приложим горното, ние изброяваме всички разрешени конструкции. Само редът на замяната трябва да върви от общ към частен. Тоест първо - най-често срещаните изрази, например"asin(", след това"sin(", след това"(".
Това са всички проверки. Остава само да заменим нашата променлива и да извършим злата изчислителна операция
++ и -- са забранени, защото променят оригиналната променлива, което може да не е разрешено. На . В началото на реда проверката може да бъде пропусната, защото първоначално низът ще бъде празен и ще го изчистим, ако се използва цикъл.
Можете да го използвате както желаете, да го поставите във функция, в цикъл. За Javascript всичко е същото.