[PHP] Class herdefinieren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
Ik zou graag het volgende willen doen:
1) Definieren Class X
2) Wat code
3) Een method aan Class X toevoegen
4) Wat code

Hierbij is het van groot belang dat deze class dezelfde naam houdt. Extenden werkt dus niet (Extenden naar dezelfde naam kan niet - Cannot redeclare class). Het gaat expliciet om een class, niet om een object. De aggregation functionaliteit heb ik niets aan.

Iemand enig idee hoe ik dit aan moet pakken?

Voorbeeld 'code':
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Class A
{   var $text = 'foo';
    function A()
    {   echo $this->text;
    }
}

// print foo
new A();

Class A extends A
{   var $text = 'bar';
}

// print bar
new A();

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Je bedoelt dat je binnen dezelfde instantie twee classes wil kunnen aanroepen die dezelfde naam moeten hebben?

Sundown Circus


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
Neen :).

Ik werk hier helemaal niet in een instantie (ik neem aan dat je instantie van een klasse i.e. een object bedoelt).

Gewoon in het hoofdscript wil ik twee keer een nieuw object maken van een klasse met dezelfde naam waarbij de inhoud van die klasse tussen die twee momenten verandert. Precies zoals in het voorbeeld dus.

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

Verwijderd

in je voorbeeld zou je het met een constructor doen om de $var te zeten...
ik snap niet helemaal waarom je een klasse exact hetzelfde zou willen noemen met een compleet andere inhoud?
wat wil je precies bereiken en waarom?

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:26
Waarom moet die class dezelfde naam hebben?

Kan je niet werken dmv encapsulation? Je houdt in je class een variabele bij, waaraan je later een ander object kunt aan hangen, dat van een bepaald type is:

pseudo code
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class InfoClass
{
}

public class BlaatInfoClass extends InfoClass
{
}

public class MelpInfoClass extends InfoClass
{
}

public class MyClassA
{
    public  InfoClass anInfoClass;
}

//----
MyClassA  woei = new MyClassA;
woei.anInfoClass = new BlaatInfoClass();

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Burat schreef op 10 december 2003 @ 12:14:
Neen :).

Ik werk hier helemaal niet in een instantie (ik neem aan dat je instantie van een klasse i.e. een object bedoelt).

Gewoon in het hoofdscript wil ik twee keer een nieuw object maken van een klasse met dezelfde naam waarbij de inhoud van die klasse tussen die twee momenten verandert. Precies zoals in het voorbeeld dus.
Als je '..waarbij de inhoud van die klasse tussen die twee momenten verandert..' zou kunnen definieren... :)

Sundown Circus


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
Oke, ik zal het even wat verduidelijken :).

Wij werken hier met een framework waar modules ingehangen worden. Voor de database connectie is er een Query Class die bij elke query gecreeerd wordt:
PHP:
1
$q = new Query("SELECT foo FROM bar");

Nu wil ik in een nieuwe module de queries onderscheppen en na een check op de normale manier uitvoeren. Nu kan ik natuurlijk de class Query iets aanpassen zodat dit wordt gedaan. Maar die class laat ik het liefst ongewijzigd.

Daarom wil ik die module - onafhankelijk van het framework - de class Query laten aanpassen zodat transparant voor andere modules deze module iets met een query kan doen.

Dit is het mooist omdat deze module in lang niet alle implementaties aanwezig zal zijn, zodat de Query Class niet vervuild is met module afhankelijke zooi.

Resumerend:
-> Ik heb een class Query in m'n framework
-> Ik heb een module die ik de class Query wil laten veranderen - transparant voor andere modules en zonder het framework aan te passen.
RedRose schreef op 10 december 2003 @ 13:35:
Als je '..waarbij de inhoud van die klasse tussen die twee momenten verandert..' zou kunnen definieren... :)
Dit is dan het volgende: De orignele Query class voert gewoon de query uit, de aangepaste Query class doet eerst een check op de parameter van de constructor (bijv: strlen() > 100 -> maar dan nuttiger ;)).

