2010. május 25., kedd

Froyo manuális frissítés

Nem bírtam kivárni, amíg a hivatalos Froyo aka Android 2.2 értesítés ideér. De nem is kellett, hiszen az első USA-beli hivatalos update-k után már el is lehetett érni a Google oldalán a manuális update-hez szükséges állományt. Sajnos ezt a google visszavonta - gondolom a kontrollálatlan elérések miatt -, de már késő volt. Aki neki kíván állni itt kezdje: Android Police.

Figyelem: csak szolgáltatófüggetlen telefonon működik az update!

Végigolvasva a hozzászólásokat szinte mindenkinek működött a manuális update, úgyhogy hajrá!

Az újdonságokról bővebben a Magyar Google Android portálon is olvashattok.

2010. május 19., szerda

32 bites ORACLE ODBC Win7 64 bit alatt

Ma megint sikerült belefutnom egy általam eddig ismeretlen dologba. A feladat egyszerű volt: egy lekérdezést behúzni Excelbe egy távoli ORACLE adatforrásból. Aki eddig elolvasta pár bejegyzésemet az tudhatja, aki nem, annak leírom: jelenleg egy Windows7 Professional 64 bites oprendszert nyúzok. Munkám során elég sokszor kell ORACLE adatbázishoz kapcsolódnom és ezt vagy PHP-ből vagy PLSQLDeveloper-ből teszem. Sajnos a PLSQLDev nem ette meg a 64 bites ORACLE 11g klienst, ezért abból egy 32 bites verzió van feltelepítve, amivel tökéletesen működik. Gondoltam így lesz ez az Excel-lel is. Hát nem. Amikor megpróbáltam ODBC DSN-t létrehozni a feltelepített ORACLE ODBC driverrel a Win7 közölte, hogy "The setup routines for the Oracle in OraClient11g_home1 ODBC driver could not be found. Please reinstall the driver." Ami azért fura, mert ezt választottam ki a listából. Gondoltam egyből, hogy 64 bit problémába ütköztem, ezért nekiláttam guglizni, ahol is két teljesen különböző megoldást találtam a problémára, jelesül:
Az első megoldást most nem fordítom, mert az nálam nem működött, hiszen az excel csak a 64 bites ODBC DSN-eket ajánlotta fel.

A második megoldás viszont meghozta a várt eredményt. A lényeg, hogy telepítsünk fel egy 64 bites instant klienst a 32 bites kliens mellé, ami pár egyszerű lépésből megtehető:

1. Töltsük le a 64 bites Basic és ODBC package-t az alábbi címről: http://www.oracle.com/technology/software/tech/oci/instantclient/htdocs/winx64soft.html
2. Tömörítsük ki őket egy könyvtárba. Nálam a 32 bites kliens a C:\Databases\ORACLE\ base könyvtárban van (\product\...), így az instant klienst a c:\Databases\ORACLE\instantclient_11_2\ könyvtárba csomagoltam ki.
3. Parancssorból futtassuk adminisztrátorként (én nem így futattam, de így is működött) az odbc_install.exe-t, amely jó esetben közli, hogy sikerült feltelepülnie.
4. Az instant kliensnek meg kell adni a TNS_ADMIN környezeti változóban, hogy hol találja a tnsnames.ora file-t. Nálam ez a 32 bites kliens jól ismert NETWORK\ADMIN alkönyvtárában található.
5. Élvezni munkánk gyümölcsét, hiszen a 64 bites ODBC adminisztrátorban megjelenik egy új ODBC driver, ami már valóban működőképesnek látszik:


Ennyi.

2010. május 7., péntek

Subversion (SVN) telepítése CentOS-re

Ritkán kell bármit is telepítenem Linux alá - leginkább azért, mert be kell, hogy valljam némileg szakbarbár módon kezelem ezt a kérdést -, de egyszerűbb feladatokkal megbírkózom. Ilyen volt egy subversion szerver telepítése is. A régi szerverünkön a Kylix-os kódok miatt még egy RedHat AS 2.1-es fut, míg az újon, megszabadulva a kötöttségektől egy CentOS telepített jóságos rendszergazdánk. Terhelni viszont általában nem szeretem őt, csak akkor, ha számomra megoldhatatlan vagy megoldhatatlannak tűnő feladattal/problémával szembesülök. Egy sima svn szerver telepítése nem ilyen.

