Rozsypały się literki z unikodu, a kotek jeszcze by chciał

Rozsypały się literki z unikodu, a kotek jeszcze by chciał

W interneciku na serwerku,
Stała stronka i contencik.
Przyszedł substr, ciachnął tekścik,
A ogonkiem spsuł unikodzik..

W projekcie, nagle, w nieprzewidzianym miejscu rozsypał się UTF-8. Na jednej podstronie, choć pozostałe generowane z tego samego szablonu – były ok. Żeby było śmieszniej, rozwalony kod był od połowy strony, wcześniejsze krzaki w źródle były ok. Dopiero po pewnym fragmencie – były źle. W połowie strony zepsuło się UTF-8 i wyświetlały się krzaki. Ciekawostka…

Winnym okazał się substr w php. To bezhołowie nawet nie podejrzewa, że istnieje coś takiego jak unikod, proszę państwa!

Zdarzyło się tak, że substr uciął treść, zgodnie z założeniem, po 1024 znakach. Pech trafił, że substr liczył znaki zgodnie z ASCII czyli jednobajtowo, a w UTF-8 znaki spoza zakresu zajmują więcej niż jeden bajt. Eksperymentalnie sprawdziłem, że to substr jest odpowiedzialny za rozkład i zgniliznę w reszcie strony.