[ Voor 18% gewijzigd door Burat op 10-12-2003 13:41 ]

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Burat schreef op 10 december 2003 @ 13:39:
Dit is dan het volgende: De orignele Query class voert gewoon de query uit, de aangepaste Query class doet eerst een check op de parameter van de constructor (bijv: strlen() > 100 -> maar dan nuttiger ;)).
Ik zie hier niet in waarin de klasse opeens van gedrag gaat veranderen? Je lijkt niet één deel van de tijd orgQuery te willen gebruiken en een ander deel van de tijd (in dezelfde runtime) newQuery te gebruiken, maar gewoon te willen switchen per runtime.

Dan zou ik ervoor kiezen om Query een proxy voor newQuery/orgQuery te laten zijn en deze te laten switchen met een aanroep. Bijvoorbeeld:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Query {

   var $m_query;
   function Query( $p_queryStr ) {

      $m_query = new OldQuery( $p_queryStr );
   }

    function setCheckMode( $p_check ) {

        if( $p_check ) 
           $m_query = new CheckedQuery( $m_query->getQueryString() );
        else
           $m_query = new OldQuery( $m_query->getQueryString() );
      }
Affijn, kan effectiever, maar het is maar een voorbeeld.

Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Ok, misschien denk ik nou te simpel, maar waarom zou je die check niet doen voordat je de query doorstuurt naar de query-class, dus in de module zelf? Je zegt het zelf al, per module zijn er andere checks, dus dan zou het mij logisch lijken de check in de erbij behorende class te plaatsen? :)

Sundown Circus


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:26
Glimi schreef op 10 december 2003 @ 13:49:
[...]

Dan zou ik ervoor kiezen om Query een proxy voor newQuery/orgQuery te laten zijn en deze te laten switchen met een aanroep. Bijvoorbeeld:
Bedoel je hier niet een strategy?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

Dit kan wel, maar ik geloof dat het probleem was, dat de TS dan alle reeds bestaande modules moet aanpassen op een nieuwe query-class (o.a. check-mode toevoegen) en dat was geloof ik niet de bedoeling. :)

Sundown Circus


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Burat schreef op 10 december 2003 @ 13:39:
Oke, ik zal het even wat verduidelijken :).

Wij werken hier met een framework waar modules ingehangen worden. Voor de database connectie is er een Query Class die bij elke query gecreeerd wordt:
PHP:
1
$q = new Query("SELECT foo FROM bar");

Nu wil ik in een nieuwe module de queries onderscheppen en na een check op de normale manier uitvoeren. Nu kan ik natuurlijk de class Query iets aanpassen zodat dit wordt gedaan. Maar die class laat ik het liefst ongewijzigd.

Daarom wil ik die module - onafhankelijk van het framework - de class Query laten aanpassen zodat transparant voor andere modules deze module iets met een query kan doen.

Dit is het mooist omdat deze module in lang niet alle implementaties aanwezig zal zijn, zodat de Query Class niet vervuild is met module afhankelijke zooi.

Resumerend:
-> Ik heb een class Query in m'n framework
-> Ik heb een module die ik de class Query wil laten veranderen - transparant voor andere modules en zonder het framework aan te passen.
De logische OO oplossing hiervoor is gewoon een subclass maken van Query, bijvoorbeeld een CheckedQuery, en dan maak je in je nieuwe module gebruik van die CheckedQuery ipv de gewone Query. En de methode waarin je de check wilt doen die definieer je dan in CheckedQuery, waarin je de check doet en zo nodig roep je de methode van Query aan als de check ok is

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

kun je er niet een classe bij schrijven Validate() ofzo?
en als je query validated is hem doorsturen naar het Query() object?
lijkt me een veel makkelijkere implementatie?

Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
Glimi schreef op 10 december 2003 @ 13:49:
[...]

