[PHP] Verwerken querystring lukt niet helemaal

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik probeer de volgende URL: http://www.site.com?q=producten/groenten/winter/ te verwerken in een array met de volgende code:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
 * Splits $_GET['q'] en vul $_GET aan met de logische delen van q
 */
if (isset($_GET['q']))
{
  $q  = explode('$', $_GET['q']);
  $qs = explode('/', $q[0]);

  $_GET['arg'] = Array();
  $_GET['pad'] = Array();

  if (is_numeric($qs[0]))
  {
    for ($i = 1; $i < count($qs); $i++)
      $_GET['arg'][] = $qs[$i]; 
    $_GET['pad'][] = $url[0];
  }
  else
  {
    for ($i = 0; $i < count($qs); $i++)
    {
      if (is_numeric($qs[$i])) $_GET['arg'][] = $qs[$i]; 
      else $_GET['pad'][] = $qs[$i];
    }
  }

  if (isset($q[1]))
  {
    $_GET['ext'] = explode(':', $q[1]);
  }

  if (isset($_GET['pad']))
    $_GET['full_pad'] = rtrim(implode('/', $_GET['pad']), '/');
  
  if (isset($_GET['arg']))
    $_GET['full_arg'] = implode('/', $_GET['arg']);
    
  if (isset($_GET['eext']))
    $_GET['full_ext'] = implode(':', $_GET['ext']);
}


Ik verwacht als output (print_r($_GET)):

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Array
(
    [q] => producten/groenten/winter/
    [arg] => Array
        (
        )

    [pad] => Array
        (
            [0] => producten
            [1] => groenten
            [2] => winter
        )

    [full_pad] => producten/groenten/winter
    [full_arg] => 
)


Maar ik krijg:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Array
(
    [q] => producten/groenten/winter/
    [arg] => Array
        (
        )

    [pad] => Array
        (
            [0] => producten
            [1] => groenten
            [2] => winter
            [3] => 
        )

    [full_pad] => producten/groenten/winter
    [full_arg] => 
)


Met andere woorden: de laatste slash in de URL zorgt ervoor dat pad[3] aangemaakt wordt. Als de URL http://www.site.com?q=producten/groenten/winter is (zonder laatste slash), wordt het wel goed verwerkt. Ik heb al geprobeerd om eerst die laatste slash eraf te trimmen, maar doe het waarschijnlijk niet goed. Wie kan mij helpen?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Eerst even dit: het is common practice om input parameters niet een nieuwe waarde te geven. Ik zou dus een nieuwe variabel maken en die met waardes gaan vullen in plaats van $_GET. Anders ga je op een anders stuk van de code denken dat die waardes ook werkelijk via de url zijn meegeven terwijl dit niet het geval is.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Cavorka
  • Registratie: April 2003
  • Laatst online: 27-03-2018

Cavorka

Internet Entrepreneur

Ik heb al geprobeerd om eerst die laatste slash eraf te trimmen, maar doe het waarschijnlijk niet goed. Wie kan mij helpen?
PHP:
1
2
3
if(substr($_GET['q'], -1) == "/") { 
    $_GET['q'] = substr($_GET['q'], 0, (strlen($_GET['q']) - 1)) ; 
}


Ik kan dit even niet testen alleen...

[ Voor 88% gewijzigd door Cavorka op 22-11-2004 17:33 ]

the-blueprints.com - The largest free blueprint collection on the internet: 50000+ drawings.


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
@Michali - het idee is dat ik zo weinig mogelijk variabelen expliciet wil globallen in elke functie. Omdat $_GET een superglobal is, ben ik van dat gedoe af :) Jouw argument snijdt overigens ook wel hout...maar wat zou er tegen zijn te denken dat die variabelen ook echt uit de querystring komen?

@Cavorka: waarom lukt het jou wel en mij niet? Ik ga na wat je gedaan hebt... :) Dank je!