Zapamiętać: na unikodzie robimy mb_substr( $string, $start, $end, ‚utf-8’)

  • O ja… Jakie rymy! Ukryte talenty odkrywasz 😉 Aż sobie wydrukuję i powieszę nad biurkiem 😀

  • http://sjp.pwn.pl/haslo.php?id=2552057

    I zapamiętać nie że używamy mb_string(), tylko że nie używamy PHP.

  • Dzięki, poprawiłem ort.

    A co do porady o nie używaniu PHP – dziękuję. Równie dobrze mógłbym to powiedzieć o dowolnym języku. Używa się tego, co się najlepiej zna i to, co w danej chwili jest najbardziej potrzebne. W takim terminie, jaki miałem narzucony, nie nauczyłbym się dobrze django, railsów czy co tam teraz używają cool kids. PHP był w chwili wyboru języka – optymalnym wyborem. Poza tym, od kiedy poznałem Laravel, a numerek wersji osiągnął wartość 5.5, to nie jest już ten sam język, o którym pisałem kiedyś, że ssie.

  • Jeśli nie PHP to co? Python i Rubby wydają się tak samo nietrafionym wyborem. Ponoć Java najlepsza ze względu na wydajność/złożoność, a PHP dostępność. Gdyby istniały jakieś fajne, darmowe frameworki to pewnie z chęcią bym przetestował C++ w tej roli. 😀

  • mt3o

    No właśnie, ma każdy język i framework można znaleźć powody na ‚nie’. Może bym spróbował groovy, ale musiałbym kombinować z serwerem. No i też jest problem, że go nie znam zbyt dobrze

    Albo nodejs z javascriptem czy nawet coffeescript, ten duet wygląda zachęcająco, jeden język do wszystkiego, tylko znowu – nie znam go aż tak dobrze.

  • …byle nie C#. Wtedy nawet PHP jest lepsze 🙂

    @SebaS86: Nie wierzę, że takich frameworków nie ma. Z drugiej, poza wszystkimi problemami z webdeveloperką, brakuje nam tylko jeszcze segfaultów.

    @topic:

    Pisałem trochę w PHP i naprawdę nie znoszę tego języka. Chociażby dlatego, że bez errorreporting(EALL) przemilczy mi on prawie wszystkie istotne dla mnie ostrzeżenia, użycie niezdefiniowanej zmiennej (czy klucza w tablicy) nie jest errorem, a nazewnictwo funkcji w bibliotece standardowej jest tak niespójne, że bez dokumentacji nie da się kodzić. No i moja przygoda z CakePHP właściwie zwieńczyła zabawę z PHP, kiedy po połączeniu wszystkich tych cech interfejs był definiowany przez klucze w tablicach asocjacyjnych, przy czym jakiekolwiek pomyłki były po prostu… ignorowane.

    Serio, Django, RoR, cokolwiek, nawet Java (ale nie C#). Ale nie PHP, chyba, że istnieje taki PHP, którego jeszcze nie widziałem i da się w nim kodzić 😉

  • sprae

    Najlepiej na Perl-a 😛

  • Oh come on. 😀 No dobra, lista koszernych języków strasznie się zawęża 😛

  • Segfaultów zaraz… a wiesz skąd się w ogóle biorą? W innych językach możesz się naciąć na null pointer exception albo inny wyjątek przy próbie dostępu do zasobu, który został zwolniony. Problem wygląda nieco inaczej, za to konsekwencje zazwyczaj są zbliżone. W C++ można uniknąć wielu takich problemów. Ich nieuchwytność też jest trochę przereklamowana. 🙂 Swego czasu postanowiłem poszukać frameworka i doszedłem do wniosku, że C++ po stronie serwerowej, serwującej dane po HTTP to coś bardzo dziwnego. Znalazłem kilka ale były albo płatne albo skażone licencją wirusową.

    A czemu nie C#? Kwestie licencyjne czy sam .Net? Jak dla mnie czysty język jest całkiem przemyślany i wygodny w użyciu.

  • Kwestie licencyjne i przenośność. A co do intuicyjności C++-a, wystarczająco miałem okazję się w nim bawić, żeby nie wierzyć, że jest to język równie „bezpieczny” jak np. Python. Wiem, skąd się biorą segfaulty – na przykład z tego, że zapomniałeś o Świętej Trójcy i jakiś wskaźnik Ci się przepisał przez automatycznie stworzony konstruktor kopiujący 😛

  • sprae

    Mimo wszystko w Facebooku robią HHVM, który tłumaczy PHP na C++. Jest w niego zaangażowana dość znana postać w świecie C++.

    http://channel9.msdn.com/Events/GoingNative/2013/Writing-Quick-Code-in-Cpp-Quickly

  • W Facebooku używają też MySQL. Wcale jeszcze to nie znaczy, że to generalnie dobry pomysł.

  • sprae

    Używali, i to w sposób całkowicie pozbawiony relacyjności. Chyba głównie przez to, że ta baza dobrze się synchronizowała.

    Po pierwsze ma działać.

  • To samo chciałem pisać. Widziałem taką implementację na MySQL i trochę się zdziwiłem, ale jeśli to działa… BD i generalnie server side to nie moja działka, ale jeśli ludzie tak chwalą NoSQL (rozumiem, że chodzi po prostu o nierelacyjne bazy danych, bo sam SQL czy jego brak nie ma tu znaczenia) to czemu nie spróbować wykorzystać wzorców na innej implementacji bazy danych.

  • @Dee:

    …byle nie C#. Wtedy nawet PHP jest lepsze 🙂

    +1

    error_reporting(EALL) przemilczy mi on prawie wszystkie istotne dla mnie ostrzeżenia

    EALL nie daje komunikatów o błędach typu niezdefiniowana zmienna, ale jest jeszcze ESTRICT. Sporo rzeczy wyłapuje Whoops wbudowany w Laravel. Jak pisałem, od wersji 5.4 i z takim frameworkiem jak Laravel, całkiem przyjemnie się z tego korzysta.

    O spójności nazewnictwa nawet nie chcę nic słyszeć, to tragedia 🙂 Polegam na świetnym IDE

    CakePHP to rzeczywiście koszmarek, ale Laravel? Albo Symfony? Są całkiem całkiem.

    http://filp.github.io/whoops/

    @SebaS86: sam zaadoptowałem klasę realizującą NoSQL na MySQL, a potem znalazłem RedBeanPHP który w locie modyfikuje strukturę bazy danych. Świetna sprawa, tylko tutaj, jak przy NoSQL łatwo się zakopać komplikując strukturę danych. No i trzeba sprawdzać dane wejściowe bardziej niż przed tradycyjnym sqli (rb ma patent na to – zablokowanie możliwości edycji bazy gdy baza zostanie już dobrze złożona). Wystarcza w niewielkich projektach, w większych – polegam na tradycyjnym podejściu.

    @dozzie:
    Tak, znam ten tekst. W wielu miejscach się zgadzam, ale ideowe podejście i „lepszość” narzędzia sobie, a rzeczywistość sobie. Jak pisałem, najlepszy język to ten który najlepiej znasz i możesz w danej chwili użyć.

    PHP ma i tak lepszą opinię niż COBOL 😛

  • PHP ma i tak lepszą opinię niż COBOL 😛

    Bo ja wiem? COBOL przynajmniej jest dziś hipsterski 😛

  • Hipsterski może być dart, go, closure, ewentualnie może lisp. COBOL to wrzód na tyłku i kaftan na oddziale zamkniętym.

    The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence.

    Edsger Dijkstra

  • sprae
  • sprae

    Jeśli chodzi o COBOL i web to właśnie ktoś mi podesłał COBOL on Wheelchair

  • mt3o

    Wypaliło mi mózg…

  • Prawie rok temu miałem bardzo podobny problem: http://drax.jogger.pl/id/498821/ 🙂 Wiesz, generalnie zgadzam się z Twoją opinią, że używa się akurat tego, co jest poręczne i najlepiej się nadaje do rozwiązania problemu. Dopuszczam jednakowoż 2 wyjątki od tej zasady:

    C# to owoc kazirodczego związku C++ z Javą, a jak by tego było mało, ojcem, nomen omen, chrzestnym jest Microsoft. Każdy prawowierny programista winien trzymać się od tego z daleka. :p Kiedyś napiszę dłuższy (i poważniejszy) tekst na ten temat, bo widzę, że środowisko go potrzebuje. 😉

    PHP zawsze był bardzo modny. Kiedy coś od dekad usilnie stara się być modne, to musi być obrzydliwe. Sęk w tym, że mody się zmieniają i ciągłe dostosowywanie się do nich, nieuchronnie skutkuje brakiem spójności. Sam to zresztą zauważyłeś. To immanentna cecha PHP. Bez cienia przesady, można powiedzieć, że w składni tego języka odbija się połowa historii naszej dyscypliny.

    W początkach PHP modny był C, więc podstawy PHP wyglądają bardzo podobnie do niego. Kiedy PHP się zmieniał (i starał się nadal być modny), królowała już Java, więc nieco bardziej zaawansowane cechy są żywcem wyjęte z niej właśnie. Nawet mechanizmu wielokrotnego dziedziczenia nie chciało się deweloperom zaimplementować, bo skoro w Javie nie zaimplementowano, to znaczy, że jest to niepotrzebne. Trudno o większą bzdurę.

    Brak modularności też jest słaby. W każdym normalnym języku programowania (nawet w Javie) biblioteka standardowa jest zbudowana z modułów. Aby użyć określonej funkcji, musisz explicite zaimportować moduł, do którego ona należy. Pomaga się to potem zorientować z czego korzystałeś i pozwala mieć w programie wiele funkcji o tej samej nazwie. Tylko w PHP biblioteka standardowa jest jednym wielkim, żałosnym grochem z kapustą (co też sam raczyłeś zauważyć).

    I na dobitkę, nic nie rozwala mnie bardziej niż: $this->funkcja();

  • Kiedyś napiszę dłuższy

    Coś w kościach czuję, że to jedno z tych postanowień noworocznych, których nigdy się nie dotrzymuje. 😉

    Brak wielodziedziczenia ma dla mnie sporo zalet. Więc, żeby zaraz tyrać jakikolwiek język za jego brak to dla mnie bardzo, bardzo, przebardzo słaby argument.

  • Po pierwsze nie ganiłem PHP za brak wielodziedziczenia bezpośrednio, tylko za bezmyślność deweloperów, ślepe wzorowanie się na tym, co akurat modne. Ale skoro już ten temat poruszyłeś, to rad bym się dowiedzieć, jakie to zalety. Bo ja to widzę tak, że nikt nie musi go używać, jeżeli uważa to za szkodliwe. Natomiast jego brak zmusza nas do dodania do specyfikacji języka dodatkowego elementu tylko po to, by załatać tę dziurę. C++ ma wielodziedziczenie, dzięki temu nikomu nawet w głowie nie postało, żeby wymyślać coś takiego, jak interfejsy. Niech żyje spójność i prostota.

    Nawet Wujek Bob (zdaje się wielki miłośnik Javy) nie potrafił podać innego powodu braku wielokrotnego dziedziczenia w tym języku niż lenistwo twórców. 😉

  • Pierwszy argument z brzegu, to wpływ na wydajność, drugi to problem z implementacją delegatów, trzeci to brak spójności w ABI – co kompilator to różne sposoby rozwiązania tego problemu, czwarty to większe wskaźniki niż wydaje się to programistom wychowanym na C.

    Chociaż w sumie te argumenty mają się nijak do zastosowania wielodziedziczenia lub nie w np. Javie. Większymi problemami są te w stylu rombu śmierci i podejrzewam, że to głównie ten element przeważył, za pozbyciem się tego elementu.

  • Argument o rombie śmierci jest z deczka idiotyczny. To sprawa programisty uważać, by czegoś takiego nie stworzyć. A jak stworzył, to niech się sam martwi. To, że to tak, jak z siekierą. Siekiera jest ciężka i ostra – taka jej funkcja. Mamy produkować lekkie i tępe siekiery tylko dlatego, że ktoś może przez nieuwagę rąbnąć się w nogę? A jeżeli już koniecznie chcemy napisać idiotoodporny kompilator, to można przecież kazać mu śledzić ścieżki dziedziczenia i wypluwać błąd w takich sytuacjach.

    Na niskopoziomowych detalach nie znam się tak dobrze, więc pozostaje mi tylko wierzyć Ci na słowo. Ale w C++, czy w Pythonie wielokrotne dziedziczenie jest i jakoś nikt nie rozpacza z tego powodu…

  • Z tego punktu widzenia, na pewno. Ale Java, niby, powstawała w duchu eliminacji takich rzeczy. Miało być bezpiecznie, a na ile im się to udało… nawet nie chcę o tym dyskutować, każdy chyba sobie zdaje sprawę co jest najbezpieczniejsze na świecie. 🙂

  • Ja kupuje tezę, że Java nie ma wielodziedziczenia z powodu problemu rombu śmierci. W javie nawet nie da się wyjątku rzucić, bez zapisania tego w deklaracji, a co dopiero mówić o takich rzeczach jak wielodziedziczenie, gdzie zdecydowanie zbyt łatwo sobie zrobić krzywdę…

  • W javie nawet nie da się wyjątku rzucić, bez zapisania tego w deklaracji

    Prawda. Kolejny idiotyzm tego języka, jeszcze bardziej wkurzający, bo o ile wielokrotne dziedziczenie przydaje się raz na ruski rok, jak nie rzadziej, o tyle wyjątki przydają się bez przerwy, a konieczność ich stałego sprawdzania bywa upierdliwa. Ale tworzenie „idiotoodpornych” języków programowania, obawiam się, więcej branży zaszkodzi, niż pomoże.

  • mcv

    SebaS86: Tak sobie czytam i stwierdziłem, że obudzę stary wątek, bo czemu nie. 😉

    Zasadniczo wielodziedziczenie nie pogarsza wydajności w stosunku do alternatywnych rozwiązań. Jeśli już, to wirtualne wielodziedziczenie – pogarsza o dodatkowe odwołanie przez wskaźnik. Czasem jak potrzeba dużo „chodzić” po klasach będzie trzeba też modyfikować wskaźnik do obiektu, żeby wskazywał na właściwy podobiekt. Ale to jest nieznaczące. Alternatywne rozwiązania (np. kompozycja) też przecież będzie wolniejsza o odwołanie przez wskaźnik, albo coś podobnego.

    Brak spójności w ABI też nie jest w żadnej mierze spowodowany wielodziedziczeniem – to kwestia kompilatorów. C++ akurat w ogóle nie ma ustandaryzowanego ABI, bo tak kiedyś powiedział Bjarne i już. Zresztą – mowa tylko o C++.

    Wskaźniki są dokładnie takie same do wielodziedziczących obiektów jak do każdych innych, jeśli miałeś na myśli C++. Może pomyliło Ci się z samymi obiektami? No tutaj jest jasne, że będą składały się z każdego rodzica + jakieś meta informacje. Tak jak przy normalnym dziedziczeniu.

    Swoją drogą, o Javie to słyszałem, że nie robili wielodziedziczenia, bo to mocno komplikuje język, założenia jakie można w nim poczynić i kompilator. A interfejsy w zasadzie nic nie kosztują.

  • mcv

    Acha – zapomniałem spytać – jaki jest problem z implementacją delegatów?