[php]Array misbruik in php

Pagina: 1
Acties:
  • 318 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44

Dit topic is afgesplitst van [alg] Slechtste programmeervoorbeelden deel 2.
Janoz schreef op donderdag 14 juni 2007 @ 13:51:
Feit blijft dat Arrays grootschalig worden misbruikt in php (om eens even over iets heel anders te beginnnen)
Ehm, leg eens uit. Hoe kan je in PHP een Array misbruiken? Het werkt toch? :+ Liever arrays dan zoiets:
PHP:
1
$${'variabele'.$i} = 481

En arrays zijn prima databases, zoals elke php-progger weet:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$rs = $database->execute($query);
$items = array();
while($rs && !$rs->EOF)
{
  $items[] = array (
    'naam' => $rs->fields('firstname').' '.$rs->fields('surname'),
    'geboortedatum' => $rs->fields('birthdate')
    //normaal iets ingewikkeldere preprocessing
  );
}

foreach($items as $item)
{
  //weergave o.i.d.
}


O-)

En objecten zijn ook arrays, bovenaan var $ding declareren is nergens voor nodig :+

[ Voor 11% gewijzigd door Janoz op 15-06-2007 09:37 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

In je eigen topic bericht laat je een goed voorbeeld zien van het gebruik van objecten waarbij door php-ers vaak een array gebruikt wordt.

Ik heb het ook specifiek over het misbruiken inderdaad. Denk bijvoorbeeld aan mensen die complete boomstructuren in 1 multidimensionale array op willen slaan.

Een array is een lijst van dingen. Een php-array kun je daarnaast ook nog als map (of dictionary) gebruiken.

Wat je echter veel ziet in php is dat mensen een array gebruiken op een plek waar een struct handiger zou zijn. Nu weet ik wel dat php geen struct heeft, maar een object zonder methodes is natuurlijk niet veel anders dan een struct.

[ Voor 37% gewijzigd door Janoz op 14-06-2007 14:55 ]

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Janoz schreef op donderdag 14 juni 2007 @ 14:38:
In je eigen topic laat je een goed voorbeeld zien van het gebruik van objecten waarbij door php-ers vaak een array gebruikt wordt.
Ehm, welk eigen topic?
Ik heb het ook specifiek over het misbruiken inderdaad. Denk bijvoorbeeld aan mensen die complete boomstructuren in 1 multidimensionale array op willen slaan.

Een array is een lijst van dingen. Een php-array kun je daarnaast ook nog als map (of dictionary) gebruiken.

Wat je echter veel ziet in php is dat mensen een array gebruiken op een plek waar een struct handiger zou zijn. Nu weet ik wel dat php geen struct heeft, maar een object zonder methodes is natuurlijk niet veel anders dan een struct.
Tja, een complete boomstructuur in een array gebruik ik dagelijks. Op mijn werk worden de templates zo gevuld, en daar kan 'lekker veel' recursie in zitten. En een object zonder methodes is niks anders dan een array (behalve dan de syntax). Maar goed, als ik het goed begrijp noem je dit misbruik:
PHP:
1
2
3
4
5
6
7
8
9
10
//g_a = global array
//l_a = local array
//l_o = local object
//l_s = local string

foreach ($g_aLangeArray as $l_aItem)
{
  $l_aPerson = $g_aLdapData[$l_aItem['iId']]['aPerson'];
  $l_stName = $l_aPerson['stName'];
}

uit mijn duim gezogen, maar had live-code van mijn werk kunnen zijn

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

En een object zonder methodes is niks anders dan een array (behalve dan de syntax).
En dat is precies wat ik nu bedoel met array misbruik ;). Er is wel degelijk een verschil tussen een struct en een map.

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Janoz schreef op donderdag 14 juni 2007 @ 15:00:
[...]

En dat is precies wat ik nu bedoel met array misbruik ;). Er is wel degelijk een verschil tussen een struct en een map.
Leg eens uit, ik volg je wat dat betreft niet meer. Ik wil iets waar ik 5 waarden met een naampje kan opslaan. Ik kan 2 dingen doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if ($user == 'Janoz')
{
  $object = new stdObject(); //zoiets was er, weet niet meer hoe die klasse heet
  $object->name = 'mbv';
  $object->pwd = '******';
  $object->birthdate = '28-02-1984';
  $object->nogiets = true;
  echo 'martin heet '.$object->name.', andere gegevens:'.printr($object,true);
}
else {
  $array = array(
    'name' => 'mbv',
    'pwd' => '******',
    'birthdate' => '28-02-1984',
    'nogiets' => true
  );
  echo 'martin heet'.$array['name'].', andere gegevens:'.printr($array,true);
}

Het werkt precies hetzelfde, en geeft dezelfde output vziw. Die 2e scheelt een heleboel keren $object-> schrijven, wat met een eigen klasse met een constructor natuurlijk verholpen is.
In C++/Java/... zou je nog het voordeel hebben dat je een beperkt aantal mogelijkheden hebt om achter $object->... te zetten, in PHP kan je er alles neerzetten wat je wilt.

Spot de fout:
PHP:
1
2
3
4
5
class test {
  var $ietsMetEenLangeNaam;
}
$var = new test();
$var->IetsMetEenLangeNaam = 'vervelend';

Volgens mij was daar wel wat aan te doen in PHP5, maargoed.
offtopic:
welk topic van mij bedoelde je?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Waarom $user="janoz"? Waarom moet $user een string zijn? Dat zou ik alvast een object maken. Daarnaast is een object een veel duidelijker atomair deel. Zorg dan wel dat je niet een stdObject neemt, maar daadwerkelijk een user object definieerd. Als het enige argument is dat $object-> veel tikwerk is dan is het misschien een idee om eens te kijken naar een recursieve functie die een boom doorwandeld. Wanneer je de varnaam niet object zou noemen, maar duidelijk user, dan maakt dat je code juist een stuk leesbaarder. Verder kunnen code completion tools je makkelijk laten zien welke properties een object heeft. Kijk eens hoe deze eruit ziet wanneer je met array in array in array werkt, en wanneer je met een gewoon objectje gebruikt.

Die fout die je daar hebt staan heb je ook met arrays (of is de key case insensitive).

Tot slot. Ik bedoelde geen topic, maar bericht, Ik had het eerder al aangepast.

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Janoz schreef op donderdag 14 juni 2007 @ 16:47:
Waarom $user="janoz"? Waarom moet $user een string zijn? Dat zou ik alvast een object maken. Daarnaast is een object een veel duidelijker atomair deel. Zorg dan wel dat je niet een stdObject neemt, maar daadwerkelijk een user object definieerd. Als het enige argument is dat $object-> veel tikwerk is dan is het misschien een idee om eens te kijken naar een recursieve functie die een boom doorwandeld. Wanneer je de varnaam niet object zou noemen, maar duidelijk user, dan maakt dat je code juist een stuk leesbaarder. Verder kunnen code completion tools je makkelijk laten zien welke properties een object heeft. Kijk eens hoe deze eruit ziet wanneer je met array in array in array werkt, en wanneer je met een gewoon objectje gebruikt.
$user='janoz' was om de 2 verschillende methodes te laten zien in 1 code-blok. Verder neem je dit simpele voorbeeldje imho veel te serieus. Dit zou onderdeel kunnen zijn van een bestand waar gegevens uit de database worden gehaald, verwerkt, en in een template worden gegooid. Dingen als users komen te vaak voor, en bestaan dus ook objecten voor. Eigenlijk zou deze constructie alleen nuttig moeten zijn voor een query met een join:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$sql = '
  SELECT ...
  FROM users u
  LEFT JOIN orders o
    ON u.id = o.userid';
$rs = $db->execute($sql);

$results = array('users' => array(), 'orders' => array());
while ($rs && !$rs->EOF)
{
  if(isset($results['users'][$rs->fields('id')]))
  {
    $current =& $results['users'][$rs->fields('id')];
    $current->addOrder(...);
  }
  else {
    $current = new User(...);
    $current->addOrder(...);
    $results['users'][$rs->fields('id')] =& $current;
  }
  $orders[] = new Order(...);
}

Als je nu 5 dingen tegelijk uit de database haalt, i.v.m. performance, dan is zo'n ad-hoc array toch veel minder werk dan een object bouwen?

Los daarvan ben ik vaak ook wel een beetje lui. Ipv 'new Order' of 'new User' is het toch vrij vaak 'array(...)', gewoon omdat het alleen maar gegevens zijn. En het volgende puntje is vaak niet eens van toepassing, omdat ik veel met VIM werk :Y)

Over code completion in pak-em-beet eclipse/PDT kan ik maar 1 ding zeggen: het werkt heel vaak niet. PHP heeft daarvoor te zwakke typering. Eclipse heeft dus 9 van de 10 keer geen idee wat voor object het is. Zodra iets uit een session komt, of uit een array, of weet ik veel, dan weet hij niet meer wat het is. En heel vaak is dat toch echt nodig, zoals in bovenstaand voorbeeldje. Het moet ergens die array in, toch? Of heb je een betere suggestie?
Die fout die je daar hebt staan heb je ook met arrays (of is de key case insensitive).
Die fout zou met een array ook prima kunnen, maar dat zou nou juist een van de belangrijke argumenten kunnen zijn om objecten te gebruiken: dat php een notice/warning/error zou geven als je een typo maakt. Doet PHP dus niet.
Tot slot. Ik bedoelde geen topic, maar bericht, Ik had het eerder al aangepast.
ah, ok. Ik zat al te zoeken naar mijn topicstarts 8)7
edit:

@hieronder: Mooi, dan ga ik mijn eigen webserver binnenkort overzetten naar PHP5 :)

Acties:
  • 0 Henk 'm!

  • daniëlpunt
  • Registratie: Maart 2004
  • Niet online

daniëlpunt

monkey's gone to heaven

MBV schreef op donderdag 14 juni 2007 @ 15:25:
Spot de fout:
PHP:
1
2
3
4
5
class test {
  var $ietsMetEenLangeNaam;
}
$var = new test();
$var->IetsMetEenLangeNaam = 'vervelend';

Volgens mij was daar wel wat aan te doen in PHP5, maargoed.
PHP:
1
2
3
4
5
6
class Test {
   private $ietsMetEenLangeNaam;
}

$var = new Test();
$var->IetsMetEenLangeNaam = 'vervelend';

Geeft een Fatal error:
Fatal error: Cannot access private property Test::$IetsMetEenLangeNaam in /Users/danielpunt/Documents/Creaties/PHP/test.php on line 7

