O tym, że PHP ssie!

O tym, że PHP ssie!

Dziś będzie o pewnym lubianym przez wszystkich języku programowania. Z pewnością w ten artykuł nie będzie wyczerpujący i dokładny. Będzie też za długi by niedzielni czytelnicy przebrnęli do końca. Przemyslenia tutaj zawarte są podparte moim doświadczeniem z tym „ssącym” językiem i krótkim (bo 2 letnim) kontaktem z porządniejszymi językami, zdobytym podczas studiów.

Język zna chyba każdy, kto dotykał problemu tworzenia stron internetowych głębiej niż tylko statyczne strony z obrazkami. Język szalenie popularny i często stosowany. Tylko, kaczka, czemu?

Personal Home Page powstał ponad 15 lat temu jako proste skrypty wykonywane po stronie serwera. Autor używał swojego wynalazku do śledzenia, kto czyta jego CV. PHP miał służyć też takim duperelom, jak wstawienie aktualnej daty, czy prosty licznik odwiedzin. Banalne makra, obsługa formularzy, w końcu – obsługa bazy danych. [1]

Dziś ten język jest obecny nawet na darmowych hostingach, a zna go chociażby syn sąsiadki, który zrobi firmie szanownego pana prezesa stronę za 10% jej rzeczywistej wartości. Personal Home Page Tools rozrósł się do takich rozmiarów, że używają go największe portale internetowe i bardzo poważne witryny. Tylko, nie rozumiem, czemu? Czemu mimo tylu wad jest taki popularny? Tego roztrząsać nie będę, skupię się raczej na samych cechach języka, które mnie przeszkadzają najbardziej.

Pierwszą wadą, która wkurza niemiłosiernie jest brak konsekwencji w rozwoju PHP.
Raz mamy nazwę w notacji podkreślnikowej, innym razem w konwencji wielbłądziej. AddSlashes i phpInfo obok ini_set. W samym PHP jeszcze da się to przełknąć, ale w zewnętrznych frameworkach jest już totalny sajgon. Wystarczy porównać framework Joomli i Zend. Jakby tego było mało, przykładowo funkcje wyszukujące przyjmują parametry w różnej kolejności. Raz jest to haystack, needle a innym razem needle, haystack. Raz jest array_map(‚callback’,$array) a innym razem array_filter($array,’callback’). Czy nie można było rozwijając język zadbać o spójne nazewnictwo? [2]

Drażni duplikowanie funkcji. Mamy funkcje implode i explode obok split i join. Czemu to służy – nie wiem. W samochodzie piąte koło się przydaje, gdy jedno padnie. W PHP to piąte koło jest podpięte cały czas, chociaż nie trzeba go wymieniać. Do wyszukiwania wewnątrz stringów możemy użyć funkcji z rodziny str*, preg*, ereg*. Różnią się sposobem działania, specyfiką, szybkością. Początkujący webmaster lub programista który specyfiki danej rodziny funkcji nie poznał stosuje je wymiennie, lub tylko tą grupę która więcej potrafi i którą wcześniej poznał. Czemu nie można było stworzyć kontenera wyszukiwania, który zwracałby odpowiedni obiekt realizujący wyszukiwanie, na przykład: match.get() match.getRegExp() match.getPreg() do pobrania odpowiednio obecnie najwydajniejszego (w danej wersji) operującego na prostych stringach, najwydajniejszego bazującego na wyrażeniach regularnych i w końcu specyficznego obiektu? Admin lub programista, gdyby chcieli, mogliby łatwo ustawić, co ma być tym najlepszym backendem. W ten sposób można ukryć implementację przed użytkownikiem, a jemu pozwolić korzystać z poleceń w sposób bezstresowy. Nie byłoby dylematów, który wybrać, nie krzywiłbym się na widok ereg, a pani dr na labolatoriach by się nie dziwiła, że preg_ jednak można zmusić do pracy… Innym problemem jest niekonsekwencja w zgłaszaniu błędów. Raz mamy e_warning innym razem wyjątek. Czasami przy nieudanym wykonaniu funkcje zwracają zero lub -1. Nie można by się tak zdecydować tylko na jeden sposób?

