Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] class definieren met een $var

Pagina: 1
Acties:

Onderwerpen


  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 09:11
Ik ben bezig om mijn zelfgebouwde CMS iets anders aan te gaan pakken. Ik wil graag de class bestanden die ik heb en dus aanroep gaan voorzien van een dynamische opbouw. Voorbeeldje:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?
error_reporting(E_ALL);
$class_name = "table";

class $class_name
{
    function __construct()
    {
        $this->test = array(1,2,3);
    }
}

$class = "help";
$$class = new $class_name();
print_r($help); 
?>


Dit werkt alleen niet. Door het gebruik van $class_name in de class definitie gaat ie stuk. Kan dit wat ik wil en zo ja, hoe moet ik dit dan doen? Ik kan de $class_name gewoon vervangen door het woord "table" en dan werkt het, maar ik wil graag dat het op die manier gedaan kan worden.

  • phex
  • Registratie: Oktober 2002
  • Laatst online: 15-11 16:07
Stel dat dit zou kunnen. Wat is het nut er van? wil je niet gewoon een instantie?

Door de naam variabel te maken maak je de code niet variabel, je geeft het enkel een variabele klasse naam.


Bedoel je niet gewoon dit?

PHP:
1
2
3
4
5
class VariableName {
}

$test =  new VariableName();
$help = new VariableName();



als je echt andere namen wil, zonder daadwerkelijk de functionaliteit wil wijzigen, zou je de klasse kunnen extenden.

Maar ik snap serieus niet waarom je dit ooit zou willen, tenzij je echt geen flauw idee hebt wat je aan het doen bent.

[ Voor 4% gewijzigd door phex op 13-09-2011 11:47 ]


  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 09:11
phex schreef op dinsdag 13 september 2011 @ 11:46:
Stel dat dit zou kunnen. Wat is het nut er van? wil je niet gewoon een instantie?

Door de naam variabel te maken maak je de code niet variabel, je geeft het enkel een variabele klasse naam.

class VariableName {
}

$test = new VariableName();
$help = new VariableName();


als je echt andere namen wil, zonder daadwerkelijk de functionaliteit wil wijzigen, zou je de klasse kunnen extenden.

Maar ik snap serieus niet waarom je dit ooit zou willen, tenzij je echt geen flauw idee hebt wat je aan het doen bent.
In mijn CMS maak ik gebruik van modules. Het komt wel eens voor dat ik een module als voorbeeld gebruik voor een andere module die dus net iets afwijkt. Het probleem is deels ontstaan uit ja, luiheid of frustratie. Bij het copy pasten van de class bestanden moet je alles weer openen en aan gaan passen om de juiste namen erin te zetten. Ik had daarom bedacht dat dit versimpelt kon worden door gebruik te maken van bijvoorbeeld de mapnaam van de module. Deze laat je dan overeenkomen met een gedeelte van de naam van de fysieke tabel in de database. Op die manier kan je dus op basis van de naam van de map een hele module de grond uit trekken die van andere gegevens uitgaat zonder een letter code te wijzigen.

Dus ik weet wel wat ik aan het doen ben, maak je geen zorgen. Ik vraag me gewoon af of dit kan of niet.

  • Cartman!
  • Registratie: April 2000
  • Niet online
Vrijwel altijd als je constructies nodig hebt met variabele variabelen dan ben je gewoon verkeerd bezig. Volgens mij is dit prima op te lossen door een gewone abstracte klasse waarin je in de construct je opties meegeeft.

  • phex
  • Registratie: Oktober 2002
  • Laatst online: 15-11 16:07
Eh, nee je weet niet wat je aan het doen bent. Als je een klasse wilt hebben die net iets afwijkt dan moet je extenden. Dan ga je geen bestanden kopieeren en bestandsnamen/functienamen aanpassen.

Dus:

PHP:
1
2
class BasisModule {}
class ExtensionModule extends BasisModule {}


