Programozás

Programozással kapcsolatos ötletek, megoldások

Rekordlista-szerű tömbök fa struktúrába rendezése - Fa menüstruktúra

Gyakori feladat olyan menüket készíteni, amik fa struktúrában épülnek fel és akár egy javascript program készít belőle lenyíló menüt. Vagy akár csak egy oldaltérképre is gondolhatunk. A következő megoldásom főként azon alapszik, amikor egy adatbázisban tárolunk valamilyen adatokat. Legyen az többszintű kategória rendszer vagy menüszerkezet. Ilyenkor többnyire van egy egyedi azonosító. Amire az alárendelt rekordok hivatkoznak egy másik mezőben. Emellett persze egyéb adatokat tartalmaz a rekord. Legalább egy megjelenítendő mező is van, ami például a menü szövege. De lehet hozzá leírás is rendelve. Különböző listák lehetnek, de ami közös bennük, az a felépítés módja. Azon túl más lehet a megjelenítés. Az egyiket például egyszerű rendezetlen listában kell megjeleníteni, a másikat talán már táblázatban. A harmadikat pedig csak tabulátorokat használva. Ráadásul ha már html megjelenítésről beszélünk, ott képbe jön a css is. HTML attribútumok, osztályok. Célszerűen, lehetőleg elérhetővé téve minden elemhez egy hivatkozást, amivel egyedien lehet szükség esetén formázni akár a második menüelem 3. gyerekének 1 gyerekét. Stb... Erre mutatok egy lehetséges, ám nem mindenre kiterjedő megoldást.

Megosztás/Mentés

R.E. Login 2.0 -tól oldalak megtekintésének korlátozása és jogok (rangok).

Kérek mindenkit, akinek nem a rangokkal, oldalak megtekintésével van problémája, a következő oldalon kérdezzen:
Meghívós loginrendszer - R.E. Login v2.0

Ez a login talán a legnépszerűbb programom. De való igaz, hogy nem készítettem hozzá részletes használati útmutatót. Mivel egy komplett leírásra egyszerre nincs időm, úgy döntöttem, a leggyakrabban feltett kérdésekre válaszolok. Amik egyben a leglényegesebbek is.

Hogyan kössem regisztrációhoz egy oldal megtekintését?

Teljes oldal letiltása

Ebben a verzióban létezik egy System osztály, ami többek között tartalmaz egy protectedSite() nevű metódust. Ez a metódus mondja meg a loginnak, hogy az adott oldal védett. Tehát nem tekintheti meg akárki. Paraméter nélkül hívva csak a belépést követeli meg. És ilyenkor a config-ban beállított ( Telepítéskor megadott, vagy utólag a classes/Config.class.php -ben beállított ) főoldalra irányít át, vagy külön beállított „Védett oldal fájlja” jelzésű ( config fájlban FILE_PROTECTED_SITE konstans ) oldal esetén utóbbira..

<?php
require_once 'init.php';
System::protectedSite();
?>
Amit ide írok, azt kizárólag belépett user tekintheti meg. A többi át lesz irányítva.
Megosztás/Mentés

Szöveg első N karakterének kinyerése reguláris kifejezéssel, php-val

Az előző bejegyzésemhez hasonló megoldást mutatok, csak most nem adott számú szót vág le a függvény egy szövegből, hanem karaktereket. Szintén állítható, hogy mi kerüljön a levágott szöveg végére, ha volt mit vágni. És szintén megadható, hogy unicode szövegként legyen-e értelmezve a megadott string. Itt mégis a lényegesebb paramétere a függvénynek a 3. paraméter. Ha egy szövegben pont egy szót kéne ketté vágni, nem biztos, hogy jól mutat. Vegyük példának azt a szöveget, hogy: „Mi ez a foszfor?”. Ennek az első 11 karakterét levágva fixen elég érdekes eredményt kapnánk, ami nem biztos, hogy megengedhető. A következő függvény harmadik paraméterével szabályozható, hogy a szövegben a félbevágott szavakat be kell-e fejezni, vagy esetleg el sem kell kezdeni. Netán nyugodtan meg lehet vágni bárhol. A megoldás most is reguláris kifejezésekkel működik, bár az mb_substr függvényt is használhattam volna.

Függvény

/**
 * Szöveg első N karakterének kinyerése
 *
 * @param int $n Hány karakter kell
 * @param string $str A string, amiből az első N karakter kell.
 * @param bool $wordwrapmod Ha null, akkor szavak közben is megvághatja  szöveget.
 *                                                      Ha true, akkor befejezi a szót, aminek a közepén vágna.
 *                                                      Ha false, akkor el sem kezdi a szót, aminek a közepén vágna.
 * @param bool $unicode Unicode karaktereket is értelmezzen.
 * @param string $more Tetszőleges szöveg, jelölés, ami akkor kerül az eredmény mögé,
 *                                              ha vágni kellett belőle.
 * @return string A levágott első N karakter
 */