[ Voor 15% gewijzigd door Reveller op 22-11-2004 17:38 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Reveller schreef op maandag 22 november 2004 @ 17:37:
@Michali - het idee is dat ik zo weinig mogelijk variabelen expliciet wil globallen in elke functie. Omdat $_GET een superglobal is, ben ik van dat gedoe af :) Jouw argument snijdt overigens ook wel hout...maar wat zou er tegen zijn te denken dat die variabelen ook echt uit de querystring komen?
Ja maar dat zijn ze simpel weg niet. Stel dat je een anders stuk van de code zou lezen en dit nog niet hebt gelezen. Dan is het vrij verwarrend als je ziet dat die variabelen wel uit de url lijken te komen, maar ze dat toch niet zijn. 1 extra global variabel verhelpt het hele probleem. Dan heb je gewoon het minimum want dit is toch echt af te raden. Hier heb je ook gewoon de $GLOBALS array voor.

[ Voor 3% gewijzigd door Michali op 22-11-2004 17:42 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 14:27
Cavorka schreef op maandag 22 november 2004 @ 17:31:
[...]

PHP:
1
2
3
if(substr($_GET['q'], -1) == "/") { 
    $_GET['q'] = substr($_GET['q'], 0, (strlen($_GET['q']) - 1)) ; 
}


Ik kan dit even niet testen alleen...
Dat kan volgens mij nog veel makkelijker:
PHP:
1
$_GET['q'] = rtrim($_GET['q'], '/');

Regeren is vooruitschuiven


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Nu ik het toch over array's heb - ik zit al een tijdje met de volgende vraag en volgens mij is er geen kant-en-klare PHP functie voor. Stel ik heb de volgende array:
PHP:
1
2
3
4
$navitems[100] = Array('parent'=>  0, 'name'=>'Locatie',     'href'=>'locatie.php');
$navitems[101] = Array('parent'=>117, 'name'=>'Route',       'href'=>'route.php');
$navitems[102] = Array('parent'=>110, 'name'=>'Plattegrond', 'href'=>'plattegrond.php');
$navitems[103] = Array('parent'=>199, 'name'=>'Fotopagina',  'href'=>'fotos.php');

Stel dat ik wil weten welke parent het navitem met de naam "Plattegrond" heeft. Als de array geen array maar een database tabel zou zijn, zou ik vragen:
PHP:
1
2
$query  = "SELECT parent FROM navitems WHERE name = 'Plattegrond'";
$parent = mysql_result($query, 0);

Als ik dezelfde info uit de array wil trekken, moet ik mijns inziens moeilijk gaan doen met functies als current() en key():
PHP:
1
2
3
4
5
6
7
while ($name = current($navitems))
{
   if ($name == 'Plattegrond') {
       echo key($navitems);
   }
   next($navitems);
}

Maar dan ben ik er nog niet. Bestaat er geen makkelijker manier?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • b19a
  • Registratie: September 2002
  • Niet online
Probeer het zo eens:
PHP:
1
2
3
4
5
6
7
while($item=each($navitems))
{
  if($item['name']=='Plattegrond')
  {
    var_dump($item);
  }
}

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Reveller schreef op maandag 22 november 2004 @ 18:06:
Als ik dezelfde info uit de array wil trekken, moet ik mijns inziens moeilijk gaan doen met functies als current() en key():
PHP:
1
2
3
4
5
6
7
while ($name = current($navitems))
{
   if ($name == 'Plattegrond') {
       echo key($navitems);
   }
   next($navitems);
}

Maar dan ben ik er nog niet. Bestaat er geen makkelijker manier?
PHP:
1
2
3
4
5
6
7
foreach ( $navitems as $item )
{
  if ( $item['name'] == "Plattegrond" )
  {
    // Doe je ding
  }
}

Das toch niets zo erg :? En je zegt dat je er dan nog niet bent. Wat wil je precies als resultaat hebben dan? Ik kan het verder niet uit je post halen.

[ Voor 4% gewijzigd door Michali op 22-11-2004 19:01 ]

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Michali schreef op maandag 22 november 2004 @ 19:01:
[...]
En je zegt dat je er dan nog niet bent. Wat wil je precies als resultaat hebben dan? Ik kan het verder niet uit je post halen.
Ik zal de situatie wat uiteen zetten. In een tabel heb ik dmv child-parent relaties een boomstructuur opgeslagen. Gedurende de applicatie wil ik een heleboel doen met de nodes uit die tabel: een navigatiemenu en cookie crumb trail bouwen bijvoorbeeld.

In het begin gebruikte ik hiervoor een functie die recursief door de database tabel ging (standaard methode), maar dit kwam al snel op 10 of meer queries per pagina en dat vond ik wat onzinnig. Daarom doe ik het nu anders: bij elke request haal ik met 1 query alle nodes op uit de tabel en stop die in een array ongeveer gelijk aan die hierboven.

Op verschillende plaatsen binnen de applicatie heb ik gegevens nodig uit die array, en ik vroeg mij dus af of het niet mogelijk is die array te "querien". Met andere woorden - dat ik een soortgelijke query op de array af kan vuren als wat ik normaal op de database zou doen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$navitems[100] = Array('parent'=>  0, 'name'=>'Locatie',     'href'=>'locatie.php');
$navitems[101] = Array('parent'=>117, 'name'=>'Route',       'href'=>'route.php');
$navitems[102] = Array('parent'=>110, 'name'=>'Plattegrond', 'href'=>'plattegrond.php');
$navitems[103] = Array('parent'=>199, 'name'=>'Fotopagina',  'href'=>'fotos.php'); 

function query_array($array, $select, $clause)
{
   // voer query uit op array
}

/**
 * Ik wil een resultaat terugkrijgen van een query als 
 * SELECT parent FROM navitems WHERE name = 'Plattegrond'. 
 * De functie moet de array doorlopen en mij "110" retourneren
 */

$parent = query_array($navitems, 'parent', 'Plattegrond');

Ik hoop dat het nu wat duidelijker is. Kort gezegd: een functie om queries op een array uit te kunnen voeren alsof je een database tabel aanspreekt...

[ Voor 10% gewijzigd door Reveller op 22-11-2004 19:46 ]

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Als je arrays makkelijk kon "queryen" dan waren relationele databases een beetje overbodig, niet?

Daarom gebruik je (My)SQL, als je wilt queryen. ;)

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


