Zend Framework & Silverlight webalkalmazás bekonfigurálása és fejlesztése Windows Server 2008 R2-ben

Ez a cikk 2010 májusában készült. Néhány linket töröltem, mert már nem működik.

Bevezető

Üdvözöllek kedves Olvasó!

Webprogramozóként
többnyire PHP, MySQL, Javascript, HTML, CSS készlettel dolgozom, az elkészült alkalmazás Linux alapú szerveren
fut.

Ugyanakkor mostanában ismerkedem a .NET világával is. Több
(ingyenes)
előadás sorozaton voltam, a devportal.hu tanulmányi heteit is megnézem,
sőt mostanában fejeztem be egy .net tanfolyamot, amire a munkaidő után
jártam.

Más PHP fejlesztővel beszélgettem már a .NET-s dolgokról, hogy milyen jó
a fejlesztői eszközkészlet, “szabványosabb” technológia, de nem
találtunk kapcsolódási pontot a két technológia között. Ezt még
nehezíti, hogy a megrendelő minél alacsonyabb áran szeretné a
fejlesztést megoldani, az ASP.NET szolgáltatók viszont drágábbak a
Linux-os szolgáltatóknál.

A “technológiai átjárót” a
Silverlight-tól remélek. Több bemutatót
megnéztem, tetszenek a gyorsan kialakítható Master-Detail felhasználói
felületek szeretném ezt a saját webes alkalmazásomban használni.

Már
próbálkoztam kisebb Silverlight alkalmazást összehozni
szabadidőmben, olyat ami az egyik hobbymhoz kapcsolódik. A versenyen egy
Zend Framework, Silverlight alapú egyszerű alkalmazás fejlesztéssel
indulok. Még csak kezdeti állapotban van, de remélem sikerül befejezni,
elegendő tapasztalatot szerezni.

(A fejlesztést, napló
írást párhuzamosan végzem, hogy minden megmaradjon
az utókornak :))

Az alkalmazásomról néhány mondat

Mit is fejlesztek?:
Harp tab creator, szájharmonika tabulatúra készítő.
Kezdő-haladó szinten diatónikus blues harmonikán szoktam játszani.
Gyakran kitalálok saját dallamokat, gondoltam jóllene ezt kényelmesen
rögzíteni, megosztani másokkal.
A kezdeti verzió még néhány funkciót fog tartalmazni.

Itt

próbálom összehozni az alkalmazást.

Még néhány
gondalat

Munkám során sokszor találkoztam olyan megrendelői igénnyel, hogy
készíts egy webes intranetes- irodai (kis) alkalmazást, de még nem
tudják, hogy milyen alapú (Linux/Windows/esetleg Macintosh) szerveren
fog futni, de még az adatbázis motor sem biztos (mysql, oracle,mssql,
access :)) )

Az igy “specifikált” munkának PHP-val neki lehet állni, pláne, ha valami
olyan PHP keretrendszert használsz, ahol konfigurációban lehet
változtatni az adatbázis típusát.

Természetesen a fejlesztés
során kerülni kell a “direkt sql”
használatát, mert ami mysql alatt lefut, máshol errort dob.

Kezdeti
lépések

Megkaptam  a virtual szerverhez a hozzáférést. Hmmm…, ilyen

környezetre
még nem telepítettem. Tanulási lehetőségnek nagyon jó!

Azonnal
neki is vágtam a kapcsolódásnak.

A Remote Desktop panelen
becsatlakoztam. A desktopon található ReadMe*-t
átfuttam, majd a Filezillával nekivágtam az FTP csatlakozásnak.

…miután
rádobbentem, hogy ez így nem lesz jó a

http://webkert2010.net/Help.aspx-n
keresztül tájokozódtam.

Readme: “..A rendszer
alaphelyzetben előkonfigurált, kizárólag FTP over
SSL kapcsolat tesz lehetővé, ehhez kérjük a megfelelő kliens használatát
(pl. az ingyenes FileZilla), passzív módban, ….)”

http://learn.iis.net/page.aspx/304/using-ftp-over-ssl/

Először
is készítettem egy saját Certificate-t, majd létrehoztam egy új
FTP site-t “Add FTP site”-t.

..~ 5x végigmentem a
lépéseken mire sikerült kapcsolódni, de ez kezdő
sorsa. :))

FTP,
feltöltés,  ZF folderek elrendezése

Kezdeti állapotban lévő alkalmazásmomat fel is zuttyantottam, ne utólag
döbbenjek.

Az alabbi Zend Framework (ezentúl röviden ZF) elrendezést választottam.

A
wwwroot folderben az index.php-t helyeztem el.

<?php
define('BASE_PATH', realpath(dirname(__FILE__) ));
// Define path to application directory
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/application'));
// Define application environment
defined('APPLICATION_ENV')
    || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
   realpath(BASE_PATH . '/library'),
   get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
            ->run();

Az index.php mellett az alábbi folderek vannak:


/application

/library (itt van a Zend könyvtár)

/css

/js

Az application folderen belül van a “szokványos” ZF elrendezés:

/controllers

/models

/views

/configs

/Bootstrap.php

A Bootstrap.php-m így néz ki:

<?php

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

 protected function _initAutoload ()
    {
        // Add autoloader empty namespace
        $autoLoader = Zend_Loader_Autoloader::getInstance();
        $resourceLoader = new Zend_Loader_Autoloader_Resource(
        array('basePath' => APPLICATION_PATH , 'namespace' => '' ,
         'resourceTypes' => array('form' => array('path' => 'forms/' ,
         'namespace' => 'Form_') ,
         'model' => array('path' => 'models/' ,
         'namespace' => 'Model_'))));
        // Return it so that it can be stored by the bootstrap
        return $autoLoader;
    }
}

Gondolom, a configs folder application.ini fejlesztői beállítása is
érdekes lehet:

[production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
includePaths.library = BASE_PATH "/library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"

resources.db.adapter = PDO_MYSQL
resources.db.params.host = localhost
resources.db.params.username = ******
resources.db.params.password = **********
resources.db.params.dbname = **************
resources.db.charset = "utf-8"
resources.db.params.driver_options.1002 = "SET NAMES utf8"
resources.db.isDefaultTableAdapter = true
resources.db.params.profiler = true

#layout
resources.layout.layoutpath = APPLICATION_PATH "/layouts"
[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

Ha más elrendezést használsz, defaultban a “fő” index.php egy public
folderben van, ami egy szinten van az application folderrel, akkor az
útvonalak változnak!!

Zend Framework verzió jelenlegi
legfrissebb : 1.10.4 mivel szükségem
lesz olyan könyvtárakra* is, amik korábbiban pl: 10.9 még nem létezett
vagy incubátor-ban  :)) volt.

