[php] Queries opslaan in de database

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • RobzQ
  • Registratie: Februari 2000
  • Laatst online: 21-12-2020

RobzQ

greedy as a pig

Topicstarter
In mijn huidige PHP script staan de SQL query's 'gewoon' in de PHP code. Ik wil het script vereenvoudigen en één van de ideeën die ik hiervoor heb ik het opslaan van een query in de database.

De huidige query in PHP ziet er zo uit:

PHP:
1
2
3
$query = "SELECT * FROM items WHERE id = $id";
$result = mysql_query ( $query );
$return = mysql_fetch_object($result);


In PHP werkt dit.

Echter, als ik de tekst van de query (SELECT * FROM items WHERE id = $id) in een tekstveld in de database opsla. Deze ophaal, in een string zet en die weer wil uitvoeren middels mysql_query dan gaat het mis.

De gehele code posten is een beetje lastig omdat ik gebruik maak van objecten. Maar in het kort komt het hier op neer:

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
class ItemType 
{
    private $queryget;

    function get_queryget() {
        return $this->queryget;
    }
    
    function db_getItemTypeById($id) {
        $query = "SELECT * FROM itemtype WHERE ID = $id";
        $result = mysql_query ( $query );
        $row = MySQL_fetch_array ( $result );
        $this->queryget = $row ["queryget"];
    }
}

$item_type = new ItemType ();
$item_type -> db_getItemTypeById(1);

$id = 1;
$query = $itemtype -> get_queryget();

$result = mysql_query ( $query );
$return = mysql_fetch_object($result);


Dit werkt niet als ik een variabele in de query (die in de db staat) gebruik: SELECT * FROM items WHERE id = $id

Maar zonder variabele werkt het prima: SELECT * FROM items WHERE id = 1

Ik denk dat er iets mis gaat omdat PHP de opgehaalde string niet meer 'parsed' dus $id wordt nooit vervangen door 1.

Nu heb ik hier twee vragen:

1) Kan ik er voor zorgen dat dit wel werkt?

Ik zat er zelf al aan te denken om de string die ik ophaal uit de database weer te parsen en dan zelfs $id te vervangen door de waarde waar ik op wil zoeken (in dit voorbeeld 1). Maar dat levert al snel veel code op en ik had juist gehoopt dit te voorkomen. Is er een snelle methode of wellicht een commando dat ik volledig over het hoofd zie?

2) Is het verstandig om queries op te slaan in de database?

En ja, ik weet dat bovenstaande code lelijk is, en je moet oppassen met variabelen in queries maar dit is even een proof of concept.

..so be wary of any man who keeps a pig farm..


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
RobzQ schreef op woensdag 20 april 2011 @ 21:23:
1) Kan ik er voor zorgen dat dit wel werkt?

Ik zat er zelf al aan te denken om de string die ik ophaal uit de database weer te parsen en dan zelfs $id te vervangen door de waarde waar ik op wil zoeken (in dit voorbeeld 1). Maar dat levert al snel veel code op en ik had juist gehoopt dit te voorkomen. Is er een snelle methode of wellicht een commando dat ik volledig over het hoofd zie?
Je moet de string evalueren en als php code laten uitvoeren. In andere woorden, eval(). Maar denk vooral aan de leus "eval is evil", waar ook genoeg over te vinden is.
2) Is het verstandig om queries op te slaan in de database?
Wil je echt versimpelingen in je code bouwen, is dit niet bepaald de beste methode. Er zijn zat andere zaken waar je zaken gemakkelijker kan scheiden. Veel wordt OOP gebruikt om gestructureerd te werken, hoewel dit niet per se nodig is. Wat je echter wel aan mogelijkheden hebt om een en ander te verhelderen zijn de volgende zaken:
  1. ORM: Je modelleert je entiteiten die je met eenvoudige (bijvoorbeeld) find(), fetch(), save() en delete() methodes kan bewerken
  2. MVC: Het scheiden van taken/verantwoordelijkheden in drie verschillende lagen
  3. Nog heel veel meer (ik bedenk me nu dat ik namelijk nog wel even door kan gaan).
Conclusie: ga dit niet doen maar maak gebruik van bestaande methodieken om je code te structureren. Je script "eenvoudiger" maken moet geen doel op zich zijn! Wat denk je wat de kosten zijn (in responsietijden) van deze methode? Weegt dat op tegen het "eenvoudiger" zijn van je scripts (die ook slechter te begrijpen zijn voor derden).

[ Voor 5% gewijzigd door mithras op 20-04-2011 21:45 ]


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:05

MueR

Admin Tweakers Discord

is niet lief