Razi mnie w tym języku porąbana składnia. Zmienne mogą sie brać z powietrza, wszystkie muszą mieć dolarka przed nazwą do którego napisać jednym palcem się nie da. Każde polecenie musi się kończyć średnikiem. I nie ma przebacz. Nie ma, że brak średnika nie zmienia niczego. Rozumiem, że dolarki to spadek po Perlu, a średniki po C, ale bez przesady. W Perlu znaczki przed zmiennymi mówią jak zmienna będzie alokowana i jaki ma charakter. W PHP – nie. Mogę wskazać wiele języków, które bez obowiazkowych średników i dolarków sobie doskonale radzą. I nie osłabia to czytelności kodu.

Cechą języka, którą poczatkujący lubią jest brak stałego typowania. Możemy bezkarnie napisać: $sql=0; $sql=”select * from tabela”; a potem napisać: $sql=mysql_query($sql); i nic złego się nie stanie. Gorzej, gdy przyjdzie nam porównywać wartości różnych typów. String z intem. String zawierający liczbę zostanie obcięty do liczby i tak zostanie porównany. Wstawimy to to do zapytania SQL i katastrofa gwarantowana. Nie mówię już o tym, że wystarczy drobna literówka w nazwie zmiennej, by kod się wykonał, ale z efektem bardzo różnym od oczekiwanego. Normalny język rzuci błędem czy wyjątkiem. Natomiast PHP przybierze kamienną twarz i będzie się śmiać w duchu: a teraz szukaj sobie gdzie jest błąd!

Zdaję sobie sprawę, że wady które wymieniłem biorą się z kompatybilności wstecznej i rozwijania silnika PHPa w nieładzie, bez koordynacji przez długi czas. Że większość tych problemów możnaby wyeliminować stosując OOP. Tylko, czemu dziś mamy w PHP tylko namiastkę obiektowości? Specyfikatory dostępu pojawiły się dopiero w PHP5. O przestrzeniach nazw do wersji 5.3 można pomarzyć jedynie. Z pewnych względów, separator też będzie udziwniony. Zamiast :: jak w c++, albo kropki jak w c# czy javie – backslash. [3] Największą zagadką pozostaje pytanie, kiedy PHP 5.3 lub PHP6 zawitają na serwery?

Inną cechą, która drażni mnie niemiłosiernie jest tendencja do myślenia za programistę i administratora serwera. PHP posiada dyrektywę safe mode, która odcina dostęp programisty od funkcji, które przy złej konfiguracji serwera mogą pozwolić coś namieszać. Z drugiej strony admin niedbale ustawi innego użytkownika na FTP, innego na webserver, wgramy plik skryptem na serwer i już nie usuniemy po FTPie. Safemode mocno utrudni to zadanie. PHP sam z siebie pozwala uruchomić polecenia powłoki. Dzięki temu zamiast pisać długi kod do wylistowania aktualnego katalogu piszemy `ls`. Proste, prawda? Ale po co? Safe mode na on i nici z tego. Kiedyś wykorzystałem notację apostrofów do uruchomienia zewnętrznego programu zamieniającego DOC na HTML. Na serwerze z safemode okazało się to niemożliwe.

Kolejną, dużo bardziej niebezpieczną funkcjonalnością jest register globals. Pozwala na podanie w formularzu (lub w pasku adresu) zmiennych i utworzenie ich automatycznie w skrypcie. Tak z powietrza. Potem zły chakier wywoła skrypt który miał być dołączany do innego, poda odpowiednie zmienne i skrypt się wykona, jak gdyby nigdy nic. A my dostaniemy włamanie na naszą witrynę. RG można wyłączyć, ale też niezawsze. Z bliżej nieznanych mi przyczyn na serwerach pewnej firmy na O, z ostatnią literką nazwy na M ustawienie dyrektywy wyłączającej RG wywołuje błąd 500 serwera. I bądź tu mądry, co jest przyczyną. Lepiej jest myśleć za programistę i powoływać za niego zmienne, a potem zmusić go do dbania o bezpieczeństwo tego skryptu.

Kolejną taką fajną funkcjonalnością jest Magic Quotes. Pierwotnie miało to zabezpieczać skrypty przed dodaniem wykonywalnych ciągów danych. W manualu do PHP zalecają wyłączenie tego, jednak wielu administratorów zdaje się mieć to zalecenie w poważaniu i pozostawia MQ włączone. A programista musi się martwić, żeby na nowym serwerze działało sprawnie…