Bovendien als je je applicatie "modulair" maakt door bestanden te kopieeren dan raad ik je aan een goed boek over objectgeorienteerd programmeren te lezen. Want wat jij nu probeer te doen zal je later een hoop irritaties geven. Maar ik zal je proberen uit te leggen waarom:

Zoals je zelf al zei zijn de classes bijna hetzelfde. Als je een bug tegen komt in class a, en class b is een letterlijke kopie, dan mag je 2 bestanden gaan fixen. Als je module a, b, c, d, e etc hebt wordt het feest alleen maar groter, net als de kans op fouten.

Je denkt dit te kunnen oplossen door variable classnames te gebruiken, maar hierdoor ontneem je jezelf de mogelijk om afwijkende classes te defineren. Alle afwijkende klasses zijn namelijk gewoon een alias van de originele klasse.
Op die manier kan je dus op basis van de naam van de map een hele module de grond uit trekken die van andere gegevens uitgaat zonder een letter code te wijzigen.
Lees je eigen uitspraak eens na, en bedenk of "class $class_name" het probleem oplost.

[ Voor 65% gewijzigd door phex op 13-09-2011 12:06 ]


  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 09:11
Sowieso extend ik al. Ik heb een default class waarin de meest voorkomende functies zitten. Dus alle classes extende die class al. De functies die specifiek zijn voor die class worden binnen die class zelf gemaakt. Dat kunnen er veel of weinig zijn, afhankelijk van de ingewikkeldheid of het gebruik van de class.

Afwijkende classes kan altijd nog prima. Ik zeg namelijk niet dat ik nog maar 1 class.php ga maken die ik keer op keer blijf includen met een andere var. Helemaal niet. De bedoeling is om gewoon per module een class.php te hebben die als naam een $var heeft. Dit zodat ik dus bij het hergebruiken van een class voor een iets andere toepassing ik niet die class bestanden inhoef om namen te wijzigen.

Ik zal wat meer uitleggen. De database heeft per module een rechten tabel en een content tabel. In de rechten tabel wordt per groep (regel) per actie (kolom) bijgehouden wat wel en niet mag. Verder is er een overkoepelende rechten tabel waar per groep (regel) per module (kolom) aangegeven wordt wat wel en niet zichtbaar mag zijn.

Zo is er bijvoorbeeld een rechten_pagina tabel met acties wijzig, nieuw, verwijder etc.
En er is een content_pagina tabel waarin de html_titel zit, tekst, titel aangemaakt door etc etc.

Per module kom je dus ff heel globaal gezien op 2 class bestanden een rechten.php en een content.php.
Wanneer het dus mogelijk is om te zeggen class $class { construct... } in bijvoorbeeld rechten.php dan hoef ik bij het hergebruiken van die module dus niet weer rechten.php aan te passen wanneer dit bijvoorbeeld helemaal niet nodig is. Over het algemeen zijn alle rechten_classes gelijk en extenden allemaal de table_class.

Misschien iets duidelijker nu.

Maar nogmaals ik wil gewoon weten of dit kan en als dit kan hoe ik dit kan doen. Ik zal daarna zelf wel gaan bepalen of ik het op die manier wil gebruiken of niet.

  • Cartman!
  • Registratie: April 2000
  • Niet online
orange.x schreef op dinsdag 13 september 2011 @ 13:05:
Ik zal daarna zelf wel gaan bepalen of ik het op die manier wil gebruiken of niet.
Ik zal eerlijk zijn, ik heb je lap tekst niet gelezen. Je manier is gewoon niet de way to go, simpel. Als je een module maakt hoort daarbij het defineren van namen gewoon bij, ik zie het probleem niet...

  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 09:11
Cartman! schreef op dinsdag 13 september 2011 @ 13:08:
[...]

Ik zal eerlijk zijn, ik heb je lap tekst niet gelezen. Je manier is gewoon niet de way to go, simpel. Als je een module maakt hoort daarbij het defineren van namen gewoon bij, ik zie het probleem niet...
Nou bedankt voor je nuttige toevoeging dan he. Volgens mij werkt het niet zo moeilijk.