[ Voor 4% gewijzigd door daniëlpunt op 14-06-2007 18:53 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

MBV schreef op donderdag 14 juni 2007 @ 17:35:
Als je nu 5 dingen tegelijk uit de database haalt, i.v.m. performance, dan is zo'n ad-hoc array toch veel minder werk dan een object bouwen?
Als het echt adhoc gegevens zijn vraag ik me af waarom ze uberhaupt bij elkaar horen. In alle andere gevallen zou ik aannemen dat het gewoon gegevens uit je domein zijn en verwacht ik dat je daar al een class voor geschreven hebt. Ik denk echter dat de sterk request georienteerde ontwikkeling die veel php-ers aanhouden er voor zorgt dat er erg weinig generiek en request brede ontwikkeling gedaan wordt waardoor die domein classe waarschijnlijk niet gemaakt zijn.
Los daarvan ben ik vaak ook wel een beetje lui. Ipv 'new Order' of 'new User' is het toch vrij vaak 'array(...)', gewoon omdat het alleen maar gegevens zijn. En het volgende puntje is vaak niet eens van toepassing, omdat ik veel met VIM werk :Y)


Over code completion in pak-em-beet eclipse/PDT kan ik maar 1 ding zeggen: het werkt heel vaak niet. PHP heeft daarvoor te zwakke typering. Eclipse heeft dus 9 van de 10 keer geen idee wat voor object het is. Zodra iets uit een session komt, of uit een array, of weet ik veel, dan weet hij niet meer wat het is. En heel vaak is dat toch echt nodig, zoals in bovenstaand voorbeeldje. Het moet ergens die array in, toch? Of heb je een betere suggestie?
Bij een array weet je al helemaal niet welke key's je moet gebruiken. De kans is bij een object groter dat eclipse er nog iets van weet te maken. Al zou het niet met code completion werken, er is ergens syntactisch aangegeven hoe je structuur eruit zien, niet at runtime omdat je toevallig een specifieke string gebruikt.
Die fout zou met een array ook prima kunnen, maar dat zou nou juist een van de belangrijke argumenten kunnen zijn om objecten te gebruiken: dat php een notice/warning/error zou geven als je een typo maakt. Doet PHP dus niet.
Dat is inderdaad wel heel erg treurig.

@hierboven: Dat gaat fout omdat de var private is. Wat geberut er als hij public is?

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Janoz schreef op donderdag 14 juni 2007 @ 20:40:
[...]

Als het echt adhoc gegevens zijn vraag ik me af waarom ze uberhaupt bij elkaar horen. In alle andere gevallen zou ik aannemen dat het gewoon gegevens uit je domein zijn en verwacht ik dat je daar al een class voor geschreven hebt. Ik denk echter dat de sterk request georienteerde ontwikkeling die veel php-ers aanhouden er voor zorgt dat er erg weinig generiek en request brede ontwikkeling gedaan wordt waardoor die domein classe waarschijnlijk niet gemaakt zijn.
Ik neem aan dat jij weet wat 'onderhoud' en 'bugfixing' betekent? Als ik je de code voor mijn nieuwe projectje laat zien, zal je daar weinig op aan te merken hebben (hoop ik). Bij mijn vorige projectje waarschijnlijk ook niet. Maar de projecten waar ik op mijn werk mee bezig ben (geweest), zijn alle vier om te huilen. En omdat het voornamelijk bugfixing is, houd ik ongeveer dezelfde stijl aan. Anders wordt ik echt gek.
[...]

Bij een array weet je al helemaal niet welke key's je moet gebruiken. De kans is bij een object groter dat eclipse er nog iets van weet te maken. Al zou het niet met code completion werken, er is ergens syntactisch aangegeven hoe je structuur eruit zien, niet at runtime omdat je toevallig een specifieke string gebruikt.
Op het moment dat je alleen de dingen opvraagt die je 10 regels erboven erin hebt gezet is dat niet zo'n probleem. Principieel gezien heb je gelijk, feitelijk maakt het geen bal uit. Zeker omdat je geen warning/error krijgt als iets niet bestaat.
@hierboven: Dat gaat fout omdat de var private is. Wat geberut er als hij public is?
Verrek, je hebt gelijk. En daar is hij dan niet case-sensitive in :? Normaal waren alle variabelen dat toch wel, alleen de functies niet? 8)7

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

MBV schreef op donderdag 14 juni 2007 @ 17:35:
Die fout zou met een array ook prima kunnen, maar dat zou nou juist een van de belangrijke argumenten kunnen zijn om objecten te gebruiken: dat php een notice/warning/error zou geven als je een typo maakt. Doet PHP dus niet.
probeer het eens en je zal zien dat PHP gewoon een notice geeft dat je een ongedifineerde key gebruikt ;)

Overigens zijn de keys van arrays binnen php gewoon case sensitive:
PHP:
1
2
$a = array("test"=>1, "Test"=>2);
print_r($a);

Array
(
    [test] => 1
    [Test] => 2
)

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Erkens schreef op donderdag 14 juni 2007 @ 22:17:
[...]

probeer het eens en je zal zien dat PHP gewoon een notice geeft dat je een ongedifineerde key gebruikt ;)
Ik had het over objecten. Zoek de fout nogmaals:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
class test
{
  var $testLangeHeleLangeVar = 0;
  
  function setVar($value)
  {
    $this->testLangeVar = $value;
  }
  function getVar()
  {
    return $this->testLangeHeleLangeVar;
  }
}

En ja, ik ben heel slordig, dus ik heb dit al minstens 10x gehad :X
Overigens zijn de keys van arrays binnen php gewoon case sensitive:
Maar dit ging over objecten/klassen met private.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

ah, dan heb ik het verkeerd begrepen, negeer mijn post maar :)
En ja, ik ben heel slordig, dus ik heb dit al minstens 10x gehad :X
tja, datzelfde heb je ook gewoon met array's, daar is weinig aan te doen behalve nutteloos tegen PHP te lopen schoppen, je bent zelf immers de persoon die het fout doet ;)
Maar dit ging over objecten/klassen met private.
Daar doe ik (helaas) weinig mee aangezien mijn code ook met PHP4 moet blijven werken alsmede PHP5.

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

MBV schreef op donderdag 14 juni 2007 @ 20:56:
[...]

Ik neem aan dat jij weet wat 'onderhoud' en 'bugfixing' betekent? Als ik je de code voor mijn nieuwe projectje laat zien, zal je daar weinig op aan te merken hebben (hoop ik). Bij mijn vorige projectje waarschijnlijk ook niet. Maar de projecten waar ik op mijn werk mee bezig ben (geweest), zijn alle vier om te huilen. En omdat het voornamelijk bugfixing is, houd ik ongeveer dezelfde stijl aan. Anders wordt ik echt gek.
Ik weet zeker wat onderhoudbaarheid en bugfixing inhouden :). Dat is juist waarom ik ageer tegen het misbruik van arrays. Vooral als ze genest worden. Dat lijkt mij dus een hel om mee te werken. Daarnaast over je project, de uiteindelijke pagina's zeggen natuurlijk weinig over de achterliggende code.
Op het moment dat je alleen de dingen opvraagt die je 10 regels erboven erin hebt gezet is dat niet zo'n probleem. Principieel gezien heb je gelijk, feitelijk maakt het geen bal uit. Zeker omdat je geen warning/error krijgt als iets niet bestaat.
Over het algemeen is iets dat ik ergens uit haal niet tien regels erboven er in gezet. Dat is nu precies het request georienteerde ontwikkelen wat ik eerder aanhaalde. De plek waar ik mijn gegevens op haal is in de data access layer. Dit is een compleet ander bestand. Ik heb mijn oude project er weer eens bij gepakt, en daar had ik dus gewoon getters en setters geimplementeerd. Ik vroeg me al af waarom ik dat nu gedaan had, maar dat is juist om daadwerkelijk error's te genereren wanneer je een typefout maakt bij het opvragen van een property. Je krijgt dan namelijk gewoon een undefined function error.

Hier de code voor de event opsom pagina:

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
<?
include('shared/db.php');
include('shared/eventdao.php');
$event = getEventById($_GET['id']);
if ($event == NULL) {
  die ('TODO: fatsoenlijke foutmelding');
}


$title = htmlspecialchars($event->getTitle());
$content="      <h1>";
$content.= date("d-m-Y",$event->getStartDate());
if ($event->getStartDate()!=$event->getEndDate())
  $content.=" tot ".date("d-m-Y",$event->getEndDate());
$content.="</h1>\n";
$content.="      <p>";
$content.=nl2br(htmlspecialchars($event->getIntro()));
$content.="      </p>\n";
$content.="      <p>";
$content.=nl2br(htmlspecialchars($event->getDescription()));
$content.="      </p>\n";
$content.="      <small><a href=\"events.php\">&laquo;terug</a></small>\n";

include('template.php');
?>


De 'template-engine' is trouwens behoorlijk simpel. Gewoon html met daarin een plekje voor de content en de title.

Het meeste werk hier zit in het formatten van de pagina. Het daadwerkelijke ophalen is 4 regels incl de test (en ja, de fout moet nog wat netter.)

Hetzelfde geldt voor de pagina waarop alle events staan:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?
include('shared/db.php');
include('shared/eventdao.php');
$events = getEventsInFuture();

$title = "Aankomende exposities";
$content="";
foreach ($events as $event){
  $content.="      <h1>".htmlspecialchars($event->getTitle());
  $content.=" <small>".date("d-m-Y",$event->getStartDate());
  if ($event->getStartDate()!=$event->getEndDate())
    $content.=" tot ".date("d-m-Y",$event->getEndDate());
  $content.="</small></h1>\n";
  $content.="      <p>";
  $content.=nl2br(htmlspecialchars($event->getIntro()));
  $content.="      </p>\n";
  $content.="      <small><a href=\"eventinfo.php?id=".$event->getId()."\">meer&raquo;</a></small>\n";
}

include('template.php');
?>

[ Voor 11% gewijzigd door Janoz op 15-06-2007 09:08 ]

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Janoz schreef op vrijdag 15 juni 2007 @ 09:05:
[...]

Ik weet zeker wat onderhoudbaarheid en bugfixing inhouden :). Dat is juist waarom ik ageer tegen het misbruik van arrays. Vooral als ze genest worden. Dat lijkt mij dus een hel om mee te werken. Daarnaast over je project, de uiteindelijke pagina's zeggen natuurlijk weinig over de achterliggende code.
Als de HTML clean is, zegt dat meestal iets over het achterliggende project. Maar het was meer om een indruk te geven wat ik aan het knutselen was: laat maar weten als je de code wilt zien :P
[...]

