Toon posts:

PHP - Dynamische klasse

Pagina: 1
Acties:

Vraag


  • fjskmdl2
  • Registratie: Februari 2011
  • Laatst online: 05-06 21:15
Wij gebruiken op het werk een eigen CMS in php geschreven, waarbij de tabellen een bepaalde namingconvention aanhouden.

Nu heb ik vroeger reeds met laravel gewerkt, en zie dat daar data kan opgehaald worden uit de database op de volgende manier:
PHP:
1
Users::where('name', 'jan')


Nu vroeg ik mij af hoe laravel dit juist voor elkaar krijgt..
Er bestaat namelijk geen mapping van de mogelijke tabellen volgens mij.

Momenteel heb ik een class DBO met enkele statische functies.
Hierbij wil ik dat wanneer je bvb Users::where() oproept, de statische functie DBO::where() opgeroepen wordt EN in DBO::where moet ik dus ook weten dat de zoekterm in de tabel users moet uitgevoerd worden.

Mijn probleem is echter:
Hoe zorg ik er voor dat die Users::where de DBO::where oproept? Ik kan namelijk geen mapping bijhouden.

Wat ik al geprobeerd heb:
Ik heb al wat zitten zoeken ivm de opties van spl_autoload_register
Hierbij kwam ik tot het onderstaande resultaat
PHP:
1
2
3
4
5
6
7
8
9
10
11
class DBO {
public static function where($fieldname, $fieldval) {
  $table_code = get_called_class(); //dit geeft echter altijd DBO terug , en niet de class alias name
  echo $table_code.'.'.$fieldname.' = '.$pk_value;
}

spl_autoload_register(function($name) {
if (!class_exists($name)) {
class_alias('dbo', $name);
}
}


Bovenstaande heeft echter altijd DBO terug via get_called_class() (en niet Users in dit geval)

Als tweede optie dacht ik om een factory class te maken, maar aangezien de meeste functies statisch zullen zijn, zal dit dus niet werken...

Kan iemand mij in de juiste richting wijzen waarop ik verder kan om dit voor elkaar te krijgen?

Alle reacties


  • Feanathiel
  • Registratie: Juni 2007
  • Niet online

Feanathiel

Cup<Coffee>

Dat kan met "static::class", welke te vinden is via Eloquent op GitHub (de library die data access regelt):

PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php

class Base {
    public static function where() {
         $class = static::class;
    }
}

class Foo extends Base {}

Foo::where();

  • Donool
  • Registratie: April 2010
  • Laatst online: 18:37
Het Laravel stuk (versimpeld) uitgelegd:
In Laravel zijn de tabel namen aanwezig in je eigen model (Dit model extend Eloquent\Model).
Je kan dan in je eigen model
code:
1
protected $table = 'JE_TABEL_NAAM'
doen OF de tabellen naamgeven volgens de Laravel conventie, dan werkt dit magisch.

Zie hier voor de conventie: https://laravel.com/docs/...loquent-model-conventions en https://github.com/larave...se/Eloquent/Model.php#L44

Op deze manier weet je
code:
1
::where
dus welke tabel hij nodig heeft.

Daarnaast maakt (o.a.) de Query Builder gebruik van magic methods als __call en __callStatic. Hiermee kan dan gekeken worden of je bijvoorbeeld een where query doet, "magisch" (dus $model->property) een property wil hebben etc.
Een (wat ouder Laravel 5.1 voorbeeld): https://github.com/larave.../Eloquent/Model.php#L3436 voor de query builder en https://github.com/larave.../Eloquent/Model.php#L3337 voor het dynamisch aanroepen van properties.

  • fjskmdl2
  • Registratie: Februari 2011
  • Laatst online: 05-06 21:15
Bedankt voor het antwoord, maar ben er eerlijk gezegd niet veel wijzer uit geworden.

De code hieronder geeft een werkend voorbeeld van hetgene ik wil, MET UITZONDERING VAN het feit dat ik voor iedere mogelijke tabel uit de database een class zou moeten definieren die extends van de class DBO.

Ik wil dat dit at runtime gebeurt, wanneer ik bvb Users::find(), Posts::find() uitvoer.

(Ik wil namelijk niet voor elke simpele query een model class moeten definiëren, een gewone findbyid zou moeten kunnen door een static method op te roepen.

Volgende 5 regeltjes zouden dus dynamisch moeten gebeuren.

PHP:
1
2
3
4
5
class Posts extends DBO {
}

class Posts extends DBO {
}



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
class DBO2 {
    protected $table_code;

    public function __construct($table_code) {
        $this->table_code = strtolower($table_code);
    }

    public function find($field_value) {
        echo $this->table_code.'.'.self::getPrimaryKey().' = '.$field_value;
    }

    private function getPrimaryKey() {
        return $this->table_code.'_id';
    }

}

class DBO {
    private $db;
    protected static $table_code;

    public static function getTableCode() {
       return get_class(new static());
    }

    public static function find($pk_value) {
        $table_code = self::getTableCode();
        $dbo = new DBO2($table_code);
        $dbo->find($pk_value);
    }
}

class User extends DBO {
}

User::find('testen');


Tweakers maakt gebruik van cookies

Tweakers plaatst functionele en analytische cookies voor het functioneren van de website en het verbeteren van de website-ervaring. Deze cookies zijn noodzakelijk. Om op Tweakers relevantere advertenties te tonen en om ingesloten content van derden te tonen (bijvoorbeeld video's), vragen we je toestemming. Via ingesloten content kunnen derde partijen diensten leveren en verbeteren, bezoekersstatistieken bijhouden, gepersonaliseerde content tonen, gerichte advertenties tonen en gebruikersprofielen opbouwen. Hiervoor worden apparaatgegevens, IP-adres, geolocatie en surfgedrag vastgelegd.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Toestemming beheren

Hieronder kun je per doeleinde of partij toestemming geven of intrekken. Meer informatie vind je in ons cookiebeleid.

Functioneel en analytisch

Deze cookies zijn noodzakelijk voor het functioneren van de website en het verbeteren van de website-ervaring. Klik op het informatie-icoon voor meer informatie. Meer details

janee

    Relevantere advertenties

    Dit beperkt het aantal keer dat dezelfde advertentie getoond wordt (frequency capping) en maakt het mogelijk om binnen Tweakers contextuele advertenties te tonen op basis van pagina's die je hebt bezocht. Meer details

    Tweakers genereert een willekeurige unieke code als identifier. Deze data wordt niet gedeeld met adverteerders of andere derde partijen en je kunt niet buiten Tweakers gevolgd worden. Indien je bent ingelogd, wordt deze identifier gekoppeld aan je account. Indien je niet bent ingelogd, wordt deze identifier gekoppeld aan je sessie die maximaal 4 maanden actief blijft. Je kunt deze toestemming te allen tijde intrekken.

    Ingesloten content van derden

    Deze cookies kunnen door derde partijen geplaatst worden via ingesloten content. Klik op het informatie-icoon voor meer informatie over de verwerkingsdoeleinden. Meer details

    janee