Ik zie hier niet in waarin de klasse opeens van gedrag gaat veranderen? Je lijkt niet één deel van de tijd orgQuery te willen gebruiken en een ander deel van de tijd (in dezelfde runtime) newQuery te gebruiken, maar gewoon te willen switchen per runtime.
Bij het initialiseren van het framework wordt van elke module een bepaald script uitgevoerd. In een van deze files wil ik de Query Class aanpassen zodat na het initialiseren van het framework door alle modules - zonder deze aan te passen - newQuery gebruikt wordt. Maar dit alleen als de nieuwe module (die de Query class aanpast) geinstalleerd is. Dat is dus niet bij alle implementaties het geval!

Ik kan inderdaad de originele Query class aanpassen en daar een check doen: als module x geinstlleerd is, doe dan y. Maar dat wil ik niet om module afhankelijke code in de algemene Query class te voorkomen.

Wie volgt mij nog? :P

De methode van who_ami (encapsulation) zou ik kunnen gebruiken. Mijn originele Query class noem ik anders. Die extend ik in Query en voeg er niets aan toe. Die kan ik dan in m'n module overschrijven met een niet-lege extensie.

Maar dan moet ik alsnog m'n framework aanpassen...

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 21:26
.oisyn schreef op 10 december 2003 @ 14:02:
[...]


De logische OO oplossing hiervoor is gewoon een subclass maken van Query, bijvoorbeeld een CheckedQuery, en dan maak je in je nieuwe module gebruik van die CheckedQuery ipv de gewone Query. En de methode waarin je de check wilt doen die definieer je dan in CheckedQuery, waarin je de check doet en zo nodig roep je de methode van Query aan als de check ok is
Daar dacht ik ook aan, echter Burat wil niets aan de bestaande class aanpassen, en dat zal hij toch moeten doen als hij voor die oplossing kiest; hij zal nl. hoogstwaarschijnlijk een aantal methods als virtual moeten gaan definieren.

In de rest van z'n framework zal hij idd niets moeten gaan aanpassen, aangezien (als PHP virtual methods kent tenminste), iedere keer de goeie implementatie zal gaan aanroepen van die method.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
.oisyn schreef op 10 december 2003 @ 14:02:
[...]


De logische OO oplossing hiervoor is gewoon een subclass maken van Query, bijvoorbeeld een CheckedQuery, en dan maak je in je nieuwe module gebruik van die CheckedQuery ipv de gewone Query. En de methode waarin je de check wilt doen die definieer je dan in CheckedQuery, waarin je de check doet en zo nodig roep je de methode van Query aan als de check ok is
Idd, dat ligt voor de hand. Maar niet alleen die nieuwe module moet CheckedQuery gebruiken - alle andere niet aangepaste modules ook!

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Burat schreef op 10 december 2003 @ 14:05:
De methode van who_ami (encapsulation) zou ik kunnen gebruiken. Mijn originele Query class noem ik anders. Die extend ik in Query en voeg er niets aan toe. Die kan ik dan in m'n module overschrijven met een niet-lege extensie.

Maar dan moet ik alsnog m'n framework aanpassen...
Whoami zegt volgens mij hetzelfde als ik doe :+ Maar als je de Query niet wilt aanpassen en je framework niet wilt aanpassen en niet de check in de module te doen (door daar een CheckedQuery obj aan te maken) dan lukt het je niet, want dan wijzig je nergens iets ;)
whoami schreef op 10 december 2003 @ 14:06:
In de rest van z'n framework zal hij idd niets moeten gaan aanpassen, aangezien (als PHP virtual methods kent tenminste), iedere keer de goeie implementatie zal gaan aanroepen van die method.
Volgens mij was PHP loosely typed en gaat het niet zo goed werken met je interfaces en virtual declaraties ;)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Burat schreef op 10 december 2003 @ 14:08:
[...]