function firstNChar($n, $str, $wordwrapmod = null, $unicode = true, $more = ' ...')
{
        $php53 = version_compare(PHP_VERSION, '5.3') >= 0;
        $w = $php53 ? '\w' : ($unicode ? '\p{L}\p{N}' : '\w');
        $W = $php53 ? '\W' :  '^'.$w;
        $x = $b = '';
        if ($wordwrapmod) {
                $x = '(?(?=['.$w.']+)['.$w.']+)';
        } else if (!is_null($wordwrapmod)) {
                $b = '(?=['.$W.']+)';
        }
        return preg_replace('~^(?>(.{0,'.(int)$n.'})'.$b.$x.').+$~is'.($unicode ? 'u' : ''), '$1'.$more, $str);
}

Példák

$nl = '<br />'.PHP_EOL;
echo firstNChar(10, "Ez egy szöveg").$nl;
echo firstNChar(10, "Ez egy szöveg", false).$nl;
echo firstNChar(10, "Ez egy szöveg", true).$nl;
echo firstNChar(10, "Ez egy szöveg", null, false).$nl;
echo firstNChar(10, "Ez egy szöveg", null, true, ' <a href="">&raquo;</a>').$nl;

Eredmény

Ez egy szö ...<br />
Ez egy ...<br />
Ez egy szöveg<br />
Ez egy sz� ...<br />
Ez egy szö <a href="">&raquo;</a><br />
Megosztás/Mentés

Szöveg első N szavának kinyerése reguláris kifejezéssel, php-val

A következő függvény az első N darab szót tudja kinyerni egy szövegből. Figyelembe veszi, hogy bár vessző, pont, stb... után szóköz kell, ezt nem mindenki tartja be. Ha egy mondat záródik az N. szó után, akkor a mondatzáró jelet is meghagyja. Egyébként levágja. Az N. szó után, ha az eredmény nem az egész szöveget tartalmazza, tetszőleges karakterlánc kiírható. Alapértelmezetten a három pont. Be lehet kapcsolni, hogy unicode karaktereket is tartalmaz-e a szöveg, vagy sem. Alapértelmezetten true-ra van állítva.

Függvény

/**
 * Szövegből első N szó kinyerése
 *
 * @param int $n Hány szó kell a szöveg elejéről
 * @param string $str A forrás szöveg
 * @param bool $unicode Unicode karakterek lehetnek-e a szövegben.
 * @param string $more Az eredmény szöveg mögé írt karakterlánc, ha az eredmény nem a teljes szöveg.  
 * @return string
 */

function firstNWord($n, $str, $unicode = true, $more = ' ...') {
        $php53 = version_compare(PHP_VERSION, '5.3') >= 0;
        $w = $php53 ? '\w' : ($unicode ? '\p{L}\p{N}' : '\w');
        $W = $php53 ? '\W' :  '^'.$w;
       
        return preg_replace('~^(\s*['.$w.']+'.
                        str_repeat('['.$W.']+['.$w.']+', $n-1).
                        '(?(?=[?!:;.])
                                [[:punct:]]\s*
                        ))\b(.+)$~isx'
.($unicode ? 'u' : ''), '$1'.$more, $str);
}

A függvény elején levő verzió ellenőrzés azért kellett, mert 5.3 -ban már a \w is illeszkedik ékezetes karakterre.

Példák

$nl = '<br />'.PHP_EOL;
echo firstNWord(5, "Ez egy").$nl;
echo firstNWord(5, "Ez egy.").$nl;
echo firstNWord(4, "Ez egy szöveg.Amiből megtartok 4 szót.").$nl;
echo firstNWord(3, "Ez egy szöveg. Amiből megtartok 3 szót.").$nl;
echo firstNWord(5, "Ez egy szöveg,amiből megtartok 5 szót.", true,  ' <a href="#">&raquo;</a>').$nl;
echo firstNWord(5, "Ez egy szöveg,amiből megtartok 5 szót.", false,  ' <a href="#">&raquo;</a>').$nl;

Eredmény

Ez egy<br />
Ez egy.<br />
Ez egy szöveg.Amiből ...<br />
Ez egy szöveg.  ...<br />
Ez egy szöveg,amiből megtartok <a href="#">&raquo;</a><br />
Ez egy szöveg,amib <a href="#">&raquo;</a><br />

Bár a fenti példákra működik a megoldás, nem kizárt, hogy nem tökéletes.

Megosztás/Mentés

"Objektumorientált" Drupal - A reflection osztályok haszna