Acties:
  • 0 Henk 'm!

  • b19a
  • Registratie: September 2002
  • Niet online
PHP:
1
2
3
4
5
6
7
8
9
<?
while(list($k,$item)=each($navitems))
{
  if($item['name']=='Plattegrond')
  {
    var_dump($item);
  }
}
?>

Heb je deze code al eens geprobeert? Deze zou je de juiste array moeten geven!

Dus jij wilt:
PHP:
1
2
3
4
5
6
7
8
9
<?
while(list($k,$item)=each($navitems))
{
  if($item['name']=='Plattegrond')
  {
    return $item['parent'];
  }
}
?>


@GrijzeVos: heb jij iets tegen op while i.c.m. each? :P

edit:
klein foutje

[ Voor 33% gewijzigd door b19a op 22-11-2004 19:54 ]


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$navitems[100] = Array('parent'=>  0, 'name'=>'Locatie',     'href'=>'locatie.php');
$navitems[101] = Array('parent'=>117, 'name'=>'Route',       'href'=>'route.php');
$navitems[102] = Array('parent'=>110, 'name'=>'Plattegrond', 'href'=>'plattegrond.php');
$navitems[103] = Array('parent'=>199, 'name'=>'Fotopagina',  'href'=>'fotos.php'); 

function query_array($array, $select, $clause)
{
  foreach($array as $bla)
  {
    if($bla["name"] == $clause)
     {
      return (isset($bla[$select]) ? $bla[$select] : false);
     }
  }
  return false;
}

$parent = query_array($navitems, 'parent', 'Plattegrond');


Overigens, als je op meer dingen dan alleen "name" wilt "queryen", dan moet je nog even een variabele toevoegen aan de functie:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
function query_array($array, $select, $clausekey, $clause)
{
  foreach($array as $bla)
  {
    if($bla[$clausekey] == $clause)
     {
      return (isset($bla[$select]) ? $bla[$select] : false);
     }
  }
  return false;
}