.htaccess
vs. IIS7

Kicsit
aggódtam, hogy mi lesz, ha nem lesz rá alternatíva?

Nem
szeretném a index.php/controllername megoldást használni.

Találtam
egy oldalt, annak útmutatásait követtem.

http://mnshankar.wordpress.com/2008/10/12/htaccess-equivalent-zend-framework-with-iis7/

Apache szerveren ZF-nél az alábbi .htaccess filet használom:

RewriteEngine
on
RewriteRule !.(js|ico|gif|jpg|png|css|xap)$ index.php

(A .xap a
Silverlight kiterjesztése)

Az utasítás szerint irányítson
mindent a publikus könyvtár index.php-ra, ha nem kivételben levő filek
szerepelnek.

IIS7-nél nincs .htaccess, de web.config
módosításával elérhető az URL átírás.

A Remote Desktop (RD)
panelen beléptem, majd megnyitottam  a IIS managert.
Connections>Site>Url rewrite

Az Actions panelen
kattintottam az ‘Import rules’-ra.
Itt feltölthető a .htaccess file, amiből generál egy web.config
állományt.

Ennek is többször futottam neki.

A ‘Rewrite
rules’ ablakba is be lehet másolni a .htaccess filet, amiből a
‘Converted rules’ ablakban az XML nézetre kattintottam, kimásoltam a
generált … részt és az eredeti web.config-ba
szerkesztettem.

Ezután így nézett ki a web.config-file.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1">
                    <match url=".(js|ico|gif|jpg|png|css|xap|mp3)$" negate="true" ignoreCase="false" />
                    <action type="Rewrite" url="index.php" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

Később még változtattam rajta, az IIS7 hosszú URL gond miatt. (Lásd az
ezzel foglalkozó fejezetet.)

IIS7,
hosszú URL Probléma

Programomban a  Silverlight kliensből a ZF -s szerver oldali
alkalmazásnak az adatokat szerializálva GET-el adom át.

Azt
vettem észre, hogy hosszú URL-k esetén :
The remote server returned error -> Not found
(Ha az url ~220 karakter hosszú akkor még elfogadja, de ha ~320 kar.,
akkor már nem.)

Silverlight-ban még lelkes kezdő vagyok, ezt a
GET-s kommunikációról olvastam próbáltam ki, POST megoldást nem találtam
PHP felé (csak ASP.NET felé, de akkor a megoldás távol állna az eredeti
feladattól. 🙂 )
Gondoltam egy Silverlight -> Javascript (JQuery) adatátadáson és
onnan POST, de nem akartam átírni az alkalmazást, ha Apache-PHP
környezetben működött.

Windows Server 2008-t is most láttam
(távolról) először. Ha egy hasonló ismeretekkel bíró fejlesztő olvassa
az írásomat, biztos, hogy bátorítást nyer. :))))

A Devportálon
feltetettem a kérdést, de még nem kaptam választ: http://devportal.hu/forums/p/9125/22975.aspx

Googliztam,
másnak is volt ilyen problémája:

http://stackoverflow.com/questions/2840885/500-error-for-long-url-iis7

Egy
IIS-el foglakozó oldalon részletesebb infókat találtam: Use Request
Filtering

http://learn.iis.net/page.aspx/143/use-request-filtering/

Ez alapján a web.config-t módosítottam, és SIKERÜLT hosszabb Url-t
megadni úgy, hogy ne dobjon hibát a szerver!

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <system.webServer>
        <rewrite>
            <rules>
                <rule name="Imported Rule 1">
                    <match url=".(js|ico|gif|jpg|png|css|xap|txt)$" negate="true" ignoreCase="false" />
                    <action type="Rewrite" url="index.php" />
                </rule>
            </rules>
        </rewrite>

    <security>
    <requestFiltering>
               <requestLimits  maxAllowedContentLength="30000000" maxUrl="260" maxQueryString="256" />
    </requestFiltering>
   </security>
 </system.webServer>
</configuration>

Az Apeche-ról, Zend Server-ről már tudok egy-2 dolgot, rájöttem az IIS-t
jó lenne megtanulni. 🙂

MySQL
install

A RD panelen
találtam egy installert, mielőtt jól elindítottam volna tájékozódtam,
ezeket a cikkeket olvastam el.

http://learn.iis.net/page.aspx/353/install-and-configure-mysql-for-php-applications-on-iis-7

http://www.trainsignaltraining.com/install-mysql-on-iis7/2008-09-10/

Az
installációt ne a Next-Next-Finish  technikával végeztem, hanem
figyeltem, hogy az alábbiak be legyenek jelölve:

‘Detailed
configuration’

‘Server Machine’

‘Multifunctional Database’

‘Online
Transaction Processing (OLTP)’

‘Enable Strict Mode’

‘Best
Support for Multilingualism’

‘Install As Windows Service’

‘Include
Bin Directory in Windows Path’

Beállítottam a Root
felhasználónevet/jelszót.

Enable root access from remote machines
(nincs bejelölve).

Azután a Konzolablakban a következő parancsokat futtatam:

# Once logged on to MySQL, use the following sequence of commands:
mysql> use mysql;
Database changed
mysql> DELETE FROM user WHERE user = '';
Query OK, 2 rows affected (0.03 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.05 sec)

#  Next, restrict the root account to log on only from localhost.
mysql> use mysql;
Database changed
mysql> DELETE FROM user WHERE user = 'root' AND host = '%';
Query OK, 2 rows affected (0.03 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.05 sec)

# Change the name of the root user with the following sequence of commands from the command prompt:
mysql> USE mysql;
Database changed
mysql> UPDATE user SET user='******' WHERE user='root';
Query OK, 1 row affected (0.19 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.23 sec)

CREATE USER 'dbfalhasznalo'  IDENTIFIED BY 'jelszo';

CREATE DATABASE IF NOT EXISTS projektemadatbazisa;

GRANT ALTER,
       ALTER ROUTINE,
       CREATE,
       CREATE ROUTINE,
       CREATE TEMPORARY TABLES,
       CREATE VIEW,
       DELETE,
       DROP,
       EXECUTE,
       INDEX,
      INSERT,
      LOCK TABLES,
       SELECT,
       UPDATE,
       SHOW VIEW
      ON projektemadatbazisa.* TO dbfalhasznalo;

PHPMYADMIN
install

Még
további mysql konzol parancsokat is próbáltam beütni, de egyre több
hibát vétettem ezért a PHPMYADMIN installáltam fel egy külön
könyvtárba.. 🙂
A config.inc.php megadtam az adatbázis felhasználóm hozzáférését.

