PHP 7.0 frissítése PHP 7.x -re

Meglehetősen barátságtalanul van megoldva a PHP7 frissítése, nem is értem, hogy miért kellett így megcsinálni, talán a shared hostingok és a lusta fejlesztők/megbízók miatt. A PHP7 esetén nem frissül automatikusan ha újabbat kérünk tőle, hanem telepít a régi mellé egy újabb változatot. Természetesen a konfigokat sem hozza át. Én szeretek a legújabb stabil dolgokkal foglalkozni és kerülöm azt, hogy mindegyik kódom alatt verziókezelni kelljen a dolgokat. Igen, tudom nem vagyok hatékony ezzel, nem is vagyok gazdag. Olvass tovább…

2017.12.02. 12:53 - legyes

Rendkívül lassú a PHP-MySQL (localhoston) Windows alatt

Én nem vagyok rajongója annak, hogy Windows alatt futtassunk PHP-MySQL kombinációt. Hisz’ eleve sokkal több erőforrást adunk oda az operációs rendszernek, mint Linux alatt. Nincs meg a fájlrendszerrel való finomhangolás lehetősége sem, valamint az IIS és én sohasem leszünk barátok. Egy projekt alkalmával arra lettem figyelmes, hogy ugyanaz a kód fényévekkel gyorsabban fut Linux alatt, mint Windows alatt, egy egyszerűen semmi logikus magyarázat nem volt rá. Nos a problémát a Windows és a MySQL DNS feloldási anomáliája okozza, de az IPv6 is bekavarhat. Szal’ a PHP-ben a MySQL szerver címénél cseréljük ki a “localhost”-ot, “127.0.0.1”-re, valamint ha nincs rá szükségünk, akkor kapcsoljuk ki a hálózati kártyán az IPv6-ot. A DNS névfeloldás tiltása a my.cnf -ben sajnos nem segít.

Előtte (cache tiltva):

Utána (cache tiltva):

2017.09.28. 14:09 - legyes

Több sor és oszlop egy cellaként MySQL és MariaDB-ben: JSON függvények és a GROUP_CONCAT() együtt

A fejlesztők 2 fajtája nem foglalkozik az adatbázis lekérdezések sebességével több kapcsolódó adatnál: a kezdők és a profik.

A kezdők lekérdezik az alap adatokat, majd egy foreach()-en belül futatják le a kapcsolódó adatok lekérdezését:

foreach ( $products as $product ) {
   $db->query( "SELECT id, thumbnail, url FROM product_images WHERE product_id = :product_id" );
}

A profik is ez csinálják, csak sokkal csillibb kivitelben. Először csinálnak egy Image class-t. Majd egy getAllByProduct( int $product_id ) metódust hozzá. A termék lekérdezésénél pedig vagy a Product konstruktorába teszik – amit a FETCH_CLASS -al használnak ki -, vagy a Product::get( int $product_id ) -be, egy ciklusban. Ami megint ugyanaz csak pepitában.   Olvass tovább…

2017.08.28. 02:22 - legyes

XML konvertálása JSON objektummá vagy asszociatív tömbbé PHP-vel

Annak ellenére, hogy a JSON nagyon hódít – nyilvánvaló okok miatt, még mindig nagyon sokan használnak XML formátumokat. Többek között ilyen az RSS feed is, de az egyik legerősebb marketinggel rendelkező bérelhető webshop API-ja is, a ShopRenteré. XML-el dolgozni viszont rémálom a JSON-höz képest. Így hát felmerült a probléma, hogy  valami egyszerű megoldás kellene, ahelyett, hogy minden XML-t végignézek. Olvass tovább…

2017.02.08. 00:45 - legyes

PHP7 – multibyte string függvények

A mai napon arra lettem figyelmes, hogy az eddig gond nélkül futó PHP-es scriptek arra panaszkodnak, hogy nincs mb_strlen() függvény. Azt hittem, hogy átsiklottam a changelog “megszűnt függvények” részénél az mb_ kezdetű függvények felett, de kiderült, hogy csak külön csomagba pakolták, ahogy anno a JSON-t is. Szóval a megoldás:

apt-get install php7.0-mbstring

Érdemes lesz odafigyelni a későbbiekben…

2016.07.05. 09:30 - legyes

Apache .htaccess konvertálása nginx konfiggá

Nem vagyok kibékülve az indiánnal, mert hihetetlenül zabálja a memóriát. Plusz olyan default beállításai vannak, amik utat nyitnak a hackeléseknek. Továbbá a .htaccess fájlok miatt sok esetben biztonsági kockázatot is jelent.

Nginx párti vagyok, még ha csak Google alapján konfigolom is. Egyre többször találkozom azzal az igénnyel, hogy Apache-ra írt oldalnak kellene működnie nginx alatt. A Winginx oldala a legnépszerűbb ilyen online konverter, de nekem sohasem volt jó, amit dobott. Viszont találtam egy használhatóbbat: http://www.anilcetin.com/convert-apache-htaccess-to-nginx/

2016.03.29. 13:43 - legyes

WordPress érdekesség, avagy miért nem jó ötlet fröccsöntött rendszereket használni

A minap a segítségem kérték, mert egy szerver spammelt, letiltották és azonosítani kellett a baj forrását. Kiderült, hogy feltörtek rajta egy WordPress blogot, és ezzel elég nagy bajt okoztak, ugyanis a WordPress PHP-ja hozzáfért egyéb könyvtárakhoz is, amiben más PHP oldalak futottak.

  1. Első alkalommal valószínűleg egy kép plugin hibát kihasználva base64-ben kódolva feljutott pár PHP fájl. Általában a szokásos dolgokra voltak kihegyezve:
    • teljes adatbázis leképezés, amihez a WordPress felhasználója hozzáfér
    • teljes könyvtárstruktúra leképezés, amihez a WordPress-t futtató PHP hozzáfér
  2. Következő lépésben elrejtett véletlenszerű könyvtárakban PHP fájlokat, amik több funkciót láttak el:
    • önmagukat terjesztették, mint file proxy
    • spam leveleket küldtek
    • webproxy-t hoztak létre
    • egyéb vicces dolgokat “telepítettek” egykattintásos szolgáltatókon hostolt címekről
  3. A legviccesebb lépése pedig az volt, hogy létező (lehetőleg index.php) PHP fájlok első sorába is elhelyezte magát a 11900. oszloptól! A fájlokba belenézve semmi érdekes nincs. De a grep mégis kidobja, hogy ott van benne az eval, sőt magát a kódot is. Nano-ban vagy mceditben az eval-hoz is ugrik, de belenézve nem látni.wordpress_hack2
    find . -name "*.php" -exec grep -H "eval" {} \; | more

    wordpress_hack

 

Update #1:

Közben találtam még egy finomságot:

wordpress_hack3

 

Mi a tanulság? Ha már fröccsöntött motorokat (WordPress, Joomla, Drupal, …) használunk, frissítsünk, amilyen gyakran csak lehet. Igen, ez is WordPress 🙂

Közel 4 óra volt kibelezni a különféle vicces dolgokat művelő PHP-kat a mappákból és még biztosan találni ezt-azt 🙁

Ui.: Most komolyan, mit nem lehet azon érteni, hogy NE HASZNÁLJ eval()-t, soha, semmiben. De főleg abban nem, ami felhasználó által bevihető inputból származik.

Update #2:

Egy kis Joomla hack. Az 1. sor: assets(), a 2. base64_decode() és már ott is az eval :(
Egy kis Joomla hack. Az 1. sor: assets(), a 2. base64_decode() és már ott is az eval 🙁

Kis olvasnivaló: https://www.exploit-db.com/exploits/17602/ és https://forums.digitalpoint.com/threads/wp-hack.2734636/ és https://jordankueh.com/2014/wordpress-remote-code-execution-base64_decode/ és https://jordankueh.com/2014/wordpress-remote-code-execution-base64_decode/ és http://msurowiecki.pl/index.php/inne/106-wordpress-under-attack-april-2013-tips-to-remove-spyware

2016.03.26. 17:38 - legyes

SQL: Ügyes trükk 2 állapot közötti váltogatásra

Sok esetben előfordult már, hogy szükségem volt egy elem láthatóságának 2 állapota közötti váltogatásra. Igazi amatőr módon eddig vizsgálgattam, hogy látható-e és ha igen, akkor el kell rejteni és fordítva. Na, ettől jóval egyszerűbb a megoldás:

UPDATE table SET field = 1 - field

forrás: http://stackoverflow.com/questions/603835/mysql-simple-way-to-toggle-a-value-of-an-int-field

2016.03.23. 14:57 - legyes

PHP: HTML fájl feldolgozása és manipulálása

Már az elején lelövöm a poént: Ha a PHP saját XML DOM parserét használod, biztosan kevesebb hajad marad a nap végére. A SimpleXML sajnos kevés ehhez, de a csodafegyver itt van: http://simplehtmldom.sourceforge.net/manual.htm .

Történt ugyanis, hogy HTML sablon alaján kell PDF-et generálnom. A sablonban táblázatok vannak formázva ( na itt bukott el a PHP XML DOM osztály, mert piszok kacifántos vele xHTML-t manipulálni ), aminek a formázását meg kellene őrizni, hisz’ ez adja majd a PDF stílusát. De vannak mezők, amik helyére be kell helyettesíteni a megfelelő értékeket.

Olvass tovább…

2016.02.29. 12:52 - legyes

PHP és MySQL adattípus túlcsordulások

Azt ügye tudjuk, hogy a PHP-ben automatikus típuskonverzió van, amire oda kellene figyelni. A PHP-ban a számok ábrázolására 2 típus áll rendelkezésre (+boolean):
– (signed) integer
– (signed) float

Ezek minden esetben előjellel vannak ellátva, így az integer típusban maximum 2^63 érték tárolható egy 64 bites rendszeren, 64 bites PHP-val. Viszont! A MySQL-ben rendelkezésre áll az előjel nélküli változat, az unsigned bigint, ami ugyanezen körülmények között 2^64 tud ábrázolni, előjel nélkül. Így marad egy nagy hézag a kettő között.  Mivel a PHP-ban automatikus típuskonverzió van, így az (unsigned big)int átalakul a PHP-ben float típussá, amiből mi semmit sem veszünk észre. A float típussal ügye csak pontosságot vesztettünk.

De mi van akkor, ha a PHP által adott választ egy szigorúbb nyelvvel akarjuk feldolgozni – vagy mert int-et várunk -, erőltetjük az int típust:

echo (int) ((int) PHP_INT_MAX+1); // -9223372036854775808

Akkor az bizony a PHP-ban is túlcsordul, ahogy azt a MySQL-ben is tenné ha signed bigint lenne és ebből mi semmit sem veszünk észre. Ugyanez, automatikus típuskonverzióval:
echo(PHP_INT_MAX+1); // 9.2233720368548E+18

Hogy ez miért okozhat gondot?

Elterjedt szokás, hogy biztonsági okok miatt lehetőleg csak ID-ket (azonosító számokat) küldünk szerver oldalra, mivel ezeket jóval könnyebb szűrni, mint a stringeket. Az adatbázisban pedig az azonosítók legtöbb esetben integer típusok, leginkább unsigned bigint-ek, autoincrement tulajdonsággal. Később pedig a szerver oldali vizsgálatnál – mivel számot várunk és az autotincrement alapból 1-ről indul – lustaságból ezt alkalmazzuk és úgy gondoljuk, hogy ezzel macera nélkül (prepared statements) meg is oldottuk az SQL injection elleni védelmet:


$id = abs($_GET['id']); // barmi nem szamra 0-t ad, ami az alap autoincerement 1-es kezdosorszama miatt nem letezo sorra mutat az adatbazisban
$results = $pdo->query('UPDATE users SET money=money+1000 WHERE id='.$id);

Ok, de eddig még sohasem okozott gondot a túlcsordulás, miért kellene rá figyelnem? 

Hát például ezért:
echo (int) PHP_INT_MAX; // 9223372036854775807
echo (int) ((PHP_INT_MAX+1000000)-1000000); // 9223372036854774784

Természetesen ez oda-vissza érvényes, azaz figyelni kell arra, hogy a PHP integer típusa több egész szám tárolására képes, mint a MySQL bizonyos integer típusai. A MySQL persze dob warningot, de ha külön nem kérdezzük meg róla, akkor jó eséllyel nem fogjuk észrevenni PHP-ben.

 

Sok forráskódban láttam már a fent említett lustaságból alkalmazott szám-konverziós védelmet. A baj az, hogy úgy hiszik elegendő csupán (int) -el erőltetni a típust. Csak hogy az negatív számokat is elfogad, így a túlcsordítással máris pozitív számmá változtathatjuk, ami viszont már tutira létezik az adatbázisban a tipikus autoincrementes megoldásoknál. Kiszámolni pedig könnyű a megfelelő mértékű túlcsordítást okozó számot, hogy a kért ID-t kapjuk eredményül. 

2015.07.19. 15:10 - legyes

Írjunk magunknak egy bugyuta játékot :)