A lépések:

A yum jó barát, egyszerű, mint a faék, ezért a szerver telepítése egy sor:
yum install subversion.x86_64

Hozzuk létre az svn usert, megfelelő jelszóval
useradd svn
passwd svn

Ha ez megtörtént, hozzuk létre a repository root-ot:
mkdir /mnt/data1/subversion/repositories

Adjunk jogot az svn usernek erre az alkönyvtárra:
chown svn.svn /mnt/data1/subversion/repositories

Át is jelentkezhetünk svn user-nek és hozzuk létre az első projekt repository-t:
cd  /mnt/data1/subversion/repositories
svnadmin create proj1

Nincs más dolgunk, mint beállítani a projekthez tartozó hozzáférési beállításokat, amiket így tehetünk meg:
szerkesszük meg a proj1/conf/svnserve.conf állományt és szedjük ki a kommentjeleket az alábbi sorok elől:
anon-access = none
auth-access = write
password-db = passwd

Hozzuk létre a proj1-hez tartozó felhasználók táborát a passwd file-ban:
user1=jelszo

Ezen a ponton akár el is indíthatnánk az svn szerverünket, de én szeretem, ha service-ként fut, boot-kor elindul, ezért hozzuk létre root-ként a /etc/init.d/subversion állományt az alábbi tartalommal:

#!/bin/bash
#
#   /etc/rc.d/init.d/subversion
#
# Starts the Subversion Daemon
#
# chkconfig: 345 90 10
# description: Subversion Daemon

# processname: svnserve

source /etc/rc.d/init.d/functions

[ -x /usr/bin/svnserve ] || exit 1

# To pass additional options (for instace, -r root of directory to server) to
# the svnserve binary at startup, set OPTIONS here.
#
OPTIONS="-r /var/www/subversion/repositories"
RETVAL=0
prog="svnserve"
desc="Subversion Daemon"

start() {
        echo -n $"Starting $desc ($prog): "
   daemon $prog -d $OPTIONS
   RETVAL=$?
   [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
   echo
}

stop() {
   echo -n $"Shutting down $desc ($prog): "
   killproc $prog
   RETVAL=$?
   [ $RETVAL -eq 0 ] && success || failure
   echo
   [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
   return $RETVAL
}

case "$1" in
  start)
   start
   ;;
  stop)
   stop
   ;;
  restart)
   stop
   start
   RETVAL=$?
   ;;
  condrestart)
        [ -e /var/lock/subsys/$prog ] && restart
   RETVAL=$?
   ;;
  *)
   echo $"Usage: $0 {start|stop|restart|condrestart}"
   RETVAL=1
esac

exit $RETVAL


Adjuk hozzá a service listához és indítsuk is el:
chkconfig --level 345 subversion on
service subversion restart

SVN kliensből az alábbi paraméterezéssel kapcsolódhatunk svn://[userame]@[hostname]/[project name] a fenti példa alapján: svn://svn@app1.server.com/proj1 - felhasználónévnek és jeszónak pedig használjuk a passwd állományban megadottakat.

Ennyi. Nekem működik.

Források: http://www.electrictoolbox.com/install-subversion-centos/ , http://behzad.nategh.com/install-subversion-on-centos-cpanel-vps-with-autostart-script-on-reboot/

2010. május 1., szombat

Átállás (migráció) PHP 5.3-ra 5.2-ről

Számtalan weboldalt fejlesztettem/fejlesztettünk az elmúlt évek során. Azért, hogy a leghatékonyabban tudjunk dolgozni létrehoztam egy keretrendszert, ami mindenféle alap és sűrűn használt funkcionalitást tartalmaz és a keretet használó modulból pár sorban elérhető. Ilyenek a session kezelés, SQL futtatás, sablonok kezelése, callback rutinok és egyéb sablon-vezérlők alkalmazása. De ez a cikk most nem is erről szól. A fejlesztést még 4-es PHP-ban kezdtük, most jelenleg 5.2-es PHP alatt fut minden portálunk. Az elmúlt hónapokban debütált a PHP 5.3.2 és most az Windows-ra való átálláskor úgy döntöttem, hogy erre már ezt a verziót fogom felpakolni. Mondanom sem kell, hogy meglepő problémákba futottam. Az eddigi PHP verzióváltásokat a portáljaink alapvetően jól tűrték, egy-két beállítás után a php.ini-ben és minden makulátlanul működött. Nem úgy, mint most. A PHP 5.3-ra való átállás bizony migrációt (fejlesztést) jelent. Az 5.3-ból ugyanis számos eddig sokat használt (de azért már verziók óta elköszönőnek jelölt) eljárást bevontak a forgalomból, valamint egy-két ini beállítást is feketelistára helyeztek. Ezek a bevont (visszavont, deprecated) eljárások ettől még használhatók, de egy E_DEPRECATED hibát dobnak minden egyes alkalommal, amikor hozzájuk fordul a kód. Lássuk ezeket név szerint (hivatalos lista) és némi magyarázattal:

A visszavont ini paraméterek a következők:
  • define_syslog_variables - a leírás szerint performanciális okokból "javasolják" az elhagyását, ha valaki mégis ilyet szeretne használni, arra ott van a define_syslog_variables() eljárás (ami szintén visszavont)
  • register_globals - hát ezt csak támogatni tudom. Már évek óta "not recommended", hiszen a PHP legtöbb sebezhetősége ebből fakadt, ettől függetlenül mind a mai napig találkozom olyan kóddal, ami feltételezi, hogy be van kapcsolva. Igazából szinte csak időt spórolunk ezzel, hiszen milyen kényelmes, ha a HTTP hívás paraméterei egyből elérhetőek egy változóban, arra viszont sokan nem gondolnak, hogy ezzel a változó értékének tesztelését, inicializálását, stb. is kihagyják a kódból, így sérülékeny, esetleg törhető kódot gyártanak.
  • register_long_arrays - ez is a HTTP változók betöltésének globális változóba történő kezelése, helyette illik a superglobal-ok használata, $_GET, $_POST, stb.
  • safe_mode
  • magic_quotes_gpc
  • magic_quotes_runtime
  • magic_quotes_sybase
  • Comments starting with '#' are now deprecated in .INI files. - hogy miért, ki tudja? mostantól csak és kizárólag a pontosvessző használható erre a feladatra.
Lássuk az eljárásokat:
  • call_user_method() (use call_user_func() instead) - már PHP 4.1 óta visszavont eljárás, remélhetőleg senki sem használja már. A call_user_func szinte ugyanazt a funkcionalitást hozza, más paraméterezéssel. A callback eljárásoknál használjuk, de számos módon segíti a munkát, hiszen stringként adható meg egy-egy eljárás neve és a hozzá tartozó paraméterezés.
  • call_user_method_array() (use call_user_func_array() instead) - mint az előző
  • define_syslog_variables()
  • dl() - runtime tudott extension-öket betölteni, most már nem. Tessék az ini file extension eljárását használni.
  • ereg() (use preg_match() instead) - reguláris kifejezés alapján keres mintát egy stringben. A probléma az, hogy a Perl stílusú reguláris kifejezéseket egy kicsit másképpkell írni, mint hagyományos társaikat, ún. elválasztó jeleket kell alkalmazni. Jelesül a Perl stílusú reguláris kifejezés mindig a delimiterrel kezdődik, ami bármilyen karakter lehet, de jellemzően per / jel. Ez utóbbiban ráadásul ún. tag-eket is lehet használni az utolsó delimiter után, mint például az i betű, ami a mintaillesztést kis-nagybetű érzékennyé teszi, mint az alábbi példában: 