A
PHPMYADMIN-om azonban csak akkor működött, ha kiszedtem a főkönyvtárban
a  web.config-ből * részt, ami a Zend Framework-höz
kellett.

  • A mindent a főkönyvtár index.php-re irányít.

Gondolom
a web.config-al kellene most valamit trükközni, amit most még nem tudok
megoldani.

Később:  Sikerült megoldanom!!!
A phpmyadmin folder is kellett raknom egy web.config file-t. Benne a
lényeg a ami törli a korábbi url átírányításokat.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
       <rewrite>
          <rules>
                      <clear />
          </rules>
      </rewrite>
    </system.webServer>
</configuration>

Így van PHPMYADMINOM is : )) 

(Ezt már nem kell:
Így felmásoltam a szerverre egy trial Mysql szerkesztőt ami Server
2008-n is fut, majd RD panelen keresztül telepítettem.
Navicat http://download.cnet.com/Navicat-MySQL-GUI/3000-10254_4-10071792.html?tag=mncol
)

Siverlight
kliens

E témában
igyekszem főleg a szerverrel való kommunikációt kiemelni.
A Silverlight-ban még kezdő vagyok, ez az ELSŐ nagyobb alkalmazásom. A
XAML-t ‘kézzel’ írtam, Blendet csak távolról, előadáson láttam.
A Drag&Drop megoldáshoz a Silverlight Toolt használtam.
http://silverlight.codeplex.com/releases/view/36060

A
hangjegyek mozgatásához (kidob, átrendez)  Bátyai Krisztián :
DragDrop Silverlight 3-ban http://kbatyai.spaces.live.com/Blog/cns!B5577FAF004325E8!429.entry
cikket használtam.

A hangnak több tulajdonsága lehet, ennél a
kezdeti verzinál is, ezért külön osztályt definiáltam.

    public class HarpSound
    {
        public String Harpnote{ get; set; }
        public String Name { get; set; }

        public override string ToString()
        {
            return Name;
        }

    }

A ‘kottázás’ során létrejött hangjegy objektumokat el kell küldenem a
szervernek, ezért szerializálnom kell.

De lépésenként.
Előbb létrehoztam egy kollekciót.

 ObservableCollection<HarpSound> lst1 = new ObservableCollection<HarpSound>();

Hozzáadtam az elemeket.

        private void MultipleHandler(object sender, RoutedEventArgs e)
        {

           Button mybutton=  sender as Button;
           HarpSound soundObj= new HarpSound() { Harpnote = mybutton.Name, Name = mybutton.Content.ToString() };
           lst1.Add(soundObj);

        }

Majd szerializáltam:

  private void SerialButton_Click(object sender, RoutedEventArgs e)
        {
            if (lst1.Count > 0)
            {
               DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObservableCollection<HarpSound>));

                MemoryStream stream = new MemoryStream();
                StreamReader sr = new StreamReader(stream);

                ser.WriteObject(stream, lst1);
                sr.BaseStream.Position = 0;
                string s = sr.ReadToEnd();

                WebClient wc = new WebClient();
                wc.OpenReadCompleted += GetHarptabOpenReadCompleted;

                string addUrl= urlpart + "A szervernek az útvonala/" + s ;
                wc.OpenReadAsync(new Uri(addUrl));
                createdUrl.Text = addUrl;
            }
            else
            {
                MessageBox.Show("Nem jelöltél ki egyetlen hangot sem! :))");
            }
        }



Érdekes lehet még…

A Silverlight átvesz a HTML
template-től  konfigurációs változókat (szerver vagy fejlesztői
környezet útvonal, stb.)

Így adom át HTML:

<param name="initParams" value="urlpart=<?php echo $this->urlpart; ?>" />

Így veszem át az SL-ben.

urlpart = App.Current.Resources["urlpart"].ToString();


Hangok betöltése TODO:

A ‘C’ hang betöltése:

<MediaElement  x:Name ="sd1" Source="http://A szervernek az útvonala/hangkönyvtár/c_sound.mp3" AutoPlay="False" MediaFailed="media_MediaFailed"/>

A Gomb – Médiaelement  dinamikus  megfeleltetéshez Dictinary-t
használtam.

Dictionary<Button, MediaElement> d;

  d = new Dictionary<Button, MediaElement>();
   // gomb, media hozzáadása
  d.Add(p1, sd1);
  d.Add(n1, sd2);

A hangok megszólaltatása (gomb felett az egér), itt isegy kezelőt
használtam mindegyikhez.

Egyszerűsítve:

        private void MultipleHandlerStartSound(object sender, MouseEventArgs e)
        {
            Button mybutton = sender as Button;

            if (mybutton.Name == "p1" && d.ContainsKey(p1))
            {
                MediaElement sound = d[p1];
                sound.Play();

            }

        }

Később a DownloadStringCompleted eseményt használtam a
OpenReadCompleted  helyett, kipróbáltam azt is.
A kódom nem sokat változott:

wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(GetHarptabOpenReadCompleted);
....
 wc.DownloadStringAsync(new Uri(addUrl));

//A metódusnak más az argumentuma
        private void GetHarptabOpenReadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
 ...
}

A fejlesztés során rájöttem, hogy a GET helyett a POST kérést szeretnék
indítani Silverlight-ból.
Találtam is egy cikket, de a határidő vége felé már nem szeretném
átírni a működő programot, majd azután kisérletezek vele.
http://viswaug.wordpress.com/2009/09/17/making-a-http-post-in-silverlight-a-k-a-thread-hopping/



Twitter
login

A harmonika kotta szerkesztéshez bejelentkezés szükséges.
Gondoltam, nem fárasztom a felhasználót a regisztrációval, ha van
Twitteres hozzáférése, ez a progi úgyis a Twitter keresztül lesz
bemutatva. (Magamnak készítettem, de más is használhatja, ha tetszik
neki :)) )

A felhasználónak nem kell a weboldalomon megadni a
jelszót, hanem a Twitter OAuth-t használja.
http://apiwiki.twitter.com/OAuth-FAQ http://apiwiki.twitter.com/OAuth-FAQ
Ehhez alkalmazásomat itt kellett regisztrálni:
http://twitter.com/oauth_clients http://twitter.com/oauth_clients

Tartottam tőle, hogy az IIS tartogat meglepetést számomra, de
mégsem.

A Twitter OAuth támogatott bejelentkezés lényege.
Beregisztrálod az alkalmazásod, meg kell kapnod az alkalmazásod
visszatérési (callback) url-jét, ami a központi bejelentkezés után a
programod megfelelő részére irányít.

