Niedawno spotkałem się z pewną… ciekawostką, którą podsunął mi jeden ze współuczestników szkolenia w jakim brałem udział. W języku PHP można komentować kod na kilka sposobów:

  1. <?php
    # to jest komentarz jednolinijkowy
    ?>
  2. <?php
    // to jest komentarz jednolinijkowy
    ?>
  3. <?php
    /* to jest komentarz
    wielolinijkowy */
    ?>

Moja ciekawostka dotyczy wersji 1 i 2. Teraz pytanie, dość proste: co zostanie wyświetlone w wyniku parsowania pliku PHP o treści:

<?php
echo 'aaa?>';
echo 'bbb';
?>

Dość oczywistym jest wynik:

aaa?>bbb

No to teraz pytanie drugie: co będzie wynikiem parsowania poniższego skryptu?

<?php
#echo 'aaa?>';
echo 'bbb';
?>

Dla mnie, i dla conajmniej kilku innych osób które od dość długiego czasu zajmują się PHP, oczywistym jest wynik:

bbb

Ale dla developerów PHP logicznym jest inny rezultat:

'; echo 'bbb'; ?> 

Cytat z manuala:

The “one-line” comment styles only comment to the end of the line or the current block of PHP code, whichever comes first. This means that HTML code after // … ?> or # … ?> WILL be printed: ?> breaks out of PHP mode and returns to HTML mode, and // or # cannot influence that. If the asp_tags configuration directive is enabled, it behaves the same with // %> and # %>.

Źródło: manual PHP


No to właśnie znalazłem buga na home.pl ;)

Dorobili ostatnio obsługę w ich .htaccess zmianę parsera dla poszczególnych rozszerzeń plików. Za pomocą konstrukcji:

:Location *.php
Use php5

Mówimy ich webserwerowi że ma traktować pliki .php za pomocą parsera PHP5. Super, nie?

No to teraz wstawmy jakąś konstrukcję z PHP5 do index.php. O, zonk. Ichnich serwer nie wie, że plik domyślny ma jakieś rozszerzenie, a szczególnie nie wie że ma rozszerzenie .php. A o tym, że takie pliki ma parsować poprzez PHP5 to juz kompletnie nic nie wie.. I sypie błędami. Ale wystarczy teraz wejść na adres /index.php, i już wszystko zaczyna działać, jak za dotknięciem magicznej różdżki :)

Obejścia moga być dwa, jedno bardziej, drugie mniej wygodne. Zacznijmy od drugiego:

do .htaccess wstawiamy:

Index index.php. Voila!

Powyższe może nie być przydatne, jeśli w innych plikach mamy na sztywno odwołania do pliku index.php - zmienianie w setce plików adresu jest mało wygodne. No to obchodzimy buga:

.htaccess:

Index index.php5
:Location *.php
Use php5

index.php5:

<?php
include “index.php”;
?>

Chciałem im to przez chata zgłosić, ale coś chyba śpią… bo pokazuje mi tylko mesga że wszyscy konsultanci zajęci ;) A, niech im będzie, puszczę im maila…

UPDATE

Dostałem od nich odpowiedź:

Dziekujemy za zgloszene. Sprawa jest nam juz znana i trwaja prace nad poprawieniem usterki.
W razie pytan pozostajemy do dyspozycji.

No nic, zobaczymy ile czasu zajmie im zrobienie tego… :)

UPDATE 2

Minął tydzień, jak na razie nic się nie zmieniło. Bug sobie dalej jest :)


banal. ale przy okazji wyszedl niezly bezsens…

# grep mysql /etc/tcpd/hosts.allow
mysqld: ALL: allow
# 

i smiga. ale czy rzeczywiscie brak wpisu (a w tym wypadku - niewlasciwy wpis) powinien powodowac segfault mysqla przy probie polaczenia ? dla mnie bzdura. niech nie pozwoli sie polaczyc, niech wywali jakis msg, ale kuzwa, nie segfault !!!

w sumie drugi raz sie przejechalem, ale nie do konca udalo mi sie wszystko powiazac…

pamietajac wlasnie ten poprzedni raz, oidp to bylo z serwerem jabbera, dodalem wpis do /etc/tcpd/hosts.allow:

mysql: ALL: allow

niestety, proces nazywa sie mysqld, a mi sie cos pozajaczkowalo. i tcpwrappers nie puszcal polaczen. ale kuzwa, dalej uwazam za maksymalna bzdure to, ze wali po oczach segfaultem zamiast zwyczajnie zabronic sie polaczyc. czy chocby siakis mesg… ech :/

dzieki ci, boze, za strace‘a… ;)


na serwerze jest sobie mysql 4.0.x. bodajze x = 24 obecnie (wczesniej bylo 20, ten sam problem), ale moge krzanic a sprawdzac mi sie nie chce. google niewiele sensownego mowia o moim problemie, wiec nieco szlag mnie trafia.
gdzie lezy problem?

musze uruchomic mysql tak, zeby mozna sie bylo zalogowac zdalnie do niego. no wiec zahaszowalem w konfigu skip-network.
ustawilem grzecznie odpowiednie bind-address. probowalem rowniez bez tego, ale nic to nie zmienia.

zrestartowalem mysql.

dodalem odpowiednie uprawnienia dla usera login@%.