Over het algemeen is iets dat ik ergens uit haal niet tien regels erboven er in gezet. Dat is nu precies het request georienteerde ontwikkelen wat ik eerder aanhaalde. De plek waar ik mijn gegevens op haal is in de data access layer. Dit is een compleet ander bestand. Ik heb mijn oude project er weer eens bij gepakt, en daar had ik dus gewoon getters en setters geimplementeerd. Ik vroeg me al af waarom ik dat nu gedaan had, maar dat is juist om daadwerkelijk error's te genereren wanneer je een typefout maakt bij het opvragen van een property. Je krijgt dan namelijk gewoon een undefined function error.
Daar heb je helemaal gelijk in voor een nieuw project. In een bestaand project dat helemaal aanpassen werkt gewoon niet. Het is al een hele verbetering dat de HTML niet meer dwars door de PHP staat :X En ik denk dat we ook een performance-probleem zouden krijgen met de database als we het simpel zouden oplossen. Bij pagina's waar het ongeveer wordt gedaan zoals jij het doet, krijg je met database-debugging aan eerst 20 pagina's met queries 8)7

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Om je data access layer te testen heb je niet de uiteindelijke pagina nodig toch? In de betreffende eventsdao.php staan de volgende functies:

PHP:
1
2
3
4
5
6
7
<?php
function getEventById($id) {...}
function getEvents() {...}
function getEventsInFuture() {...}
function updateEvent($event) {...}
function deleteEvent($event) {...}
?>


Je kunt keurige single purpose php bestandjes maken die simpel elke methode kunnen testen om aan te geven dat het werkt. Ja, daarin kun je misschien wel lappen debugcode hebben, maar dat staat compleet los van de uiteindelijke template engine of wat je ook maar als view gebruikt. Nadat je de boel getest hebt kun je in principe er redelijk vanuit gaan dat die 5 functions gewoon werken bij het implementeren van de view.

Dit is wat ik bedoel met het niet request gebaseerd ontwikkelen wat veel php-ers blijkbaar niet kunnen. Die hele event dao is niet gekoppeld aan een pagina of request. De event dao is gekoppeld aan een tabel in de database en wordt vervolgens in meerdere pagina's gebruikt.

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


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Even een algemene opmerking @ Janoz waar nou eigenlijk dit hele topic over gaat:

Ik zie het zo: Je hebt de 'puristen' die echt *alles* zo ver mogelijk uit willen normaliseren omdat ze dat gewend zijn vanuit bijvoorbeeld Java, of .Net, en de "let's get it done" mentaliteit van PHP programmeurs/scripters. In short, je kan dingen *heel* erg ranzig oplossen in PHP, maar je kan het ook héél erg ranzig oplossen in Java

De hele kunst aan het 'misbruiken' van een array is dat het geen misbruiken is. Jij hebt het over structs, hashes of objecten, maar in PHP is een array eigenlijk een mix van alle 3.

In java heb je de hasmap, linkedhashmap, linkedlist, treelist, weet ik veel wat voor meuk allemaal maar daar wil je in een scripttaal vaak helemaal niet over na denken en dat hoeft dan ook niet aangezien je de mogelijkheid hebt om key/value pairs op te geven waarbij de KEY een STRING is.

Verder ben jij waarschijnlijk ook een voorstander van setXXX en getXXX methods, terwijl ik daar een hekel aan heb om dat te definieren voor elke property als ik dat misschien helemaal niet nodig heb. Dan gebruik ik daar of een standaard objectje of misschien wel een array met key/value pairs voor en een __set() / __get() combinatie.

Het grote verschil zit 'm denk ik in het feit dat je hier met scripts werkt ipv gecompileerd/memory-optimized spul, en het blijft een kwestie van wat je het prettigst vindt werken imo.

Ik vind het iig niet prettig dat ik in java niet gewoon een key/value pair wat ik zelf kan kiezen in een hashmap kan stoppen maar dan weer LabelValueBeans moet aanmaken of gebruiken, dát vind ik weer misbruik van objecten en cpu cycles...

Just my €0,02

[ Voor 6% gewijzigd door SchizoDuckie op 15-06-2007 10:39 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Dat is zeker waar, en in elke andere taal dan PHP gebruik ik dat ook (/me heeft helaas niet serieus in een andere taal geprogrammeerd, de afgelopen 2 jaar ;).). Maar soms doet een pagina te lang over laden, dan zet ik die query debugger aan. Soms maak je zo'n functie anders dan je 3 maanden later denkt dat je hem hebt gemaakt, dan helpt een unit-test niet. Soms wil ik gewoon snel weten uit welke tabel iets wordt gehaald. En zo kan ik nog wel even doorgaan.

Maareh, waarom zijn dat losse functies? Hoe gooi je je database-handle door? Of zit dat allemaal in een klasse (factory-achtig)? * MBV heeft een grote hekel aan globals :)

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

MBV schreef op vrijdag 15 juni 2007 @ 10:37:

Maareh, waarom zijn dat losse functies? Hoe gooi je je database-handle door? Of zit dat allemaal in een klasse (factory-achtig)? * MBV heeft een grote hekel aan globals :)
Singleton ;)

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

Verwijderd

Alleen een beetje jammer dat in een standaard php webomgeving een sessie variabele meer singleton is dan een standaard implementatie van het singleton pattern ;)

[ Voor 6% gewijzigd door Verwijderd op 15-06-2007 11:03 ]


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Verwijderd schreef op vrijdag 15 juni 2007 @ 11:03:
[...]
Alleen een beetje jammer dat in een standaard php webomgeving een sessie variabele meer singleton is dan een standaard implementatie van het singleton pattern ;)
Die volg ik ff niet...

Een singleton is een object referentie die je krijgt met bijv. dbConnection::getInstance(), en die 1malig aangemaakt wordt op het moment dat ie er nog niet is.

een object in een sessie heeft daar weinig mee te maken, want daar zullen waarden geserialized en ge-deserialized voor moeten worden, en zal óók m.b.v. __sleep() / __wakeup() de db connectie weer eraangeknoopt moeten worden.

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

SchizoDuckie schreef op vrijdag 15 juni 2007 @ 10:33:
Ik zie het zo: Je hebt de 'puristen' die echt *alles* zo ver mogelijk uit willen normaliseren omdat ze dat gewend zijn vanuit bijvoorbeeld Java, of .Net, en de "let's get it done" mentaliteit van PHP programmeurs/scripters. In short, je kan dingen *heel* erg ranzig oplossen in PHP, maar je kan het ook héél erg ranzig oplossen in Java
Hiermee impliceer je dat mijn manier van werken waarschijnlijk langer zou duren. Dit is echter absoluut niet het geval. De DAO (Waarvan ik de implementatie hier niet heb staan) is in principe gewoon te genereren. Zoek bij google maar eens op php dao generator, maar je kunt hem ook zelf maken. Hiermee kun je vanuit je database model gewoon je classes en de DAO genereren. Database maken moet je sowieso doen en het genereren kost je vervolgens 2 seconden. De gegenereerde code kun je vervolgens net zo transparant gebruiken als ik hierboven gedaan heb. Ik neem niet aan dat iemand het met mij oneens kan zijn als ik zeg dat mijn code hierboven erg duidelijk, overzichtelijk en goed onderhoudbaar is.
De hele kunst aan het 'misbruiken' van een array is dat het geen misbruiken is. Jij hebt het over structs, hashes of objecten, maar in PHP is een array eigenlijk een mix van alle 3.

In java heb je de hasmap, linkedhashmap, linkedlist, treelist, weet ik veel wat voor meuk allemaal maar daar wil je in een scripttaal vaak helemaal niet over na denken en dat hoeft dan ook niet aangezien je de mogelijkheid hebt om key/value pairs op te geven waarbij de KEY een STRING is.
In deze context zie ik structs en objecten eigenlijk als 1. Beide is het een 'eigen type definitie'. De andere twee gebruiken zijn en map en een lijst. Wat ik met mijn oorspronkelijke opmerking wil zeggen is dat het eerste gebruik gewoon misbruik is van de mogelijkheden. Dat iets met een taal kan, betekent nog niet dat het daarom ook maar zo moet?

De meuk in java en dotnet is trouwens helemaal niet zo lastig. Zoals ik eerder al aangaf zijn er twee typen. Iets met key->value en iets met een lijst (dus alleen values). Vervolgens heb je in Java en .net hier verschillende implementaties van omdat de ene implementatie in de ene situatie efficienter is en de andere in een andere. Van de buitenkant zijn het echter allemaal of een List, of een Map, dus zo ingewikkeld is dat helemaal niet. Het enige waar je, en dat geldt ook voor een scripttaal, over na moet denken is of je een lijst of een map nodig hebt.
Verder ben jij waarschijnlijk ook een voorstander van setXXX en getXXX methods, terwijl ik daar een hekel aan heb om dat te definieren voor elke property als ik dat misschien helemaal niet nodig heb. Dan gebruik ik daar of een standaard objectje of misschien wel een array met key/value pairs voor en een __set() / __get() combinatie.
In crimson heb ik ooit een macro gemaakt waarmee ik automatisch van een propertie een getter en setter kon maken. 1 druk op de knop en klaar. Luiheid hoeft dus helemaal geen argument te zijn terwijl je code er wel een stuk robuster van wordt. Zou je een vergelijkbare macro hebben dan heb je dat na 1 tikfout in een label al weer terug verdient.
Het grote verschil zit 'm denk ik in het feit dat je hier met scripts werkt ipv gecompileerd/memory-optimized spul, en het blijft een kwestie van wat je het prettigst vindt werken imo.
Of je nu met gecompileerd spul of script spul werkt (om jouw woorden te gebruiken) maakt helemaal niet uit hoe je werkt. In beide gevallen schrijf je code en heb je het liefst dat deze goed is, makkelijk onderhoudbaar en overzichtelijk.
Ik vind het iig niet prettig dat ik in java niet gewoon een key/value pair wat ik zelf kan kiezen in een hashmap kan stoppen maar dan weer LabelValueBeans moet aanmaken of gebruiken, dát vind ik weer misbruik van objecten en cpu cycles...
Wat is dit voor onzin? Je kunt je hashmap met vele types definieren. Je moet een zelf opgelegde beperking van struts niet doortrekken naar het hele platform. Ik heb het idee dat je je viewcode veel te ver je applicatie in laat komen. Maar goed, op basis van enkel het woordje LabelValueBean kan ik er natuurlijk weinig meer over zeggen ;).