Kapsz egy  kulcspárt
(consumerkey-consumersecret), amiből tudja a szolgáltatás ki ez az
alkalmazás. Helyes bejelentkezés esetén vissza irányít, helytelennél
jelzi, hogy nem megfelelő a hozzáférés.

A prgramból hívás,
fogadáskódrészlete:

   //Beállítás

 public function init()
    {

    		 $this->configuration = array(
		    'callbackUrl' => 'http://weboldalam/callback',
		    'siteUrl' => 'http://twitter.com/oauth',
		    'consumerKey' => 'XXXXXXXXXXXXX',
		    'consumerSecret' => 'xxxxxxxxxxxxxxxxxxxxx'
		);
    }

//Hívás

    public function indexAction()
    {

    	$this->getHelper('viewRenderer')->setNoRender();
    	$this->_helper->layout->setLayout('zerolayout');

    	$consumer = new Zend_Oauth_Consumer($this->configuration);
        //print_r($consumer) ;

    	       $ns = new Zend_Session_Namespace('Sessionnévterem', true); 

			    if (!isset($ns-> TWITTER_ACCESS_TOKEN)) {
			    $token = $consumer->getRequestToken();
			    //$_SESSION['TWITTER_REQUEST_TOKEN'] = serialize($token);
			    $ns-> TWITTER_REQUEST_TOKEN = serialize($token);

			     $consumer->redirect();
			}
			else{

				//Token létezik 

			}

    }

//Fogadás

    public function callbackAction(){

    	$this->getHelper('viewRenderer')->setNoRender();
    	$this->_helper->layout->setLayout('zerolayout');

      $ns = new Zend_Session_Namespace('Sessionnévterem', true); 

        if (!empty($_GET) && isset($ns-> TWITTER_REQUEST_TOKEN)) {

    		$consumer = new Zend_Oauth_Consumer($this->configuration);
		    $token = $consumer->getAccessToken($_GET, unserialize($ns-> TWITTER_REQUEST_TOKEN));
		    $ns-> TWITTER_ACCESS_TOKEN = serialize($token);
		    $tweetObj=unserialize($ns-> TWITTER_ACCESS_TOKEN);

		   //SESSION mentés
		   $ns->username=$tweetObj->screen_name;
		   $ns->userid=$tweetObj->user_id;

      $ns-> TWITTER_REQUEST_TOKEN=null;

    /**
     * With Access Token in hand, let's try accessing the client again
     */

   $this->_redirect('/index');

} else {
    /**
     * Mistaken request? Some malfeasant trying something?
     */
    exit('Invalid callback request. Oops. Sorry.');
}

    }

Még érdekes lehet, hogy az oldalon elkészített ‘kották’ címeit egy
Twitter oldalon publikálom.

//hozzáférési osztály példányosítása
$twitter =new Zend_Service_Twitter($this->config->twitter->username,$this->config->twitter->pswd);

//Üzenet írása
 $response = $twitter->status->update("The "".$mytweetmessage."" harptab published by ".$ns-> username);

Javascript
(Json) kommunikáció

A
Silverlight kliensnél említett SerialButton_Click metódusban a
GetHarptabOpenReadCompleted kezeli le a szerver válaszát.

  private void SerialButton_Click(object sender, RoutedEventArgs e)
        {
             ***

                WebClient wc = new WebClient();
                wc.OpenReadCompleted += GetHarptabOpenReadCompleted;

                string addUrl= urlpart + "A szervernek az útvonala/" + s ;
                wc.OpenReadAsync(new Uri(addUrl));
                createdUrl.Text = addUrl;
            ***
        }

Sikeres válasz esetén meghívja a HTML template-ben szereplő javascript
metódust.

        private void GetHarptabOpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{

                if (e.Error == null)
                {

                    HtmlPage.Window.Invoke("slcall");
                  ****
                }
                else{

                }

}

JQuery hívás.

(script type="text/javascript")

// lista frissítése
function slcall(){

        //lekérdezi a friss tartalmat
	$.get('<?php echo $this->baseUrl(); ?>'+'/utvonal/', show_useractivities);
}

(/script)

Bejelntkezett felhasználó törölheti a műveit a listából AJAX-os módon.

/** Törlés **/

$(document).ready(activities_init);
function activities_init(){
	//console.log('START1');
$('#lista td a.deletebutton').live('click',delete_activity);

}

function delete_activity(){

	var where_is=this.href.indexOf('#');
	var id = this.href.substring(where_is+1,this.href.length);

		if(confirm(
		'Törölni akarja ezt a bejegyzést?'
		)){
                  $.getJSON('<?php echo $this->baseUrl(); ?>'+'/harptabs/deleteHarptab/id/'+id,remove_row);
		}

}

Loggolás,
hibák gyűjtése

Zend_Log használata

Googliztam a
Zend  Framework oldalakon készítettem, felvettem a Library
könyvtárba egy plugint.
A plugin segítségével bejegyzéséket tudok gyűjteni egy táblába.

class MYAPP_Plugin_Logger extends Zend_Controller_Plugin_Abstract
{ 

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    { 

		  $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
		  $configArray = $bootstrap->getOptions();
		  $this->config = new Zend_Config($configArray);    	

    	          $logLevel = intval($this->config ->logLevel); 

    $params = array('host'		=>'localhost',
	                'username'	=> $this->config->resources->db->params->username,
					'password'  => $this->config->resources->db->params->password,
					'dbname'	=> $this->config->resources->db->params->dbname
	               );

         $db = Zend_Db::factory('Pdo_Mysql', $params);
        $columnMapping = array(
            'timestamp' => 'timestamp',
            'lvl' => 'priorityName',
            'msg' => 'message'
        ); 

        $writer = new Zend_Log_Writer_Db($db, 'log', $columnMapping); 

       $writer->addFilter(new Zend_Log_Filter_Priority($logLevel)); 

        Zend_Registry::set('logger', new Zend_Log($writer));
    }
}

A vizsgálandó kódrészletet Try-Catch -be tettem.

try{
********
********
} 

 catch (Zend_Exception $e) {  

Zend_Registry::get('logger')->info('error: '. $e->getMessage());

}

Saját
hibaoldal beállítása az IIS-n

A weboldalon hibás url esetén a
szerveren beállított hibaoldal jelenik meg.
Ez nem túl felhasználóbarát ezért készítettem saját hibaoldalt, hogy
visszairányítsam az elveszett látogatót.

Előtte tájékozódtam,
milyen beállításokat kell a szerveren megnézni:http://learn.iis.net/page.aspx/405/delegating-errormode-in-httperrors/

A
windowssystem32inetsrvconfigapplicationhost.config fájlt kellett
megkeresni.
Ezt a beállítást ellenőrízni:

<section name="httpErrors" overrideModeDefault="Allow" />