Welk voordeel denk je te gaan halen met het opslaan van queries in je database? Waarom zou je voor elke query niet 1 maar 2 trips naar je database willen maken, plus een hoop extra processing? Je kan ook gewoon direct een lengte touw pakken en jezelf daarmee opknopen.

Als je dit al gaat doen moet je in ieder geval niet met eval werken, maar met een vorm van prepared statements. String replaces op je zojuist uit je database gehaalde query om daar de juiste argumenten in te gooien. Maar vertel eerst eens wat je nou denkt te winnen?

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • kluyze
  • Registratie: Augustus 2004
  • Niet online
Wil je niet gewoon een stored procedure? Dan staat je query eigenlijk in de db alleen kan de db daar nog een aantal optimalisaties op doen.

Het nut van een query in de db zie ik ook niet onmiddellijk. Dan zou ik eerder ergens een aparte configfile maken waar de queries in staan die via prepared statements uitgevoerd kunnen worden.

Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Je kan ook gewoon direct een lengte touw pakken en jezelf daarmee opknopen.
8)7

Dit wil je absoluut niet. Wat is de achterliggende gedachte? Want dit maakt het niet makkelijker.

Stel je queries staan in de database daarin staan dus variablen als $id en $name of whatever. Omdat je de query niet in je code hebt staan wordt het alleen maar lastiger als developer omdat je zowel in de database als in de code moet zoeken naar de variablen die je nodig hebt.

[ Voor 11% gewijzigd door ReenL op 20-04-2011 22:25 . Reden: Het is laat :S ]


Acties:
  • 0 Henk 'm!

  • RobzQ
  • Registratie: Februari 2000
  • Laatst online: 21-12-2020

RobzQ

greedy as a pig

Topicstarter
Het voordeel dat ik er mee denk te behalen is de volgende:

De database (en script) is in de loop van de tijd gegroeid en verre van consequent.

Bijvoorbeeld: In de ene tabel heb ik de titel van een item "title" genoemd, in een andere tabel "naam", in weer een andere tabel "titel" enz.

Nu ben ik bezig om de oude code om te zetten naar OOP. En ik wil liever niet voor iedere tabel een nieuw object maken. Dus ik dacht dit op te lossen door een functie te maken die uit alle tabellen de benodigde data kan trekken. Het resultaat in 1 gestandaardiseerd object zet zodat ik die verder in de code kan gebruiken.

Stel ik noem deze functie getItem met als argumenten een id en een type. getItem($id, $itemtype).

Daar was ik mee bezig maar kwam er al snel achter dat ik dan binnen dat object een hele lijst met verschillende query's krijg (voor iedere tabel een eigen set, insert, update, select enz..).

Dus.. het leek me wel slim een tabel te maken met itemtypes met daarin een beschrijving van de verschillende itemtypes + een beschrijving van de query's die nodig zijn om de data op te halen, toe te voegen etc..

idnameaddquerygetqueryupdatequery
1NieuwsINSERT INTO blaSELECT naam as title, enz FROM blaenz..
2LinkINSERT INTO toetSELECT titel as title, enz FROM toetenz..


Dan hoef ik alleen nog het item ID en type te weten en kan ik vanaf daar alle data ophalen. Deze in een object zetten en verder gebruiken.

Een soort van data abstractie laag dus. Komt er ooit nog een itemtype bij, dan is het een kwestie van de tabel aanmaken in MySql en de tabel ItemTypes uitbreiden met een nieuwe set query's voor de nieuwe tabel.

Leek mij heel handig en snel. En eigenlijk werkt het prima. Behalve dan het gebruik van variabelen in de query.

[ Voor 0% gewijzigd door RobzQ op 20-04-2011 22:28 . Reden: Typo ]

..so be wary of any man who keeps a pig farm..


Acties:
  • 0 Henk 'm!

  • Precision
  • Registratie: November 2006
  • Laatst online: 12-08 21:08
Nieuws en link zijn verschillende entiteiten, maak telkens een andere model (MVC).
Edot: Als je toch bezig bent met het herschrijven (OOP), kijk dan eens naar MVC of zelfs naar een framework, combineer het eventueel met ORM.

[ Voor 47% gewijzigd door Precision op 20-04-2011 22:37 ]

Crisis? Koop slim op Dagoffer - Op zoek naar een tof cadeau?


Acties:
  • 0 Henk 'm!

  • ReenL
  • Registratie: Augustus 2010
  • Laatst online: 14-09-2022
Je zoekt dus een ORM

Kan toch veel makkelijker:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$table = new UserTable();
$table->insert($user);
$table->find($id);
$table->update($id, $user);

class UserTable extends DbTable {
    protected $_table = 'user';
    protected $_primary = 'id';
}