Ik stel een vraag. Dan kan je een antwoord geven met daarbij waarom het wel of niet handig is. Maar om dan bij voorbaat iets af te keuren omdat het niet in jouw denkwijze past... Dat is niet een antwoord dat ik zoek.

  • Cartman!
  • Registratie: April 2000
  • Niet online
Je komt met een idee wat gewoon totaal niet handig is en daar geef ik mijn mening op met onderbouwing (een van de 1e posts). Als jij dan oogkleppen op wilt zetten: be my guest. Als je het zo goed weet, waarom kom je hier dan bij ons om advies vragen? :)

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 26-11 11:39

Janoz

Moderator Devschuur®

!litemod

Ik snap niet hoe je erbij komt dat je in je class allemaal namen aan moet passen. Ik heb sterk het idee dat je een beetje het verschil tussen een class en een instantie van die class mist en dat je functionaliteit uit naamgeving afleid die je eigenlijk middels properties zou moeten doen.

Ook in je tweede uitgebreide post zie ik geen enkele reden waarom je een variabele class nodig hebt. Wat ik wel zie is een mogelijke onhandigheid in je database. Misschien is het niet zo handig om rechten op een actie telkens als een kolom toe te voegen.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • mOrPhie
  • Registratie: September 2000
  • Laatst online: 21-11 07:55

mOrPhie

❤️❤️❤️❤️🤍

Hoewel het varren van je classes totale waanzin is imho, is dit wellicht wat je zoekt voor het instantieren van gevarde classes: http://php.net/manual/en/book.reflection.php

Verder: Je verhaal is wat onduidelijk (waarom zou je functionaliteit willen kopieren in een nieuwe class en dan alleen de naam willen wijzigen???), maar van wat ik uit je verhaal kan halen is het wellicht een idee om naar het decorator pattern te kijken die bedoeld is om functionaliteit als (herbruikbare) legoblokjes op elkaar te kunnen leggen. :)

Een experimentele community-site: https://technobabblenerdtalk.nl/. DM voor invite code.


  • Voutloos
  • Registratie: Januari 2002
  • Niet online
orange.x schreef op dinsdag 13 september 2011 @ 13:05:
Per module kom je dus ff heel globaal gezien op 2 class bestanden een rechten.php en een content.php.
Als het dezelfde classes zijn, heb je geen aparte classes nodig maar instances.

$fooRights = new Rights(...parameters...);
$barRights = new Rights(...parameters...);

Done.

(los van of je aparte instances moet hebben per module, je hebt in ieder geval niet per se aparte classes nodig)

{signature}


  • phex
  • Registratie: Oktober 2002
  • Laatst online: 15-11 16:07
offtopic:
Over een kolom per access right, lijkt mij geen gigantisch probleem. Je zou een many to many koppeling kunnen maken tussen regel, recht en user, maar afhankelijk van of de rechten flexibel zijn lijkt het mij niet per definitie nodig.


Maar dus al ik goed begrijp heb je een model class en een rechten class per model en die extenden een basis class/abstract.

PHP:
1
2
3
4
5
class ModuleTable extends Table {
}

class ModuleRights extends Rights {
}


en nu moet Module variabel worden?

PHP:
1
2
3
4
5
6
7
$module = 'Test';

$moduleClass = $module . 'Table';
$rightsClass = $module . 'Rights';

$module = new $moduleClass();
$rights = new $rightsClass();


Dat gaat wel werken.

Waar ik mij wel zorgen over maak is het feit dat je al heel ver zit in moeilijke constructies om iets, wat gewoon basis OO is, te doen. Namelijk een klasse extenden en daar een instantie van maken eventueel met parameters om de flexibiliteit te krijgen die je zoekt.

[ Voor 26% gewijzigd door phex op 13-09-2011 13:48 ]


  • WouZz
  • Registratie: Mei 2000
  • Niet online

WouZz

Elvis is alive!

