Néhány mobil, tablet, és asztali eszköz képernyő méretének gyűjteménye:
http://screensiz.es/
2019. január 20., vasárnap
Néhány képernyő méret
Címkék:
asztali,
képernyőméretek,
mobil,
tablet
2018. november 15., csütörtök
Google Chrome & sw.js & localhost & SSL
Röviden:
- localhost https kapcsolat alatt self signed ssl tanusítvány van beállítva.
- service worker sw.js regisztráció hibába ütközik tanusítvány probléma
- "An SSL certificate error occurred when fetching the script." és társai console hibaüzenetek.
- a google szerint a "unsafely-treat-insecure-origin-as-secure" chrom flag majd biztos megoldja.
- nem jön össze több kombóban sem
- De hoppá, hoppá, az újabb Chrome böngészőkben van erre egy elegánsabb megoldás
- Tehát: chrome://flags/#allow-insecure-localhost
2018. szeptember 17., hétfő
PHP: "/public" eltávolítása az URL-ből
Ez a probléma általában előjön az én esetemben.
A relativitás híve vagyok. Egy oldal menjen az éles tárhelyen a gyökérből, vagy akár egy almappából a fejlesztés helyén.
Persze a mai trendek nagyon tolják a "csinálj mindennek egy-egy virtualhost-ot" jellegű tutorialokat, és minden legyen bebetonozva.
Általában fel-felbukkan egy-egy olyan oldal, ahol még a képek, és más erőforrások elérését is "/" karakterrel kezdik, hogy az biztosan az oldalhoz tartozó document root szerver beállítástól legyen értelmezve. Hogy ez miért jó? Még nem tudom. De az is megtörténhet, hogy egyszer, előbb-utóbb a szemem elé akad egy cikk, amely elmagyarázza, hogy így fontos másodperceket is meg lehet spórolni a nagy látogatottságú és/vagy nagy erőforrás igényű oldalaknál.
Hasonló volt a helyzet a CDN tárhelyekről hosztolt harmadik féltől származó javascript, css, és font csomagok esetén is. Valóban gyorsabb lenne a kiszolgálás, ha a legtöbb dolgot külföldi CDN-ről menne. (cdnjs, jsdelivr, stb..), de mint később néhány cikk rávilágított, hogy a magyarországi hálózati rendszer felépítése éppen az ellenkező hatást váltja ki, és tovább tarthat több esetben a kiszolgálás, mint ha azt közvetlenül az oldal tárhelyéről szolgálódna ki, vagy egy másik magyarországi CDN tárhelyről.
No mindegy is.
Visszatérve a címben lévő témához.
Általában belefutok a fenti problémába. Főleg, ha olyan tárhely hozzáférést kapok, ami közvetlenül a document root mappára mutat és nem lehet egy szinttel feljebb másolni.
Persze itt most jöhet a következő jó gondolat: "miért nem másolja ki az ember fia az egész public mappát az oldal gyökerébe?" Mert néhány kísérlet talán ki lehet találni néhány fontos és létező útvonalat, amit nem kellene látni. "De erre meg ott van a .htaccess, vagy egy-egy üres index.html, stb..."
A vitát lehet folytatni még egy darabig. Ez vitathatatlan.
Szóval a lenti linken egy kis kód részlet érhető el, amely az URL-ben lévő "/public" karakter sorozatot távolítja el az URL-ből átirányítással:
https://gist.github.com/racztiborzoltan/e6ab85c3b54d7e8bc0d482ec3cee17e0
Szép napot!
A relativitás híve vagyok. Egy oldal menjen az éles tárhelyen a gyökérből, vagy akár egy almappából a fejlesztés helyén.
Persze a mai trendek nagyon tolják a "csinálj mindennek egy-egy virtualhost-ot" jellegű tutorialokat, és minden legyen bebetonozva.
Általában fel-felbukkan egy-egy olyan oldal, ahol még a képek, és más erőforrások elérését is "/" karakterrel kezdik, hogy az biztosan az oldalhoz tartozó document root szerver beállítástól legyen értelmezve. Hogy ez miért jó? Még nem tudom. De az is megtörténhet, hogy egyszer, előbb-utóbb a szemem elé akad egy cikk, amely elmagyarázza, hogy így fontos másodperceket is meg lehet spórolni a nagy látogatottságú és/vagy nagy erőforrás igényű oldalaknál.
Hasonló volt a helyzet a CDN tárhelyekről hosztolt harmadik féltől származó javascript, css, és font csomagok esetén is. Valóban gyorsabb lenne a kiszolgálás, ha a legtöbb dolgot külföldi CDN-ről menne. (cdnjs, jsdelivr, stb..), de mint később néhány cikk rávilágított, hogy a magyarországi hálózati rendszer felépítése éppen az ellenkező hatást váltja ki, és tovább tarthat több esetben a kiszolgálás, mint ha azt közvetlenül az oldal tárhelyéről szolgálódna ki, vagy egy másik magyarországi CDN tárhelyről.
No mindegy is.
Visszatérve a címben lévő témához.
Általában belefutok a fenti problémába. Főleg, ha olyan tárhely hozzáférést kapok, ami közvetlenül a document root mappára mutat és nem lehet egy szinttel feljebb másolni.
Persze itt most jöhet a következő jó gondolat: "miért nem másolja ki az ember fia az egész public mappát az oldal gyökerébe?" Mert néhány kísérlet talán ki lehet találni néhány fontos és létező útvonalat, amit nem kellene látni. "De erre meg ott van a .htaccess, vagy egy-egy üres index.html, stb..."
A vitát lehet folytatni még egy darabig. Ez vitathatatlan.
Szóval a lenti linken egy kis kód részlet érhető el, amely az URL-ben lévő "/public" karakter sorozatot távolítja el az URL-ből átirányítással:
https://gist.github.com/racztiborzoltan/e6ab85c3b54d7e8bc0d482ec3cee17e0
Szép napot!
2018. szeptember 5., szerda
PHP & Microsoft Excel & CSV import & encoding
Csak egy link, ami többet mond száz szónál:
https://stackoverflow.com/a/4440143
Én a linkelt megoldást preferálom.
https://stackoverflow.com/a/4440143
Én a linkelt megoldást preferálom.
2018. szeptember 4., kedd
Kategória fa lekérdezése 3 szintig egy SQL utasításban
Optimalizálni kellett egy nagyobb kategória fának a lekérdezését, hogy egy SQL utasítással lehessen lekérdezni az összes szükséges információt, így ne legyen annyiszor megszólítva az adatbáziskezelő.
Természetesen már korábban is belefutottam a problémába, de eddig nem publikáltam semmit.
Tehát álljon itt egy SQL utasítás megjegyzésekkel:
--
-- SQL utasítás, amely faszerkezetbe rendezett kategóriákat tud
-- maximum 3 szintig listázni.
-- Az eredményt lineárisan bejárva a programozási nyelvben is lehet
-- egy több dimenziós tömböt felépíteni, mert nem fog előfordulni,
-- hogy a felsőbb szint esetleg később jönne a listában!
--
SELECT
-- TODO: További oszlopokat szabadon hozzáadni!
-- Az első táblában lévő információkra van szükségünk:
c_1.id
-- Ebben az oszlopban a kategória hierarchiának megfelelően fordított
-- sorrendben kerülnek "," karakterrel összefűzésre
-- Az eredményhalmaz feldolgozása során nagy segítséget nyújthat egy többdimenziós
-- szerkezet összeállításához.
, CONCAT_WS(",", c_1.id, c_2.id, c_3.id) AS category_hierarchy
-- Ez az oszlop azt számolja ki, hogy hányadik kategória szinten
-- fog elhelyezkedni az adott sorban lévő "c_1"-es kategória
, 1 + LENGTH(CONCAT_WS(",", c_1.id, c_2.id, c_3.id))
- LENGTH( REPLACE ( CONCAT_WS(",", c_1.id, c_2.id, c_3.id), ",", "") ) AS level_number
-- A listázott kategóriához hozzácsatoljuk, ha lehetséges a szülő kategóriáját,
-- és a szülő kategóriához hozzácsatoljuk annak a szülőjét is, ha lehetséges:
FROM category_tree AS c_1
LEFT JOIN category_tree AS c_2 ON c_1.parent_id = c_2.id
LEFT JOIN category_tree AS c_3 ON c_2.parent_id = c_3.id
WHERE
-- Ez csak apróság, de általában mindenhol jelen van egy "Látható-e a kategória"
-- típusú oszlop információ, ami alapján csak a publikus kategóriák lesznek listázva
-- Természetesen láthatóság nem csak a levél kategóriára lesz ellenőrizve.
-- Ha a szülő nem látható, akkor nem lenne értelme listázni a benne lévő
-- elemeket
(
c_1.status = 1
-- A 2. és 3. csatolt táblában az IS NULL is szükséges, mert nem biztos
-- hogy minden sorhoz lehetett további szülő és szülő-szülő kategóriát
-- csatolni. Ekkor ugye a LEFT JOIN miatt ezek a mezők NULL értékúek lesznek.
AND (c_2.status IS NULL OR c_2.status = 1)
AND (c_3.status IS NULL OR c_3.status = 1)
)
-- Ez a feltétel azt köti ki, hogy az 1. vagy a 2. vagy 3. szintnek a gyökérben
-- kell végződnie, amelynek már nincs szülője
AND (
c_1.parent_id IS NULL
OR c_2.parent_id IS NULL
OR c_3.parent_id IS NULL
)
ORDER BY
-- Szükséges növekvő sorban a szint számnak megfelelő sorba rendezni az
-- eredményeket, hogy az eredményhalmaz lineáris feldolgozása során ne legyen
-- olyan kategória, amelynek a szülője még nem került volna feldolgozásra.
level_number ASC
-- Érdemes valamilyen egyértelmű sorszámozást tartalmazó oszlop alapján
-- még rendezni az eredményeket:
, c_1.sequence_number ASC
Természetesen már korábban is belefutottam a problémába, de eddig nem publikáltam semmit.
Tehát álljon itt egy SQL utasítás megjegyzésekkel:
--
-- SQL utasítás, amely faszerkezetbe rendezett kategóriákat tud
-- maximum 3 szintig listázni.
-- Az eredményt lineárisan bejárva a programozási nyelvben is lehet
-- egy több dimenziós tömböt felépíteni, mert nem fog előfordulni,
-- hogy a felsőbb szint esetleg később jönne a listában!
--
SELECT
-- TODO: További oszlopokat szabadon hozzáadni!
-- Az első táblában lévő információkra van szükségünk:
c_1.id
-- Ebben az oszlopban a kategória hierarchiának megfelelően fordított
-- sorrendben kerülnek "," karakterrel összefűzésre
-- Az eredményhalmaz feldolgozása során nagy segítséget nyújthat egy többdimenziós
-- szerkezet összeállításához.
, CONCAT_WS(",", c_1.id, c_2.id, c_3.id) AS category_hierarchy
-- Ez az oszlop azt számolja ki, hogy hányadik kategória szinten
-- fog elhelyezkedni az adott sorban lévő "c_1"-es kategória
, 1 + LENGTH(CONCAT_WS(",", c_1.id, c_2.id, c_3.id))
- LENGTH( REPLACE ( CONCAT_WS(",", c_1.id, c_2.id, c_3.id), ",", "") ) AS level_number
-- A listázott kategóriához hozzácsatoljuk, ha lehetséges a szülő kategóriáját,
-- és a szülő kategóriához hozzácsatoljuk annak a szülőjét is, ha lehetséges:
FROM category_tree AS c_1
LEFT JOIN category_tree AS c_2 ON c_1.parent_id = c_2.id
LEFT JOIN category_tree AS c_3 ON c_2.parent_id = c_3.id
WHERE
-- Ez csak apróság, de általában mindenhol jelen van egy "Látható-e a kategória"
-- típusú oszlop információ, ami alapján csak a publikus kategóriák lesznek listázva
-- Természetesen láthatóság nem csak a levél kategóriára lesz ellenőrizve.
-- Ha a szülő nem látható, akkor nem lenne értelme listázni a benne lévő
-- elemeket
(
c_1.status = 1
-- A 2. és 3. csatolt táblában az IS NULL is szükséges, mert nem biztos
-- hogy minden sorhoz lehetett további szülő és szülő-szülő kategóriát
-- csatolni. Ekkor ugye a LEFT JOIN miatt ezek a mezők NULL értékúek lesznek.
AND (c_2.status IS NULL OR c_2.status = 1)
AND (c_3.status IS NULL OR c_3.status = 1)
)
-- Ez a feltétel azt köti ki, hogy az 1. vagy a 2. vagy 3. szintnek a gyökérben
-- kell végződnie, amelynek már nincs szülője
AND (
c_1.parent_id IS NULL
OR c_2.parent_id IS NULL
OR c_3.parent_id IS NULL
)
ORDER BY
-- Szükséges növekvő sorban a szint számnak megfelelő sorba rendezni az
-- eredményeket, hogy az eredményhalmaz lineáris feldolgozása során ne legyen
-- olyan kategória, amelynek a szülője még nem került volna feldolgozásra.
level_number ASC
-- Érdemes valamilyen egyértelmű sorszámozást tartalmazó oszlop alapján
-- még rendezni az eredményeket:
, c_1.sequence_number ASC
2018. augusztus 31., péntek
Laravel: cookie beállítása, hogy elérhető is legyen azonnal a response objektum megszületése előtt
Kóstolgatom a Laravel PHP keretrendszert.
Egyik problémám a címben némileg hosszan és hanyagul lett megfogalmazva.
Mert ugye van itt ez a:
Cookie::queue('key', 'value', 5);
Amivel a response létrejötte előtt lehet olyan cookie-kat definiálva, ami majd automatikusan hozzá lesz dobva a response objektumhoz, ha az már létezni tetszik. (nagyjából)
De nekem az kellett, hogy ha én azt mondom sablonosan, hogy
cookie_beallitasa($name, $value);
akkor a függvény meghívását követő sorban már ki tudjam adni a
\Cookie::get($name);
metódus hívást és éppen az előbb beállított $value értéket kapjam.
Erre jutottam:
$request->cookies->set('name', 'value');
echo \Cookie::get('name'); // output: 'value'
Hova is kellett ez nekem:
Egy middleware osztályba, ami a request handler lefutása előtt kellett, hogy beállítson néhány dolgot a cookie értékek közé.
Ui.: Valószínű, hogy van erre egy sokkal frappánsabb és egyszerűbb megoldás, de egy kevés google keresgélés után mindig a ::queue() metódusba futottam, de az éppen nem oldja meg a problémámat.
Egyik problémám a címben némileg hosszan és hanyagul lett megfogalmazva.
Mert ugye van itt ez a:
Cookie::queue('key', 'value', 5);
Amivel a response létrejötte előtt lehet olyan cookie-kat definiálva, ami majd automatikusan hozzá lesz dobva a response objektumhoz, ha az már létezni tetszik. (nagyjából)
De nekem az kellett, hogy ha én azt mondom sablonosan, hogy
cookie_beallitasa($name, $value);
akkor a függvény meghívását követő sorban már ki tudjam adni a
\Cookie::get($name);
metódus hívást és éppen az előbb beállított $value értéket kapjam.
Erre jutottam:
$request->cookies->set('name', 'value');
echo \Cookie::get('name'); // output: 'value'
Egy middleware osztályba, ami a request handler lefutása előtt kellett, hogy beállítson néhány dolgot a cookie értékek közé.
Ui.: Valószínű, hogy van erre egy sokkal frappánsabb és egyszerűbb megoldás, de egy kevés google keresgélés után mindig a ::queue() metódusba futottam, de az éppen nem oldja meg a problémámat.
2018. augusztus 30., csütörtök
PHP_INI_SCAN_DIR környezeti változó a PHP-ban
Mire is jó ez a PHP_INI_SCAN_DIR?
Ha ez a környezeti változó be van állítva a PHP futási környezetében, akkor az ebben tárolt útvonalon megpróbál minden *.ini fájlt betölteni, amellyel felüldefiniálhatóak a korábban már beolvasott "php.ini" beállítások.
Bővebben angolul a PHP dokumentációjában: http://php.net/manual/en/configuration.file.php#configuration.file.scan
FONTOS:
Ne tévesszük össze a futtatható php parancssori kapcsolói közül a "-c <path>|<file>" lehetőséggel. Ez utóbbi arra való, hogy ha érvényes fájlra vagy könyvtárra mutat, akkor a php beállításokat tartalmazó fájlokat onnan próbálja beolvasni. Ha a -c kapcsoló nem mutat érvényes fájlra vagy könyvtárra, akkor a PHP az alapértelmezett helyek valamelyikén keres majd megfelelő ini állományt.
Ui.: A fenti változó nagyon hasznosnak fog bizonyulni a saját kis webszerveren további pofozgatásában, mert már meguntam, hogy az egyik PHP verzióban egy kicsit másképpen vannak beállítva olyan általános értékek, mint például a feltölthető maximális fájlméret (max_upload_filesize) vagy a POST kérések maximális mérete (post_max_size) és hasonlók.
Ha ez a környezeti változó be van állítva a PHP futási környezetében, akkor az ebben tárolt útvonalon megpróbál minden *.ini fájlt betölteni, amellyel felüldefiniálhatóak a korábban már beolvasott "php.ini" beállítások.
Bővebben angolul a PHP dokumentációjában: http://php.net/manual/en/configuration.file.php#configuration.file.scan
FONTOS:
Ne tévesszük össze a futtatható php parancssori kapcsolói közül a "-c <path>|<file>" lehetőséggel. Ez utóbbi arra való, hogy ha érvényes fájlra vagy könyvtárra mutat, akkor a php beállításokat tartalmazó fájlokat onnan próbálja beolvasni. Ha a -c kapcsoló nem mutat érvényes fájlra vagy könyvtárra, akkor a PHP az alapértelmezett helyek valamelyikén keres majd megfelelő ini állományt.
Ui.: A fenti változó nagyon hasznosnak fog bizonyulni a saját kis webszerveren további pofozgatásában, mert már meguntam, hogy az egyik PHP verzióban egy kicsit másképpen vannak beállítva olyan általános értékek, mint például a feltölthető maximális fájlméret (max_upload_filesize) vagy a POST kérések maximális mérete (post_max_size) és hasonlók.
Címkék:
környezeti változó,
php,
PHP_INI_SCAN_DIR
2018. augusztus 24., péntek
FtpUse - Windows alatt FTP felcsatolása meghajtóként
Az FtpUse egy aprócska program, amit feltelepítve parancssorosan lehet meghajtó betűjelhez rendelni egy-egy ftp kapcsolatot.
Szerintem nagyon egyszerű a használata.
A programról bővebben a https://www.ferrobackup.com/map-ftp-as-disk.html URL címen.
Ui.: az első próbálkozások után nem igazán tudtam hordozható állapotra varázsolni, de ez valószínűleg a Dokan meghajtók miatt lehet.
A Dokan könyvtárról bővebben itt: https://dokan-dev.github.io/
Szerintem nagyon egyszerű a használata.
A programról bővebben a https://www.ferrobackup.com/map-ftp-as-disk.html URL címen.
Ui.: az első próbálkozások után nem igazán tudtam hordozható állapotra varázsolni, de ez valószínűleg a Dokan meghajtók miatt lehet.
A Dokan könyvtárról bővebben itt: https://dokan-dev.github.io/
2018. augusztus 14., kedd
Reguláris kifejezés: Az URL abszolút hivatkozás?
Reguláris kifejezéssel általában így szoktam tesztelni, hogy egy URL abszolút hivatkozás-e:
^((https?):)?//
A fenti kifejezés illeszkedik az alábbiakra:
http://www.example.com
https://www.example.com
//www.example.com
http://example.com
https://example.com
//example.com
De nem illeszkedik például az alábbiakra:
assets/page.js
/relative-from-document-root/assets/page.js
^((https?):)?//
A fenti kifejezés illeszkedik az alábbiakra:
http://www.example.com
https://www.example.com
//www.example.com
http://example.com
https://example.com
//example.com
De nem illeszkedik például az alábbiakra:
assets/page.js
/relative-from-document-root/assets/page.js
Magyarázat:
- A szöveg elejére nézi az illeszkedést a "^" karakter
- A szöveg elején 0 vagy egyszer szerepelhet a "https" karaktersorozat, amelyben az "s" karakter 0 vagy egyszer fordulható elő a "http" szöveg után
- Az illeszkedő "http" vagy "https" szöveget követni kell egy ":" karakternek
- Ha van illeszkedő "http:" vagy "https:" karaktersorozat a szöveg elején, akkor ezek 0 vagy egyszer fordulhatnak elő ("((https?):)?")
- Ha volt protokoll illeszkedés, akkor utána legyen egy "//" karaktersorozat, vagy protokoll nélküli feltüntetés esetén a szöveg azonnal a "//" karaktersorozattal kezdődjön
www kiegészítés
Ha szükséges a "www." előtagra való illeszkedés is, akkor a fenti kifejezés kibővül az alábbira:
^((https?):)?//(www.)?
Használjátok egészséggel!
XSLT - minden másolása
Jó dolog ez az XSLT!
Például ha azt szeretnénk, hogy egy XML forrásból minden elem át legyen másolva a generált tartalomba, akkor a következő egyszerű és rekurzív XSLT sablont is lehet definiálnunk:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
Például ha azt szeretnénk, hogy egy XML forrásból minden elem át legyen másolva a generált tartalomba, akkor a következő egyszerű és rekurzív XSLT sablont is lehet definiálnunk:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
Röviden:
A fenti szabály illeszkedik minden xml csomópontra és xml attributumra. Ha illeszkedik, akkor ugye
lefut.
Működése: az illeszkedő elemet (legyen az éppen aktuálisan egy csomópont, vagy attributum) másold át a cél dokumentumba. A másolás után alkalmazd újra az összes definiált XSLT sablon szabályt az aktuális csomóponton belül közvetlenül minden gyerek csomópontra, vagy attributumra.
Zseniális?
Update: egy angol nyelvű bővebb cikk a fentiekről: http://www.usingxml.com/Transforms/XslIdentity
Update: egy angol nyelvű bővebb cikk a fentiekről: http://www.usingxml.com/Transforms/XslIdentity
2018. augusztus 12., vasárnap
PHP "arg_separator.output" beállítási lehetőség legyen inkább "&"
Előtörténet:
2018-at írunk, és van egy honlap, amely egy mondjuk valamennyire régebbecske tárhelyen foglal helyet. Kapott egy kis felújítást és a későbbiekben is fog kapni ezt-azt. Mondjuk, hogy ez egy olyan kis hobby oldalam. Elvállaltam.
A tárhely PHP 5.3.10. Nem mai darab, ezt azt hiszem ki lehet jelenteni.
Saját localhost-on szintén egy PHP 5.3.29 lett beállítva az oldal fejlesztéséhez. Lent minden tökéletes volt. Felmásoltam.
A probléma ott kezdődött, hogy egy oldalon volt egy átirányítás, ha nem voltak bizonyos url paraméterek a kérésben. A szükséges default url paraméterekkel készítettem egy url, és azt header() függvénnyel ki is lett küldve, ami lent tökéletesen működött.
A szükséges plusz paraméterek a http_build_query() függvénnyel lettek hozzáfűzve az új URL-hez, és egy Location: header kíséretében ki lett küldve az éterbe.
De az átirányított url-ben a "&" paraméterek helyett "&" szerepelt. Ez így nem kóser, és elkezdtem kutatni.
A hibakeresés addig mindent rendben talált, hogy a http_build_query() függvény még helyes kimenetet ad.
Talán a header() függvényben van valami turpisság, illetve annak valamilyen beállítása?
...
Végül odáig fajult a dolog, hogy összehasonlítottam a lenti és a fenti phpinfo() kimenetét, azon belül a konfiuráiciós értékek listáját. Először tovább siklott a tekintetem, de utána ráakadtam a címben említett "arg_separator.output" beállítási lehetőségre, ami vajon mi volt az éles helyen? Hát persze, hogy "&" és lent nálam pedig az "&" érték.
Mivel az éles tárhelyen nem férek hozzá a php.ini beállításokhoz közvetlenül, de szerencsére az ini_set() függvény nem lett letiltva, ezért ezen keresztül lett orvosolva a hiba.
Milyen kis apróság, és közel 1 órás nagyon izgalmas hibakereséssel gazdagította (?) az életemet.
2018-at írunk, és van egy honlap, amely egy mondjuk valamennyire régebbecske tárhelyen foglal helyet. Kapott egy kis felújítást és a későbbiekben is fog kapni ezt-azt. Mondjuk, hogy ez egy olyan kis hobby oldalam. Elvállaltam.
A tárhely PHP 5.3.10. Nem mai darab, ezt azt hiszem ki lehet jelenteni.
Saját localhost-on szintén egy PHP 5.3.29 lett beállítva az oldal fejlesztéséhez. Lent minden tökéletes volt. Felmásoltam.
A probléma ott kezdődött, hogy egy oldalon volt egy átirányítás, ha nem voltak bizonyos url paraméterek a kérésben. A szükséges default url paraméterekkel készítettem egy url, és azt header() függvénnyel ki is lett küldve, ami lent tökéletesen működött.
A szükséges plusz paraméterek a http_build_query() függvénnyel lettek hozzáfűzve az új URL-hez, és egy Location: header kíséretében ki lett küldve az éterbe.
De az átirányított url-ben a "&" paraméterek helyett "&" szerepelt. Ez így nem kóser, és elkezdtem kutatni.
A hibakeresés addig mindent rendben talált, hogy a http_build_query() függvény még helyes kimenetet ad.
Talán a header() függvényben van valami turpisság, illetve annak valamilyen beállítása?
...
Végül odáig fajult a dolog, hogy összehasonlítottam a lenti és a fenti phpinfo() kimenetét, azon belül a konfiuráiciós értékek listáját. Először tovább siklott a tekintetem, de utána ráakadtam a címben említett "arg_separator.output" beállítási lehetőségre, ami vajon mi volt az éles helyen? Hát persze, hogy "&" és lent nálam pedig az "&" érték.
Mivel az éles tárhelyen nem férek hozzá a php.ini beállításokhoz közvetlenül, de szerencsére az ini_set() függvény nem lett letiltva, ezért ezen keresztül lett orvosolva a hiba.
Milyen kis apróság, és közel 1 órás nagyon izgalmas hibakereséssel gazdagította (?) az életemet.
2018. augusztus 2., csütörtök
Apache beállítás - FcgidInitialEnv
Előtörténet:
Röviden: elkezdtem magamnak egy saját kis fejlesztői webszervert összerakni már évek óta folyamatosan, amiről valószínűleg több bejegyzés is fog születni, mert érdemesnek tartom megosztani néhány kódrészletet.
Az apache-ban (amiből egyenlőre csak egy példányt tudok futtatni, de ez nem lesz mindig így) egy újabb lehetőséget szerettem volna megvalósítani, ami sikerült is, mások segítségével. Köszönet Nagy Gergőnek és közvetve Dankó Dávidnak, aki Nagy Gergőnek segített ezt magvalósítani.
pl.: "localhost/php55" és a "localhost/php56" alatt ugyanaz a root mappa kerüljön kiszolgálásra, de eltérő PHP verziók segítségével. Ezt sikerült is megoldani, amihez soft linkekre volt szükségem, valamint néhány fcgi php folyamat definiálására.
(Majd néhány kódmorzsát megosztok később.)
A dolog eddig úgy látszott, hogy tökéletesen működik.
DE! Egy új projektet kellett beindítani localhost alatt, de panaszkodott, hogy nem tudja írni a session mentéséhez mappát. Kis kutakodás után rájöttem, hogy a php.ini-ben a session.save_path beállításnál használt környezeti változómat nem látja a fcgi-ban indított PHP-m. Normál apache PHP modulként működött a dolog.
Rövid kerekített 5 perces keresgélés után meg is lett a megoldás. Az apache httpd.conf fájlban az fcgi definiálásakor szükséges volt megadni FcgidInitialEnv beállítást is.
Dokumentáció:
https://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#fcgidinitialenv
Ui.: Mire képes az "apache és php fejlesztői csomagom"?
- egyetlen apache verzió
- több php verzió (5.3.x, 5.4.x, 5.5.x, 5.6.x, 7.0.x, 7.1.x, 7.2.x, 7.3.x), amelyből mindig a legújabb patch verziók vannak használva. A frissítés manuálisan történik, ami általában 3-4 percet vesz igénybe.
- "localhost" url kiszolgálása a apache_php_module segítségével, amely az alapértelmezetten beállított php verziót veszi alapul és annak megfelelőn állítja be az apache-ot is. Ennek a megváltoztatásához egy fájlban egy érték átállítására és az apache újraindítására van szükség.
- "localhost:80xx" különböző portokon különböző PHP verziók szolgálják ki a php fájlokat
- "localhost/phpxx" url-eken történő kiszolgálás különböző php verziókkal úgy, hogy mindegyik ilyen url ugyanazt a mappát mutatja, mint a "localhost" url.
Ui. 2.: Erről a kis saját fejlesztő csomagomról még írkálok ezt-azt. Egyetlen paranccsal indítható apache, több mysql, több php, composer, nginx, nodejs, stb..., és időnként van benne fejlődés, fejlesztés is, mint például, ahogy most is.
Röviden: elkezdtem magamnak egy saját kis fejlesztői webszervert összerakni már évek óta folyamatosan, amiről valószínűleg több bejegyzés is fog születni, mert érdemesnek tartom megosztani néhány kódrészletet.
Az apache-ban (amiből egyenlőre csak egy példányt tudok futtatni, de ez nem lesz mindig így) egy újabb lehetőséget szerettem volna megvalósítani, ami sikerült is, mások segítségével. Köszönet Nagy Gergőnek és közvetve Dankó Dávidnak, aki Nagy Gergőnek segített ezt magvalósítani.
pl.: "localhost/php55" és a "localhost/php56" alatt ugyanaz a root mappa kerüljön kiszolgálásra, de eltérő PHP verziók segítségével. Ezt sikerült is megoldani, amihez soft linkekre volt szükségem, valamint néhány fcgi php folyamat definiálására.
(Majd néhány kódmorzsát megosztok később.)
A dolog eddig úgy látszott, hogy tökéletesen működik.
DE! Egy új projektet kellett beindítani localhost alatt, de panaszkodott, hogy nem tudja írni a session mentéséhez mappát. Kis kutakodás után rájöttem, hogy a php.ini-ben a session.save_path beállításnál használt környezeti változómat nem látja a fcgi-ban indított PHP-m. Normál apache PHP modulként működött a dolog.
Rövid kerekített 5 perces keresgélés után meg is lett a megoldás. Az apache httpd.conf fájlban az fcgi definiálásakor szükséges volt megadni FcgidInitialEnv beállítást is.
Dokumentáció:
https://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html#fcgidinitialenv
Ui.: Mire képes az "apache és php fejlesztői csomagom"?
- egyetlen apache verzió
- több php verzió (5.3.x, 5.4.x, 5.5.x, 5.6.x, 7.0.x, 7.1.x, 7.2.x, 7.3.x), amelyből mindig a legújabb patch verziók vannak használva. A frissítés manuálisan történik, ami általában 3-4 percet vesz igénybe.
- "localhost" url kiszolgálása a apache_php_module segítségével, amely az alapértelmezetten beállított php verziót veszi alapul és annak megfelelőn állítja be az apache-ot is. Ennek a megváltoztatásához egy fájlban egy érték átállítására és az apache újraindítására van szükség.
- "localhost:80xx" különböző portokon különböző PHP verziók szolgálják ki a php fájlokat
- "localhost/phpxx" url-eken történő kiszolgálás különböző php verziókkal úgy, hogy mindegyik ilyen url ugyanazt a mappát mutatja, mint a "localhost" url.
Ui. 2.: Erről a kis saját fejlesztő csomagomról még írkálok ezt-azt. Egyetlen paranccsal indítható apache, több mysql, több php, composer, nginx, nodejs, stb..., és időnként van benne fejlődés, fejlesztés is, mint például, ahogy most is.
Címkék:
apache,
conf,
httpd,
saját fejlesztő webszerver,
webszerver beállítás
2018. július 26., csütörtök
restart (ismét)
Azt hiszem, hogy megpróbálom újrakezdeni ezt a blog dolgot.
A korábbi bejegyzések is megmaradnak.
Majd meglátjuk.
De az is megtörténhet, hogy keresek és találok blogger.com alternatívát.
A korábbi bejegyzések is megmaradnak.
Majd meglátjuk.
De az is megtörténhet, hogy keresek és találok blogger.com alternatívát.
2015. április 30., csütörtök
Phalcon v2.0.0 UPGRADE
Kb. 1 hete jött ki a Phalcon v2.0.0, amelynek a legfőbb célja, hogy a v1.3.x-es verzióvonal forráskódjait átültessék a PHP szintakszisához elég közel álló Zephir nyelvre, ami szintén a Phalcon készítők gyermeke.
\Phalcon\Mvc\Model\ValidatorInterface->validate() metódus fejléc megváltozott
Phalcon v2.0 alatt
public function validate($record);
-->
public function validate(\Phalcon\Mvc\ModelInterface $record);
Zephir röviden:
Mindenki vessen egy pillantást a Zephir köztes nyelvre, amely hidat képez a C és a PHP között, és leegyszerűsítheti a saját PHP modulok írását. Mi sem bizonyítja ezt jobban, mint a most kiadott Phalcon v2.0.0 *.zep kiterjesztésű forrás állományai.
Ennyit a Zephir-ről!
A Phalcon v1.3.x --> v2.0.0 upgrade folyamatról írt néhány sort a Phalcon csapata is a blogjukban.
Ebből a cikkből is látszik, hogy elsődleges céljuk egy Zephir alapú v2.0.0 verzió megalkotása volt felhasználva a v1.3.4-es verzió kódjait és funkcionalitását, ami azt eredményezi, hogy a lehető legnagyobb mértékben kompatibilis a v2.0.0 a v1.3.4-el, kivéve néhány pontot természetesen. :)
Egy Phalcon-ra épített projektben az upgrade során szerzett tapasztalataim a következők voltak:
(a lista még bővülhet)
------------------------------------------------------------
\Phalcon\DI\InjectionAwareInterface->setDi() metódus fejléce megváltozott:
public function setDI($dependencyInjector)
-->
public function setDI(\Phalcon\DiInterface $dependencyInjector)
------------------------------------------------------------
\Phalcon\Mvc\Application->registerModules metódus fejléce megváltozott:
public function registerModules($modules, $merge=null){ }
-->
public function registerModules(array $modules, $merge = null) {}
------------------------------------------------------------
A \Phalcon\Config értékek nem lehetnek callback és/vagy Closure típusúak, mert
akkor a ->merge() metódus ki fog akadni!!!
Egyetlen egyszer be tudja a ->merge() állítani a Closure típusú értéket, de ha egy már Closure típusú érték helyére egy újabbat kellene összefésülni, akkor fog kiakadni "Call to undefined method Closure::count()" kivétel üzenettel.
A jelenséget ez az if elágazás okozza a Phalcon forrásában:
https://github.com/phalcon/cphalcon/blob/phalcon-v2.0.0/phalcon/config.zep#L227
Egyetlen egyszer be tudja a ->merge() állítani a Closure típusú értéket, de ha egy már Closure típusú érték helyére egy újabbat kellene összefésülni, akkor fog kiakadni "Call to undefined method Closure::count()" kivétel üzenettel.
A jelenséget ez az if elágazás okozza a Phalcon forrásában:
https://github.com/phalcon/cphalcon/blob/phalcon-v2.0.0/phalcon/config.zep#L227
------------------------------------------------------------
\Phalcon\Mvc\Router->getDefaultModule() metódus nem létezik Phalcon v2.0 alatt
------------------------------------------------------------
\Phalcon\Events\EventsAwareInterface::setEventsManager() metódus fejléce eltér
Phalcon v2.0 alatt:
\Phalcon\Events\EventsAwareInterface::setEventsManager($eventsManager)
-->
\Phalcon\Events\EventsAwareInterface::setEventsManager(Phalcon\Events\ManagerInterface $eventsManager)
------------------------------------------------------------
Az alábbi utasítás formát át kell írni:
\Phalcon\Mvc\Model::find(array(
'conditions' => '...',
'bind' => array( 1 => 'VALUE'),
'bindTypes' => array(\Phalcon\Db\Column::BIND_PARAM_***),
));
A következőre:
\Phalcon\Mvc\Model::find(array(
'conditions' => '...',
'bind' => array( 1 => 'VALUE'),
'bindTypes' => array( 1 => \Phalcon\Db\Column::BIND_PARAM_***),
));
Röviden:
A 'bindTypes' tömbnek az indexelése most már minden esetben követnie kell a 'bind' tomb indexelését.
------------------------------------------------------------
Az alábbi utasítás formát át kell írni:
\Phalcon\Mvc\Model::find(array(
'conditions' => '...',
'bind' => array( 1 => 'VALUE'),
'bindTypes' => array(\Phalcon\Db\Column::BIND_PARAM_***),
));
A következőre:
\Phalcon\Mvc\Model::find(array(
'conditions' => '...',
'bind' => array( 1 => 'VALUE'),
'bindTypes' => array( 1 => \Phalcon\Db\Column::BIND_PARAM_***),
));
Röviden:
A 'bindTypes' tömbnek az indexelése most már minden esetben követnie kell a 'bind' tomb indexelését.
------------------------------------------------------------
\Phalcon\Mvc\Model\ValidatorInterface->validate() metódus fejléc megváltozott
Phalcon v2.0 alatt
public function validate($record);
-->
public function validate(\Phalcon\Mvc\ModelInterface $record);
------------------------------------------------------------
2014. április 13., vasárnap
Phalcon XSLT sablon motor
Már egy ideje pofozgatom az alábbi XSLT alapú sablon motort, amely kifejezetten a Phalcon PHP-s keretrendszerhez lett kialakítva:
Packagist link:
https://packagist.org/packages/racztiborzoltan/phalcon-xslt-view-engine
Github:
https://github.com/racztiborzoltan/phalcon-xslt-view-engine
Még nem igazán tartom tökéletesnek, de a céljaimnak egyenlőre meg fog felelni. Amúgy is sokat fejlődött az első kiadáshoz képest!
De egyre jobban érik egy v2.x ág elindításának a gondolata.
Próbáljuk meg egészséggel fogyasztani! :)
Packagist link:
https://packagist.org/packages/racztiborzoltan/phalcon-xslt-view-engine
Github:
https://github.com/racztiborzoltan/phalcon-xslt-view-engine
Még nem igazán tartom tökéletesnek, de a céljaimnak egyenlőre meg fog felelni. Amúgy is sokat fejlődött az első kiadáshoz képest!
De egyre jobban érik egy v2.x ág elindításának a gondolata.
Próbáljuk meg egészséggel fogyasztani! :)
Címkék:
phalcon,
php,
view engine,
xslt
2014. április 1., kedd
(nem csak) Drupal bölcsességek
GIT workflow-k ismét felütötték a kíváncsiság hangjait bennem, így néhány percre leléptem, és többek között erre a linkre bukkantam. (Vigyázat!!! A linken van a link! :))
DE!!!!
Az előbbi linken az alábbi okosságokat is találtam, amelyek többsége nem csak a drupalos fejlesztőkre érvényes:
http://szantogabor.com/bolcsessegek
DE!!!!
Az előbbi linken az alábbi okosságokat is találtam, amelyek többsége nem csak a drupalos fejlesztőkre érvényes:
http://szantogabor.com/bolcsessegek
2014. március 28., péntek
PHP Snippet: View szintek gyorsítótárazása Phalcon-ban
Nem nagyon találtam meg a Phalcon dokumentációjában, csak némi google zaklatás után.
A helyzet: Phalcon View objektumban beállítható, hogy legyen gyorsítótárazva a nézet, de ekkor a legfelső szinttől a teljes tartalmat gyorsítótárazza. Ha a renderelési szint lejjebb van állítva, akkor nem készít gyorsítótár bejegyzést.
DE!!! Van egy a dokumentációban nem említett beállítás, amellyel megadható, hogy a View objektum melyik szintjének kimenete legyen eltéve a gyorsítótárba.
Ezt pedig a következőképpen lehetséges:
$view->cache(array(
'level' => \Phalcon\Mvc\View::LEVEL_ACTION_VIEW
));
----
Örültem a szerencsének!
-----------------------------------------------------------
Kiegészítés a fenti bejegyzéshez (2014-04-02)
Nem minden esetben történik meg a fentebb említetthez hasonló beállítások mellett a megfelelő View szintek gyorsítótárazása.
Az alábbi érdekes jelenségeket tapasztaltam ezzel kapcsolatban:
A helyzet: Phalcon View objektumban beállítható, hogy legyen gyorsítótárazva a nézet, de ekkor a legfelső szinttől a teljes tartalmat gyorsítótárazza. Ha a renderelési szint lejjebb van állítva, akkor nem készít gyorsítótár bejegyzést.
DE!!! Van egy a dokumentációban nem említett beállítás, amellyel megadható, hogy a View objektum melyik szintjének kimenete legyen eltéve a gyorsítótárba.
Ezt pedig a következőképpen lehetséges:
$view->cache(array(
'level' => \Phalcon\Mvc\View::LEVEL_ACTION_VIEW
));
----
Örültem a szerencsének!
-----------------------------------------------------------
Kiegészítés a fenti bejegyzéshez (2014-04-02)
Nem minden esetben történik meg a fentebb említetthez hasonló beállítások mellett a megfelelő View szintek gyorsítótárazása.
Az alábbi érdekes jelenségeket tapasztaltam ezzel kapcsolatban:
- Ha nincs megadva a ->cache() metódusban a gyorsítótárazandó szint, akkor csak a LEVEL_MAIN_LAYOUT renderelési View szint esetén fog automatikusan gyorsítótárazni.
(Ez a pont inspirálta a fenti bejegyzést! :)) - A View esetén beállított renderelési szintnek nagyobbnak kell lennie a gyorsítótárazandó View szintnél, hogy beinduljon az automatikus gyorsítótárazás
- LEVEL_LAYOUT renderelési szint esetén bármilyen gyorsítótárazandó szint beállítása esetén két eredményt sikerült kicsiholnom:
- Nem volt gyorsítótár bejegyzés létrehozva,
- Vagy állandóan csak a LEVEL_LAYOUT szint lett csak a gyorsítótárba letárolva, annak ellenére, hogy pl. LEVEL_ACTION_VIEW lett megjelölve a gyorsítótárazandó View szintnek
- Egy hasznos, gyakorlati kísérletezgetések utáni tanács:Ha a ->cache() metódusban a 'level' értéknek TRUE-t adunk meg, akkor éppen a View-nak beállított renderelési szint teljes tartalma fog a gyorsítótárba bekerülni.
Valamint, ha ugyanez a 'level' érték FALSE-t kap, akkor nem lesz gyorsítótár generálva!
2013. május 7., kedd
PHP függvény hívás gyors teszt
in medias res:
<?php
$foo = function($a, $b, $c)
{
$j = 5-10-34-1+3/5;
// echo 'foo function';
};
function foo($a, $b, $c)
{
$j = 5-10-34-1+3/5;
}
class Bar
{
public static function static_foo($a, $b, $c)
{
$j = 5-10-34-1+3/5;
}
public function foo($a, $b, $c)
{
$j = 5-10-34-1+3/5;
}
}
$max = 10000;
echo '1 - '.$max;
echo '<br />';echo '<br />';
echo 'foo(1, 2, 3)';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
foo(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$foo = function($a, $b, $c){ /* ... */ }';echo '<br />';
echo '$foo(1,2,3)';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
$foo(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$function = "foo";';echo '<br />';
echo '$function(1, 2, 3)';echo '<br />';
$i = 0;
$function = 'foo';
$time = microtime(true);
while ($i<$max)
{
$function(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo "call_user_func('foo', 1, 2, 3)";echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func('foo', 1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo "call_user_func_array('foo', array(1, 2, 3))";echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array('foo', array(1, 2, 3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo "call_user_func(array('Bar', 'foo'), 1,2,3)";echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array(array('Bar', 'foo'), array(1,2,3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo 'call_user_func_array(array("Bar", "foo"), array(1,2,3))';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array(array('Bar', 'foo'), array(1,2,3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo 'call_user_func_array("Bar::foo"), array(1,2,3))';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array('Bar::foo', array(1,2,3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$bar->{$function}(1, 2, 3)';echo '<br />';
$i = 0;
$bar = new Bar(1, 2, 3);
$time = microtime(true);
while ($i<$max)
{
$function = 'foo';
$bar->{$function}(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$class::$function(1, 2, 3)';echo '<br />';
$i = 0;
$class = 'Bar';
$function = 'static_foo';
$time = microtime(true);
while ($i<$max)
{
$class::$function(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
?>
---------------------------------------------
Majd egy nálam produkált egyik kimenet:
1 - 10000
foo(1, 2, 3)
0.1220018863678
$foo = function($a, $b, $c){ /* ... */ }
$foo(1,2,3)
0.23000001907349
$function = "foo";
$function(1, 2, 3)
0.13000011444092
call_user_func('foo', 1, 2, 3)
0.21000099182129
call_user_func_array('foo', array(1, 2, 3))
0.22499990463257
call_user_func(array('Bar', 'foo'), 1,2,3)
0.27999997138977
call_user_func_array(array("Bar", "foo"), array(1,2,3))
0.29000091552734
call_user_func_array("Bar::foo"), array(1,2,3))
0.29000020027161
$bar->{$function}(1, 2, 3)
0.13499999046326
$class::$function(1, 2, 3)
0.13499999046326
---------------------------------------------
Kb. a dobogó:
<?php
$foo = function($a, $b, $c)
{
$j = 5-10-34-1+3/5;
// echo 'foo function';
};
function foo($a, $b, $c)
{
$j = 5-10-34-1+3/5;
}
class Bar
{
public static function static_foo($a, $b, $c)
{
$j = 5-10-34-1+3/5;
}
public function foo($a, $b, $c)
{
$j = 5-10-34-1+3/5;
}
}
$max = 10000;
echo '1 - '.$max;
echo '<br />';echo '<br />';
echo 'foo(1, 2, 3)';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
foo(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$foo = function($a, $b, $c){ /* ... */ }';echo '<br />';
echo '$foo(1,2,3)';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
$foo(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$function = "foo";';echo '<br />';
echo '$function(1, 2, 3)';echo '<br />';
$i = 0;
$function = 'foo';
$time = microtime(true);
while ($i<$max)
{
$function(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo "call_user_func('foo', 1, 2, 3)";echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func('foo', 1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo "call_user_func_array('foo', array(1, 2, 3))";echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array('foo', array(1, 2, 3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo "call_user_func(array('Bar', 'foo'), 1,2,3)";echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array(array('Bar', 'foo'), array(1,2,3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo 'call_user_func_array(array("Bar", "foo"), array(1,2,3))';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array(array('Bar', 'foo'), array(1,2,3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo 'call_user_func_array("Bar::foo"), array(1,2,3))';echo '<br />';
$i = 0;
$time = microtime(true);
while ($i<$max)
{
call_user_func_array('Bar::foo', array(1,2,3));
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$bar->{$function}(1, 2, 3)';echo '<br />';
$i = 0;
$bar = new Bar(1, 2, 3);
$time = microtime(true);
while ($i<$max)
{
$function = 'foo';
$bar->{$function}(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
echo '$class::$function(1, 2, 3)';echo '<br />';
$i = 0;
$class = 'Bar';
$function = 'static_foo';
$time = microtime(true);
while ($i<$max)
{
$class::$function(1, 2, 3);
$i++;
}
echo microtime(true) - $time;
echo '<br />';echo '<br />';
?>
---------------------------------------------
Majd egy nálam produkált egyik kimenet:
1 - 10000
foo(1, 2, 3)
0.1220018863678
$foo = function($a, $b, $c){ /* ... */ }
$foo(1,2,3)
0.23000001907349
$function = "foo";
$function(1, 2, 3)
0.13000011444092
call_user_func('foo', 1, 2, 3)
0.21000099182129
call_user_func_array('foo', array(1, 2, 3))
0.22499990463257
call_user_func(array('Bar', 'foo'), 1,2,3)
0.27999997138977
call_user_func_array(array("Bar", "foo"), array(1,2,3))
0.29000091552734
call_user_func_array("Bar::foo"), array(1,2,3))
0.29000020027161
$bar->{$function}(1, 2, 3)
0.13499999046326
$class::$function(1, 2, 3)
0.13499999046326
---------------------------------------------
Kb. a dobogó:
- 1. hely
- foo(1, 2, 3)
- 2. hely
- $function = "foo"; $function(1, 2, 3)
- $bar->{$function}(1, 2, 3)
- $class::$function(1, 2, 3)
- 3. hely:
- call_user_*()
2012. október 27., szombat
Virtualbox linux natív képernyő felbontáshoz szükséges lehet
Kijött a Xubuntu 12.10 is az Ubuntu 12.10 megjelenésével egyidőben!
Mivel úgy látszik még mindig ismerkedek a linux-okkal, és most már nem annyira biztos, hogy a Debian mellett fogom letenni a voksom, ezért feltoltam egy Virtualbox-os virtuális gépre a Xubuntu legújabb változtatát.
De telepítés után és a Virtualbox Integrációs Szolgáltatások feltelepítése után nem ismerte fel a monitorom teljes felbontását, és teljes képernyős módban is max. 1024x768-as felbontás tudott maximum!
Megoldás:
Némi keresgélés után találtam ezt a blog bejegyzést (biztos sok egyéb helyen is van megoldás):
http://ubuntuforums.org/showthread.php?t=1880909
Három csomagot kell telepíteni, ha még nem lennének a rendszerben:
Nekem ez nálam megoldotta a problémát, valószínű mindenki másnál is meg fogja! Valamint ha jól sejtem, akkor az Ubuntu család összes tagjánál is ugyanezeket kell telepíteni, ha gond lenne (Kubuntu, Lubuntu, Ubuntu, Edubuntu, stb...)
Mivel úgy látszik még mindig ismerkedek a linux-okkal, és most már nem annyira biztos, hogy a Debian mellett fogom letenni a voksom, ezért feltoltam egy Virtualbox-os virtuális gépre a Xubuntu legújabb változtatát.
De telepítés után és a Virtualbox Integrációs Szolgáltatások feltelepítése után nem ismerte fel a monitorom teljes felbontását, és teljes képernyős módban is max. 1024x768-as felbontás tudott maximum!
Megoldás:
Némi keresgélés után találtam ezt a blog bejegyzést (biztos sok egyéb helyen is van megoldás):
http://ubuntuforums.org/showthread.php?t=1880909
Három csomagot kell telepíteni, ha még nem lennének a rendszerben:
- virtualbox-guest-dkms - ez a virtualbox "quest-additions"-el már felmászott korábban
- virtualbox-guest-utils - személy szerint ez nem volt telepítve nálam
- virtualbox-guest-x11 - ezzel is rendelkeztem már, úgy mint az első csomaggal
Nekem ez nálam megoldotta a problémát, valószínű mindenki másnál is meg fogja! Valamint ha jól sejtem, akkor az Ubuntu család összes tagjánál is ugyanezeket kell telepíteni, ha gond lenne (Kubuntu, Lubuntu, Ubuntu, Edubuntu, stb...)
2012. október 24., szerda
Windows 7 nem hibernál
Az általában rám jellemző, részletesebb, de a témához jelentős mértékben nem kapcsolódó bevezető szöveg, amely sokak számára felesleges, értelmetlen, és/vagy unalmas is:
------------------------------------------
Egyre komolyabbá kezd válni a gondolat, hogy leváltom a Windows 7-et. Ezt a dolgot már morzsolgatom magamban. Linux disztró válogatás, tesztelgetés. Asztali környezet válogatás tesztelgetés. Mind ezt csak Virtualbox-ban. Persze közben volt egy éles telepítés Linux Mint személyében, amely mellé az automatikusan csomagolt MATE asztali környezetet gondoltam ki. Próbálgattam élesben is, de gyorsan feledésbe merült nagyobb rááldozható szabadidő, és egyéb tényezők miatt!
De most okt. 23. előtti kedden elérkezettnek láttam az időt, hogy ismét egy hosszabb válogatási időszak végén (mert ugye a tehetség kutató műsorok korát éljük :)) pontot tegyek egy disztro mellé, ami az elmúlt 2-3 hétben alakult végeredménnyé. Ez a Debian lett!
Első éles telepítésre során kiakadt a GRUB a telepítési folyamatban. Ez sikeresen kinyírta a Windows boot-olást is, amit egy partíció boot flag újbóli kiosztása megoldott a live cd-ről elindított partícionáló segítségével.
Második próbálkozásra szépen felkúszott a Debián (becézve: "debi", vesd össze: 'Olyan debi vagyok, hogy mindjárt OMG leszek' :))
Számomra (,web fejlesztéshez) szükséges néhány alap Windows program alternatívájának, vagy éppen linux-os változatának telepítése (pl. MySQL Workbench, Eclipse, xCHM, stb..). Egy kis driver kutakodás hang és wifi után. Az előbbi hiányosságot betudom a Debian-ra jellemző régebbi, de biztosan stabil csomagok meglétének. (Nem vagyok linux-os, de a kernel is még 2.x). Némi ügyeskedéssel úgy gondolom, mindent le lehet cserélni (Pl. Iceweasel --> Firefox). Hang és wifi az internetes leírások alapján elég könnyen sikerült belőni. Örülök. Estére egy újabb problémába ütköztem: hibernálás után elszállt a hang. Ezt még meg kell "gugliznom". Talán majd ha eredményre jutok, még ide is feldobok néhány hasznos fórum hivatkozást.
To be continued ... in a other galaxy far, far away!
Most itt pontot (illetve kötöjelet) teszek ezen rész végére!
------------------------------------------
A lényeg:
A következő jelenség ütötte meg a szememet:
Windows 7-ben a Start menüben a hibernálás művelet helyett kikapcsolta a monitoromat (megj.: laptopom van!), valamint egyszerűn csak zárolta a felhasználói fiókomat a redmondi operációs rendszer 6.1-es verziójú változata. (Még csak az kellene, hogy egy mondatban kétszer szerepeljen a Windows 7 kifejezés :))
Irány a Google, de két nagy irányba mentek el a válaszolók: vagy driver frissítés kell, vagy (esetleg és) az energiagazdálkodásnál ki kell kapcsolni a jelszó kérését a rendszer visszatérésekor.
De, amit mostanában ritkábban szoktam, magyarul is megpróbáltam rákeresni a bajomra, és ím ez lett az eredménye:
http://pcforum.hu/tudastar/63933/Windows+7+nem+hibernal.html
A tudástárban folyó csevegés végén megszületett az én megoldásomra is a gyógyír: Valószínűleg a pár nappal ezelőtt telepített Linux (Debian) "gyökér" partíciója (sorry linux közösség!) átvette a boot flag-et a Win7-es partíciótól.
Nincs más dolga az embernek, mint átbillenteni egy Windows (pl. EASEUS Partition Master Home Edition), vagy egy Linux-os (pl. GParted) partíció kezelőben a Windows-t tartalmazó partíció boot flag-jét, azaz boot-olhatónak (indíthatónak, aktívnak) kell megjelölni!
------------------------------------------
A lényeg lényege:
Windows mellé telepített Linux esetén a telepítés után érdemes a megnézni a partíciós táblát annak érdekében, hogy a személyes véleményem szerint hasznos hibernálás megfelelően funkcionáljon!
------------------------------------------
Ui.: Itt nem igen érvényes a "Lényeg lényegében lényegtelen!" mondat! :)
------------------------------------------
Egyre komolyabbá kezd válni a gondolat, hogy leváltom a Windows 7-et. Ezt a dolgot már morzsolgatom magamban. Linux disztró válogatás, tesztelgetés. Asztali környezet válogatás tesztelgetés. Mind ezt csak Virtualbox-ban. Persze közben volt egy éles telepítés Linux Mint személyében, amely mellé az automatikusan csomagolt MATE asztali környezetet gondoltam ki. Próbálgattam élesben is, de gyorsan feledésbe merült nagyobb rááldozható szabadidő, és egyéb tényezők miatt!
De most okt. 23. előtti kedden elérkezettnek láttam az időt, hogy ismét egy hosszabb válogatási időszak végén (mert ugye a tehetség kutató műsorok korát éljük :)) pontot tegyek egy disztro mellé, ami az elmúlt 2-3 hétben alakult végeredménnyé. Ez a Debian lett!
Első éles telepítésre során kiakadt a GRUB a telepítési folyamatban. Ez sikeresen kinyírta a Windows boot-olást is, amit egy partíció boot flag újbóli kiosztása megoldott a live cd-ről elindított partícionáló segítségével.
Második próbálkozásra szépen felkúszott a Debián (becézve: "debi", vesd össze: 'Olyan debi vagyok, hogy mindjárt OMG leszek' :))
Számomra (,web fejlesztéshez) szükséges néhány alap Windows program alternatívájának, vagy éppen linux-os változatának telepítése (pl. MySQL Workbench, Eclipse, xCHM, stb..). Egy kis driver kutakodás hang és wifi után. Az előbbi hiányosságot betudom a Debian-ra jellemző régebbi, de biztosan stabil csomagok meglétének. (Nem vagyok linux-os, de a kernel is még 2.x). Némi ügyeskedéssel úgy gondolom, mindent le lehet cserélni (Pl. Iceweasel --> Firefox). Hang és wifi az internetes leírások alapján elég könnyen sikerült belőni. Örülök. Estére egy újabb problémába ütköztem: hibernálás után elszállt a hang. Ezt még meg kell "gugliznom". Talán majd ha eredményre jutok, még ide is feldobok néhány hasznos fórum hivatkozást.
To be continued ... in a other galaxy far, far away!
Most itt pontot (illetve kötöjelet) teszek ezen rész végére!
------------------------------------------
A lényeg:
A következő jelenség ütötte meg a szememet:
Windows 7-ben a Start menüben a hibernálás művelet helyett kikapcsolta a monitoromat (megj.: laptopom van!), valamint egyszerűn csak zárolta a felhasználói fiókomat a redmondi operációs rendszer 6.1-es verziójú változata. (Még csak az kellene, hogy egy mondatban kétszer szerepeljen a Windows 7 kifejezés :))
Irány a Google, de két nagy irányba mentek el a válaszolók: vagy driver frissítés kell, vagy (esetleg és) az energiagazdálkodásnál ki kell kapcsolni a jelszó kérését a rendszer visszatérésekor.
De, amit mostanában ritkábban szoktam, magyarul is megpróbáltam rákeresni a bajomra, és ím ez lett az eredménye:
http://pcforum.hu/tudastar/63933/Windows+7+nem+hibernal.html
A tudástárban folyó csevegés végén megszületett az én megoldásomra is a gyógyír: Valószínűleg a pár nappal ezelőtt telepített Linux (Debian) "gyökér" partíciója (sorry linux közösség!) átvette a boot flag-et a Win7-es partíciótól.
Nincs más dolga az embernek, mint átbillenteni egy Windows (pl. EASEUS Partition Master Home Edition), vagy egy Linux-os (pl. GParted) partíció kezelőben a Windows-t tartalmazó partíció boot flag-jét, azaz boot-olhatónak (indíthatónak, aktívnak) kell megjelölni!
------------------------------------------
A lényeg lényege:
Windows mellé telepített Linux esetén a telepítés után érdemes a megnézni a partíciós táblát annak érdekében, hogy a személyes véleményem szerint hasznos hibernálás megfelelően funkcionáljon!
------------------------------------------
Ui.: Itt nem igen érvényes a "Lényeg lényegében lényegtelen!" mondat! :)
Feliratkozás:
Bejegyzések (Atom)