En druk over cpu-cycles zou ik me sowieso niet zo maken. Onderhoudbaarheid van je applicatie is met de huidige snelheidsmonsters een veel belangrijker kostentechnisch aspect.

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


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Volgens mij gaat dit topic helemaal niet meer over het misbruik van arrays in PHP, maar het misbruik van PHP zelf. Omdat het een zwak getypeerde taal is leren mensen zichzelf kennelijk de meest ranzige gebruiken aan. Niet voor niets leer je op een fatsoenlijke opleiding programmeren op een platform als Java.

Ik heb zelf een half jaar gewerkt bij een webdesignbedrijfje waar ik als taak had een PHP CMS op te poetsen (dit CMS was voor 1 klant ontwikkeld) zodat dit aan andere bedrijven verkocht kon worden. Dit was 'organisch' gegroeid tot best een groot en complex systeem, maar de personen voor mij hadden een "can't be arsed" instelling als het aankwam op onderhoudbaar programmeren, en dus werd alles maar op een grote hoop gegooid.

Met een duidelijke object-georienteerde data layer is je applicatie veel en veel makkelijker te onderhouden, en bovendien kan waarschijnlijk een groot deel van je code dan voor soortgelijke projecten hergebruikt worden (en dan direct, zonder hak en breekwerk te moeten plegen).
Janoz schreef op vrijdag 15 juni 2007 @ 13:20:
Wat is dit voor onzin? Je kunt je hashmap met vele types definieren. Je moet een zelf opgelegde beperking van struts niet doortrekken naar het hele platform. Ik heb het idee dat je je viewcode veel te ver je applicatie in laat komen. Maar goed, op basis van enkel het woordje LabelValueBean kan ik er natuurlijk weinig meer over zeggen ;).
Inderdaad. Grasping for straws.

Uit m'n blote (java 1.2) hoofd:
code:
1
2
3
4
Hashtable table;
table = new Hashtable();
table.add("key1", "value1");
table.add("key2", "value2");


Etc. Daarnaast worden er te pas en te onpas vergelijkingen gemaakt. Eerst is een PHP array eigenlijk een object, dan is het weer een lijst. Make up your mind!

[ Voor 28% gewijzigd door Hydra op 15-06-2007 13:35 ]

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

MBV schreef op vrijdag 15 juni 2007 @ 10:37:
Dat is zeker waar, en in elke andere taal dan PHP gebruik ik dat ook (/me heeft helaas niet serieus in een andere taal geprogrammeerd, de afgelopen 2 jaar ;).). Maar soms doet een pagina te lang over laden, dan zet ik die query debugger aan. Soms maak je zo'n functie anders dan je 3 maanden later denkt dat je hem hebt gemaakt, dan helpt een unit-test niet. Soms wil ik gewoon snel weten uit welke tabel iets wordt gehaald. En zo kan ik nog wel even doorgaan.
Zoals je in mijn voorbeelden kunt zien is het hele uitlees deel maar een paar regels. Zou je meer gegevens ophalen op een pagina dan kan dit langer worden, maar over het algemeen blijft het dan makkelijk op 1 scherm staan. Je kunt dus in 1 oogopslag exact zien welke gegevens voor die pagina opgehaald worden. In andere gevallen include ik meerdere van deze kleine stukjes code. Wanneer een pagina traag is is de boel erg makkelijk te splitsen. Ik zou dat kleine stukje dataophaal code gewoon in een apparte php kunnen copy pasten en daarmee werken. Ik heb dan alle database uitleescode bij elkaar staan en kan keurig het hele database access debuggen zonder dat ik in de orginele pagina overal debugstatements tussen moet flikkeren.

Die functie is verder niet speciaal. Hij geeft of 1 object terug of een lijst van objecten. De structuur van deze objecten ligt syntactisch vast. Juist als je array's zou gebruiken zou je niet merken of je nu eigenlijk een lijst van maps hebt, of dat je rechtstreeks die map terug gekregen hebt.
Maareh, waarom zijn dat losse functies? Hoe gooi je je database-handle door? Of zit dat allemaal in een klasse (factory-achtig)? * MBV heeft een grote hekel aan globals :)
Als je gewoon mysql_query gebruikt hoef je niet eens een connection mee te geven. Een preconditie van die DAO file is dat er een DB verbinding bestaat.

Hieronder heb ik een linkje naar de dao staan. Hij is niet zo heel netjes (Ik ben geen uber purist :).. dit is mijn manier van 'getting it done' ). Er is erg weinig commentaar en de fout afhandeling is ook lelijk.
eventdao.php

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


Acties:
  • 0 Henk 'm!

Verwijderd

SchizoDuckie schreef op vrijdag 15 juni 2007 @ 11:09:
Een singleton is een object referentie die je krijgt met bijv. dbConnection::getInstance(), en die 1malig aangemaakt wordt op het moment dat ie er nog niet is.
Eenmalig op request scope (/tijdens script executie), wat dus eigenlijk weer vrij veel is :)

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Verwijderd schreef op vrijdag 15 juni 2007 @ 14:06:
Eenmalig op request scope (/tijdens script executie), wat dus eigenlijk weer vrij veel is :)
Is er in PHP al iets als een session/application scope die blijft 'draaien' eigenlijk? Ik doe al tijden niks meer met PHP, maar ik vind het zo zonde om voor iedere request een verbinding op te moeten bouwen.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Hydra schreef op vrijdag 15 juni 2007 @ 14:15:
[...]


Is er in PHP al iets als een session/application scope die blijft 'draaien' eigenlijk? Ik doe al tijden niks meer met PHP, maar ik vind het zo zonde om voor iedere request een verbinding op te moeten bouwen.
de session array van PHP blijft gewoon bewaard gedurende de browser sessie, echter hier kan je niet resources in opslaan, althans niet default. Maar als het gaat om mysql zou je bijvoorbeeld naar mysql_pconnect kunnen kijken.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Erkens schreef op vrijdag 15 juni 2007 @ 14:53:
de session array van PHP blijft gewoon bewaard gedurende de browser sessie, echter hier kan je niet resources in opslaan, althans niet default. Maar als het gaat om mysql zou je bijvoorbeeld naar mysql_pconnect kunnen kijken.
Ja, die gebruikte ik sowieso altijd al, maar het gaat me meer om 't idee dat dat soort dingen niet persistent zijn. Jammer dat dat nog steeds zo is.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Erkens schreef op vrijdag 15 juni 2007 @ 14:53:
[...]

de session array van PHP blijft gewoon bewaard gedurende de browser sessie, echter hier kan je niet resources in opslaan, althans niet default. Maar als het gaat om mysql zou je bijvoorbeeld naar mysql_pconnect kunnen kijken.
Wat hij zich afvraagd is of het 'blijft draaien'. Dat is dus niet zo. Aan het begin wordt er gedeserialized en aan het einde geserialized. Het is dus eigenlijk een soort psuedo scope. Dat is ook de reden dat er geen resource handles in opgeslagen kunnen worden. Of je dat zou willen en mysql staan daar helemaal los van.

offtopic:
@hieronder. Lees je reactie nog eens. Daarin staat niet het antwoord op de vraag 'blijft het draaien'. Dat is inderdaad een logisch gevolg van het feit dat er geen persistence php proces is, maar dat betekent niet dat het in het algemeen logisch is. In de .net, j2ee en ruby (en vele andere) wereld is het namelijk erg logisch dat er wel een proces blijft draaien. Zo breed bekeken is het juist helemaal niet logisch dat php dat niet heeft. Dat is bijvoorbeeld erg handig wanneer je een ssh of een ftp connectie levend wilt houden. Dit is in php zo goed als onmogelijk.

Echter wil ik hier niet weer de php-scope discussie beginnen. Daarover zijn al meerdere topics geweest voor zover ik me kan herinneren. Dit topic gaat over het array misbruik dat je overal in de php wereld tegenkomt.

[ Voor 38% gewijzigd door Janoz op 15-06-2007 15:34 ]

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


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Janoz schreef op vrijdag 15 juni 2007 @ 15:07:
[...]

Wat hij zich afvraagd is of het 'blijft draaien'. Dat is dus niet zo. Aan het begin wordt er gedeserialized en aan het einde geserialized. Het is dus eigenlijk een soort psuedo scope. Dat is ook de reden dat er geen resource handles in opgeslagen kunnen worden. Of je dat zou willen en mysql staan daar helemaal los van.
Dat zeg ik toch? Zolang er geen "PHP" proces draait op de server is het immers niet mogelijk om uberhaupt php code te runnen. Overigens kan je prima resource handles opslaan, alleen heb je er niks aan omdat de betreffende resources niet meer bestaan ;)

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
Janoz schreef op vrijdag 15 juni 2007 @ 15:07:
Wat hij zich afvraagd is of het 'blijft draaien'. Dat is dus niet zo.
Dat kwam uit zijn uitleg ook prima naar voren :)

https://niels.nu


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Janoz schreef op vrijdag 15 juni 2007 @ 13:40:
[...]

Zoals je in mijn voorbeelden kunt zien is het hele uitlees deel maar een paar regels. Zou je meer gegevens ophalen op een pagina dan kan dit langer worden, maar over het algemeen blijft het dan makkelijk op 1 scherm staan. Je kunt dus in 1 oogopslag exact zien welke gegevens voor die pagina opgehaald worden. In andere gevallen include ik meerdere van deze kleine stukjes code. Wanneer een pagina traag is is de boel erg makkelijk te splitsen. Ik zou dat kleine stukje dataophaal code gewoon in een apparte php kunnen copy pasten en daarmee werken. Ik heb dan alle database uitleescode bij elkaar staan en kan keurig het hele database access debuggen zonder dat ik in de orginele pagina overal debugstatements tussen moet flikkeren.
Ik bedoelde de output van het query-log die bovenaan de pagina komt staan zodra je $AdoDB->debug=true bovenaan je pagina krijgt. Als je op basis van een query 481 objecten aanmaakt die allemaal zelf een query doen, en vervolgens de parent ook een query laten doen, dan zit je zo aan 240 pagina's scrollen :X
Die functie is verder niet speciaal. Hij geeft of 1 object terug of een lijst van objecten. De structuur van deze objecten ligt syntactisch vast. Juist als je array's zou gebruiken zou je niet merken of je nu eigenlijk een lijst van maps hebt, of dat je rechtstreeks die map terug gekregen hebt.