Nem rég el kellett kezdenem drupalban fejleszteni. Számomra nagyon új és furcsa volt, hogy gyakorlatilag sehol egy igazi osztály, vagy az objektumorientáltság jele. Ez annyiban érdekes, hogy számomra egy jól strukturált OOP-re épülő forráskód sokkal érthetőbb, mint függvények sokasága, ahol ráadásul minden függvény ott lebeg a globális térben. Az is, ami kizárólag a modulnak kell. Ugyanez a változókkal. Na most kezdő drupalosként, hogy otthonosabban érezzem magam a forráskódban, megpróbáltam kierőszakolni az osztályok használatát úgy, hogy közben kigenerálom a függvényeket is, de csak azokat, amiket a drupalnak meg kell tudni hívni automatikusan. Hangsúlyozom, hogy a következő megoldást az ötlet és a megvalósítás miatt teszem közzé. Nem ajánlásként.

Megosztás/Mentés

PHP jelentősebb változásai napjainkig - Kezdetektől a trait-ekig

Emlékszem, mikor még a PHP 4 volt számomra az egyetlen verzió. Majd igen késve belekóstoltam a PHP 5-be és tetszett, amit láttam. Azóta is folyamatosan fejlődött. Kapott új függvényeket is, de mégsem volt olyan látványos a változás. Hozzáteszem, a unicode változónevek használata sem jelentéktelen, ami már 5.3 előtt is létezett, de a valódi haszna mégis megkérdőjelezhető. Majd az 5.3 -as verzióban többek között bevezették a névtereket. Persze nem nagyon volt még akkor olyan szerver, ahol ez a verzió futott volna. És mivel névterek nélkül is jól megvoltam addig, ezt a funkciót inkább nem is használtam. De az idő nem állt meg és elértünk az 5.2-es széria támogatottságának végéig. Amikor már mindenkit az 5.3-ra való átállásra ösztönöznek a PHP nyelv fejlesztői. Egyelőre még mindig több szerveren csak 5.2 van. Többek között a rimelek.hu szolgáltatóján is. Tervezik viszont ők is, hogy bevezetnek 5.3-as szervert is, amire kérésre át lehet majd kerülni. Van ingyenes szolgáltató, ami már korábban váltott. Ilyen a Freeweb.hu is. Lehet több is van. Nem néztem utána. Már 5.3.8 -nál tart ez a széria. És bár korábban sokan hallhattak a 6-os verzióról, a következő az 5.4 lesz.

A PHP 5.4 ismét olyan újításokat vezet be, ami miatt megint lehet egy kicsit dicsérni a nyelvet. De hogyan jutottunk ide?

Megosztás/Mentés

Egyszerű helyesírás-ellenőrző PHP-val. - pspell könyvtár

Egy kis helyesírás-ellenőrző programot fogok mutatni, amihez a PHP pspell könyvtárát használtam. Lényegében 3 függvényt használtam fel. Ezek pedig a pspell_new, pspell_check és pspell_suggest. Ezekkel már elérhető, hogy egy magyar szótár alapján az egyes szavak helyességét vizsgáljuk. Központozást és egyéb mondattani jellemzőket nem néz.

Szükséges

hozzá az aspell csomag. Illetve magyar szótárhoz az aspell-hu is. Ezen kívül a php5-pspell könyvtár kell, amit linuxon ( debian, ubuntu ) vagy apt-get -tel kell feltelepíteni, vagy aki a php-t is saját maga fordítja, az a --with-pspell kapcsolót kell használja. Ahhoz viszont szükséges előbb a libpspell-dev csomag is.

pspell_new

Ezzel lehet egy új szótárt megnyitni. Az első paraméterben a „hu_HU” megadja, hogy magyar szótár kell. A második paraméter különböző nyelvjárások megadására szolgál, mint például amerikai, brit, kanadai angol. Megadható zsargon is, de most a fontosabb két paraméter a 4. és 5. Ezek sorban a karakterkódolás és a mód. A móddal korlátozható a hibás szavakra adott javítási javaslatok száma. Én a leggyorsabb és legkevesebb javaslatot adó PSPELL_FAST konstanst adtam meg.

pspell_check

Ezzel lehet ellenőrizni egy szót. Fontos, hogy minden átadott string egy szónak számít. Tehát a mondatok szavakra darabolását meg kell oldani. Beleértve az írásjeleket is.

pspell_suggest

Végül pedig maradt a javaslatok lekérdezése. A javaslatokat ez a függvény tömbként adja vissza.

Helyesírás-ellenőrző program