phex schreef op dinsdag 13 september 2011 @ 13:45:
[...]

en nu moet Module variabel worden?

PHP:
1
2
3
4
5
6
7
$module = 'Test';

$moduleClass = $module . 'Table';
$rightsClass = $module . 'Rights';

$module = new $moduleClass();
$rights = new $rightsClass();
Tip: geef je de module mee aan de constructor: (zie Voutloos)
PHP:
1
2
3
4
$module = 'Test';

$table = new Table($module);
$rights = new Rights($module);

Nog beter, maak van module ook een class / object:
PHP:
1
2
class TestModule extends Module {}
$module = new TestModule();


Daarna kan je ook nog gaan nadenken over hoe je die classes eigenlijk aan elkaar wil associëren. Welkom in de wondere wereld van OOD.

On track


  • phex
  • Registratie: Oktober 2002
  • Laatst online: 15-11 16:07
Mja je eerste voorbeeld is hoe het zou moeten, alleen ik hoopte dat hij dat zelf door zou gaan krijgen.

Jouw 2e voorbeeld is juist hoe hij het nu heeft, alleen hij heeft geen flauw idee hoe hij deze moet benaderen omdat hij zijn classnames dynamisch opbouwt.

Ik vind je laatste opmerking een beetje flauw. de OT heeft duidelijk aangegeven dat je je geen zorgen moet maken, hij weet precies wat hij aan het doen is.

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
phex schreef op dinsdag 13 september 2011 @ 14:58:
Ik vind je laatste opmerking een beetje flauw. de OT heeft duidelijk aangegeven dat je je geen zorgen moet maken, hij weet precies wat hij aan het doen is.
Het zegt van wel, maar de code zegt duidelijk van niet. En dat is vooral opbouwend bedoeld; Iedereen probeert hier juist advies te geven over een betere manier om het op te lossen.

Opbouwend commentaar is nooit flauw. Misschien is de 'welkom' een tikkie bijdehand, maar blaas dat vooral niet op. :)

{signature}


  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 09:11
Over die rechten class hebben jullie een punt. Daar kan ik idd beter een standaard class voor gaan maken en die als meerdere instanties aanroepen.

Maar dan nog heb ik voor de modules een bepaalde wijze van opbouwen van code in mijn hoofd die het makkelijk zou maken als het kon. Blijkbaar kan het niet, dus heeft het weinig zin om daar nog verder over te praten. Maar voor mij was het wel handig geweest.

Het zal denk ik te maken hebben met mijn, foute, benadering van classes en objecten. Ik weet in zoverre dat het "fout" is maar het werkt en het werkt voor mij het meest logisch. Ik zie een class, of een instantie van de class als een portal tussen de code en de database.

Normaal zeg je
PHP:
1
$pagina = new pagina($id);


Wat ik doe is als volgt
PHP:
1
2
$pagina_class = new pagina();
$pagina = $pagina_class->get_by_id($id);


Dit is omslachtiger omdat het niet hoeft, maar wat ik het voordeel vind is dat ik voor mijn gevoel praat tegen de tabel zelf. $pagina_class = de tabel. Zo kan ik dus zeggen $paginas = $pagina_class->get_by_categorie($categorie_id); Nogmaals, ik weet dus dat dit niet helemaal de bedoeling is, maar dit werkt voor mij het beste. Een class is in mijn gebruik dus eigenlijk een dood iets, althans de 1e instantie (bijv $pagina_class), het is gewoon een doorgeefluik. Het voordeel daarvan vind ik dat ik niet na hoef te denken hoe mijn classes heten... ik hoef daarna nooit meer te zeggen $bla = new iets(); ik weet namelijk dat die $pagina_class altijd bestaat en ik die dus overal in de code kan zeggen $paginas = $pagina_class->iets();

Maar dat verklaart nog niet helemaal de reden waarom ik die class dynamisch wil maken, maar dat doet er verder ook niet zozeer toe, omdat het namelijk niet kan.