A default hibaoldalak helye:

        <httpErrors lockAttributes="allowAbsolutePathsWhenDelegated,defaultPath">
          ***
            <error statusCode="403" prefixLanguageFilePath="%SystemDrive%inetpubcusterr" path="403.htm" />
            <error statusCode="404" prefixLanguageFilePath="%SystemDrive%inetpubcusterr" path="404.htm" />
          ***
        </httpErrors>

A web.configot ezzel bővítettem:

      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" prefixLanguageFilePath="" path="/error.htm" responseMode="ExecuteURL" />
      <remove statusCode="403" subStatusCode="-1" />
      <error statusCode="403" prefixLanguageFilePath="" path="/error.htm" responseMode="ExecuteURL" />
    </httpErrors>

A hibaoldalam a főkönyvtárban:

<html>
<body>
    <a  style="font-size:80px" href="">YOU LOST. CLICK ME! :) </a>
</body>
</html>

Tapasztalatok,
jótanácsok

Az
IIS7 szerverre való fejlesztés során azt plusz elvárást tűztem ki
magammnak, hogy olyan programot készítsek, ami ugyanúgy “elszaladna”
Windows, Linux környezetben.
Szerintem ezt megoldottam 🙂 Örülök a lehetőségnek kipróbálhattam,hogy
“műxik” IIS-n is.

Aki Apache-ról IIS-re kívánja hosztolni alkalmazását és használ
“mindenféle” .htaccess parancsot, ajánlom, hogy előtte
mindenképpen nézze meg, tesztelje, hogy mi az IIS-n a web.config
változata.

Nekem menetközben 2-t  kellett megoldani (fő
könyvtár Zend projekt:  index.php-re irányítás, phpmyadmin: a
“fentiek” figyelmen kívül hagyása).

Az alábbi cikkeket találtam:

Translate
.htaccess Content to IIS web.config http://learn.iis.net/page.aspx/557/translate-htaccess-content-to-iis-webconfig/

URL
rewrite http://www.iis.net/download/URLRewrite

Aki Silverlight & PHP programot szeretne készíteni javaslom,
tanulmányozza alaposan a kommunikációs megoldásokat (SOAP, WSDL, JSON),
szerezzen be valami jó könyvet a témában.  🙂
Nekem 2 fejlesztő környezet között is váltogatnom kellett (Visual Studio
Express, PsPad), dobálni át a PHP projektbe a xap fájlt, elég nehézkes
volt.

A TwitHarptab

készítéshez a szájharmonika iránti lelkesedés adott kitartást, sokszor
éjszaka is szuttyogtam a progival.
Ha kapnék pozitív értékelést a progira, a munkára, az jó lenne, mert
szeretnék még néhány más hangolású harmonikát venni, anélkül, hogy a
családom reklamálná, azért mégse vagyok egy Herfli Davidson :))

Természetesen
ez a program verzió még nagyon kezdeti. Szeretném, ha az  ütemeket
is kezelné (egész, fél, negyed, nyolcad, triola,…), nomeg a szünet
hosszokat.
A “dizájnosabb” Silverlight felülethez természetesen Blend kell, illetve
megtanulni a használatát.

Különben ajánlom mindenkinek a harmonikázást, ha még nem “tolja”, nem
játszik más hangszeren. Megnyugtató, remek, akár röpke pár perces
kikapcsolódásnak is jó, nagy móka.

Minden jót!

Üdv,

Zsolt

Háttérinformációk:

A szájharmonikánál ilyen kottát szoktak
használni:

http://www.1000harmonicatabs.com/fsongs/folsom_prison_blues.html

A
+ jel a fújt hang, – a szívott, a szám pedig a megfelelő lyuk a 10 -s
fekvésű harmonikán.

Folsom Prison Blues

4  5    5   -5   6  4  4
I hear the train a-comin'; 

 4    5  5     -5    6   4
it's rollin' 'round the bend,

 4  5   5    -5   5   6   4
And I ain't seen the sunshine 

  5   5   5     4    5
since I don't know when,

 5   -4   4  -4  4  -4  4
I'm stuck at Folsom Prison 

-4   -4    4     5  4   3
and time keeps draggin' on.

 4    4    -4   -4   4  -4 3
But that train keeps a-rollin' 

3   3   2   3  2   1
on down to San Antone.

 

 

PHP infok, tippek

A PHP rejtett tulajdonságai, Ilia Alshanetsky weboldaláról: http://ilia.ws/archives/241-IPC-Hidden-Features-of-PHP-Slides.html

Névterek használata: http://phpmaster.com/php-namespaces/

ezSQL http://www.catswhocode.com/blog/php-fast-and-easy-sql-queries-using-ezsql

PHP mail: http://phpmaster.com/sending-emails-with-php/

Grafikon,  pChart

pChart is a PHP library that will help you to create anti-aliased charts or pictures directly from your web server.

Lokolaizáció: Localizing PHP Applications “The Right Way”, Part 2

Error Handling in PHP

Building an ORM in PHP

PHPUNIT: Getting Started with PHPUnit

Practicing Regular Expressions with Search and Replace

Post és a hozzátartozó kommentek lekérdezésének esete:  The N+1 Problem

A PHP rejtett tulajdonságai, Ilia Alshanetsky weboldaláról: http://ilia.ws/archives/241-IPC-Hidden-Features-of-PHP-Slides.html

Névterek használata: http://phpmaster.com/php-namespaces/

ezSQL http://www.catswhocode.com/blog/php-fast-and-easy-sql-queries-using-ezsql

PHP mail: http://phpmaster.com/sending-emails-with-php/

Grafikon,  pChart
pChart is a PHP library that will help you to create anti-aliased charts or pictures directly from your web server.

Lokolaizáció: Localizing PHP Applications “The Right Way”, Part 2

Error Handling in PHP

Building an ORM in PHP

PHPUNIT:
http://webmania.cc/cakephp-unit-teszteles/

Getting Started with PHPUnit

Testing Error Conditions with PHPUnit

Practicing Regular Expressions with Search and Replace

Post és a hozzátartozó kommentek lekérdezésének esete:  The N+1 Problem

Levelet kaptam…

Pénz Istennő

Ez a Pénz Istennő!
Küldd el 6 barátodnak, vagy családnak és gazdag leszel 4 napon belül. Küldd el 12- nek
és gazdag leszel 2 napon belül.
Nem viccelek! Váratlan anyagi gyarapodást hoz.
Ha kitörlöd, sohasem tudod meg, hogy valóban működik-e?”
Azt mondja az egyik okosság: ne azt mondd, amit nem akarsz, hanem azt, Amit, nagyon
akarsz!
Így hát én azt mondom: BIZTOS, hogy ez az Istennő, segíteni fog nekünk!
Ezt az “üzenetet” mindenki így fogja fel!!!!!!
Azt mondja az írás, hogy működik….
“Pénz, ami Feléd megy az úton…… Reménykedjünk, hogy valóban működik!