Demo-t sajnos nem tudok mutatni, mert a tárhelyemen nincs telepítve a pspell. Ezért csak leírom, mit tud a program. Egy megadott szövegben megkeresi a hibás szavakat, majd azokat aláhúzva és kiemelve pirossal, megjeleníti. A hibás szavakra kattintva megjelennek a javaslatok, ha az űrlapon ez az opció ki van pipálva. Lehetne tovább cifrázni azzal, hogy a javaslatra kattintva a szövegben lecseréli a szót, de ezt én most nem oldottam meg.

És a program forráskódja:

Megosztás/Mentés

Ifsetor és kukac operátor php 5.3 -ban

A PHP 5.3 -ban bevezettek egy nem nagyon hangoztatott operátort. Aminek a függvény alakja az „ifsetor” névre hallgatott volna. Azt viszont elvetették a fejlesztők. Az operátor hasonló a már rég ismert és más nyelvekben is használt ternáris operátorhoz.

echo $x ?: $default;

Gyakorlatilag a következő kód rövidítése:

echo $x ? $x : $default;

Tehát:

$x = 0;
echo $x ?: 20;

Kiírja, hogy 20, mert az $x logikai hamissá konvertálható. De a

$x = 12;
echo $x ?: 20;

Kiírja, hogy 12, mert az $x itt már logikai típusként igaz értéket venne fel.

Persze személy szerint azt hiszem, ezzel kaptunk egy nem túl hasznos, ámde érdekes operátort. Ugyanis erre így nem gyakran van szükség. Talán csak a következő példát tudnám most hirtelen elképzelni:

Megosztás/Mentés

Többdimenziós tömbök értékeinek szelektív lekérdezése php-ban

Az ötletet a különböző keretrendszerekben megtalálható hasonló metódusok adták, amik adatbázisból lekérdezett eredményhalmaz átrendezésére használhatók. A különböző rekordokat egy kétdimenziós tömbben is visszakaphatjuk, ami vagy numerikusan indexelt, vagy valamelyik adott oszlop értéke szerint. Például felhasználó azonosítója. Az összetett kulcsok által indexelésre viszont ezek sem adnak megoldást. Továbbá vannak olyan helyzetek, amikor egy tömbből konkrét indexekhez ( oszlopokhoz ) tartozó értékekre van szükség és csak azokra. Erre talán azt tudnám példaként említeni, amikor egy nem általunk írt függvény az átadott összes tömbelemet feldolgozza. Ezeken túl a következő függvény a nem létező indexekhez tartozó értékeket figyelmen kívül hagyja.

Példa tömb:

$array = array(
        4 => array('id' => 1, 'name' => 'Takács Ákos','age' => 25),
        8 => array('id' => 345, 'name' => 'Kovács Géza', 'age' => 31),
        1 => array('id' => 13, 'name' => 'Tóth Töhötöm', 'age' => 12),
        56 => array('id' => 98, 'name' => 'Teszt Eszter', 'age' => 43)
);

Példa select lista készítéséhez

<?php
$persons = fetch($array, 'name', 'id');
?>
<select name="persons">
<?php foreach ($persons as $id => $name) : ?>
        <option value="<?php echo (int)$id; ?>"><?php echo htmlspecialchars($name); ?></option>
<?php endforeach; ?>
</select>

Eredmény:

<select name="persons">
        <option value="1">Takács Ákos</option>
        <option value="345">Kovács Géza</option>
        <option value="13">Tóth Töhötöm</option>
        <option value="98">Teszt Eszter</option>
</select>

További példák a használatára:

Megosztás/Mentés

Triggerek használata MySQL-ben

Triggerek a MySQL 5.0 óta léteznek. Egy trigger bizonyos táblaműveletek hatására kiváltódó események kezelésére szolgál, amiben tárolt eljáráshoz hasonló szintaktikával további műveletek végezhetők. Bár még nem olyan kifinomult a MySQL trigger, mint például Oracle-ben, de be fogom mutatni, hogy így is hasznos szolgálatot tehet, amennyiben van jogosultságunk a használatára.

Triggerek létrehozása:

Egy utasítás esetén:
create trigger triggerneve  mikorfusson milyenmuveletre for each row sqlutasitas;
Több utasítás esetén:

delimiter $$
create trigger triggerneve  mikorfusson milyenmuveletre
for each row begin
      /*További sql utasítások*/
end$$
delimiter ;

mikorfusson: Lehet before vagy after.
Azaz egy művelet előtt is lefuthat, vagy csak az után.

milyenmuveletre: Lehet insert, update vagy delete

A „create” előtti sorra azért van szükség, mert a trigger törzsében levő sql utasítások utáni pontosvessző lezárná a triggert is. Meg kell tehát változtatni a delimitert, azaz az utasításokat határoló karaktert. A trigger lezárása után pedig vissza lehet azt állítani. Most pedig jöjjön egy életszerű példa a triggerek használatára!

Megosztás/Mentés