$parent = query_array($navitems, 'parent', 'name', 'Plattegrond');

[ Voor 100% gewijzigd door Grijze Vos op 22-11-2004 20:02 ]

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


Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Grijze Vos schreef op maandag 22 november 2004 @ 19:48:
Als je arrays makkelijk kon "queryen" dan waren relationele databases een beetje overbodig, niet?
Het gaat mij om twee dingen:

• de load op de database verminderen
• de parsetime terugdringen

Volgens mij is het efficienter om 1 keer alle nodes (plm. 200) op te halen, en vanaf dat moment met PHP de array door te spitten dan telkens een gang naar de database te maken. Je script moet immers wel op de uitkomst daavan "wachten".

Misschien is de winst maar minimaal, maar alle minimale winsten bij elkaar zorgt toch voor een betere applicatie in mijn ogen.

Als ik er overigens naast zit, en telkens een gang naar de database is wel sneller, od als ik andere argumenten mis, dan hoor ik dat graag!

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • b19a
  • Registratie: September 2002
  • Niet online
Een goed uitgevogelde Query kost je maar 0,00025 seconde om uit de database te worden gehaald. Het lijkt me dus niet zo lang duren om zoiets te doen. Het duurt misschien nog wel langer om ze allemaal op te halen en in array te stoppen en dan te verwerken.

Acties:
  • 0 Henk 'm!

  • Reveller
  • Registratie: Augustus 2002
  • Laatst online: 05-12-2022
Ik heb net bij mij gemeten met een simpele select query:

• 1 query kost 0,0015 seconden
• 100 queries 0,16 seconden
• 10.000 queries 14,5 seconden

Ik had nog nooit een benchmark (hoe eenvoudig deze ook is) uitgevoerd, en het kost idd maar weinig tijd. Toch kom ik op dit forum regelmatig mensen tegen die zeggen eerst de hele bups uit de database te halen, om het daarna de output met verschillende functies te bewerken. Wat is dan het argument? Dat het beter is bij een hoog aantal concurrent users? Dat het "best practice" is?

"Real software engineers work from 9 to 5, because that is the way the job is described in the formal spec. Working late would feel like using an undocumented external procedure."


Acties:
  • 0 Henk 'm!

  • T-MOB
  • Registratie: Maart 2001
  • Laatst online: 14:27
Reveller schreef op maandag 22 november 2004 @ 21:36:
Ik heb net bij mij gemeten met een simpele select query:

• 1 query kost 0,0015 seconden
• 100 queries 0,16 seconden
• 10.000 queries 14,5 seconden

Ik had nog nooit een benchmark (hoe eenvoudig deze ook is) uitgevoerd, en het kost idd maar weinig tijd. Toch kom ik op dit forum regelmatig mensen tegen die zeggen eerst de hele bups uit de database te halen, om het daarna de output met verschillende functies te bewerken. Wat is dan het argument? Dat het beter is bij een hoog aantal concurrent users? Dat het "best practice" is?
Het argument is dat het véél sneller gaat. Natuurlijk maken 100 queries in .16 seconden geen indruk op een mens. Als je echter dezelfde output kunt genereren in .016 seconden dan ben je wél 10x zo snel. Voor een weinig bezochte website is dat inderdaad niet relevant, maar denk je eens in dat Tweakers.net 10x zoveel servercapaciteit zou moeten gaan inslaan omdat "100 queries .16 seconden" kosten. Dat is dus het concurrent users verhaal.

Daarnaast kan ik je uit ervaring (en dat voor een PHP prutz0r ;)) vertellen dat queries niet altijd in .0015 s kunnen worden uitgevoerd. Als je heel veel data nodig hebt dan duren ze gewoon langer. Als je jezelf dan hebt aangeleerd hebt om alles met queries op te lossen "omdat dat makkelijker is en toch geen resources kost" dan kom je van een koude kermis thuis. Een beetje best-practice dus ook ja...

Regeren is vooruitschuiven

Pagina: 1