[...]


Als je gewoon mysql_query gebruikt hoef je niet eens een connection mee te geven. Een preconditie van die DAO file is dat er een DB verbinding bestaat.
Dat zou hier dus nooit werken: dingen komen uit 3 verschillende databases, van 2 verschillende db-servers. Daarnaast zijn er nog 100 voordelen van AdoDB: stel je voor dat je wilt overstappen naar PostGre, of dat je ook een verbinding hebt naar een MSSQL server? Hier is dat netjes geregeld: een .ini-file die op basis van de host en de gevraagde database-verbinding de goede username/passwd combinatie, IP en verbindingstype geeft. Dan wordt een object aangemaakt. Nadeel is dat het vervolgens in een global wordt gegooid :(
Hieronder heb ik een linkje naar de dao staan. Hij is niet zo heel netjes (Ik ben geen uber purist :).. dit is mijn manier van 'getting it done' ). Er is erg weinig commentaar en de fout afhandeling is ook lelijk.
eventdao.php
Ken jij de functie intval? :P
Tja, het is niet mijn stijl van programmeren. Queries maak ik zo min mogelijk variabel, een $fields zal ik nooit gebruiken.
Hydra schreef op vrijdag 15 juni 2007 @ 15:00:
[...]


Ja, die gebruikte ik sowieso altijd al, maar het gaat me meer om 't idee dat dat soort dingen niet persistent zijn. Jammer dat dat nog steeds zo is.
Ik zou dat doen met __wakeup: in de constructor $this->db = db::getInstance, en in de __wakeup ook. Klaar :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

MBV schreef op vrijdag 15 juni 2007 @ 15:56:
Ik bedoelde de output van het query-log die bovenaan de pagina komt staan zodra je $AdoDB->debug=true bovenaan je pagina krijgt. Als je op basis van een query 481 objecten aanmaakt die allemaal zelf een query doen, en vervolgens de parent ook een query laten doen, dan zit je zo aan 240 pagina's scrollen :X
Nergens propageer ik het aanroepen van een query per object. Nu zit in dit specifieke voorbeeld geen master detail relatie, maar in een ander stuk wel. Alle objecten maak ik aan middels 1 resultset. (Daarvoor is de offset in createDingFromRow).
Dat zou hier dus nooit werken: dingen komen uit 3 verschillende databases, van 2 verschillende db-servers. Daarnaast zijn er nog 100 voordelen van AdoDB: stel je voor dat je wilt overstappen naar PostGre, of dat je ook een verbinding hebt naar een MSSQL server? Hier is dat netjes geregeld: een .ini-file die op basis van de host en de gevraagde database-verbinding de goede username/passwd combinatie, IP en verbindingstype geeft. Dan wordt een object aangemaakt. Nadeel is dat het vervolgens in een global wordt gegooid :(
Al die verschillende verbindingen is iets dat je in je data access layer regelt. Hier is de data access layer een erg simpele mysql laag. Niets houd je tegen om een adoDB implementatie te maken die zo net is als het maar kan en vervolgens exact dezelfde functie aanroepen heeft. Die kun je vervolgens 1 op 1 in mijn project hangen zonder ook maar 1 letter code aan te passen in de rest van de applicatie. Er ie een reden dat ik niet zo snel met de DAO aan kwam zetten. De daadwerkelijke implementatie van mijn DAO staat compleet los van deze discussie. Het gaat puur om wat er uit die methoden komt en wat je er in stopt. Het gaat om de interface, niet om de implementatie.
Ken jij de functie intval? :P
Tja, het is niet mijn stijl van programmeren.
die *1 is gewoon een super verkorting van:
PHP:
1
2
3
if (!intval($value)){
   $value = 0;
}

ik vind het heel logisch wanneer iemand daar over gaat vallen.
Queries maak ik zo min mogelijk variabel, een $fields zal ik nooit gebruiken.
Ik zie echter niet in wat je probleem is met $fields. Ten eerste is de scope van die var minimaal en ten tweede zorgt dat er voor dat ik in het hele bestand maar op 1 plek definieer wat de kolomnamen zijn en wat de volgorde van die kolomnamen zijn. Vervolgens kan ik op 1 plek implementeren hoe die kolommen uit de resultset gelezen kunnen worden. Bij elke query weer opnieuw een uitlees deel en een opsomming van je kolommen lijkt mij juist een stuk foutgevoeliger.

[ Voor 12% gewijzigd door Janoz op 15-06-2007 16:18 ]

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Mijn AdoDB implementatie zou ik nooit 1-op-1 in jouw code over kunnen/willen zetten: Ik heb een object nodig om de handle in op te slaan. Ok, met globals zou het kunnen, maar dat wil ik altijd vermijden.
Intval was idd te flauw, dat doet namelijk exact hetzelfde als *1:
The integer value of var on success, or 0 on failure.
Over $fields: Als je alles nodig hebt, waarom niet x.* gebruiken? En als je niet alles nodig hebt, dan verschilt dat per keer. Volgordes gebruiken vind ik smerig, als je dan een veldje toevoegt in je query kan je vrij snel je applicatie slopen.

Maar dat heeft allemaal niks met arrays misbruiken te maken, toch? ;)

Acties:
  • 0 Henk 'm!

Verwijderd

zal ik dan nog even wat myths debunken,

mysql_pconnect is persistent zolang de webserver draait. het idee van mysql_pconnect is dat een database connectie niet telkens bij elke request wordt opgezet maar dat deze in een soort van pool terecht komt. wanneer de webserver en request krijgt om een nieuwe verbindinge op te zetten wordt eerst gekeken of een er nog een soort gelijke connectie in de pool zit, zo ja dan wordt die terug gegeven. zo niet, dan wordt er een nieuwe gemaakt die ook meteen onderdeel van de pool wordt.

zo kan een enkele connectie gedurende uren, of zelfs dagen worden gedeeld door duizenden hits. hier zit ook meteen een veiligheids risico. de database server ziet maar 1 connectie dus je moet uitkijken omdat locking soms per connectie wordt gedaan en niet per request. Mysql5 lost dit o.a. op.

wat betreft de array's, dat zijn self-balancing binary search tree's die als een assocciative array worden gepresenteerd. key's, zelf numerieke key's zijn dus eigenlijk fictief. en kwa programmeur kun je wienig doen om onder de natuur van deze array's uit te komen. dit is wat array's zijn en daar moet je het mee doen.

wat betreft de vraag van wel of geen setters/getters? hangt geheel af van je scope en doel. gebruik je ze als tijdelijke opslag, gebruik dan gewoon een array. moeten de gegevens door geheel de applicatie worden gebruikt, dan ontkom je er niet aan om een object te maken en het OOP pad te kiezen.

ranzig programmeren in PHP? in elke taal kun je ranzig programmeren. ranzig wil gewoon zeggen dat je dingen niet doet volgens het boekje en dat je dus rust op onbetrouwbare maar schijnbaar werkende functionaliteit. promoot PHP ranzig programmeeren? mischien, en voor de net beginnende programmeur is dat geen enkel probleem.

maar als je naar 2 of 3 jaar nog steeds niet volgens het boekje kunt programmeren dan kun je je afvragen of je wel voor de juiste richting hebt gekozen. want als je PHP in 2 of 3 jaar niet onder de knie kunt krijgen dan weet ik niet welke laag-drempelige taal je het dan zou moeten leren. de PHP manual op www.php.net is toch echt heel duidelijk over hoe het moet. doe het dan ook zoals daar staat beschreven en ga niet de cowboy lopen uithangen met iemand anders deadline en bron van inkomsten.

PHP is een taal met zijn eigen sterke en zwake punten. ken deze en leef erna.
je kunt ze vinden op http://nl3.php.net/manual/en/index.php

Acties:
  • 0 Henk 'm!

  • flowerp
  • Registratie: September 2003
  • Laatst online: 11-09 18:20
MBV schreef op donderdag 14 juni 2007 @ 17:35:
Over code completion in pak-em-beet eclipse/PDT kan ik maar 1 ding zeggen: het werkt heel vaak niet. PHP heeft daarvoor te zwakke typering.
Misschien beetje offtopic, maar ter vergelijking: in Java speelt eigenlijk hetzelfde in de web-layer. In EL maakt het helemaal niet uit of het onderliggende object properties heeft of dat het een Map is. Ik schrijf dan bijvoorbeeld:

Java:
1
#{someObj.foo}


Als someObj een Map is, dan wordt dit runtime omgezet naar someObj.get( "foo" ); Is someObj echter een gewoon object, dan wordt het omgezet naar someObj.getFoo();

Op het moment dat je een verzameling waardes hebt in een backing bean, die je even snel op de JSF pagina wilt afdrukken, dan zit je met het zelfde dilemma. Definieer ik er een aparte (inner) class voor en geef ik die terug, of stop ik de waardes in een Map en geef ik die terug. Voor verdere typesafeness maakt het in dat geval ook niet meer uit.

Het grappige is ook dat normaal gesproken, in business code, someObj.getFoo(); sneller is dan someObj.get("foo"); De eerste is een directe method call, terwijl de andere een lookup moet doet (hashcode nemen, naar bucket gaan, eventueel door bucket moet itereren, etc).

Bij Java in de web-later (met EL) is het juist andersom. someObj.getFoo(); wordt een call dmv reflection, terwijl voor someObj.get("foo"); eerst getest kan worden of someObj een Map is, waarna een cast gedaan kan worden en een directe method call plaatsvind. ;)
Eclipse heeft dus 9 van de 10 keer geen idee wat voor object het is. Zodra iets uit een session komt, of uit een array, of weet ik veel, dan weet hij niet meer wat het is.
Bij Eclipse/WTP is dat ook het geval. Alleen als je een (managed) bean declareerd weet Eclipse wat voor object het is en werkt method completion. Maar een object kan idd ook uit de session scope komen of uit de request scope en daar gewoon programmatisch ingestopt zijn door een servlet, backing bean, taglib tag, etc.

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
@flowerp: grappig, dat stuk Java heb ik nooit gebruikt dus ik wist niet dat Java net zo vervelend is met die dingen als PHP ;)

Over Eclipse: het 'frustrerende' is dat je het zelf precies weet, bijvoorbeeld omdat je een array van 100 dezelfde objecten hebt gemaakt, en daar dan met foreach heen loopt. Ik zou bij dat soort dingen een type hint willen geven, maar dat kan dan weer niet.

@Docey: hoe zit dat dan met temp-tables?