// Gebruik primary en table in deze functies data uit het object halen kan met toArray
class DbTable {
    public function find($id);
    public function insert(Persistable $object);
    public function update($id, Persistable $object);
}

abstract class Persistable {
    public function toArray();
}

class User extends Persistable {
    public function toArray(); // Implement toArray here
}


Ik zeg niet dat bovenstaand de oplossing is, maar wel dat er oplossingen zijn zonder query's in de db op te slaan.

Zie ook doctrine-project.org, propal en zend_db.

[ Voor 25% gewijzigd door ReenL op 20-04-2011 22:37 ]


Acties:
  • 0 Henk 'm!

  • RobzQ
  • Registratie: Februari 2000
  • Laatst online: 21-12-2020

RobzQ

greedy as a pig

Topicstarter
Dank voor jullie antwoorden zover. Ik heb weer meer informatie om op verder te zoeken. En de gegeven hints lijken me in de goede richting te wijzen.

Voor je het weet ben je zelf iets aan het bedenken wat er al lang is :-)

..so be wary of any man who keeps a pig farm..


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 13:38
Als je al je queries in een database zou zetten. Hoe moet je dan aan je query komen om je queries uit die database te krijgen? Lijkt me best wel een dilemma.

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • TJHeuvel
  • Registratie: Mei 2008
  • Niet online
RobzQ schreef op woensdag 20 april 2011 @ 23:21:
Voor je het weet ben je zelf iets aan het bedenken wat er al lang is :-)
Kijk ook even naar het onlangs aan MySQL toegevoegde Stored Procedures, volgens mij is dit namelijk precies wat je zoekt. In principe staan de queries gewoon opgeslagen op de server als functies, en je applicatie roept deze aan met de juiste parameters.

Freelance Unity3D developer


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:05

MueR

Admin Tweakers Discord

is niet lief

Ook stored procedures zijn niet de oplossing voor z'n probleem. Zijn probleem is een inconsequent database ontwerp. Dan kan je een hoop moeilijke omwegen gaan bedenken om het in de code allemaal uniform te krijgen, je kan ook je database ontwerp opnieuw doen. TS is toch bezig z'n code te herschrijven. Dat je daarna nog eens kijkt naar de noodzaak van stored procedures of iets dergelijks kan, maar om vanwege inconsequent gebruik van naming conventions nu naar SP te grijpen ?

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • RobzQ
  • Registratie: Februari 2000
  • Laatst online: 21-12-2020

RobzQ

greedy as a pig

Topicstarter
MueR schreef op donderdag 21 april 2011 @ 09:51:
Ook stored procedures zijn niet de oplossing voor z'n probleem. Zijn probleem is een inconsequent database ontwerp. Dan kan je een hoop moeilijke omwegen gaan bedenken om het in de code allemaal uniform te krijgen, je kan ook je database ontwerp opnieuw doen. TS is toch bezig z'n code te herschrijven. Dat je daarna nog eens kijkt naar de noodzaak van stored procedures of iets dergelijks kan, maar om vanwege inconsequent gebruik van naming conventions nu naar SP te grijpen ?
Even de database opnieuw ontwerpen is makkelijker gezegd dan gedaan. Niet omdat ik geen db kan ontwerpen maar vooral omdat het een lopende site betreft met meer dan tien jaar aan opgeslagen informatie.

Maar je hebt in de basis zich wel gelijk. Als het db design consequent was geweest dan had ik nu minder problemen gehad.

Ik ga de db denk ik niet helemaal opnieuw ontwerpen (de structuur is in principe prima) maar wel tabel voor tabel aanpassen (vooral de veldnamen gelijk trekken). Als dat lukt dan ben ik ineens van veel problemen af denk ik.

..so be wary of any man who keeps a pig farm..


Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 13:38
Door enkel namen te veranderen ga je geen architectuur problemen oplossen.

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.


Acties:
  • 0 Henk 'm!

  • RobzQ
  • Registratie: Februari 2000
  • Laatst online: 21-12-2020

RobzQ

greedy as a pig

Topicstarter
Freeaqingme schreef op donderdag 21 april 2011 @ 22:53:
Door enkel namen te veranderen ga je geen architectuur problemen oplossen.
Klopt. Maar het lost voor nu wel even mijn probleem op.

Ik ben de architectuur al op meerdere, andere, fronten aan het aanpakken zoals het omzetten van oude (pre OOP) code naar objecten, scheiding van data- logica en presentatie en centralisatie van form handling. En dat is voor nu wel even genoeg op de persoonlijke todo lijst ;)

..so be wary of any man who keeps a pig farm..


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

RobzQ schreef op donderdag 21 april 2011 @ 23:48:
[...]