Rajtam nem múlik, továbbadom, de kiegészítem Weöres Sándor versével:

Szórd szét kincseid – a gazdagság legyél te magad.
Nyűdd szét díszeid – a szépség legyél te magad.
Feledd el mulatságaid – a vígság legyél te magad.
Égesd el könyveid – a bölcsesség legyél te magad.
Pazarold el izmaid – az erő legyél te magad.
Oltsd ki lángjaid – a szerelem legyél te magad.
Üzd el szánalmaid – a jóság legyél te magad.
Dúld fel hiedelmeid – a hit legyél te magad.
Törd át gátjaid – a világ legyél te magad.
Vedd egybe életed-halálod – a teljesség legyél te magad.

“Pozitív gondolatok” Android program

Anroid programozást tanulok.
Első egyszerű, ingyenes  alkalmazásom az Android Market-n: Pozitív gondolatok

Leírás:
Pozitív állítások (nemcsak) Agykontrollosoknak.
A gondolatoknak teremtő erejük van. Ha nap mint nap “programozzuk” magunkat negatív gondolatokkal, pl:
“Félek ettől a vizsgától. Elegem van a világból. Hülye vagyok.”, akkor nehezen boldogulunk az életben.

Ez a program 100 pozitív gondolatot tartalmaz. Indítás után a képernyőt pötyögtetve véletlenszerűen változik a szöveg.
Érdemes naponta elővenni, az állításokat hangosan vagy magunkban elismételni.


Reguláris kifejezések

 

A PHP esetén több függvénykönyvtárból is választhatunk, ha reguláris kifejezésekkel szeretnénk foglalkozni: az egyik a POSIX kompatibilis ereg_* függvény család, valamint a Perl kompatibilis PCRE csomag által nyújtott preg_* funkciók. Mi az ereg_* függvényekkel nem foglalkozunk, mert több szempontból is szerényebb képeségekkel bír, mint a PCRE csomag: egyrészt lassabb is (egyes becslések szerint körülbelül 30%-kal), másrészt kevesebb lehetõséget is nyújt.

Reguláris kifejezésekkel kapcsolatban érdemes megemlíteni, hogy némileg közhiedelem, hogy lassúak, általában már nagyon egyszerû feladatok esetén is alig lassabb, mint a sima szöveg kezelõ függvények, de kicsit is összetettebb feladatok esetén szinte biztosan állítható, hogy jobban járunk egy jól irányzott reguláris kifejezéssel, mintha szöveg kezelõ funkciók sorozatával oldanánk meg az adott problémát. Persze ha valamit megoldhatunk egyetlen strpos, str_replace parancs segítségével, akkor felesleges regexpeket használni.