Régebben szinte függővé tett a Zandagort nevű játék. Egy tökéletes bizonyíték volt arra, hogy a PHP-MySQL-Javascript (AJAX) is képes lehet élhető és élvezhető játékot kiszolgálni. Sajnos mostanság kissé leáldozóban van a csillaga. Kíváncsi voltam, hogy vajon én képes vagyok-e ilyesmit alkotni? Így hát belekezdtem. Nem hiszem, hogy valaha lesz belőle játék, de megtaláltam a tökéletes hobbit azt hiszem. Hátrányai között van sajnos, hogy ezt is a számítógép előtt kell űzni, valamint nincs az a perc, amikor szabadulni lehetne a gondolattól, hogy ez vagy azt hogyan is lehetne megvalósítani?

Mit is tud most? Jelenleg egy számítógép által vezérelt játékost és egy emberit. A számítógép semmit sem csinál, csak véletlenszerűen cirkál saját bolygói között. Az emberi flották az egérrel vezérelhetők: bal klikkel kiválaszt, jobb klikkre cél koordinátára/flottára/bolygóra megy. Agresszív mód esetén nem a cél flotta pozíciójára megy, hanem üldözőbe veszi, amíg utol nem éri. A térkép x időközönként frissíti a pozíciókat, amit MySQL számol ki tárolt eljárással. A szerver oldali időzítés csak késleltetéssel megy, végtelen ciklusban (php: sleep(3);), a kliens oldalon setInterval+jQuery.post kérdezgeti a flották pozícióit. Sajnos még most nem koordináta rendszer alapján tájékozódnak, csak képpontok alapján, de már próbálkozom többféle megoldással a térkép scrollozására:

A nyilakra kattintva (vagy a billentyűzeten nyomkodva a nyíl billentyűket) a háttérkép és az objektumok is x képpontnyit mozdulnak a kívánt irányba. További célok között szerepel, hogy az egérrel és a képernyő szélére pozicionálással is lehessen scrollozni. Ha ez megvan, akkor át kell alakítani képpont alapú pozíciókról, 2D koordináta rendszer alapúra.

Próbálkoztam pár fejlett megoldással a térkép scrollozásra, és nagyon jókat, látványosakat találtam, SVG-vel és egyéb módon megoldva,, zoom lehetőséggel, hasonlóan a Google Mapshoz. De ezek egyenlőre meghaladják képességeimet. A Zandagort fejlesztője segített nekem 2 példával is, de ezt is szerettem volna magam megoldani, így belefogtam a háttérkép eltolás játékba. Itt jegyzem meg, hogy a background-position-x és background-position-y csak a Chrome-ban és IE kompatibilis módban megy, helyette background-position: 100px -50px; van 🙂 .

A háttérkép a Zandagortból, az ikonok ingyenes ikon letöltőhelyekről származnak egyenlőre. A radarkör és a célvonal a Raphael JS bővítmény segítségével működik. De nem is az a lényeg…

2012.11.03. 01:14 - legyes
1 2