Klopt. Maar het lost voor nu wel even mijn probleem op.
Ja, en voor later veroorzaakt het nog meer problemen. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

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

drm

f0pc0dert

Op zich ben je goed bezig met het feit dat je dingen wilt hiden waar de applicatie geen weet van hoeft te hebben. Laat je niet ontmoedigen door negatieve reacties, want je gedachtengang is goed, alleen wil je het principe met de verkeerde tools implementeren. Probeer alleen wel om het principe los van de tools te zien. Je hebt het feitelijk over een designkwestie die niet op moet willen lossen met tools maar die je op zou moeten lossen met refactoring en een hernieuwde architectuur. Je zou dus eigenlijk vooral moeten kijken naar wat de ideale situatie is, los van de eventuele implementatie. M.a.w. zou je het anders doen als je het met andere software zou moeten implementeren, zo ja waarom dan, zo nee waarom dan niet.

Kortom, neem even afstand van de zaak en kijk ernaar zonder de keuze voor PHP / MySQL een rol te laten spelen. Denk na over architectuur in plaats van tools.

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


Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 21-09 14:28
RobzQ schreef op donderdag 21 april 2011 @ 22:37:
[...]

Even de database opnieuw ontwerpen is makkelijker gezegd dan gedaan. Niet omdat ik geen db kan ontwerpen maar vooral omdat het een lopende site betreft met meer dan tien jaar aan opgeslagen informatie.

Maar je hebt in de basis zich wel gelijk. Als het db design consequent was geweest dan had ik nu minder problemen gehad.

Ik ga de db denk ik niet helemaal opnieuw ontwerpen (de structuur is in principe prima) maar wel tabel voor tabel aanpassen (vooral de veldnamen gelijk trekken). Als dat lukt dan ben ik ineens van veel problemen af denk ik.
Als je een complete rebuild aan het doen bent kan je in je project een deel maken wat de conversie doet vanaf live platform naar het nieuwe platform. Als je dat in scripts doet kan je die procedure compleet doortesten tijdens je test releases waardoor het weinig issues oplevert.

Als je de boel gaat ombouwen, je dus niet overnieuw begint, zou je een aantal test procedures op je models kunnen zetten om te testen welke data ze nu terug geven. Vervolgens maak je de test zo dat alles gelijk is, dus overal title of name, en dan ga je de models aanpassen. Vervolgens pak je de rest zoals de views en doe je daar weer hetzelfde.

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:05

MueR

Admin Tweakers Discord

is niet lief

RobzQ schreef op donderdag 21 april 2011 @ 22:37:
Even de database opnieuw ontwerpen is makkelijker gezegd dan gedaan. Niet omdat ik geen db kan ontwerpen maar vooral omdat het een lopende site betreft met meer dan tien jaar aan opgeslagen informatie.
Batched import scripts zijn heel geduldig hoor, die kunnen dat prima omzetten. Tenzij je een site hebt met ongeveer een tiende aan content volumes van Tweakers, moet dat best gaan.
Ik ga de db denk ik niet helemaal opnieuw ontwerpen (de structuur is in principe prima) maar wel tabel voor tabel aanpassen (vooral de veldnamen gelijk trekken). Als dat lukt dan ben ik ineens van veel problemen af denk ik.
Nou, waarschijnlijk niet. Inconsequentie in tabelnamen en kolomnamen is hooguit ronduit irritant bij het ontwikkelen, verder niets. Maar het is natuurlijk je eigen keuze, jij hebt het meeste kijk op je eigen database.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

Als de DB genormaliseerd wordt, kun je er nooit fouten in krijgen en heb je ook een database die op de best mogelijke wijze voor je presteert.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

CptChaos schreef op vrijdag 22 april 2011 @ 09:55:
Als de DB genormaliseerd wordt, kun je er nooit fouten in krijgen en heb je ook een database die op de best mogelijke wijze voor je presteert.
Je eerste bewering is ronduit onjuist want je kan nog steeds foute data erin stoppen en de manier waarop je query's werken kunnen ook veel stuk maken. Het tweede is semi-waar maar verdient de nuance dat je soms juist moet denormaliseren voor betere prestaties. ;) Onder "normaliseren" verstaan we gebruikelijk de derde normaalvorm, maar soms is het nodig om door te gaan tot de vijfde. ;)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • CH4OS
  • Registratie: April 2002
  • Niet online

CH4OS

It's a kind of magic

NMe schreef op vrijdag 22 april 2011 @ 12:41:
Je eerste bewering is ronduit onjuist want je kan nog steeds foute data erin stoppen en de manier waarop je query's werken kunnen ook veel stuk maken.
Klopt, maar dan ligt de fout bij de invoer en niet de database zélf.
Pagina: 1