Mire is jók a reguláris kifejezések? Reguláris kifejezésekkel szövegek egy halmazát tudjuk általánosan leírni, mégpedig úgy, hogy egy ezeket egy speciális jelentéssel bíró metakaraktereket tartalmazó mintával határozzuk meg. Elõször is nézzük át, hogy milyen elemek találhatóak egy reguláris kifejezésben:
o karakterek: minden nem metakarakter karakter saját magát jelenti
o : escape karakter, ezzel érhetjük el, hogy amúgy speciális jelentéssel bíró karakterekre is hivatkozni tudjunk
o karakter megadási módok:
– rövidítések: n, t, r stb.
– oktális forma: ddd (ddd az oktális szám)
– hexa forma: xhh
– unicode hexa forma: x{hh..}, uhh.. (u módosító kell hozzá)
– kontroll karakterek: cx (x tetszõleges karakter)
o karakter osztályok:
– .: a pont általában tetszõleges karaktert határoz meg kivéve az újsor
– C: egy byte-ot jelent
– X: egy unicode szekvenciát jelent (u módosító kell hozzá)
– w, W: egy tetszõleges szóban elõfordulható karakter, illetve ennek fordítotja (locale függõ)
– d, D: egy tetszõleges szám karaktert, illetve ennek fordítottja
– s, S: tetszõleges whitespace karakter, illetve ennek fordítottja
– az elõbi 3 esetén érdekes lehet, hogy csak ASCII karaktereket találnak meg, ezért Unicode karakterek esetén használjuk a megfelelõ p{X}, pX karakter osztályokat
– p{X}, pX: Unicode karaktereket szûrhetünk a tulajdonságaik alapján (L-Letter, N-Number, Z-Separator stb.)
– P{X}, PX: az elõbbi ellentéte (PL -> nem betû)
– []: saját karakter osztályok
o metakarakterek karakter osztályon belül: (escape), ^ (negálás), – (tartomány megadása), ] (karakter osztály lezárása)
o [a-zA-Z0-9], [^a-z], [ntrCXwWdDsSb…..]
o horgonyok:
– ezek feltételeket határoznak meg, nulla hosszúságúak (nem fogyasztanak el karaktert a szövegbõl)
– ^, $: szöveg eleje és vége (m módosító esetén újsor karakterre is illeszkednek)
– A, z, Z: szöveg eleje, vége, vége vagy vége elõtti újsor karakter (függetlenek az m módosítótól)
– G: illesztés kezdeténél illeszkedik (preg_match 5. paramétere határozza meg)
– b, B: szó határon illeszkedik, illetve annak ellentétje (szintén locale függõ, valamint karakter osztályon belül a b backspace karaktert jelenti) (szintén csak ASCII karaktereket találnak meg)
– elõre tekintés (lookahead): (?=), (?!) (negatív)
– hátra tekintés (lookbehin): (?<=), (?<!) (negatív)
o vezérlõ karakterek:
– (): gyûjtõ zárójel, a tartalma által megtalált szövegre 1, 2 stb. módon tudunk hivatkozni (ezeknél érdekes lehet, hogy így néz ki az oktális karakter megadási mód)
– |: csoportosítás (foo|bar)
– ?, *, +, {n,m}: számosság meghatározók (nulla vagy egy, nulla vagy több, egy vagy több, megadott számú találat, az intervalum bármelyik oldala lehet nyitott), ezek mohók (greedy), a lehetõ legtöbb karaktert próbálják meg elfogyasztani.
– ??, *?, +?, {n,m}?: lusta (lazy) számosság meghatározók (jelentés ugyanaz), viszont ezek a lehetõ legkevesebb karaktert próbálják meg elfogyasztani.
– ?+, *+, ++, {n,m}+: nem eresztõ (possessive) számosság meghatározók: ennek a backtracking mechanizmus miatt lesz jelentõsége, errõl majd lesz késõbb szó.
– (?:): nem gyûjtõ zárójel (hasznos lehet, hogy ha csak csoportosításra használnánk amúgy a zárójelet, akkor a “gyûjtés” miatti memória foglálás és adminisztráció felesleges)
– (?<Name>): nevesített capturing (a találatot ilyen néven keresztül fogjuk elérni, hasznos lehet, mert ez esetben nem függünk attól, hogy a regexbe bekerül esetleg még egy gyûjtõ zárójel)
– (?>): atomi grouping: szintén a backtracking mechanizmus miatt van jelentõsége
– (?(condition)yes-pattern), (?(condition)yes-pattern|no-pattern): feltételes egyezés vizsgálata, majd látunk rá példát
o módosítók:
– /…/xzy: a minta vége után felsorolhatjuk õket
– (?modifier): innentõl kezdve él a módosító ((?i) vagy (?-i) vagy kombinalva (?m-i))
– (?modifier:….): a zárójelen belül érvényes az adott módosító
– (?#…): komment
– #: komment (x módosító)
– Q…E: közöttük tetszõleges szöveg lehet, literálként lesz értelmezve
– módosítók:
o i: kis betû, nagy betû érzéketlen lesz a minta
o s: ilyenkor a . illeszkedik az újsor karakterre is
o m: ilyenkor a ^ és a $ csak a teljes szöveg elején illetve végén illeszkedik
o x: a whitespace karakterek nem lesznek részei a regexpnek (lesz rá példa)
o e: preg_replace esetén lesz érdekes, látunk rá példát
o u: UTF-8-ként lesz értelmezve a minta
o A, U, X, S, D

Általános jótanácsok:
o nem kötelezõ a / jelet használni határoló jelnek, lehet bármi más, a lényeg, hogy a regexpen belül escapleni kell.
$pattern = “!…!…!”;
o ha nem ismert tartalmú szöveget kell beilleszteni egy mintába, akkor használjuk a preg_quote parancsot (ha nem / jel a határoló, akkor meg kell adni a függvénynek).
$pattern = “!…”.preg_quote($_GET[‘search’], “!”).”…!”;
o használjunk nevesített capturinget, kevésbé hibaérzékeny.
o ha egy zárójel csak csoportosításra szolgál, akkor jelezzük, hogy nincs szükség a capturingre.
o a kicsit is bonyolultabb reguláris kifejezéseket kommentezzük, mintha sima programkód lenne, különben a késõbbiek során szintén elég nehezen módosíthatókká válnak.
/**
FAQ hozzaadasa egy kategoriahoz
@param int    $category_id    + Ebben a kategoriaban kell letrehozni a FAQ-ot
@param string $question       + FAQ-hoz tartozo kerdes
@param string $answer         + FAQ-hoz tartozo valasz
*/
public function actionAdd($category_id, $question, $answer) {
Controller_Faq::addItem($category_id, $question, $answer);
redirect(‘/faq/editor/ViewFaqs.cmd?category_id=’.$category_id);
}

function getActionParamsDefinition($pageClass, $action)
{
$reflection = new ReflectionClass($pageClass);
try {
$reflection = $reflection->getMethod(‘action’.$action);
} catch (ReflectionException $e) {
PEAR::raiseError(‘The requested action (‘.$action.’) not supported on this page!’);
}

if (null === ($comment = $reflection->getDocComment())) {
PEAR::raiseError(‘The requested action (‘.$pageClass.’->action’.$action.'()) has no DocComment!’);
};

// Nevesitett gyujto almintakat hasznlunk a konnyebb erthetoseg kedveert
$pattern = ‘
/# parameter informaciok kinyerese a kommentbol
@param                                             # kulcsszo megkereses
s+                                                # elvalasztas
(?P<type>int|string|array|boolean|float|number)    # lehetseges tipusok
s+                                                # elvalasztas
(?P<name>$[a-z_x7f-xff][a-z0-9_x7f-xff]*)     # parameter neve
s+                                                # elvalasztas
(?:                                                # leiras, ne gyujtse be a tartalmat
# kotelezo, opcionalis
(?:(?P<ismandatory>[+]))?                        # DEPRECATED egy darab plusz jel – mar nem hasznaljuk
# validatorok, opcionalis
(?:(                                          # nyito zarojel
(?P<validators>[a-z0-9_,]+)                # validatorok: szovegek vesszovel elvalasztva
))?                                           # zaro zarojel
.*?$                                           # leiras maradek resze
)
/imsx
‘;
// A $mataches tomb nulladik elemének mérete megadja a parameterek szamat.
preg_match_all($pattern, $comment, $commentParams);

Számosság:
o alap esetben ezek a módosítók mohók, a lehetõ legtöbb karaktert próbálják meg elfogyasztani:
$string = “…<a>1…</a>…<a>2…</a>….”;
$pattern = “/<a>.*</a>/”; // “<a>1…</a>…<a>2…</a>”
o ha ez számunkra nem jó, akkor hasznéljunk lusta módosítókat:
$string = “…<a>1…</a>…<a>2…</a>….”;
$pattern = “/<a>.*?</a>/”; // “<a>1…</a>”
o {n,m} forma esetén tetszõleges variácó létezik: {,m}, {n,}, {n,m}, {n}

Karakter osztályok:
o használhatunk POSIX kompatibilis megadási formát is: :alpha:, :alnum:, :ascii:, :cntrl:, :digit:, :graph:, :lower:, :print:, :space:, :upper:, :xdigit:. Ezeket lehet negálni is: :^alnum:. Például: [[:ascii:]], [[:^digit:]]
o [^]: a negált karakter osztályok minden karakterre illeszkednek, amelyik nincs benne az adott osztályban, még az újsorra is
$string = “<img …n…>”;
$pattern = “/<img.+?>/”;
$pattern = “/<img[^>]+>/”;

Módosítók:
o i: egyértelmû, szükség esetén használjuk.
o s: ha szeretnénk, hogy a . illeszkedjen minden karakterre, akkor kell használnunk.
$string = “<img …n…>”;
$pattern = “/<img.+?>/s”;
o m: ha szeretnénk, hogy a ^ és a $ ne csak a teljes szöveg elejére és végére illeszkedjen, akkor kell használnunk.
o S: ha gyakran futtatunk egy regexpet, akkor érdemes lehet kipróbálni ezt az opciót, ugyanis ezzel arra utasítjuk a PCRE motort, hogy elemezze jobban a regexpet, és optimálisabban hajtsa végre.
o u: példa email cím ellenõrzõ.
o e: ezzel azt érjük el preg_replace esetén, hogy a helyettesítendõ szöveg PHP kódként értékelõdik ki (majd látunk rá példát).

Egyszerûbb példák:
o IP cím ellenõrzése:
$matching255 = “(?#100 alatti szamok)[1-9]?[0-9]|(?#1xx)1[0-9]{2}|(?#200-249)2[0-4][0-9]|(?#25x)25[0-5]”;
preg_match(“/$matching255/”, “255”);

//25 (a csoportosítás elsõ eleménél ha találat van, akkor vége az illesztésnek)
preg_match(“/^$matching255$/”, “255”);

//25 (precedencia)
preg_match(“/^($matching255)$/”, “255”);
//255
$ipAddressPattern = “/^(($patternFor255).){3}($patternFor255)$/”;
o változónevek ellenõrzése:
$pattern = “/^$[a-z]+([A-Z][a-z]+)*$/”;
o szóismétlések megkeresése:
$pattern = “/b(w+)s+\1b/i”;
o email cím ellenõrzése:
$pattern = “/^[wd!#$%&’*+-/=?^`{|}~]+(.[wd!#$%&’*+-/=?^`{|}~]+)*@([a-zd][-a-zd]*[a-zd].)+[a-z][-a-zd]*[a-z]/i”;

Horgonyok:
o ahogy említettük, ezek nem fogyasztanak el karaktereket a szövegbõl, nulla hosszúságúak, segítségükkel különbözõ feltételek teljesülését tudjuk elõírni
o alap horgonyok: ^, $, A, Z, z, b
$_GET[“phone”] = “xxx30-123-1234xxx”;
preg_match(“/d{2}-d{3}-d{4}/”, $_GET[“phone”]); // TRUE
preg_match(“/^\d{2}-\d{3}-\d{4}$/”, $_GET[“phone”]); // FALSE

preg_match vs. preg_match_all
o a elõbbi az elsõ egyezést találja meg, a második az összeset.
o preg_match_all esetén hasznos lehet a PREG_SET_ORDER opció megadása: alap esetben a találatok tömbje elsõdlegesen a gyûjtõ zárójel sorszáma szerint van index-szelve, de ha megadjuk ezt az opciót, akkor a találatok sorendje lesz az elsõdleges index (a példa alapján ez érthetõ is lesz).
<?php
$subject = “….(1|2)….(2|3)…”;
$pattern = “/((d+)|(d+))/”;

preg_match($pattern, $subject, $match);
echo ‘<pre>’.htmlentities(print_r($match, true)).'</pre>’;
// Array
// (
//     [0] => (1|2)
//     [1] => 1
//     [2] => 2
// )

preg_match_all($pattern, $subject, $match);
echo ‘<pre>’.htmlentities(print_r($match, true)).'</pre>’;
// Array
// (
//     [0] => Array
//         (
//             [0] => (1|2)
//             [1] => (2|3)
//         )
//
//     [1] => Array
//         (
//             [0] => 1
//             [1] => 2
//         )
//
//     [2] => Array
//         (
//             [0] => 2
//             [1] => 3
//         )
//
// )

preg_match_all($pattern, $subject, $match, PREG_SET_ORDER);
echo ‘<pre>’.htmlentities(print_r($match, true)).'</pre>’;
// Array
// (
//     [0] => Array
//         (
//             [0] => (1|2)
//             [1] => 1
//             [2] => 2
//         )
//
//     [1] => Array
//         (
//             [0] => (2|3)
//             [1] => 2
//             [2] => 3
//         )
//
// )
foreach($match as $item) {}
?>

preg_replace:
o ftp, http, https URL-eket szeretnénk linkekre cserélni.
preg_replace(“!((ht|f)tps?://S+)!”, ‘<a href=”1″>1</a>’, $text);
o ugyanaz mint feljebb, de szeretnénk, hogy csak a ténylegesen létezõ URL-ekbõl legyen link, itt jön be a képbe az e módosító:
preg_replace(“!((ht|f)tps?://S+)!e”, ‘isExistentUrl(1) ? “<a href=”1″>1</a>” : “1 (dead link)”‘, $text);
o nagyon egyszerû template motor:
$string = “…{foo}…”;
$templateVars[“foo”] = “bar”;
preg_repalce(“/{(w+)}/e”, “$templateVars[1]”, $string);
o PHPMailer kiegészítése:

Backtracking:
o alap esetben az ilesztés folyamata:
$string = “foo12”;
$pattern = “/w+13/”;
// foo12   – illeszti az f-et
// [f]oo12 – illeszti az o-t
// [fo]o12 – illeszti a következõ o-t
// [foo]12 – illeszti az 1-est
// [foo1]2 – itt nem sikerül a 3-at illeszteni, ezért visszalép és felad egy karaktert
// [fo]o12 – itt nem sikerül az 1-et illeszteni, ezért visszalép és felad egy karaktert
// [f]oo12 – itt nem sikerül az 1-et illeszteni, ezért visszalép és felad egy karaktert
// foo12 – nem sikerült az ilesztés
o adott esetben mi tudhatjuk, hogy nincs értelme visszalépnie, és ezt jelezhetjük is, erre szolgálnak a nem eresztõ (possessive) számosság meghatározók.
$string = “foo12”;
$pattern = “/w++13/”;
// foo12   – illeszti az f-et
// [f]oo12 – illeszti az o-t
// [fo]o12 – illeszti a következõ o-t
// [foo]12 – illeszti az 1-est
// [foo1]2 – nem sikerült az illesztés
o ennek egyik alternatív megadási formája az atomic grouping:
$pattern = “/(?>w+)13/”;
o egy érdekes példa, csak hogy érzékeltessük ennek jelentõségét: legyen a feladatunk, hogy a wikire jelemzõ MindenSzoNagybetuvelKezdodik jellegû szavakat kell kigyûjteni. Az alap ötlet kapásból megvan:
$pattern = “/(([A-Z][a-z]+)+)/”;
Ha azonban van egy ilyen szövegünk: “JoHosszuFileNevAmiHasonlitArraAmitKeresunk.php”, akkor a backtracking miatt lényegesen meg tud nõni a kiértékelés ideje, amit lecsökkenthetünk (egy teszt szerint például 1,5 másodpercrõl 0,05-re), ha így adjuk meg a regexpet:
$pattern = “/(?>([A-Z][a-z]+)+)/”;

jozsi123
[j]ozsi123
[jo]zsi123
[joz]si123
[jozs]i123
[jozsi]123
[jozsi1]23
[jozsi12]3
jozsi123
[j]
|  marad   |  talalt  |
| jozsi123 |          |
|          |          |
|          |          |
|          |          |
|          |          |