zrobilem flush-privileges.

wszystko ladnie smiga, proba polaczenia z mysql z podanym parametrem -h:

% mysql -h adres -u user -p

po chwili mam mesga, ze polaczenie zerwane w trakcie wykonywania query czy jakos podobnie, po zalogowaniu na serwer (dobrze ze mam klucze, bo bez mysql na serwer normalnie nie da sie zalogowac…) service mysql status pokazuje ze nie dziala ale podsystem zablokowany (zginal tak szynko ze z /var/lock/subsys nie usunal locka).

w logach:

/usr/sbin/mysqld: gotowe do polaczenia PLD Linux Distribution MySQL RPM
mysqld got signal 11;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
We will try our best to scrape up some info that will hopefully help diagnose
the problem, but since we have already crashed, something is definitely wrong
and this may fail.

key_buffer_size=8388608
read_buffer_size=131072
max_used_connections=0
max_connections=100
threads_connected=0
It is possible that mysqld could use up to
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = 225791 K
bytes of memory
Hope that’s ok; if not, decrease some variables in the equation.

moge sobie dowolnie mieszac zmiennymi, ilosc potrzebnej mu pamieci w msg spada do jakichs 60mb etc (chwilowo na serwerze zostalo tylko 512mb ramu, ale to przejsciowe), ale ten mesg sie dalej pokazuje wraz z wykladaniem sie mysql przy probioe polaczenia zdalnego.

proba polaczenia z serwera, ale z podanym parametrem -h adres powoduje dokladnie to samo. tylko dzialania na sockecie sa ok :/ nic nie czaje. no nic, moze zaraz na pisze na listy pld, moze cos pomoga (probowalem juz nawet mielic mysql samemu etc, i dalej to samo :///).

a tutaj mamy rozwiazanie problemu


jako, ze ’stary’ wordpress (wersja 1.5) miala pare bugow, ktore mnie ostro denerwowaly (jak np znikanie linkow dzialu ‘pages’ gdy sie weszlo w ktoras ze stron), zdecydowalem sie uzyc wersji pobranej dzis bezposrednio z svn (oznaczonej jako 1.5.1 alpha). to co mnie najbardziej wkurzalo, to poprawili. poza jedna rzecza - dalej w .htaccess generuja sie regulki do mod_rewrite ktore zle dzialaja na apache 1.x. i musialem to znow robic recznie (co zajelo mi chyba z pol godziny, bo nie pamietam w ktorym pliku jest funkcja generujaca powyzsze, a struktura wordpressa od strony kodu jest dla mnie co nieco zagmatwana…)
ale w koncu dziala
chwilowo wiecej bugow poza powyzszymi regulkami, nie znalazlem. mam nadzieje ze nie ma ;)

gdyby kogos ineteresowalo zeby to poprawic, stosowny patch jest pod tym linkiem


to tak w skrocie. od dwoch godzin walcze z prymitywem. po prostu kurwa z prymitywem. prosty skrypt w pythonie, wykonujace banalne kurwa query, wsadzajace do mysql jeden pojedynczy kurwa rekord. to samo query wykonane z poziomu phpmyadmina dziala. z konsolki mysqlowej - dziala. ale ze skryptu nie. czemu ? nie wiem. kurwa, jak bozie kocham, nie wiem. 25 innych skrypcikow, ktore rowniez wykonuja po jednym/dwa query, dziala jak trzeba. wszystko smiga. ale ten jeden nie chce. kurwa, niech chociaz wyswietli czemu nie chce! ale nie, po co. teoretycznie nie ma zadnego bledu!

zadnego!!! nie rzuca zadnym wyjatkiem, kod powrotu ze skryptu zerowy, wszystko wporzo. ale rekord w bazie sie nie pojawia.

ciekakurwawostka:

jest autoincrement id. id wynosi 114. po dodaniu tego wlasnie zapytania poprzez phpmyadmin. sprobuje to samo zrobic z poziomu skryptu: oczywiscie nie dziala, bo po co. ale teraz wykonuje jeszcze_raz to samo zapytanie z poziomu phpmyadmin, rekord oczywiscie sie pjawia… ale z id 116 ! kurwa… czary i magia. zaciagnelem najswiezsza wersje mysqldb, i wszystko co tylko moglo miec na to wplyw, i ni huhu nie dziala. wtf ?

dobra, madafaka. juz wiem mniej wiecej co jest grane. jebane mysqldb nie dziala z tabelami w innodb. aaaarrrghhh…. ciekawe co google mi na to powiedza…

hm, notki na stronie mysqldb twierdza, ze nie powinno byc problemow… jebukurwadu.

dymam to. jutro moze na news zajrze zobacze co mi powiedza…

update

doszedlem o co chodzi. innodb obsluguje transakcje, no wiec powinno to wygladac tak:

conn.BeginTrans()
conn.Execute(query)
conn.CommitTrans()

niestety, powyzszy kod wywala mi:

Traceback (most recent call last):
  File "./add_db_dns_record.py", line 40, in ?
    conn.BeginTrans()
  File "/usr/share/python2.4/site-packages/adodb_mysql.py", line 43, in BeginTrans
    self._conn.begin()
AttributeError: 'Connection' object has no attribute 'begin'

no i dupa blada. zglosilem bugreporta, zobaczymy czy i co mi napisza…