Kan iemand mij helpen met de uitleg van preg_replace_callback resp. preg_replace
Ik heb een stuk code en daar wil ik wat in aanpassen. Nu heb ik al wel een stukje over de reguliere expressie's gelezen en snap er al wel wat meer van maar om dit helemaal te begrijpen lukt mij niet. Ook niet met php.net/manual.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$ruwe_string = 21 sep 15:30: Club team 1 - Club team 2;
$Pubdate = Sat, 21 Sep 2013 15:30:00 +0200;
$regex = '#(.*), (\d*) (.*) (\d*) (\d*):(\d*):(\d*) +(.*)#';
$replacement = '<td>$2-$3-$4</td><td>$5:$6 uur</td>'; //Deze zie ik nergens gebruikt worden in de //preg_replace_callback en toch komt het eruit bij het resultaat!?
$Result = preg_replace_callback($regex, array(&$this, '_callback'), $Pubdate);
echo $Result; //Dit is dan het resultaat: <td>21-09-2013</td> <td>15:30 uur</td>
//2e stap
$regex = "#(\d*) (.*) (\d*):(\d*):(.*)#";
$replacement = '<td>$5</td>';
$Result .= preg_replace($regex, $replacement, $ruwe_string);
echo $Result; //Dit is dan het resultaat: <td>21-09-2013</td><td>15:30 uur</td><td> Club team 1 - Club team 2</td>
?>
$ruwe_string = 21 sep 15:30: Club team 1 - Club team 2;
$Pubdate = Sat, 21 Sep 2013 15:30:00 +0200;
$regex = '#(.*), (\d*) (.*) (\d*) (\d*):(\d*):(\d*) +(.*)#';
$replacement = '<td>$2-$3-$4</td><td>$5:$6 uur</td>'; //Deze zie ik nergens gebruikt worden in de //preg_replace_callback en toch komt het eruit bij het resultaat!?
$Result = preg_replace_callback($regex, array(&$this, '_callback'), $Pubdate);
echo $Result; //Dit is dan het resultaat: <td>21-09-2013</td> <td>15:30 uur</td>
//2e stap
$regex = "#(\d*) (.*) (\d*):(\d*):(.*)#";
$replacement = '<td>$5</td>';
$Result .= preg_replace($regex, $replacement, $ruwe_string);
echo $Result; //Dit is dan het resultaat: <td>21-09-2013</td><td>15:30 uur</td><td> Club team 1 - Club team 2</td>
?>
Dit is wel het resultaat wat ik wil hebben maar hoe nou die 'preg' methods tot dit resultaat komen ben ik nog niet achter. Ik hoop dat mij iemand daar verder mee kan helpen.
En wat ik eigenlijk nodig heb, naast dat ik graag wil begrijpen hoe dit werkt, is de datum (21-09-2013), want daar wil ik mee verder rekenen.
Ik kan het met substr, er ook uit trekken maar ik wil graag weten hoe ik het met deze functie's kan doen.
Nico
Gewijzigd op 29/08/2013 10:58:15 door Nkamp Kamp van de
tutorial die ik kan volgen echter ik krijg niet de uitkomst die zij daar aangeven.
De ouput volgens de tutorial zou 081225 moeten zijn wat ik ook kan volgen/begrijp. Echter bij mij is het gewoon 122508.
Ik draai het op mijn localhost windows 7. En ik voer het niet uit vanaf de cmd console zoals bij de tutorial.
Evenzo het andere voorbeeld
de output is nog steeds 122508 terwijl dit volgens de tutorial 081225 zou moeten zijn.
Nu heb ik nog twee andere vragen:
1. wat is nou eigenlijk in essentie een 'callback' functie?
2. Als ik het goed begrijp is de replace de callback functie en retouneert deze functie een array $this. Oh nu zie ik het dit is een variabele. Ik heb dit verward met this->.
Maar ik vind het er nog steeds vreeemd uitzien:
3. Het volgende zie ik ook in de callback functie voorbeelden staan:
Nu weet ik wel zoveel van arrays af dat je die kunt benaderen/vullen met [x].
- Maar wat doet die '($matches[2])' er nog weer achter?
- En wat is de betekenis van het @ teken?
Hallo nu dacht ik het gevonden hebben, althans een Code (php)
1
2
3
4
5
6
2
3
4
5
6
<?php
$string = '12/25/08';
$pattern = '|(d{2})/(d{2})/(d{2})|';
$replacement = '$3$1$2';
echo preg_replace($pattern, $replacement, $string);
?>
$string = '12/25/08';
$pattern = '|(d{2})/(d{2})/(d{2})|';
$replacement = '$3$1$2';
echo preg_replace($pattern, $replacement, $string);
?>
De ouput volgens de tutorial zou 081225 moeten zijn wat ik ook kan volgen/begrijp. Echter bij mij is het gewoon 122508.
Ik draai het op mijn localhost windows 7. En ik voer het niet uit vanaf de cmd console zoals bij de tutorial.
Evenzo het andere voorbeeld
Code (php)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
<?php
$string = '12/25/08';
$pattern = '|(d{2})/(d{2})/(d{2})|';
$callback_fn = 'process';
echo preg_replace_callback($pattern, $callback_fn, $string);
function process($matches) {
print_r($matches);
return $matches[3].$matches[1].$matches[2];
}
?>
$string = '12/25/08';
$pattern = '|(d{2})/(d{2})/(d{2})|';
$callback_fn = 'process';
echo preg_replace_callback($pattern, $callback_fn, $string);
function process($matches) {
print_r($matches);
return $matches[3].$matches[1].$matches[2];
}
?>
de output is nog steeds 122508 terwijl dit volgens de tutorial 081225 zou moeten zijn.
Nu heb ik nog twee andere vragen:
1. wat is nou eigenlijk in essentie een 'callback' functie?
2. Als ik het goed begrijp is de replace de callback functie en retouneert deze functie een array $this. Oh nu zie ik het dit is een variabele. Ik heb dit verward met this->.
Maar ik vind het er nog steeds vreeemd uitzien:
3. Het volgende zie ik ook in de callback functie voorbeelden staan:
Nu weet ik wel zoveel van arrays af dat je die kunt benaderen/vullen met [x].
- Maar wat doet die '($matches[2])' er nog weer achter?
- En wat is de betekenis van het @ teken?
Gewijzigd op 29/08/2013 11:06:41 door nkamp Kamp van de
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
$string = '12/25/08';
$pattern = '|(d{2})/(d{2})/(d{2})|';
echo preg_replace_callback($pattern, 'process', $string);
// dit is onze eigen callback functie welke automatisch door preg_replace_callback wordt aangeroepen:
function process($matches) {
// laat de array zien zodat we beter begrijpen wat er in $matches zit:
print_r($matches);
// geef de matches terug in een andere volgorde:
return $matches[3].$matches[1].$matches[2];
}
?>
$string = '12/25/08';
$pattern = '|(d{2})/(d{2})/(d{2})|';
echo preg_replace_callback($pattern, 'process', $string);
// dit is onze eigen callback functie welke automatisch door preg_replace_callback wordt aangeroepen:
function process($matches) {
// laat de array zien zodat we beter begrijpen wat er in $matches zit:
print_r($matches);
// geef de matches terug in een andere volgorde:
return $matches[3].$matches[1].$matches[2];
}
?>
Toevoeging op 29/08/2013 09:49:53:
Het @ teken onderdrukt foutmeldingen.
Maar het is misschien dom van mij maar wat is hier nou zo 'callback' ('terug roepen') aan? Je retouneert een bepaalde waarde maar dan doen zoveel funtie's, toch?
Het voorbeeld van Frank kan ik goed volgen. Waarvoor dank. Maar mijn code 'probleem' daar zit ik naar te kijken als een konijn in een paar auto koplampen. Bv. ik begrijp denk te begrijpen dat er een array geretouneert wordt, maar hoe benader ik die dan? en wat doet die & er nog weer voor? is dat een pointer?
Sorry de gewone PHP zaken snap ik denk ik maar dit is voor mij zoiets aparts, en toch wil ik het graag begrijpen.
Nkamp Kamp van de op 29/08/2013 11:18:37:
... maar wat is hier nou zo 'callback' ('terug roepen') aan? Je retouneert een bepaalde waarde maar dan doen zoveel funtie's, toch? ...
Wel, er zijn ook functies waar je een exit() aanroept; of or die('...') . Dan komt die niet terug.
Dat is naamgeving die al een hele tijd mee gaat. Ook in verschillende talen.
Ik interpreteer de naam vooral zo: (met andere woorden, ik verkoop het maar als mijn mening)
Dus, je maakt een fantastische functie. Je denkt: dit kan ik hergebruiken, of anderen kunnen dit gebruiken.
Middenin die functie heb je input of output nodig, naar of van de gebruiker van de functie (dus ook een scripter)
Wel, met een callback geef je dus de mogelijkheid dat die functie generiek kan gemaakt worden, en dat de gebruiker jouw functie onderbreekt.
nu komt het:
Je verwacht dan wel dat de gebruiker zo vriendelijk is om een functie mee te geven die terug keert naar jouw functie, en eventueel een waarde teruggeeft.
... tja, 't is een beetje lastig uit te leggen.
(Ik moet een goed voorbeeld vinden...)
Nkamp Kamp van de op 29/08/2013 11:18:37:
... en wat doet die & er nog weer voor? is dat een pointer? ...
Zo ongeveer, ja. Als je een C (C++) achtergrond hebt, vergelijk het dan met een poiter.
Als je wil Google'n, zoek dan op 'passing by reference'
Dus, wat normaal gebeurt:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$a = 5; // $a krijgt een plekje in het geheugen, en krijgt een waarde toegewezen
$b; // $b krijgt een plekje in het geheugen
$b = $a; // maak een kopie van de inhoud van $a en steek die in het plekje geheugen waar $b staat
?>
$a = 5; // $a krijgt een plekje in het geheugen, en krijgt een waarde toegewezen
$b; // $b krijgt een plekje in het geheugen
$b = $a; // maak een kopie van de inhoud van $a en steek die in het plekje geheugen waar $b staat
?>
Met die pointer (in php mag men het zo niet noemen ...) daarentegen:
Code (php)
1
2
3
4
5
2
3
4
5
<?php
$a = 5; // $a krijgt een plekje in het geheugen, en krijgt een waarde toegewezen
$b = &$a; // zowel $a als $b gaan nu naar het zelfde plekje in het geheugen wijzen.
// Vanaf nu kan je dat plekje in het geheugen dus zowel aanspreken met $a als met $b
?>
$a = 5; // $a krijgt een plekje in het geheugen, en krijgt een waarde toegewezen
$b = &$a; // zowel $a als $b gaan nu naar het zelfde plekje in het geheugen wijzen.
// Vanaf nu kan je dat plekje in het geheugen dus zowel aanspreken met $a als met $b
?>
In een functie is dat interessant omdat je de pointer zelf kan meegeven; dus je geeft het adres van een variabele mee aan een functie ipv. een kopie van de waarde.
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
$a;
zeg_iets($a);
echo $a;
function zeg_iets(&$foo) {
$foo = 'Hello World'; // $foo krijgt het adres mee van de variabele waarmee je deze functie aanstreekt (de parameter).
}
?>
$a;
zeg_iets($a);
echo $a;
function zeg_iets(&$foo) {
$foo = 'Hello World'; // $foo krijgt het adres mee van de variabele waarmee je deze functie aanstreekt (de parameter).
}
?>
---
Merk op: een object wordt altijd by reference doorgegeven. Een array niet.
Gewijzigd op 29/08/2013 14:28:03 door Kris Peeters
Bedankt voor de moeite die je genomen hebt om het mij te proberen uitleggen. Ik kom er wat verder mee.
Het zal meer aan mij liggen dan jou maar callback... Ik heb een aantal jaren geleden java 1.4 certificering gedaan maar ik kan mijn de kreet callback niet herinneren. Ook nog wel wat in C gedaan. Maar je hebt gelijk ik heb even gegoogled en 'Java callback'.
Kijk met exit() of or die() kom je inderdaad niet terug. Maar dat is denk ik meer om een 'technische' reden dan om een functionele reden. En die kun je ook nog netjes met een try/catch afvangen, toch?
Jou uitleg kan ik niet helemaal volgen. Althans ik weet niet hoe ik het voor mij moet zien dat je "...midden in de functie input of output nodig hebt...". Ik zit na te denken maar volgens mij stopt een functie "midden" in niet, of? Er vindt toch altijd een event (door gebruiker) plaats en dan wordt een functie afgevuurd etc. en die komt netjes aan z'n eind, althans dat zou moeten, met een resultaat.
Want als je een functie wilt hergebruiken dan zou ik eerder denken aan de signatuur uitbreiden met een optionele parameter. En bij classes ga je toch met overerving (overriding) aan de gang.
passing by reference/passing by value ken ik vanuit Java/C++. En dat kan ik ook goed volgen. Maar in mijn geval
, hoe moet ik dit "array(&$this, '_callback')" interpreteren? Oh, of komt het resultaat in $Result en is dat een array? schiet mij nu te binnen. Want hoe benader ik anders de items is de &$this array?
En wat ik nog niet begrijp waarom mijn resultaten van de turorial niet overeenkomen.
Ik ben meer beeldend ingesteld en probeer te visualiseren wat er gebeurd.
Gewijzigd op 30/08/2013 10:35:47 door nkamp Kamp van de
De uitleg staat tussen de code
Het punt is dat je ziet hoe mijn functie nood heeft aan informatie van buitenuit. En dit middenin de functie.
Dus, mijn functie wordt even verlaten; een callback wordt aangeroepen van waar input verwacht wordt.
Hoe die callback dat doet ... is niet het probleem van mijn functie. Dat moet de schrijver van de callback zelf maar zien.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
kiesWinnar('haal_genomineerden');
/**
* De functie kiest een winnaar van een tombola.
* De functie kiest willekeurig een aantal letters
* Met die letters moet de naam geselecteerd worden uit een db. Hiervoor roepen we de callback
* de callback levert een array van genomineerden.
* de functie kiesWinnar() kiest dan een winnar uit de genomineerden, op basis van "iets"
*/
function kiesWinnar($callback) {
$letters = array();
for ($i=0; $i<10; $i++) { // max 10 letters
$letters[] = chr(65 + rand(0, 25)); // genereert willekeurig 1 letter; A->Z
// nu willen we op basis van deze letters tussen 5 en 20 genomineerden.
$genomineerden = $callback($letters); // het is aan de schrijver van de callback om, naar eigen systeem, de users te leveren
$count = count($genomineerden);
if ($count >= 5 && $count <= 20) {
$winnaar = $genomineerden[rand(0, $count-1)]; // dit is gewoon random, maar stel je voor dat hier iets interessants gebeurt
return $winnaar;
}
// else: nog een letter bij doen en opnieuw proberen of de callback tussen 5 en 20 namen geeft.
}
}
/*
* Dit is de callback.
*/
function haal_genomineerden($letters) {
$sql = "SELECT username, points, type FROM users WHERE ..." // op basis van de letters
$result = array();
while($row = mysql_fetcht_assoc($sql)) {
$result[] = $row;
}
return $result;
}
?>
kiesWinnar('haal_genomineerden');
/**
* De functie kiest een winnaar van een tombola.
* De functie kiest willekeurig een aantal letters
* Met die letters moet de naam geselecteerd worden uit een db. Hiervoor roepen we de callback
* de callback levert een array van genomineerden.
* de functie kiesWinnar() kiest dan een winnar uit de genomineerden, op basis van "iets"
*/
function kiesWinnar($callback) {
$letters = array();
for ($i=0; $i<10; $i++) { // max 10 letters
$letters[] = chr(65 + rand(0, 25)); // genereert willekeurig 1 letter; A->Z
// nu willen we op basis van deze letters tussen 5 en 20 genomineerden.
$genomineerden = $callback($letters); // het is aan de schrijver van de callback om, naar eigen systeem, de users te leveren
$count = count($genomineerden);
if ($count >= 5 && $count <= 20) {
$winnaar = $genomineerden[rand(0, $count-1)]; // dit is gewoon random, maar stel je voor dat hier iets interessants gebeurt
return $winnaar;
}
// else: nog een letter bij doen en opnieuw proberen of de callback tussen 5 en 20 namen geeft.
}
}
/*
* Dit is de callback.
*/
function haal_genomineerden($letters) {
$sql = "SELECT username, points, type FROM users WHERE ..." // op basis van de letters
$result = array();
while($row = mysql_fetcht_assoc($sql)) {
$result[] = $row;
}
return $result;
}
?>
Snap je hiermee het concept, het principe?
Gewijzigd op 30/08/2013 11:12:49 door Kris Peeters
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$string = '12/25/08';
$pattern = "|(\d{2})/(\d{2})/(\d{2})|";
echo preg_replace_callback($pattern, 'process', $string);
// dit is onze eigen callback functie welke automatisch door preg_replace_callback wordt aangeroepen:
function process($matches) {
// laat de array zien zodat we beter begrijpen wat er in $matches zit:
print_r($matches);
// geef de matches terug in een andere volgorde:
return $matches[2].'-'.$matches[1].'-'.$matches[3];
}
?>
$string = '12/25/08';
$pattern = "|(\d{2})/(\d{2})/(\d{2})|";
echo preg_replace_callback($pattern, 'process', $string);
// dit is onze eigen callback functie welke automatisch door preg_replace_callback wordt aangeroepen:
function process($matches) {
// laat de array zien zodat we beter begrijpen wat er in $matches zit:
print_r($matches);
// geef de matches terug in een andere volgorde:
return $matches[2].'-'.$matches[1].'-'.$matches[3];
}
?>
Bedankt. Je kunt het stom noemen en misschien is dat zo, maar het komt nu langzaam binnen. Aangezien in mijn geval '_callback' dacht ik dat het iets specifieke PHP syntax is, ook mn. door de underscore icm. preg_replace_callback. Iets als een constructor want daar staan ook underscores voor.
Ik heb nooit aan een 'platte' functie _callback gedacht.
Ik dacht ook die voorbeelden zijn weer net niet wat ik hier bij de hand heb. Bovendien staat er drie regels voor preg_replace_callback nog een $replacement, die helemaal niets te maken heeft met preg_replace_callback. En ik zie ook wel dat dit niet in de aanroep oid zit. Maar ik denk wat gebeurd daar nou, wat is dit?
Het is geen code van mijzelf maar 50 regels verder op vind ik in de class inderdaad de functie _callback! en die doet bijna hetzelfde wat Frank z'n process functie doet nl. de datum omzetten via de publication date, netjes met <td></td> eromheen zoals in de $replacement gedeclareerd(daarom dacht ik ook dat dit er wat mee te maken had).
Ja, omdat ik dus niet echt die functie preg_replace_callback ken, stond ik compleet op het verkeerde been.
Het enige wat ik nog steeds niet begrijp is die aanroep array(&$this, '_callback') ipv gewoon _callback, zoals ook in Franks voorbeeld 'process'. Wat is nou de reden van: 'array(&$this,'? Wat staat er nu in &$this?
In mijn situatie wordt alleen maar een stukje text als '<td>'.$matches[2] etc. geretouneerd door de _callback functie. Dus waarom moet dan array(&$this erbij. Ik heb het zojuist even verwijderd maar dan werkt het niet meer. Dus het is wel nodig!