[ Voor 8% gewijzigd door orange.x op 13-09-2011 15:33 ]


  • phex
  • Registratie: Oktober 2002
  • Laatst online: 15-11 16:07
ok i'll bite.

Neem voorjezelf de volgende terminology even door

OOP Wikipedia: Object-oriented programming
Inheritance Wikipedia: Inheritance (object-oriented programming)
Objects Wikipedia: Object (computer science)
MVC Wikipedia: Model–view–controller
ORM Wikipedia: Object-relational mapping
DAO Wikipedia: Active record pattern


Wat je eigenlijk wil: Models van je database (ORM/DAO).

Alleen je gebruikt classes alsof het variabelen zijn. Classes zijn juist niet variabel. Classes zijn een verzameling eigenschappen en methodes die een specifiek deel van je software voor hun rekening nemen.

Classes maak je "variabel" door er een instantie van te maken.

Anyway doe ons en jezelf een groot plezier en koop een goed boek. Deze materie ga je niet snappen door simpelweg wat willekeurige code aan elkaar te plakken en hopen dat het doet wat je wilt.

Als je dit advies negeert en gewoon stug doorgaat dan blijf je jezelf voor de gek houden. Dan ga je afschuwelijke code produceren waar niemand iets mee kan behalve jij.

Nu lijkt dat misschien niet erg omdat het voor jezelf is, maar je zult nooit iemand om hulp kunnen vragen omdat niemand jouw interpretatie van jouw code snapt.

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
orange.x schreef op dinsdag 13 september 2011 @ 15:22:
Dit is omslachtiger omdat het niet hoeft, maar wat ik het voordeel vind is dat ik voor mijn gevoel praat tegen de tabel zelf. $pagina_class = de tabel. Zo kan ik dus zeggen $paginas = $pagina_class->get_by_categorie($categorie_id);
Je wil eigenlijk iets van een PaginaRepository hebben dus ;)
Maar dat verklaart nog niet helemaal de reden waarom ik die class dynamisch wil maken, maar dat doet er verder ook niet zozeer toe, omdat het namelijk niet kan.
Eigenlijk is dat juist wel van belang. De kans is groot dat je met een idee in je hoofd zit dat op een andere manier slimmer opgelost kan worden. Run-time code genereren is eigenlijk bijna nooit een goed idee.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • Cartman!
  • Registratie: April 2000
  • Niet online
Misschien is het nog iets te hoog gegrepen maar kijk eens naar Doctrine 2: http://www.doctrine-project.org/docs/orm/2.0/en/index.html

Die werkt (zoals Woy al aangeeft) met repositories die je tabel voorstellen en die returnt objecten die je records voorstellen.

  • Ventieldopje
  • Registratie: December 2005
  • Laatst online: 26-11 20:53

Ventieldopje

I'm not your pal, mate!

Het opzetten is misschien even doorbijten in het begin maar daarna werkt het echt subliem en zal je een hoop tijd schelen, het heeft immers geen zin om het wiel opnieuw uit te vinden.

Zeker in combinatie met de commandline tool van Doctrine heb je zo een complexe database opgezet, enige wat je hoeft te doen eigenlijk is de mapping schrijven (bijv. in XML) en de commandline tool de entities, proxies en database laten genereren!

www.maartendeboer.net
1D X | 5Ds | Zeiss Milvus 25, 50, 85 f/1.4 | Zeiss Otus 55 f/1.4 | Canon 200 f/1.8 | Canon 200 f/2 | Canon 300 f/2.8


  • orange.x
  • Registratie: Maart 2002
  • Laatst online: 09:11
Ik heb de tip van Doctrine eerder vandaag gekregen en ga daar vanavond of deze week even naar kijken. Uiteraard heeft het weinig zin om het wiel opnieuw uit te vinden.

@Woy:
Ik zal vanavond nog ff een uitgebreide uitleg van mijn hersenspinsel geven en wat meer info geven over hoe mijn CMS opgebouwd is. Wellicht dat het dan duidelijker wordt.
Pagina: 1