Od czasu gdy PHP używa baz danych, a pseudoprogramiści w PHP budują strony internetowe spotykamy SQL Injection. Gdyby chociaż zapytania były prekompilowane, a dopiero potem uzupełniane treściami, problemu by nie było. PDO to potrafi. Tylko PDO jest bardzo młode i niewiele osób je stosuje. Efekt? Na labolatorium w którym prowadzacy kazał się zarejestrować w napisanym przez niego systemie gromadzacym oceny ustawiłem sobie piątkę jako ocenę końcową, na pierwszych zajęciach. Oczywiście było full disclosure, ale wykładowca był niepocieszony. Czy projektując język nie dało się o tym pomyśleć?

Zbliżając się do podsumowania chcę powiedzieć, że PHP jest łatwy do nauki. I powinien pozostać językiem do nauki. Taki nowoczesny Pascal. Pozwala na bardzo wiele, dużo toleruje. Początkujący pod okiem mistrza zostałby zganiony za błędy i nauczył się, jak pisać porządnie. Bez potworków w makaronowym kodzie. Cóż, tak niestety nie jest.

Kolejne wersje języka wyglądają coraz porządniej, ale dziedzictwo starszych wersji jest trudne do udźwignięcia. Zmusza do utrzymywania całego tego nagromadzonego przez lata bajzlu. Najlepiej byłoby całość rozwalić i zbudować odnowa. Taką koncepcję, wraz z wskazaniem koniecznych zmian przedstawił na swoim blogu Zyx [4]. Mi osobiście postulowane przez niego zmiany się podobają, jednak chcę uciekać od tego języka. Im szybciej i im dalej, tym lepiej. Java, Python, C++, C#. Z naciskiem na 2 ostatnie.

Na końcu wyjaśnię, że do napisania tego tekstu bardziej mnie zmobilizowały wejścia na mój blog z keywordu „php ssie” i jego wysoka pozycja w ^g na to hasło, niż moje ewentualne problemy z tym językiem. Na tę chwilę ich po prostu nie mam, dyskutuję za to z pythonem. 😛