Idd, dat ligt voor de hand. Maar niet alleen die nieuwe module moet CheckedQuery gebruiken - alle andere niet aangepaste modules ook!
ok, dat was idd wat ik begreep uit je eerste post, maar later zei je
Daarom wil ik die module - onafhankelijk van het framework - de class Query laten aanpassen zodat transparant voor andere modules deze module iets met een query kan doen.
en dat je de Query class het liefst ongewijzigd liet. Waarom laat je 'm het liefst ongewijzigd als alle modules gebruik moeten gaan maken van de nieuwe code?

[ Voor 24% gewijzigd door .oisyn op 10-12-2003 14:13 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ok, even samenvatten om te kijken of ik je goed begrijp hoor :)

Je hebt een Query class, en een bepaalde module X. Als module X niet geladen is, dan hoeft er geen check uitgevoerd te worden in de query. Maar zodra module X wel geladen is, dan moet er een check gebeuren

Maw, module X moet het gedrag van je Query class wijzigen, snap ik het zo goed? :)

Dan zou ik iets doen met het factory pattern, voor zover dat mogelijk is in PHP :) Je hebt een standaard factory (een functie of class dat een Query object aanmaakt) die je kunt wijzigen. Je module X implementeert een andere factory en zet die als default, zodat als er een Query object wordt aangemaakt een functie of methode in de factory van module X wordt aangeroepen, zodat hij bijvoorbeeld een CheckedQuery kan teruggeven zonder dat de rest daar ergen in heeft

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • RedRose
  • Registratie: Juni 2001
  • Niet online

RedRose

Icebear

.oisyn schreef op 10 december 2003 @ 14:16:
Dan zou ik iets doen met het factory pattern, voor zover dat mogelijk is in PHP :) Je hebt een standaard factory (een functie of class dat een Query object aanmaakt) die je kunt wijzigen. Je module X implementeert een andere factory en zet die als default, zodat als er een Query object wordt aangemaakt een functie of methode in de factory van module X wordt aangeroepen, zodat hij bijvoorbeeld een CheckedQuery kan teruggeven zonder dat de rest daar ergen in heeft
Ik zat inderdaad net dit topic te zoeken over factorying in PHP/ :)

Sundown Circus


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

edit:
darn, gmta 8)7


Wat je ook nog kan doen is een query factory bouwen. Dan hoef je enkel de factory aan te passen als je van een andere klasse gebruik wilt maken. Er zitten alleen 2 nadelen aan:
[list=1]• Je zult eenmalig alle code aan moeten passen om gebruik te maken van die factory.
• Het is dan of een Query, of een checkedquery, of je moet nog een parameter aan de factory mee kunnen geven wat voor query je wilt. Dat laatste lijkt me niet wenselijk

Het voordeel is echter dat als je globaal wilt switchen tussen Query of CheckedQuery je alleen de factory aan hoeft te passen. Je zou dat dan ook op basis van een constante in de aanroepende scripts kunnen doen.

Voorbeeldje:
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
define ( 'USE_CHECKED_QUERIES',   1 );

class QueryFactory {
   function QueryFactory () {
      trigger_error ( "Cannot instantiate factory class" );
      // bij wijze van "netjes"
   }
   
   function createInstance ( $param ) {
      $className = QueryFactory::getQueryClassName ();
      return new $className ( $param );
   }

   function getQueryClassName () {
      if ( USE_CHECKED_QUERIES ) {
          return 'CheckedQuery';
      } else {
          return 'Query';
      }
   }
}

class Query {
   function Query ( $queryString ) {

   }
}

class CheckedQuery extends Query {
   function CheckedQuery ( $queryString ) {
      Query::Query ( $queryString ); // call parent constructor
   }  
}
// - - - - - - - - - - - - 

$query = QueryFactory::createInstance ( "SELECT sjaak FROM piet" );
echo get_class ( $query );


Je kunt hier natuurlijk 1000 verschillende variaties op bedenken; het feit dat je op basis van strings gewoon klassen kunt creeeren maakt het allemaal heel soepel.