[ Voor 5% gewijzigd door MBV op 16-06-2007 10:00 ]


Acties:
  • 0 Henk 'm!

Verwijderd

mysql_pconnect shared de connectie dus ook temp-tables zijn geshared. dat wil dus zeggen dat het ene php-script de temp-tables van de andere kan lezen en schrijven. MySQL kan het onderscheid niet maken tussen welke php instantie nou die query maakte.

MySQL 5 heeft hier volgensmij wat verbetering voor waardoor MySQL wel het onderscheid kan maken tussen welke php instantie nou die query maakte. staat trouwens ook allemaal beschreven op de officiele manual pagina van mysql_pconnect(). die is hier te vinden: http://www.php.net/manual/en/function.mysql-pconnect.php en ook een meer algemene pagina over persistente database connectie's: http://www.php.net/manual...ersistent-connections.php.

er zijn trouwens ook enkele benchmarks geweest die laten zien dat als apache of MySQL niet goed zijn getuned het gebruik van mysql_pconnect() zelfs langzamer is dan mysql_connect(). tevens is het zo dat door de structuur van child-proccesses by apache1.x, de client soms bij een andere child-proccess uitkomt en omdat mysql_pconnect per proccess werkt heeft dus elke child-proccess zijn eigen connection-pool en niet apache als geheel. Apache2, gebruikt treads en dus 1 pool.

Acties:
  • 0 Henk 'm!

  • _JGC_
  • Registratie: Juli 2000
  • Laatst online: 19:01
Verwijderd schreef op zaterdag 16 juni 2007 @ 15:48:
er zijn trouwens ook enkele benchmarks geweest die laten zien dat als apache of MySQL niet goed zijn getuned het gebruik van mysql_pconnect() zelfs langzamer is dan mysql_connect(). tevens is het zo dat door de structuur van child-proccesses by apache1.x, de client soms bij een andere child-proccess uitkomt en omdat mysql_pconnect per proccess werkt heeft dus elke child-proccess zijn eigen connection-pool en niet apache als geheel. Apache2, gebruikt treads en dus 1 pool.
Je schiet je jezelf in je voet als je Apache2 threaded met PHP gaat gebruiken: de modules die PHP levert of gebruikt zijn nog altijd niet threadsafe en slopen na een tijdje serveren je apache server door geheugencorruptie.

Acties:
  • 0 Henk 'm!

Verwijderd

_JGC_ schreef op zondag 17 juni 2007 @ 02:26:
[...]

Je schiet je jezelf in je voet als je Apache2 threaded met PHP gaat gebruiken: de modules die PHP levert of gebruikt zijn nog altijd niet threadsafe en slopen na een tijdje serveren je apache server door geheugencorruptie.
dat apache2 en php nog niet goed samengaan weten we wel, maar het ging om het idee. apache1 werkt met child-proccess welke dus elk hun eigen geheugen en resources hebben terwijl treaded webservers zoals apache2 of bijvoorbeeld IIS of zeus, welke werken met treads en dus 1 geheugen en resource pool hebben voor alle treads.

dit is ook een mooie manier om je MySQL server dicht te laten slippen als je bijvoorbeeld max_connections op 100 hebt staan en je hebt 120 child-proccesses in apache1.x dan kan het dus zo zijn dat je geen connectie krijgt omdat elk van die 120 child-proccesses dus 1 connectie naar de database server houdt zonder dat er ook maar 1 request hoeft binnen te komen. als je geen persistente connectie's gebruikt worden connecties constant afgebroken en opgebouwd waardoor je dus alleen actieve connecties hebt maar met mysql_pconnect() kun je dus een situaties creeren waarbij je 120 in-actieve connectie's hebt. dit kun je alleen oplossen door ofwel MySQL danwel apache te herstarten. 1 van beide moet zijn connectie pool verbreken. tot dan is het connection timed out.

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Apache2 kan je toch ook als fork laten werken?

Maareh, wat heeft dit met array's te maken?

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Zie MBV. Het topic gaat in principe over het verschil tussen een struct/object, een map en een lijst.

Maar weer terug ontopic mensen?

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


Acties:
  • 0 Henk 'm!

Verwijderd

In php heeft de discussie Map of Array geen recht van bestaan want php kent simpelweg geen Array ;)

En de php 'Map' misbruiken vind ik opzich prima, maar dan wel achter een juiste abstractie. Ik vind het belangrijker in een project hoe ik stukken code moet aanspreken dan hoe de implementatie er uit ziet. Overigens zou ik wel voor classes en structs gaan.

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Wat janoz dus vindt is dat je beter klasses kan gebruiken voor de meeste maps, zodat je eerder 'ziet' dat je een fout maakt.

En stiekem heb je wel array's in PHP: $array[1] zou ik een array noemen, omdat $array["1"] een map is. En dat je die kan mixen weet ik wel, maar het 'voelt' toch anders aan.

offtopic:
kon je trouwens ook een object als key gebruiken?

[ Voor 48% gewijzigd door MBV op 18-06-2007 09:50 ]


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

@mark: Idd, in php is er geen verschil tussen maps en lijsten. Er is imho echter wel een groot verschil tussen maps en lijsten aan de ene kant en structs/objecten aan de andere kant. Omdat veel php-ers helemaal niet gewend zijn om met types te werken, laat staan eigen types, wordt dit door hun allemaal op een grote hoop gegooit.

Het topic ging dus in principe niet over de tekortkomingen van het php platform, maar over de imho tekortkomingen van veel php ontwikkelaars.

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


Acties:
  • 0 Henk 'm!

Verwijderd

Janoz schreef op maandag 18 juni 2007 @ 09:53:
Het topic ging dus in principe niet over de tekortkomingen van het php platform, maar over de imho tekortkomingen van veel php ontwikkelaars.
Ik wil het niet een tekortkoming van de php ontwikkelaars in het algemeen noemen. Ik denk eerder een tekortkoming van de verschillende php tutorial sites. Over het algemeen zijn php ontwikkelaars pragmatisten en copy-n-pasten ze die 'slechte gewoonte' zo hun project in. Ik vind daar opzich weinig mis mee mits je het maar achter een juiste facade weet te smeden.

Ik ben uiteraard voorstander van het gebruik van classes. Ik ben het ook gewoon eens met de argumenten van Janoz. Maar ik weet gewoon nog steeds niet of php ook maar iets met classes moet doen, het is er de 'realm' wat mij betreft niet voor. Het past niet bij het karakter van de taal.

Acties:
  • 0 Henk 'm!

Verwijderd

Ik heb het volgende probleem:
1. In bestand nr. 1 staat een query en die neemt een aantal variabelen en zoekt daarop meerdere waarden uit een MySQL database
2. De waarden dienen in twee "arrays" gesplitst te worden.
3. Array nr. 1 gaat in de X-as van een te tekenen grafiek
4. Array nr. 2 gaat in de Y-as van een te tekenen grafiek
5. Een tweede PHP bestand bevat de code voor het tekenen van de grafiek (JPGraph)
6. Zowel array nr. 1 als Array nr. 2 dienen te worden "overgepompt" naar bestand nr. 2

Probleem is namelijk dat bestand nr. 1 ook wat andere waarden op het scherm moet weergeven en de code van JPGraph genereert een plaatje wat conflicteert met de tekst die ik wil weergeven.
ik kan de code van JPGraph niet in bestand 1 houden want ik kan geen <img src="class genereer_plaatje(variabelen)"> gebruiken. Ik moet <img src="bestand2.php"> gebruiken.

Ik stop dus nu alles in een array, waarbij ik meerdere arrays voor de Y-as genereer.

Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Dat is misschien waar, maar ik vind het toch wel een stuk makkelijker werken. Misschien niet voor de voorbeeldjes die ik gaf, maar wel in het algemeen. Mijn site www.mvdvlist.nl/images_new moest ik voor een opdrachtje op de TU/e uitbreiden met Web2.0 geneuzel, zoeken m.b.v. RDF enzo. Ik heb mijn bestaande klassen geabstraheerd, een nieuwe implementatie ervan gemaakt en ik was klaar :Y)

niet dat het echt werkte, maar dat was vooral omdat ik niet direct doorhad hoe dat gedoe met RDF moest gaan werken en hoe ik de zoekresultaten onderweg moest opslaan ;)

