Tutorials >
PHP >
Technieken, tricks en tips
|
Gepost op: 14 april 2006 - 22:54 |
|
|
|
PHP expert
|
Ja daar zat ik al wat op te wachten Bedankt Koen (y)
Als ik het goed snap wordt bij __sleep() de waardes onthouden van de variablen. Maar kan je dan andere waardes geven aan dezelfde variablen van je class en als je later in je script die vorige waarders nodig hebt die dan terug aanroepen? Of blijven die in sleep-mode?
misschien een voorbeeld:
<?
class oop
{
private $foo;
private $var;
private $blaat;
public function __construct( $foo , $var , $blaat )
{
$this->foo = $foo;
$this->var= $var;
$this->blaat= $blaat;
}
public function __sleep()
{
return $foo.$var.$blaat;
}
public function initAgain( $foo , $var , $blaat )
{
$this->foo = $foo;
$this->var= $var;
$this->blaat= $blaat;
}
public function Tellen( )
{
return strlen( $this->foo.$this->var.$this->blaat );
}
public function __wakeup()
{
//niets empty nadda rien
}
public function show()
{
return $this->foo.$this->var.$this->blaat;
}
}
$obj = new oop( "poes" , "hond" , "cavia");
$string = serialize($obj);
$obj->initAgain( "tijger" , "panter" , "leeuw");
echo $obj->Tellen(); //output: 17
$string2 = unserialize($string);
echo $string2->show(); //output: poeshondcavia
?>
<? class oop { private $foo; private $var; private $blaat; public function __construct( $foo , $var , $blaat ) { $this->foo = $foo; $this->var= $var; $this->blaat= $blaat; } public function __sleep() { return $foo.$var.$blaat; } public function initAgain( $foo , $var , $blaat ) { $this->foo = $foo; $this->var= $var; $this->blaat= $blaat; } public function Tellen( ) { return strlen( $this->foo.$this->var.$this->blaat ); } public function __wakeup() { //niets empty nadda rien } public function show() { return $this->foo.$this->var.$this->blaat; } } $obj = new oop( "poes" , "hond" , "cavia"); $obj->initAgain( "tijger" , "panter" , "leeuw"); echo $obj->Tellen(); //output: 17 echo $string2->show(); //output: poeshondcavia ?>
Klopt dit mijn class?
ps: voor de mensen die Tri Pham niet kennen, hij schreef vooral artikels over OOP op phpfreakz.nl:
http://phpfreakz.nl/artikelen.php?aid=116
http://phpfreakz.nl/artikelen.php?aid=113
die methode van Tri Pham ziet er wel makkelijk/handig uit
stijn |
|
|
|
Gepost op: 15 april 2006 - 00:06 |
|
|
|
PHP expert
|
$string en $obj zijn niet meer verbonden vanaf het moment dat het wordt geserializeerd. Het maakt dus niet uit _wat_ je allemaal met $obj gaat doen. Dit heeft geen effect op $string. |
|
|
|
Gepost op: 15 april 2006 - 10:31 |
|
|
|
PHP expert
|
a ok , dan moet je na je serialize opnieuw je class initialiseren?
<?
//...
$obj = new oop( "poes" , "hond" , "cavia");
$string = serialize($obj);
$obj = new oop( "tijger" , "panter" , "leeuw");
$obj->initAgain( "tijger" , "panter" , "leeuw");
echo $obj->Tellen(); //output: 17
$string2 = unserialize($string);
echo $string2->show(); //output: poeshondcavia
?>
<? //... $obj = new oop( "poes" , "hond" , "cavia"); $obj = new oop( "tijger" , "panter" , "leeuw"); $obj->initAgain( "tijger" , "panter" , "leeuw"); echo $obj->Tellen(); //output: 17 echo $string2->show(); //output: poeshondcavia ?>
bedankt
[edit @ hieronder]
ok, bedankt |
|
|
|
Gepost op: 15 april 2006 - 12:35 |
|
|
|
PHP expert
|
Nee, je snapt het niet denk ik.
1) $string2 is een verkeerde naam omdat het een object is
2) $string2 en $obj hebben na het serializeren NIETS meer met elkaar te maken. Alles wat je met $obj doet heeft geen gevolg op $string en de geünserializeerde versie hier van. Het is de bedoeling dat je hierdoor zo'n actie zou kunnen uitvoeren.
file1.php
<?php
// class definitie
$obj = new EenClass("var1", "var2");
$serializedObject = serialize($obj);
mysql_query("INSERT into aTable (someColumn) VALUES ('". $serializedObject ."')");
?>
<?php // class definitie $obj = new EenClass("var1", "var2"); mysql_query("INSERT into aTable (someColumn) VALUES ('". $serializedObject ."')"); ?>
file2.php
<?php
// class definitie
$serializedObject = mysql_result(mysql_query("SELECT someColumn FROM aTable WHERE something"), 0);
$obj = unserialize($serializedObject);
// nu kan je verder werken met een object dat je eerder gebruikte in file1.php
?>
<?php // class definitie // nu kan je verder werken met een object dat je eerder gebruikte in file1.php ?>
Je kan het ook via cookies, sessies of textfiles doorgeven. |
|
|
|
Gepost op: 18 april 2006 - 14:42 |
|
|
|
Beheerder
|
aanvulling op Serializeren, __sleep() en __wakeup()
Het doorgeven van sessie variabelen van de ene pagina naar de andere pagina werkt onder water ook met __sleep() en __wakeup()
Verder goed artikel |
|
|
|
Gepost op: 18 april 2006 - 16:53 |
|
|
|
PHP expert
|
Ik vind het jammer dat je niet spreekt over interfaces Koen in punt 6.
Voor de anderen , je kan punt 6 (met die abstract template) ook met interface en implements maken. Hier me code:
http://www.pastebin.be/934/
Als je ze beide uitvoert zie je geen verschil maar er is wel een verschil in code. In de interface mag je niets anders defineren of de functies uitwerken. Je moet de functies defineren. In abstract class kan je wel nog andere functies defineren, zoals final dagVerloop();
Als je de interface wilt gebruiken moet je dan de interface implementeren in je nieuwe class.
Als je nu je functie dagVerloop wilt kan je dit ook 2 keer zetten in je class Western en Indiaan maar dit is 2x werk voor niets en kan je dus een andere class maken. Merk wel op dat je dan het type moet defineren moest 'Mens' niet staan bij de parameter in functie dagVerloop zou je niets zien (of error) omdat het type niet herkent wordt.
stijn
[edit @koen hieronder]
Ja , het ziet er bijna hetzelfde uit. Het kan gebruikt worden als "template" die interface (ja toch:?:). Het is een toevoeging , maar toch bedankt voor die verbeteringen |
|
|
|
Gepost op: 18 april 2006 - 17:01 |
|
|
|
PHP expert
|
Citaat: Ik vind het jammer dat je niet spreekt over interfaces Koen in punt 6.
Omdat het dan niet meer volgens het Template method pattern (TMP) gaat.
Hier is declaratie van een 'verloop'-functie verplicht. Anders werk je gewoon met een interface.
Citaat: Als je nu je functie dagVerloop wilt kan je dit ook 2 keer zetten in je class Western en Indiaan maar dit is 2x werk voor niets en kan je dus een andere class maken.
Dan is het al helemaal niet meer volgens het 'TMP'.
Citaat: Merk wel op dat je dan het type moet defineren moest 'Mens' niet staan bij de parameter in functie dagVerloop zou je niets zien (of error) omdat het type niet herkent wordt.
Niet waar.
Wat jij doet is gewoon het gebruik van interfaces tonen en niet het gebruik van het TMP (wat dus wel de bedoeling was).
Interfaces zijn bedoeld om een 'blauwdruk' te geven, een beetje 'vooropgestelde uitleg' van een klasse. Het TMP wil al 'vooropgestelde acties' geven, via een abstracte klasse.
@marten: niet met __sleep() en __wakeup() maar met serializeren. Je kan
een sessiewaarde niet laten slapen volgens mij. (buiten binnen een
klasse dan)
|
|
|
|
Gepost op: 24 april 2006 - 17:56 |
|
|
|
PHP expert
|
Aanvulling bij TMP en de interfaces (zie hierboven)
http://www.pastebin.be/967/
als je de code hierboven bekijkt zie je dat je hier te maken hebt met een interface en een abstract class. Deze 2 classes kan je gaan combineren met elkaar in een nieuwe class bijvoorbeeld. Ik heb hier de class pc genomen maar je kan ook een andere class toevoegen (server , game-pc , studio , ...).
LET OP: gebruik eerst extends en dan pas implements.
CONST: Stel dat je een constante wilt gebruiken in je class dan gebruik je de term const (zie o.a. mijn script van hierboven). Deze constantes kan je dan aanroepen buiten je classes mbv:
className::constName
TIP: Stel dat je een script hebt met allemaal abstracte classes en je included deze in je nieuwe class file. Je wilt een nieuwe abstract class maken maar dan als uitbreiding op de vorige class van je include. Dan doe je het zo:
http://www.pastebin.be/968/
vragen bij deze toevoeging van technieken in OOP kan je altijd pm naar ik
stijn
ps: class is maar een voorbeeld , beetje geforceerd , maar het is het idee dat telt
[Vervolg op aanvulling]
destruct functie:
http://www.pastebin.be/969/
zoals je kan zien staat er nu een __construct en een __destruct functie in mijn class. De destruct functie wordt pas aangeroepen wanneer alle verwijzingen naar de class afgehandeld zijn of verwijdert zijn. Zoals je ziet in mijn script wordt eerst alle code uitgevoerd en op het laatste pas mijn __destruct functie!
Autoloading:
Ziezo je hebt nu klaar met al je classes voor je website (mysql.class.php , login.class.php , cookie.class.php). Deze 3 files gaan we nu gebruiken. het is een voorbeeld. Ok we gaan verder.
Wat je nu gaat doen is hoogstwaarschijnlijk het volgende om al deze classes te gebruiken.
<?php
//includen
include("mysql.class.php");
include("login.class.php");
include("cookie.class.php");
//code
$mysql = new mysql();
$login = new login();
$cookie = new cookie();
?>
<?php //includen include("mysql.class.php"); include("login.class.php"); include("cookie.class.php"); //code $login = new login(); $cookie = new cookie(); ?>
vanaf nu is dit verleden tijd (voor de php 5'ers toch ). In PHP5 is er de functie __autoload toegevoegd. Dat wil zeggen dat hij alle classes probeert te laden voor hij error geeft van CLASS DOES NOT EXISTS!!!
Dan ziet jou script er nu zo uit:
<?php
//autoload
function __autoload( $class )
{
include( $class . '.class.php');
}
//code
$mysql = new mysql();
$login = new login();
$cookie = new cookie();
?>
<?php //autoload function __autoload( $class ) { include( $class . '.class.php'); } //code $login = new login(); $cookie = new cookie(); ?>
zoals je ziet gaat hij de classes includen hij kijkt naar de naam van de class die hij aanroept en gaat dan dus de file includen. Je kan alles in deze functie zetten
Met wat experimenteren leer je wat en wat lezen op PHP[dot]net nog meer.
veel plezier, stijn1989
site: http://be2.php.net/manual/nl/language.oop5.php |
|
|
|
Gepost op: 24 april 2006 - 19:49 |
|
|
|
PHP expert
|
Citaat: De destruct functie wordt pas aangeroepen wanneer alle verwijzingen naar de class afgehandeld zijn of verwijdert zijn.
oei, oei, oei, grote fout! Dit is niet waar, de __destruct methode wordt aangeroepen wanneer EEN instantie van de klasse verwijderd (door unset, of via de omweg: opnieuw waarde toekennen) wordt of wanneer EEN instantie van de klasse is afgehandeld (op het einde van de code).
__autoload ken ik ook al een tijdje en ik vind het wel interessant.
Citaat: Dat wil zeggen dat hij alle classes probeert te laden voor hij error geeft van CLASS DOES NOT EXISTS!!!
Dat is niet echt waar. De __autoload methode wordt gewoon aangeroepen op het moment dat er een instantie wordt gemaakt van een klasse die niet bestaat, dit wil niet persé zeggen dat __autoload daadwerkelijk alle klassen zal laden. Het kan evengoed zijn dat je een errorrapport verstuurt oid.
'include' heeft trouwens geen haakjes nodig.
Ik zie dat je goed opweg bent met oo-programmeren, hier en daar maak je nog wel grove fouten maar je leert door vallen en opstaan. Ik raad je aan je ook aan de naming conventions te houden met betrekking tot klasnamen. Deze worden namelijk (volgens de naming conventions) met een hoofdletter geschreven. Elke "proffesionele" klasse die je tegenkomt begint ook met een hoofdletter, let er maar op. Verder beginnen variabelen met kleine letter en functies (en methodes) ook. Constanten worden met enkel hoofdletters geschreven.
@bovenste post van stijn1989:
Citaat: Ja , het ziet er bijna hetzelfde uit. Het kan gebruikt worden als "template" die interface
Hieruit kan ik enkel afleiden dat je het niet hebt begrepen.
Het "template method pattern" heeft als eigenschap dat het met een abstracte klasse werkt. Hierin beschrijf je de werking (het algoritme). Dit is van toepassing op alle instanties (en childklassen) van deze abstracte klasse. Als je geen algoritme beschrijft heeft het niets meer met het "template method pattern" te maken maar maak je gebruik van predefinition en het eisen van sommige methodes.
Hier zit nog een groot verschil in. |
|
|
|
Gepost op: 24 april 2006 - 21:19 |
|
|
|
PHP expert
|
bedankt koen
van de __destruct was het een vertaalfoutje. Ik las het op PHP.net over de laatste 2 functies.
Ik moet toegeven dat dit artikel me wel een serieus start gegeven heeft om verder te gaan in oo-programming
klein vraagje: is een interface dan ook een algoritme , ik weet wel dat je er de functies kan defineren en dan in de child classes ze gaan uitwerken.
stijn
ps: bedankt voor je informatie omtrent naamconventies |
|
|
|
Gepost op: 24 april 2006 - 22:52 |
|
|
|
PHP expert
|
Een algoritme is een structuur die gevolgd wordt waarvan de afloop van een bewerking afhaald.
Het algoritme van + is dat de waarde wordt opgeteld. Een klasse (of interface) heeft geen algoritme, een methode daarentegen kan aan de hand van argumenten een variabele waarde terugsturen. Dit gebeurd aan de hand van een algoritme. |
|
|
|
Gepost op: 02 mei 2006 - 16:04 |
|
|
|
Onbekend
|
Het heeft toch geen zin om bij singleton de php4 constructor te blokkeren als je toch al private gebruikt? |
|
|
|
Gepost op: 02 mei 2006 - 17:42 |
|
|
|
PHP expert
|
Dat is een feit. Maar het is om aan te tonen dat je kan kiezen. Als je in php5 programmeert maar nog altijd via de 'normale' constructor methode werkt (dus de klassenaam) dan kan je deze private maken. Werk je met de __construct-methode dan maak je deze private. Je kan dus kiezen welke van de twee, maar wees wel consequent en ga niet in de ene klasse met __construct werken en in de andere met 'klassenaam-constructor'. |
|
|
|
Gepost op: 02 juni 2006 - 23:05 |
|
|
|
PHP expert
|
zou je misschien een paar oefeningen bij de recursieve hoofdstukje kunnen zetten
ik wil het graag onder de knie hebben |
|
|
|
Gepost op: 04 juli 2006 - 14:12 |
|
|
|
PHP expert
|
Ben door de uitleen battle weer eens deftig begonnen met OOP (damn you examens). Nu bij die fluent interfaces vroeg ik me af of dit ook kon voor static classes. Ik zit dus vast met me php5 server en kan het dus niet testen (voorlopig) maar volgens mij is het juist als ik de theorie volg van jou Koen.
Dit heb ik geschreven: http://www.pastebin.be/1071/
[edit]
blijkbaar klopt dit niet want self is geen object , terwijl $this wel is |
|
|
|
Gepost op: 18 juli 2006 - 11:59 |
|
|
|
PHP expert
|
OO voor PHP5: typehinting
typehinting is zéér handing als je veel werkt met classes en ze samen wilt laten werken. Ik heb een kort voorbeeldje geschreven:
http://www.pastebin.be/1369/
Class Test2 heeft een functie show met parameter Test $do.
Wat betekend dit nu?
Dat is zeer makkelijk te vertellen. $do kan nu iedere functie/variable van de class Test oproepen. In de functie show zie je dat hij de functie boe en de variable $var oproept van de class Test.
Als waarde voor de parameter Test $do moet je het object meegeven van de class Test (logisch allemaal). Dat zie je ook bij me voorbeeld.
Wat heeft dit nu voor nut?
Stel je hebt een mysql class en een login class. In de login class wil je misschien zien of de gebruiker wel in de database staat. In plaatst van mysql_query(); etc te doen kan je je functies gebruiken van je mysql class met behulp van typehinting
Vragen kan je altijd pm'n of op het fora zetten.
groet, stijn
[edit]
Met typehinting kan je geen static functies/variablen oproepen. |
|
|
|
Gepost op: 24 januari 2009 - 00:34 |
|
|
|
PHP gevorderde
|
Een leuke aanvulling zou de factory pattern zijn (naast de singleton pattern). Je kunt op php site de nodige documentatie vinden.
Deze patternen zijn volop in gebruik in ZF dus ik vind ze zeker nuttig. |
|
|
Enkel aanvullende informatie is welkom. Geen prijzende of afkeurende reacties. |
|
|
|