![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 53 Pomógł: 1 Dołączył: 28.09.2007 Skąd: Gdynia Ostrzeżenie: (0%) ![]() ![]() |
Początkowo zadałem pytanie jak rozwiązać problem, i w jakimś amoku sam go rozwiązałem.
Problem jest stary jak PHP. Powiedzmy, że chcemy wykonać wygenerowany kod via eval(), ale nie mamy pewności, że nie spowoduje on błędu fatalnego - kładąc główny kod. Po co? Ja na przykład zrobiłem kompilator własnego języka. Nie będę się już wdawał w szczeóły po co. Był potrzebny i już. Klient zamówił - klient dostał. Problem jednak w tym, że klient skrypty w tym nowym języku musi dość często aktualizować. W dodatku klient nie jest programistą. Dlatego język skryptu maksymalnie przypomina naturalny język polski. Nie udało się jednak uciec przed jakąś podstawową składnią, w końcu to też język programowania, który w dodatku robi dość skomplikowane operacje na danych. Jeśli w skrypcie użytkownika pojawi się błąd, którego nie wykryje mój kompilator - powstanie błędny kod wynikowy, który wysypie kod główny. A to się po prostu nie ma prawa zdarzyć. Klient musi otrzymać informację, że ma w skrypcie błąd, dostać jakąś podpowiedź w postaci np fragmentu kodu, którego nie udało się wykonać. Ważne, żeby dostał informację KTÓRY z kilkunastu skryptów się wysypał. Pozostałe MUSZĄ się wykonać. Używając eval() - niewykonalne. Prosty test: @eval('return test::test();'); Jeśli nie ma klasy test - kod się sypnie. Nic po eval() się już nie wykona. Bo jak czytałem na StackOverflow - błędy fatalne są fatalne. Dobra, to teraz rozwiązanie, czyli SUPER EVAL (IMG:style_emoticons/default/smile.gif) Uwaga: żeby nie było, poprawiłem tą funkcję - dodałem escapeshellarg, inaczej kod by się wysypał od pojedynczego quota. Funkcja zachowuje się jak zwykły eval() z jednym wyjątkiem: w przypadku błędu fatalnego zwraca komunikat o błędzie jako string. Oczywiście można ją przerobić, żeby zwracała informację o tym, czy wystąpił błąd, i wartość wyjściową, to już kwestia trywialna. Oczywiście pewnie jest to wolniejsze od zwykłego evala, ale jest jedynym sposobem na uruchomienie kodu mogącego zawierać błąd. Co istotne, w razie błędu zwracany jest właściwy numer linii w której wystąpił. Nie ma żadnych ograniczeń jeśli chodzi o używanie include, require i klas wewnątrz kodu. Przyda się komuś? Ten post edytował pp-layouts 14.01.2010, 12:57:46 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 27.09.2025 - 22:56 |