"/^[a-z0-9][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$/i"
E-mail cím validáció tehát ezentúl:
function validate_email_deprecated($email) {
    if (!eregi("^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$", $email)) {
        echo 'bad email';
    } else {
        echo 'good email';
    }
}
function validate_email($email) {
    if (!preg_match("/^[[:alnum:]][a-z0-9_.-]*@[a-z0-9.-]+\.[a-z]{2,4}$/i", $email)) {
        echo 'bad email';
    } else {
        echo 'good email';
    }
}
  • ereg_replace() (use preg_replace() instead) - lásd. ereg
  • eregi() (use preg_match() with the 'i' modifier instead) lásd ereg
  • eregi_replace() (use preg_replace() with the 'i' modifier instead) - lásd ereg
  • set_magic_quotes_runtime() and its alias, magic_quotes_runtime() - nem nagyon értem ezt a magic_quotes mizériát, de ezt az eljárást kb. 5 perc alatt lehet megírni, és csak ott használni, ahol értelme van.
  • session_register() (use the $_SESSION superglobal instead) - ahogy javasolja, használjuk a superglobal-t, már 4.1 óta így javasolják
  • session_unregister() (use the $_SESSION superglobal instead) - ahogy javasolja, használjuk a superglobal-t, már 4.1 óta így javasolják
  • session_is_registered() (use the $_SESSION superglobal instead) - ahogy javasolja, használjuk a superglobal-t, már 4.1 óta így javasolják
  • set_socket_blocking() (use stream_set_blocking() instead)
  • split() (use preg_split() instead) - lásd ereg
  • spliti() (use preg_split() with the 'i' modifier instead) lásd ereg
  • sql_regcase() - ha erre valaha is szükséged lesz, használd a link alatt található hozzászólásokban található eljárást
  • mysql_db_query() (use mysql_select_db() and mysql_query() instead) - egy adott query lefuttatása egy adott adatbázisban. A probléma az volt vele, hogy nem ideiglenesen váltott adatbázist, hanem véglegesen, ezért rengeteg hibára adhatott okot. Sokkalta célszerűbb, és okosabb fejlesztői üzemmód, ha az ilyen query-ket a fenti két eljárásra alapozzuk, talán jobban belénk vásődik, hogy ha egyszer kiadjuk a mysql_select_db utasítást, akkor onnan illik is visszaváltani (persze, ha kell), vagy egyszerűen használjuk a select * from database.table szintaxist, ami csak a lekérdezés erejéig használja a másik adatbázis sémát.
  • mysql_escape_string() (use mysql_real_escape_string() instead) - ahogy írja, 4.1 óta célszerűbb az utóbbit használni.
  • Passing locale category names as strings is now deprecated. Use the LC_* family of constants instead. - ez van, sosem használtam ilyet.
  • The is_dst parameter to mktime(). Use the new timezone handling functions instead. - eddig ezzel lehetett állítgatni, hogy az eljrásr használja-e a nyári időszámítást vagy sem, amikor visszaadja a UNIX időt a megadott dátum alapján. Mostantól be KELL állítani a megfelelő timezone értéket a php.ini-ben, eféleképpen: date.timezone = Europe/Budapest a [date] szakaszban.
Én most állok neki PHP 5.3-sítani a keretrendszerünket. A fentiek közül kevés eljárást használok, de úgy érzem lesz vele meló, hiszen: tesztelni, tesztelni, tesztelni. A keretrendszert több mint 50 portál/weboldal használja jelenleg, és pl. a reguláris kifejezéseken alapuló eljárások cseréje, bár egyszerűnek látszik mégis a teljes keretrendszer funkcionalitását érinti.

A migrációt ezért valószínűleg úgy fogom kezdeni, hogy pl. minden ereg eljárást lecserélek egy ereg_migr-re, amit viszont már a fenti szabályok szerint fogok én megírni az új eljárásokkal és a régiekkel egyetemben. Így lehetőségem lesz egy darab konstanssal ki-be kapcsolni az "5.3-as üzemmódot", ha a tesztelés ideje alatt valamilyen oknál fogva mégis cserélnem kell azt az éles szerveren, ahol még az 5.2-es PHP fut.

Pl:

régi kód:

if (eregi("xy",...)) ...

új kód:

function phpMinV($v)
{
   
$phpV = PHP_VERSION;

    if (
$phpV[0] >= $v[0]) {
        if (empty(
$v[2]) || $v[2] == '*') {
            return
true;
        } elseif (
$phpV[2] >= $v[2]) {
            if (empty(
$v[4]) || $v[4] == '*' || $phpV[4] >= $v[4]) {
                return
true;
            }
        }
    }

    return
false;
}

$is53 = phpMinV('5.3');


function ereg_mig( string $pattern , string $string [, array &$regs ]) {
  if  ($is53) return preg_match("/".$pattern."/",...); else return ereg($pattern,...);
}


Azért előbb vagy utóbb érdemes kiírtani az ilyen kódrészeket...

Jó mulatást mindenkinek a migrációhoz!