hth :)

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
.oisyn schreef op 10 december 2003 @ 14:11:
en dat je de Query class het liefst ongewijzigd liet. Waarom laat je 'm het liefst ongewijzigd als alle modules gebruik moeten gaan maken van de nieuwe code?
Omdat ze alleen gebruik moeten maken van de nieuwe code als die specifieke module geinstalleerd is. Als dat niet het geval is, dan gewoon de normale/oude code gebruiken. En het is niet zo dat vanaf nu altijd die module geinstalleerd zal zijn - soms wel soms niet :).
.oisyn schreef op 10 december 2003 @ 14:16:
Ok, even samenvatten om te kijken of ik je goed begrijp hoor :)

Je hebt een Query class, en een bepaalde module X. Als module X niet geladen is, dan hoeft er geen check uitgevoerd te worden in de query. Maar zodra module X wel geladen is, dan moet er een check gebeuren

Maw, module X moet het gedrag van je Query class wijzigen, snap ik het zo goed? :)
Geheel correct!
Dan zou ik iets doen met het factory pattern, voor zover dat mogelijk is in PHP :) Je hebt een standaard factory (een functie of class dat een Query object aanmaakt) die je kunt wijzigen. Je module X implementeert een andere factory en zet die als default, zodat als er een Query object wordt aangemaakt een functie of methode in de factory van module X wordt aangeroepen, zodat hij bijvoorbeeld een CheckedQuery kan teruggeven zonder dat de rest daar ergen in heeft
*pakt OOM boek erbij*

Dit kan inderdaad. Maar dan moet ik alsnog het framework aanpassen :P. Dat is op zich niet erg als het op deze manier gaat omdat het Query object zelf geen module afhankelijke code bevat.

Maar wat ik mij afvroeg - of je on-the-run een class kan aanpassen - is intussen beantwoord. PHP staat niet toe dat een klasse definitie wordt aangepast.

We gaan dus even factorizen!

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • Burat
  • Registratie: Oktober 1999
  • Niet online

Burat

bos wortels

Topicstarter
drm schreef op 10 december 2003 @ 14:30:
Wat je ook nog kan doen is een query factory bouwen. Dan hoef je enkel de factory aan te passen als je van een andere klasse gebruik wilt maken. Er zitten alleen 2 nadelen aan:
[list=1]• Je zult eenmalig alle code aan moeten passen om gebruik te maken van die factory.
En het is natuurlijk ontzettend onprettig om in alle implementaties in alle modules
PHP:
1
$q = new Query($str);

te vervangen door
PHP:
1
$q = Query::getInstance($str);

Daarom heb ik iets gemaakt wat aleen in PHP kan en zowel erg grappig als ranzig is :).
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
// De normale/oude query class
Class stdQuery
{   function stdQuery($str)
    { ...
    }
}

// De bijzondere query class die het een ander doet voor bepaalde queries
Class logQuery extends stdQuery
{   function logQuery($str)
    {   ...
        stdQuery::stdQuery($str);
    }
}

// Even laten weten dat het geinstalleerd is
define("MOD_LOGENTITY", true);

// De *uche* 'factory' class :)
class Query
{   function Query($str)
    {   if(defined('MOD_LOGENTITY') && MOD_LOGENTITY)
        {   $this = new logQuery($str);
        }
        else
        {   $this = new stdQuery($str);
        }
    }
}


Als de constante 'MOD_LOGENTITY' niet defined is, bijvoorbeeld als de module niet geinstalleerd is, dan geeft $q = new Query een object terug van het type stdQuery. Als de constante wel defined is, geeft dat een object terug van het type logQuery.

Ik zal zo ff kijken of het in PHP 5 nog werkt :).

Homepage | Me @ T.net | Having fun @ Procurios | Collega's gezocht: Webontwikkelaar PHP


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

:X :X :X

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz

Pagina: 1