PHP moet zeker iets met klasses doen: het wordt op projecten van steeds grotere schaal gebruikt, die zonder klasses absoluut onoverzichtelijk worden. Ik werk nu bijvoorbeeld op een project van 100.000 regels (wc -l, dus niet echt betrouwbaar ;)), en een ander project van 13.000 regels. Dat zijn als het goed is alleen de .php en .template bestanden, zonder de svn-bestanden. Als daarbij netjes met klasses gewerkt was, dan was ik een stuk blijer geweest :(

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

@Mark: Ik denk dat je daar behoorlijk gelijk in hebt. Er wordt volgens mij veel bad practices gepropageerd via veel tutorial sites. Hoeveel mensen weten bijvoorbeeld dat de bekende 'or die()' constructie niks meer is dan een booleanse expressie die gebruikt maakt van lazy evaluation?

Vandaar dit topic eigenlijk. De oorspronkelijke opmerking in het 'slechte programmeer voorbeelden' topic was meer een licht utopische poging tot re-education.

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


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Janoz schreef op maandag 18 juni 2007 @ 10:53:
@Mark: Ik denk dat je daar behoorlijk gelijk in hebt. Er wordt volgens mij veel bad practices gepropageerd via veel tutorial sites.
Veel van die tutorial sites (alsmede vele usercomments in de php manual) zijn outdated of gewoon geschreven door iemand die het ook weer via een andere brakke tutorial weet.
Maar als je een beetje inzicht en kennis van de taal hebt moet je daar vrij makkelijk en snel doorheen kunnen prikken, dus de "schuld" ligt niet voor de volle 100% bij dat soort copy/paste werk.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Dat OO niet bij PHP past is ook maar gewenning. Als je er een tijdje mee werkt, dan weet (en wil) je ook niet anders meer. Het zit niets in de weg, dus waarom niet?

Geneste maps in array formaat gebruik ik ook wel af en toe; vooral voor kleine snelle taken. Om daar dan een paar klassen voor te schrijven is misschien een beetje overbodig. Ik gebruik het dan ook niet echt als programmeertaal maar meer als scripttaal. Als het een wat grotere vorm aanneemt, dan kies ik toch wel snel voor klassen.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Verwijderd schreef op maandag 18 juni 2007 @ 10:02:
[...]
Ik wil het niet een tekortkoming van de php ontwikkelaars in het algemeen noemen. Ik denk eerder een tekortkoming van de verschillende php tutorial sites.
Daar kan ik het alleen maar mee eens zijn. Ik huiver als ik hier op GoT een topic over PHP dicht zie gaan met de melding 'ga maar naar phpfreakz.nl oid om php te leren voordat je een nieuw topic aanmaakt', want dan weet je gewoon dat die persoon bad practices aangeleerd krijgt.


Ik denk dat Janoz gelijk heeft dat de oorzaak voornamelijk te vinden is in het request-oriented coden wat vaak gedaan wordt. Mijn eigen forum software is ooit op eenzelfde manier geschreven. Langzaamaan kwamen er OO elementen in die code, en nu is het een soort half procedureel half OO halfbreed gedrocht geworden wat me heeft doen besluiten om toch maar van scratch af aan 2.0 te schrijven. Veel van geleerd hoor, van slechte code schrijven, daar niet van.

Maar goed, een echte goede oplossing is niet makkelijk te bedenken, tenminste, ik ben er nog niet uit. Als je alles netjes OO doet, dan krijg je al snel belachelijk veel queries, en dat werkt ook niet echt optimaal. PHP heeft nou eenmaal niet iets als hibernate.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Waarom zou je, bij het gebruik van een data access layer en transfer objecten ineens meer queries krijgen? Je kunt keurig de special purpuse queries in je DAL implementeren. De getEventsInFuture in mijn eerder geposte code is daar een voorbeeld van.

php heeft inderdaad gen OR mapper als hibernate, maar ik denk persoonlijk dat zoiets bij een applicatie scope missende omgeving zijn doel compleet voorbij schiet. Voor php lijkt me tooling als DaoGen veel toepasselijker.

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


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Janoz schreef op maandag 18 juni 2007 @ 12:47:
Waarom zou je, bij het gebruik van een data access layer en transfer objecten ineens meer queries krijgen? Je kunt keurig de special purpuse queries in je DAL implementeren. De getEventsInFuture in mijn eerder geposte code is daar een voorbeeld van.
Ik zal even kijken of ik een voorbeeld kan schetsen.
Neem even forum software als voorbeeld. Je hebt users, en je hebt forum topics, forum posts.

Nu wil ik alle posts uit een topic, inclusief de user informatie. Nu moet ik in de DAL een functie schrijven die voor elke post de userinfo ophaalt, en hier een object van maakt en teruggeeft.

Een manier is om een user object te creeren adhv het userID, en die aan je post object te hangen, maar dit geeft dan dus een query explosie. De andere manier is om inderdaad een query te maken die al die data in 1x queried, en dan alle post en user objecten aanmaakt, maar dan zit je toch al niet meer zo heel ver van die request-based methode af? Het enige verschil is dan dat jij een zak objecten creeert, en in de andere methode dus een associatief array wordt gegeven.

array(
[0] => array(
["userID"] => 1,
["userName"] => "Grijze Vos"
),
[1] => array(..etc..)
)

Waarbij die hele meuk objecten aanmaken redelijk wat overhead geeft lijkt me.
Je kunt natuurlijk nog zeggen dat jouw DAL dan netjes een aparte layer is, maar die kun je ook creeeren met de tweede methode.

Als je dan gaat kijken, dan is jouw methode misschien handiger omdat je er tools bij kunt gebruiken die makkelijk eea genereren voor je, en dat zal met die associatieve arrays dan niet echt gaan, maar dat is dan ook (op dit moment iig) voor mij een van de weinige echte voordelen die ik zie.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

MBV schreef op maandag 18 juni 2007 @ 09:49:
En stiekem heb je wel array's in PHP: $array[1] zou ik een array noemen, omdat $array["1"] een map is. En dat je die kan mixen weet ik wel, maar het 'voelt' toch anders aan.
Waarom voelt een geassocieerde datastructuur met een string als key anders aan als een geassocieerde datastructuur met een int als key? :)

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!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Grijze Vos schreef op maandag 18 juni 2007 @ 13:15:
Een manier is om een user object te creeren adhv het userID, en die aan je post object te hangen, maar dit geeft dan dus een query explosie. De andere manier is om inderdaad een query te maken die al die data in 1x queried, en dan alle post en user objecten aanmaakt, maar dan zit je toch al niet meer zo heel ver van die request-based methode af? Het enige verschil is dan dat jij een zak objecten creeert, en in de andere methode dus een associatief array wordt gegeven.
Die query explosie is inderdaad overbodig. Een master detail relatie verwerk ik inderdaad op de manier die jij schetst. Er is echter wel een verschil. Ik houd een tijdelijke map bij van user objecten. Ik creeer alleen een nieuwe user wanneer ik er nog geen heb. Ik wil niet zeggen dat dat niet meer ver afligt van de request-based methode.

het verschil tussen wat ik bedoel en de request-based methode is dat in mijn geval die getForumThread() methode geimplementeerd is in een data access layer deel samen met bijvoorbeeld de 'getActiveTopics' en de 'addReacion()' methode, en niet in showForumThread.php.
array(
[0] => array(
["userID"] => 1,
["userName"] => "Grijze Vos"
),
[1] => array(..etc..)
)

Waarbij die hele meuk objecten aanmaken redelijk wat overhead geeft lijkt me.
Je kunt natuurlijk nog zeggen dat jouw DAL dan netjes een aparte layer is, maar die kun je ook creeeren met de tweede methode.
Objecten aanmaken is helemaal niet zo duur als jij hier voor doet komen. Daarnaast is het aanmaken van een nieuwe array ook niet gratis (dit doe jij hier ook voor elke entry).
Als je dan gaat kijken, dan is jouw methode misschien handiger omdat je er tools bij kunt gebruiken die makkelijk eea genereren voor je, en dat zal met die associatieve arrays dan niet echt gaan, maar dat is dan ook (op dit moment iig) voor mij een van de weinige echte voordelen die ik zie.
Het grootste voordeel is de leesbaarheid en onderhoudbaarheid van je code. Je hebt op 1 plek duidelijk geimplementeerd hoe je object eruit moet zien en niet op vele plekken hoe de key's heten die je gebruikt om je array te vullen. Daarnaast bied het gebruik van transfer objecten je de mogelijkheid om centraal afleidbare info te genereren.

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


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Het voordeel van een aparte DAL is dat je de queries bij elkaar houdt: als je iets verandert in je DB, dan weet je waar je moet zoeken. Zolang je in je objecten geen rare dingen doet zal de overhead wel meevallen denk ik.

Je zou het eens kunnen proberen:
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
//quick-n-dirty, voor het idee
class factory {
  var $db;
  var $users;
  function factory() {
    $this->db =& database::getInst();
  }
  function getAllUsers() {
   $sql = 'SELECT * FROM users';
   $rs = $this->db->execute();
   $resultArray = $rs->getArray();
   foreach ($resultArray as $row)
   {
     $users[$row['id']] = new user($row['...']....);
   }
   return $users;
  }
}

class user {
  var ...;
  function user($...) {
    $this->... = $...;
  }
}

Ik kan me slecht voorstellen dat dit veel langer duurt dan de map-methode. Voordeel is dat je $user->getRights() kan definieren, of $user->getPostCount(), en nog veel meer...

In die factory kan je allerlei functies definieren om je users aan te maken volgens bepaalde criteria. Voordeel: herbruikbaar, makkelijk queries aanpasbaar maken, dat soort dingen. En doordat je aan caching doet (in $users) wordt elke user maar 1x opgevraagd. Dat kan best wel eens queries schelen :)

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Janoz schreef op maandag 18 juni 2007 @ 12:47:
php heeft inderdaad gen OR mapper als hibernate, maar ik denk persoonlijk dat zoiets bij een applicatie scope missende omgeving zijn doel compleet voorbij schiet. Voor php lijkt me tooling als DaoGen veel toepasselijker.
Check doctrine eens, redelijk volwassen OR mapper voor php.

http://www.phpdoctrine.net/doctrine/manual/new/

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 02:21

Janoz

Moderator Devschuur®

!litemod

Ik zeg niet dat het niet mogelijk is, ik zeg dat een full fledged php OR-mapper alla Hibernate of NHibernate zijn doel compleet voorbij schiet.

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


Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Janoz schreef op maandag 18 juni 2007 @ 14:38:
Ik zeg niet dat het niet mogelijk is, ik zeg dat een full fledged php OR-mapper alla Hibernate of NHibernate zijn doel compleet voorbij schiet.
En ik wilde je alleen even attent maken op een aardig stukje php software waarvan je eventueel nog niet op de hoogte zou kunnen zijn. :) En ondanks dat doctrine erg uitgebreid is qua feauture set heb ik dit nooit ervaren als iets wat bij het bouwen van php applicaties overkill zou zijn. Maargoed, weer volledig offtopic van mij :P

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Goede punten hebben jullie. Ik heb net even wat zitten experimenteren, en kwam erachter dat dit kon:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class user
{
  private $id;
  private $name;
  private $password;

  public function getName()
  {
    return $this->name;
  }

}

  $link = mysql_connect('localhost', '******', '*****');
  $db = mysql_select_db('objtest', $link);

  $sql = "SELECT * FROM user WHERE id=1";
  $res = mysql_query($sql, $link);

  $lal = mysql_fetch_object($res, 'user');

  print_r($lal);
?>


code:
1
2
3
4
5
6
7
(greyfox@cinna)~/test $php test.php
user Object
(
    [id:private] => 1
    [name:private] => GreyFox
    [password:private] => 0123456789abcdef
)


Dan zit je niet eens met de overhead om eerst een array te vullen vanuit de mysql function call om daarna je object aan te maken.