[1] http://minimax.aster.net.pl/kursy/php-podrecznik/intro-history.html
[2] http://www.phpdevblog.net/2009/08/haystack-needle-sheet.html
[3] http://wiki.php.net/rfc/namespaceseparator
[4] http://www.zyxist.com/pokaz.php/jak_mogloby_wygladac_php
http://ferrante.pl/2007/07/07/mamo-umiem-php/

  • BTM

    1) str* i preg*/eregi* – pierwsze operuje na stringach, pozostałe na wyrażeniach regularnych

    2) safe_mode, magic_quotes, register_globals – część już pożegnana, część odpada w PHP6

    3) literówka w nazwie zmiennej? IDE Ci nie pokazuje, że jest unused / undefined? To daj error_reporting na E_ALL a może i E_STRICT

    4) SQL Injection – tu wini programista produktu końcowego a nie język / jego projektanci

    Zresztą – mądrze mówisz dopiero na końcu – jeżeli ktoś ma dyscyplinę, wiedzę i chęci to będzie pisał dobry kod. Nie widziałeś sphagetti-code w C, Javie czy innym C#? Na pewno widziałeś.

    Za ile ten wątek wpadnie do najczęściej komentowanych na Joggerze? Obstawiam, że do jutra rana będzie na pierwszym miejscu 🙂

  • @BTM:
    Sądzisz, że mój blog trafi do top ten? 😀 Jest piątek wieczór. Nie wierzę, że tyle osób siedzi i czyta joggera zamiast wyjść i się kulturalnie bawić 😀

  • Ja nie wychodzę dziś z domu. Całego tekstu też nie przeczytałem. Nie znam PHP. Ale domyślam się czemu może być tak popularny. Właściwie sam to napisałeś. PHP możemy znaleźć na prawie każdym hostingu i w PHP pisze syn sąsiadki co tylko udowadnia jak mała jest bariera wejścia do PHP. Mała bariera wejścia powoduje, że znakomita większość programistów PHP to straszne leszcze, które tworzą koszmarne potworki.

  • Dobra, wymiękłem w połowie. Jak rozumiem autor nie bardzo orientuje się w PHP, jest przykładem właśnie takiego ‚syna sąsiadki’, który owszem, stronę napisze, może nawet będzie działać, tylko potem to wszystko jest do przepisania. I to jest największa wada PHP, że każdy może się go nauczyć i potem się chwalić jaki to on mądry i co potrafi z niego wytrzaskać.

    Parę uwag, ~BTM zapodał wiele cennych, ale ja jeszcze dorzucę kilka:
    – praktycznie wszystkie języki skryptowe mają dynamiczne typowanie, np. Python, Ruby, JavaScript etc…
    – autor nie słyszał chyba (syndrom ‚syna sąsiadki’) o operatorach np. ===
    – funkcje ereg* są już przestarzałe i nie wypada ich używa (dokumentacja twoim przyjacielem)
    – część funkcji to aliasy, bo najwyraźniej ktoś chciał je takie…
    – obiekty w PHP pojawiły się bodaj od wersji 4tej, jednak dopiero w 5tej można ich jakoś używać.
    – itd.

  • Jeśli już mnie wywołałeś…
    Pierwszy akapit pominę, bo jest jeno przypuszczeniem opartym o produkt mojej niechęci do pewnego języka.. Cóż, mniejsza o to, nie lubię takich wniosków, ale ich nie powstrzymam.

    Odnośnie ===
    Autor, owszem, słyszał, wie, jak działa operator porównania zmiennej wraz z porównaniem typu. Jednakże widział wystarczająco dużo skryptów, w którym zachodziła przedstawiona w tekście sytuacja, by taki przypadek opisać. I nadal ma zdanie, że w tej kwestii lepsze jest rozwiązanie z Javy, wymuszające zgodność typów przy porównaniu. Poniekąd wygodne jest rozwiązanie z C, ale ono jest przegięciem w drugą stronę (mam na myśli głównie 0 przy arytmetyce wskaźników)

    W kwestii pozostałych punktów – napisałeś podobne treści, co ja, tylko w krótszej i bardziej przejrzystej formie…

  • Pierwszy akapit pominę, bo to próba obrony swojego stanowiska.

    Co do operatora, PHP to język jest skryptowy, więc ma dynamiczne typowanie (bo to jest prostsze do operowania, no i to zaszłość z Perla), więc istnieje do operator porównywania typów. Wbrew pozorom dynamiczne typowanie można całkiem miło wykorzystać. Strach pomyśleć, co będzie jak zaczniesz uczyć się z JavaScript.

    Jeśli chodzi o arytmetykę na wskaźnikach w C, to wynika ona z tego, że działa na numerów adresów w pamięci, to nie jest jakiś wymysł projektantów języka.

  • Może w to nie uwierzysz, ale znam js. Miałem też do czynienia z actionscript – są bardzo podobne. I powiem, że dla mnie as jest bardziej zrozumiały i wygodny od wersji trzeciej, gdzie wprowadzono deklarowanie typów zmiennych.

    Wiem, skąd w C się bieże artytmetyka wskaźników i jak działa. Po prostu podoba mi się to, że mogę do wskaźnika przypisać zero, a następnie ten wskaźnik testować w if’ie. Wg mnie jest to wygodne. Wygodniejsze niż zmienne biorące się z powietrza.
    A przy okazji perla (którego nie znam prawie wcale, do czego się przyznaję), jak to jest, że jedne zmienne tablicowe mają za przedrostek @ a inne %. Czy PHPowe wszystkomające zmienne są aż takie fajne, że nie można było skopiować rozwiązania perlowego? I w tym momencie pytam się bez złych intencji – ciekawi mnie to po prostu.

  • > Wygodniejsze niż zmienne biorące się z powietrza.

    Patrz pierwszy komentarz.

    > Czy PHPowe wszystkomające zmienne są aż takie fajne, że nie można było skopiować rozwiązania perlowego?

    Wydaje mi się, że ujednolicono wszystkie zmienne, aby nie mieszać użytkownikom języka.

  • IDE nie zawsze jest rozwiązaniem. Szczególnie, że nie zawsze IDE potrafi w pełni rozpoznać, o co tak na prawdę w projekcie chodzi. Miałem trochę do czynienia z Joomlą, w której Netbeans i Eclipse/PDT nie wyłapywały wszystkich zależności, nie były w stanie poprawnie rozpoznać co z czego dziedziczy – i w efekcie przestałem ich używać, zadowalając się czymś lżejszym. Przełączenie się na E_ALL i E_STRICT też nie jest rozwiązaniem – gdy w takiej Joomli włączysz oba, dostaniesz multum komunikatów z ostrzeżeniami. Nie o to chodzi.

  • Z tym IDE, to cię akurat rozumiem, choć bodaj od 5tki można zadeklarować typ argumentu (właściwie to nie typ, ale jakiego obiektu jest argument), Eclipse wtedy sobie jakoś radził z podpowiadaniem. Co od Joomli, cóż, widać, trzeba ją poprawić.

  • BTM

    @mt3o: Joomla, pewnie jak każde inne "Wielkie Open Sourceowe PHP Cudo" ma totalny śmietnik w kodzie. Szczególnie, że pisane było głównie pod PHP4 a potem hackowane na PHP5.

    Ja swój framework pisałem od podstaw i np. phpEd doskonale sobie radzi z rozpoznawaniem nawet i własnych obiektów – a jak nie radzi to dodajesz dokumentacje w formacie JavaDoc i już sobie radzi. Jak dalej nie radzi – zawsze zostaje jawne rzutowanie. Ale jak sam mówisz – to jest po stronie IDE a nie języka.

  • BTM: zajrzyj do kodu Magento. Też jest OpenSourcowy, bardzo dobry kod. Jak się umie, to można.

  • Stąd mój wniosek, że takie rzeczy powinny być rozwiązywane na poziomie języka, a nie, ekhem, programisty.

  • BTM

    Sigvatr: domyślam się, ale Magento było już na PHP5 robione. Zajrzyj do kodu osCommerce 😉

  • Zły programista potrafi zrobić sajgon w każdym języku.
    BTM: tak, od 5/

  • Magento jest pod php5. Nawet 5.2 (z powodu zend frameworka). Znam go dość pobieżnie, ale chcę wykorzystać w pracy licencjackiej na temat e-commerce, więc siłą rzeczy – muszę go lepiej poznać. Oscommerce nawet się nie próbuję dotykać. Boję się go po prostu 🙂

  • motasz się. raz narzekasz, że PHP na siłę myśli za programistę, a potem, że PHP nie myśli za programistę i coś nie jest rozwiązane na poziomie języka.

  • Może niezbyt jasno to napisałem. PHP myśli za programistę/administratora (RG, Magic Quotes, Safe mode), co powoduje problemy z bezpieczeństwem, lub usuwa bardzo wygodną funkcjonalność. Tymczasem znacznie bardziej wolałbym, aby PHP wzorem Javy wymuszał odpowiedni styl programowania. I był bardziej IDE friendly 😉

  • Mt3o: więc zamiast PHP używaj servletów. PHP ma swoje wady, ale ma też pewne założenia i m.in. dynamiczne typowanie jest jednym z nich.

    > myśli za programistę/administratora (RG, Magic Quotes, Safe mode)

    Dobry programista wie to jak wyłączyć.
    Co do Safe mode, to jest bardziej dla właścicieli hostingów, żeby synowie sąsiadek nie ro**** serwera, czy innych kont.

  • PHP ssie, ale nikt jeszcze nie wymyślił lepszego języka do Weba, Ruby z ROR, czy Python z Django? Proszę.., tylko jacyś gimnazjaliści którzy programują od tygodnia coś w tym piszą, tak wiem że są duże webappy w tym pisane, ale i tak z stabilnością PHP nic nie wygra, dlatego większość dynamicznego contentu nadal na PHP śmiga, amen 🙂

  • Ten język nie był zaprojektowany, on był sklecony na szybko. Proszę: http://en.wikiquote.org/wiki/Rasmus_Lerdorf Potem już było tylko gorzej – przez kompatybilność wstecz.

    Pecet: Nie masz pojęcia o czym piszesz. Programujesz w czymś poza PHP?

  • wikiquotes — ty tez nie masz pojecia, bo sam dajesz linka do wikiquotes które jest oparte o mediawiki, a zgadnij w czym jest mediawiki napisane? no właśnie, my point exactly

  • Jogger jest napisany w PHP. Skomentowałem za pomocą tego formularza, wysyłającego dane do skrypu PHP. Czyli co, cały komentarz się nie liczy, bo skorzystałem z PHP?

    Programujesz w czymś poza PHP?

  • wikiquotes– Zdarza mi się napisać coś w C++

  • Ok, więc nie znasz na tyle składni Ruby ani Pythona co składni C. Pytanie jak obiektywny możesz być mówiąc, że tamte języki rodzą frameworki dla gimnazjalistów – skoro nie robiłeś w nich nic. Mogłbym dalej pytać czy zrobiłeś jakies webaplikacje bądź chociażby strony, ale sobie daruję.

    Duże serwisy (takie jak Facebook, Digg czy Flickr) są napisane w PHP, ponieważ powstały na początku tej dekady – wtedy nie było tak rozreklamowanej alternatywy i liczył się biznes. Łatwiej zatrudnić taniego programistę, jeśli jest ich mnóstwo na rynku. W artykule ładnie to jest opisane.

    PHP nie jest przyjazne developerowi, a żeby je uczynić trzeba albo 1) dodać narzut w postaci frameworka zwalniającego go do szybkości alternatyw 2) wydać mnóstwo pieniędzy na sprzęt lub przepisać wszystko na prekompilowany kod (jak Facebook zrobił ostatnio).

  • BTM

    @wikiquotes: pst, w przypadku Ruby, Pythona czy innej Javy też zwykle używa się frameworków więc ten argument jakoś do mnie nie przemawia 😉

    Facebók zrobił ostatnio – ale let’s face it – jak ktoś napisze serwis pokroju FB to najmniejszym jego zmartwieniem będzie to, co ludzie myślą o języku jaki wybrał 😉

  • @Sigvatr: Servlety chciałbym mieć. Niestety hostingi jakie mi się zwykle trafiają nie wspierają javy, nie zawsze mam wpływ na wybór hostingu. Stąd uczę się pythona, który znacznie częściej jest wspierany przez hosting.

    Odnośnie safemode i RG, to problem jest w tym, że nie zawsze da się wyłączyć. W pewnej witrynie wisi i grozi luka związana z RG tylko dlatego, że po ustawieniu dyrektywy w .htaccess apache robi błąd 500 i odmawia współpracy. To samo występuje, gdy wyłączę to z poziomu php.ini i skryptu. Jest jeszcze jakaś możliwość, której ja nie znam?

  • http://pl.php.net/manual/pl/function.get-defined-vars.php i unsetujesz wszystko poza interesującymi cię POST i GET. Tak, wiem, kolejny hack – ale jak admin serwera daje dupy to sorry.

  • Krzysztof Trynkiewicz

    Stary… ===, magic quotes, register globals, safe mode… przeczytales jakis samouczek o php4 i oceniasz jezyk, czy tylko takie sprawiasz wrazenie?

    wytykasz bledy adminow httpd, programistow nie uzywajacych pdo, nie potrafiacych robic porownan, nie potrafacych zabezpieczyc skryptow…

    tylko gdzie tu cos o jezyku? ze sa dynamiczne typowania? o zgrozo 😀

    nc

  • @Krzysztof Trynkiewicz: Niech i tak będzie, że tylko samouczek przeczytałem. Nie mam zamiaru udowadniać, ze na napisałem w danym języku 20 czy 20 000 linii kodu.
    Gdzie jest o języku? Jeśli to co powyżej nie jest, to może fragment o niekonsekwentnym nazewnictwie i kolejności parametrów jest? Chociaż w sumie to nie jest problem języka, tylko devów tego języka. Ech, dobra, zaraz zmienię tytuł tekstu na: wszystko prócz php ssie….

    @BTM: jest jeszcze jedno ale: nie mam pewności, czy wszystkie pliki ze skryptami w tej tam Joomli mają sprawdzenie, czy nie zostały przypadkiem wywołane wprost, zamiast przez require/include… Nawet gdybym na początku index.php usunął wszystkie zmienne z RG, nie mam pewności, że nigdzie więcej nie wystąpi ryzyko. Hack sprytny, ale nie idealny. Zapamiętam go. Dzięki!

  • BTM

    Nie znam się na Joomli, ale na bank jest jakiś jeden plik, który jest przez inne "widziany" – chociażby konfiguracyjne jakiś, połączenie z DB. Jak hackować to na maxa! Hack the Planet!

  • Matikx

    Wszystko zależy od programisty… To on nadaje językowi charakter, to jest prawie tak samo jak z językiem żywym/mówionym. Albo masz akcent wyuczony z rejonu, albo mówisz jak syntezator [ co mi się kojarzy z niektórymi rejonami WB].