[ Voor 4% gewijzigd door Janoz op 18-06-2007 15:32 . Reden: Zie /oisyn's opmerking verder naar beneden. Just to be sure... ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

Verwijderd

Brakkie schreef op maandag 18 juni 2007 @ 14:26:
[...]


Check doctrine eens, redelijk volwassen OR mapper voor php.

http://www.phpdoctrine.net/doctrine/manual/new/
Persoonlijk vind ik dat de tijd die het kost om zo'n stukje software te begrijpen en toe te kunnen passen in combinatie met de eventuele fouten en hiaten veelal langer duren dan zelf iets maken. Je eigen oplossing is dan mischien niet geheel feilloos of supergoed, het is wel de code die je snapt en waar je sneller fouten in kunt opsporen.

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Verwijderd schreef op maandag 18 juni 2007 @ 15:07:
[...]


Persoonlijk vind ik dat de tijd die het kost om zo'n stukje software te begrijpen en toe te kunnen passen in combinatie met de eventuele fouten en hiaten veelal langer duren dan zelf iets maken. Je eigen oplossing is dan mischien niet geheel feilloos of supergoed, het is wel de code die je snapt en waar je sneller fouten in kunt opsporen.
Je moet dus nooit libraries gebruiken?

Systeem | Strava


Acties:
  • 0 Henk 'm!

Verwijderd

Nooit is een groot woord.
Vaak wil je snel ergens een oplossing op en ga je zoeken op internet. Je struikelt dan over de halfbakken oplossingen en ergens in een forum komt iemand aanlopen met een pakket zoals jij net deed. Als je dat dan gaat installeren en gebruiken dan los je niet gelijk je probleem op maar creeer je eigenlijk alleen maar nieuwe. Je moet alles goed doorlezen (vaak sla je dat zoveel mogelijk over) , je gaat wat testen en er komt dan wat uit wat net niet voldoet aan je wensen. Vervolgens sla je aan het aanpassen, terwijl als je het goed bekijkt je al zover was. Immers wat er als output uitkwam voldeed niet aan je wensen en dat was de reden dat je ging zoeken.

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Grijze Vos schreef op maandag 18 juni 2007 @ 13:15:
Ik zal even kijken of ik een voorbeeld kan schetsen.
Neem even forum software als voorbeeld. Je hebt users, en je hebt forum topics, forum posts.

Nu wil ik alle posts uit een topic, inclusief de user informatie. Nu moet ik in de DAL een functie schrijven die voor elke post de userinfo ophaalt, en hier een object van maakt en teruggeeft.

Een manier is om een user object te creeren adhv het userID, en die aan je post object te hangen, maar dit geeft dan dus een query explosie. De andere manier is om inderdaad een query te maken die al die data in 1x queried, en dan alle post en user objecten aanmaakt, maar dan zit je toch al niet meer zo heel ver van die request-based methode af? Het enige verschil is dan dat jij een zak objecten creeert, en in de andere methode dus een associatief array wordt gegeven.
Ik zie niet zo goed waarom het tweede geval persé uit associative array zou gebruiken? In het voorbeeld dat jij schets gebruik ik :

PHP:
1
2
$p = new Post(); // Eigenlijk zou je het met een static willen doen, maarja php-nukken  he ;)
$posts_set = $p->findAll(array('topic_id' => 5));


$posts is nu een non-associative array met gewoon alle Post objecten die aan de condition voldoen. Verder staat er in mijn post class :

PHP:
1
2
3
4
class Post extends Model {
  public belongsTo = array('Author' => array('className' =>'User'));
  // ... Verder is niet er niet zoveel nodig, alles wordt uit geerfd uit Model
}


De mapper weet nu dat er een 1-op-1 relatie is tussen een post en een user, en dat die de naam 'Author' heeft. Eén op één relaties zijn makkelijk; die prefetcht hij automagisch door een mooie join te genereren, dus daar kan kan je gewoon gebruiken

PHP:
1
2
3
4
5
6
7
8
$author = $posts[0]->Author; // En dat is dus een volledig user object. 
// Je kan dan ook weer doen :
$posts = $author->Posts // En dan heb je weer een set met posts van deze user :P
// En dan
$topic = $posts[0]->Topic // En dan heb je weer een Topic object :P
// En dan 
$topicstarter = $topic->Starter // Deze was geprefetcht met een join, 1-op-1 relatie
$posts = $topic->Posts // Deze worden pas bij deze aanroep opgehaald, want 1-op-n


Dan heb je dus hardstikke netjes geneste objecten, waarbij je maar één query gebruikt hebt voor een set met objecten en hun bijbehorende 1 op 1 relaties. :) En dan heb ik voor al deze objecten nog geen millimeter specifieke SQL hoeven schrijven ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Brakkie schreef op maandag 18 juni 2007 @ 15:08:
Je moet dus nooit libraries gebruiken?
Tsja het hoeft niet direct zo zwart-wit. Ik vind persoonlijk dat doctrine geen mooi spul want het is een 'tightly-coupled' framework. En in die zin helemaal niet vergelijkbaar met een OR mapper als Hibernate. Het ontbreken van die verdomde applicatie scope zorgt er ook voor dat het maken van een mapping definitie als overbodig aanvoelt. Misschien dat die verschillende optimizer lagen de impact van het keer op keer herdefinieren van de mapping doet verwaarlozen, maar het blijft gewoon niet goed voelen. Hoewel ik mijn vinger nog niet op de zere plek weet te leggen.
eamelink schreef op maandag 18 juni 2007 @ 15:17:
En dan heb ik voor al deze objecten nog geen millimeter specifieke SQL hoeven schrijven ;)
Persoonlijk vind ik het niet hoeven schrijven van specifieke SQL zo'n beetje het slechtste argument wat je kunt gebruiken om een OR-mapper in te zetten. Je zet een OR-mapper in om de 'tedious job' van het mappen van een resultset naar een object uit handen te nemen. Geen wonder dat een fatsoenlijke OR mapper je behoorlijk veel vrijheid geeft in het opbouwen van queries (hibernate kent bijvoorbeeld criteria, hibernate query language en plain old sql).

[ Voor 31% gewijzigd door Verwijderd op 18-06-2007 15:25 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik weet niet of je een random salt gebruikt voor je MD5 of of dat niet je echte wachtwoord is, maar het is wellicht toch handig om die hash even weg te halen :)

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!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
.oisyn schreef op maandag 18 juni 2007 @ 15:21:
[...]


Ik weet niet of je een random salt gebruikt voor je MD5 of of dat niet je echte wachtwoord is, maar het is wellicht toch handig om die hash even weg te halen :)
Oh, da's de MD5 hash van '1234', is maar testdata. ;)

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

oooh, je pincode. Ok, dat geeft idd niets :+

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!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

Verwijderd schreef op maandag 18 juni 2007 @ 15:19:
Persoonlijk vind ik het niet hoeven schrijven van specifieke SQL zo'n beetje het slechtste argument wat je kunt gebruiken om een OR-mapper in te zetten. Je zet een OR-mapper in om de 'tedious job' van het mappen van een resultset naar een object uit handen te nemen.
Dat niet alleen, een OR mapper moet ook kunnen omgaan met geneste objecten die zich vertalen in meerdere tabellen in een relationele db. Als het slechts het mappen van een resultset naar een object was, dan kom je al een heel eind met de functie mysql_fetch_object zoals Grijze Vos laat zien.
Geen wonder dat een fatsoenlijke OR mapper je behoorlijk veel vrijheid geeft in het opbouwen van queries (hibernate kent bijvoorbeeld criteria, hibernate query language en plain old sql).
Allicht, maar dat betekent niet dat het de bedoeling is om heel regelmatig eigen SQL erin te kloppen. Normaliter gebruik je de criteria, pas als dat niet meer voldoende flexibel is of niet de juiste performance oplevert ga je zelf aan de slag met SQL. Het zit er voornamelijk in voor de flexibiliteit :)
Verwijderd schreef op maandag 18 juni 2007 @ 15:14:
Nooit is een groot woord.
Vaak wil je snel ergens een oplossing op en ga je zoeken op internet. Je struikelt dan over de halfbakken oplossingen en ergens in een forum komt iemand aanlopen met een pakket zoals jij net deed. Als je dat dan gaat installeren en gebruiken dan los je niet gelijk je probleem op maar creeer je eigenlijk alleen maar nieuwe. Je moet alles goed doorlezen (vaak sla je dat zoveel mogelijk over) , je gaat wat testen en er komt dan wat uit wat net niet voldoet aan je wensen. Vervolgens sla je aan het aanpassen, terwijl als je het goed bekijkt je al zover was. Immers wat er als output uitkwam voldeed niet aan je wensen en dat was de reden dat je ging zoeken.
Ach, de keuze van je methode van interactie met de database valt niet echt onder het kopje 'vaak wil je snel ergens een oplossing op'. Er zijn namelijk geen problemen die je kan oplossen met een OR mapper, de boel wordt er alleen een stuk makkelijker op :P. Maar die keuze maak je over het algemeen voordat je met een applicatie start en dan heb je genoeg tijd om te kijken welke methode je wilt gebruiken en gaat het 'even snel' niet op :)

[ Voor 34% gewijzigd door eamelink op 18-06-2007 16:29 ]


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Grijze Vos schreef op maandag 18 juni 2007 @ 15:03:
Goede punten hebben jullie. Ik heb net even wat zitten experimenteren, en kwam erachter dat dit kon:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class user
{
  private $id;
  private $name;
  private $password;

  public function getName()
  {
    return $this->name;
  }

}

  $link = mysql_connect('localhost', '******', '*****');
  $db = mysql_select_db('objtest', $link);

  $sql = "SELECT * FROM user WHERE id=1";
  $res = mysql_query($sql, $link);

  $lal = mysql_fetch_object($res, 'user');

  print_r($lal);
?>


code:
1
2
3
4
5
6
7
(greyfox@cinna)~/test $php test.php
user Object
(
    [id:private] => 1
    [name:private] => GreyFox
    [password:private] => 0123456789abcdef
)


Dan zit je niet eens met de overhead om eerst een array te vullen vanuit de mysql function call om daarna je object aan te maken.
Dat is nog sneller, op de een of andere manier heb ik daar niet eens aan gedacht :x

Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
MBV schreef op maandag 18 juni 2007 @ 16:42:
[...]

Dat is nog sneller, op de een of andere manier heb ik daar niet eens aan gedacht :x
Ik bedacht me toen we hier aan het discussieren waren dat dit wel handig zou zijn om te kunnen, en toen zag ik in de docs staan dat dit sinds 5.0.0 is toegevoegd. ;) (Was al bang dat ik ranzig moest gaan hacken om dit gedaan te krijgen.)

[ Voor 9% gewijzigd door Grijze Vos op 18-06-2007 17:40 ]

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • MBV
  • Registratie: Februari 2002
  • Laatst online: 20-09 22:44
Wat ik zelf heb gedaan in een joomla-module: een rij van het query-resultaat meegeven in de constructor, en in de constructor de velden eruit halen. Dan kan ik in de constructor wat dingen aanpassen, wat natuurlijk ook in de getter/setter functies zou kunnen. Hmm, ik zou het kunnen omschrijven. Tja, het werkt al hè? :P
Pagina: 1